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