OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [MCF5235_GCC/] [system/] [serial.c] - Blame information for rev 591

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 584 jeremybenn
/*
2
    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.
3
 
4
    This file is part of the FreeRTOS distribution.
5
 
6
    FreeRTOS is free software; you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License** as published by
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    FreeRTOS is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with FreeRTOS; if not, write to the Free Software
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
20
    A special exception to the GPL can be applied should you wish to distribute
21
    a combined work that includes FreeRTOS, without being obliged to provide
22
    the source code for any proprietary components.  See the licensing section
23
    of http://www.FreeRTOS.org for full details of how and when the exception
24
    can be applied.
25
 
26
    ***************************************************************************
27
    ***************************************************************************
28
    *                                                                         *
29
    * Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *
30
        *                                                                         *
31
        * This is a concise, step by step, 'hands on' guide that describes both   *
32
        * general multitasking concepts and FreeRTOS specifics. It presents and   *
33
        * explains numerous examples that are written using the FreeRTOS API.     *
34
        * Full source code for all the examples is provided in an accompanying    *
35
        * .zip file.                                                              *
36
    *                                                                         *
37
    ***************************************************************************
38
    ***************************************************************************
39
 
40
        Please ensure to read the configuration and relevant port sections of the
41
        online documentation.
42
 
43
        http://www.FreeRTOS.org - Documentation, latest information, license and
44
        contact details.
45
 
46
        http://www.SafeRTOS.com - A version that is certified for use in safety
47
        critical systems.
48
 
49
        http://www.OpenRTOS.com - Commercial support, development, porting,
50
        licensing and training services.
51
*/
52
 
53
/* ------------------------ MCF523x includes ------------------------------ */
54
#include "mcf5xxx.h"
55
#include "mcf523x.h"
56
 
57
/* ------------------------ FreeRTOS includes ----------------------------- */
58
#include "FreeRTOS.h"
59
#include "queue.h"
60
#include "task.h"
61
 
62
#include "serial.h"
63
 
64
/* ----------------------- Defines ----------------------------------------- */
65
#define BAUDRATE_VALUE(fsys, baud)      ( ( fsys )/(32UL * baud) )
66
#define MCF_UART_VECTOR                 ( 64 + 13 )
67
#define COM_NIFACE                      1
68
#define COM_BLOCK_RETRYTIME             10
69
 
70
/* ------------------------ Static functions ------------------------------ */
71
static void     prvSerialISR( void );
72
 
73
/* ------------------------ Static variables ------------------------------ */
74
typedef struct
75
{
76
    portBASE_TYPE xInitialized;
77
    xQueueHandle xRXChars;
78
    xQueueHandle xTXChars;
79
} xComPortIF_t;
80
 
81
static xComPortIF_t xComPortIF[ COM_NIFACE ];
82
 
83
/* ------------------------ Begin implementation -------------------------- */
84
xComPortHandle
85
xSerialPortInitMinimal( unsigned long ulWantedBaud,
86
                        unsigned portBASE_TYPE uxQueueLength )
87
{
88
    extern void     ( *__RAMVEC[] ) (  );
89
    xComPortHandle xReturn;
90
    portBASE_TYPE xOldIPL;
91
 
92
    /* Create the queues used to hold Rx and Tx characters. */
93
    xComPortIF[ 0 ].xRXChars =
94
        xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE )sizeof( signed char ) );
95
    xComPortIF[ 0 ].xTXChars =
96
        xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE )sizeof( signed char ) );
97
 
98
    /* If the queues were created correctly then setup the serial port hardware. */
99
    if( ( xComPortIF[ 0 ].xRXChars != 0 ) && ( xComPortIF[ 0 ].xTXChars != 0 ) )
100
    {
101
        xOldIPL = portSET_IPL( portIPL_MAX );
102
 
103
        /* UART 0: Reset transmitter, receiver and mode register pointer */
104
        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x3 );
105
        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x2 );
106
        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x1 );
107
 
108
        /* Enable receive interrupts. */
109
        MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;
110
 
111
        /* 8 Databits, 1 Stopbit and no parity */
112
        MCF_UART_UMR0 = MCF_UART_UMR_PM( 0x3 ) | MCF_UART_UMR_SB( 0x7 ) | MCF_UART_UMR_BC( 0x3 );
113
 
114
        /* UART 0 Clocking */
115
        MCF_UART_UCSR0 = MCF_UART_UCSR_RCS( 0xd ) | MCF_UART_UCSR_TCS( 0xd );
116
        MCF_UART_UBG10 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) >> 8U;
117
        MCF_UART_UBG20 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) & 0xFFU;
118
 
119
        /* UART 0: Enable interrupts */
120
        __RAMVEC[MCF_UART_VECTOR] = prvSerialISR;
121
        MCF_INTC0_ICR13 = MCF_INTC0_ICRn_IL( 0x2 ) | MCF_INTC0_ICRn_IP( 0x1 );
122
        MCF_INTC0_IMRL &= ~MCF_INTC0_IMRL_INT_MASK13;
123
 
124
        /* UART 0 Miscellaneous */
125
        MCF_UART_UACR0 = 0;
126
 
127
        /* UART 0: Enable pins */
128
        MCF_GPIO_PAR_UART = MCF_GPIO_PAR_UART_PAR_U0RXD | MCF_GPIO_PAR_UART_PAR_U0TXD;
129
 
130
        /* Enable the UART. */
131
        MCF_UART_UCR0 = MCF_UART_UCR_RXC( 0x1 ) | MCF_UART_UCR_TXC( 0x1 );
132
 
133
        xComPortIF[ 0 ].xInitialized = TRUE;
134
        xReturn = ( xComPortHandle ) &xComPortIF[ 0 ];
135
 
136
        ( void )portSET_IPL( xOldIPL );
137
    }
138
    else
139
    {
140
        xReturn = ( xComPortHandle ) 0;
141
    }
142
 
143
    return xReturn;
144
}
145
 
146
signed          portBASE_TYPE
147
xSerialGetChar( xComPortHandle pxPort, signed char * pcRxedChar,
148
                portTickType xBlockTime )
149
{
150
    int i;
151
    portBASE_TYPE xResult = pdFALSE;
152
    /* Lookup the correct interface. */
153
    for( i = 0; i < COM_NIFACE; i++ )
154
    {
155
        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
156
        {
157
            break;
158
        }
159
    }
160
    /* This COM port is available. */
161
    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )
162
    {
163
        /* Get the next character from the buffer.  Return false if no characters
164
         * are available, or arrive before xBlockTime expires.
165
         */
166
        if( xQueueReceive( xComPortIF[ i ].xRXChars, pcRxedChar, xBlockTime ) )
167
        {
168
            xResult = pdTRUE;
169
        }
170
    }
171
    return xResult;
172
}
173
 
174
void
175
vSerialPutString( xComPortHandle pxPort, const signed char *
176
                  const pcString, unsigned short usStringLength )
177
{
178
    int i;
179
    signed char *pChNext;
180
 
181
    /* Send each character in the string, one at a time. */
182
    pChNext = ( signed char * )pcString;
183
    for( i = 0; i < usStringLength; i++ )
184
    {
185
        /* Block until character has been transmitted. */
186
        while( xSerialPutChar( pxPort, *pChNext, COM_BLOCK_RETRYTIME ) != pdTRUE ); pChNext++;
187
    }
188
}
189
 
190
signed          portBASE_TYPE
191
xSerialPutChar( xComPortHandle pxPort, signed char cOutChar,
192
                portTickType xBlockTime )
193
{
194
    int i;
195
    portBASE_TYPE xResult = pdFALSE;
196
    portBASE_TYPE xOldIPL;
197
    /* Lookup the correct interface. */
198
    for( i = 0; i < COM_NIFACE; i++ )
199
    {
200
        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
201
        {
202
            break;
203
        }
204
    }
205
    /* This COM port is available. */
206
    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )
207
    {
208
        /* Place the character in the queue of characters to be transmitted. */
209
        if( xQueueSend( xComPortIF[ i ].xTXChars, &cOutChar, xBlockTime ) == pdPASS )
210
        {
211
            /* Turn on the Tx interrupt so the ISR will remove the character from the
212
             * queue and send it. */
213
            MCF_UART_UIMR0 = MCF_UART_UIMR_TXRDY | MCF_UART_UIMR_RXRDY_FU;
214
            xResult = pdTRUE;
215
        }
216
    }
217
    return xResult;
218
}
219
 
220
signed          portBASE_TYPE
221
xSerialPutCharNOISR( xComPortHandle pxPort, signed char cOutChar )
222
{
223
    int i;
224
    portBASE_TYPE xResult = pdFALSE;
225
    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );
226
    /* Lookup the correct interface. */
227
    for( i = 0; i < COM_NIFACE; i++ )
228
    {
229
        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
230
        {
231
            break;
232
        }
233
    }
234
    /* This COM port is available. Support for this only available for COM1 right now. */
235
    if( ( i != COM_NIFACE ) && ( i == 0 ) )
236
    {
237
        /* Wait until the transmit buffer is ready. */
238
        while( !( MCF_UART_USR0 & MCF_UART_USR_TXRDY ) );
239
        /* Place the character in the transmit buffer. */
240
        MCF_UART_UTB0 = cOutChar;
241
        xResult = pdTRUE;
242
    }
243
    ( void )portSET_IPL( xOldIPL );
244
    return xResult;
245
}
246
 
247
void
248
vSerialPutStringNOISR( xComPortHandle pxPort, const signed char *
249
                       const pcString, unsigned short usStringLength )
250
{
251
    int i;
252
    signed char *pChNext;
253
    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );
254
 
255
    /* Send each character in the string, one at a time. */
256
    pChNext = ( signed char * )pcString;
257
    for( i = 0; i < usStringLength; i++ )
258
    {
259
        /* Block until character has been transmitted. */
260
        while( xSerialPutCharNOISR( pxPort, *pChNext ) != pdTRUE );
261
        pChNext++;
262
    }
263
    ( void )portSET_IPL( xOldIPL );
264
}
265
 
266
void
267
vSerialClose( xComPortHandle xPort )
268
{
269
    /* Not supported as not required by the demo application. */
270
}
271
 
272
void
273
prvSerialISR( void )
274
{
275
    static signed char cChar;
276
    static portBASE_TYPE xHigherPriorityTaskWoken;
277
 
278
    /* We have to remvoe the effect of the GCC. Please note that the
279
     * __attribute__ ((interrupt_handler)) does not work here because we
280
     * have to do the storing of the registers ourself. Another problem
281
     * is the usage of a frame pointer which is unlinked on entry.
282
     */
283
#if _GCC_USES_FP == 1
284
    asm volatile ( "unlk %fp\n\t" );
285
#endif
286
    /* This ISR can cause a context switch, so the first statement must be
287
     * a call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
288
     * variable declarations.
289
     */
290
    portENTER_SWITCHING_ISR();
291
        xHigherPriorityTaskWoken = pdFALSE;
292
 
293
    /* Ready to send a character from the buffer. */
294
    if( MCF_UART_USR0 & MCF_UART_USR_TXRDY )
295
    {
296
        /* Transmit buffer is ready. Test if there are characters available. */
297
        if( xQueueReceiveFromISR( xComPortIF[ 0 ].xTXChars, &cChar, &xHigherPriorityTaskWoken ) ==
298
            pdTRUE )
299
        {
300
            /* A character was retrieved from the queue so can be sent. */
301
            MCF_UART_UTB0 = cChar;
302
        }
303
        else
304
        {
305
            /* Leave only receiver enabled. */
306
            MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;
307
        }
308
    }
309
    if( MCF_UART_USR0 & MCF_UART_USR_RXRDY )
310
    {
311
        cChar = MCF_UART_URB0;
312
        xQueueSendFromISR( xComPortIF[ 0].xRXChars, &cChar, &xHigherPriorityTaskWoken );
313
    }
314
    /* Exit the ISR.  If a task was woken by either a character being
315
     * or transmitted then a context switch will occur.
316
     */
317
    portEXIT_SWITCHING_ISR( xHigherPriorityTaskWoken );
318
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.