]> git.sur5r.net Git - freertos/blob - Demo/ARM7_STR75x_IAR/serial/serial.c
Update to V4.6.1 - including PIC32MX port.
[freertos] / Demo / ARM7_STR75x_IAR / serial / serial.c
1 /*\r
2         FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org 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.org 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.org; 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.org, 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         See http://www.FreeRTOS.org for documentation, latest information, license\r
28         and contact details.  Please ensure to read the configuration and relevant\r
29         port sections of the online documentation.\r
30 \r
31         Also see http://www.SafeRTOS.com a version that has been certified for use\r
32         in safety critical systems, plus commercial licensing, development and\r
33         support options.\r
34         ***************************************************************************\r
35 */\r
36 \r
37 /*\r
38         BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART0.\r
39 */\r
40 \r
41 /* Library includes. */\r
42 #include "75x_uart.h"\r
43 #include "75x_gpio.h"\r
44 #include "75x_eic.h"\r
45 #include "75x_mrcc.h"\r
46 \r
47 /* Scheduler includes. */\r
48 #include "FreeRTOS.h"\r
49 #include "queue.h"\r
50 \r
51 /* Demo application includes. */\r
52 #include "serial.h"\r
53 \r
54 #define serINVALID_QUEUE                                ( ( xQueueHandle ) 0 )\r
55 #define serNO_BLOCK                                             ( ( portTickType ) 0 )\r
56 \r
57 /*-----------------------------------------------------------*/\r
58 \r
59 /* Queues used to hold received characters, and characters waiting to be\r
60 transmitted. */\r
61 static xQueueHandle xRxedChars;\r
62 static xQueueHandle xCharsForTx;\r
63 \r
64 static volatile portBASE_TYPE xQueueEmpty = pdTRUE;\r
65 \r
66 /*-----------------------------------------------------------*/\r
67 \r
68 /* The interrupt service routine - called from the assembly entry point. */\r
69 __arm void vSerialISR( void );\r
70 \r
71 /*-----------------------------------------------------------*/\r
72 \r
73 /*\r
74  * See the serial2.h header file.\r
75  */\r
76 xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )\r
77 {\r
78 xComPortHandle xReturn;\r
79 UART_InitTypeDef UART_InitStructure;\r
80 GPIO_InitTypeDef GPIO_InitStructure;\r
81 EIC_IRQInitTypeDef  EIC_IRQInitStructure;       \r
82 \r
83         /* Create the queues used to hold Rx and Tx characters. */\r
84         xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );\r
85         xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );\r
86 \r
87         /* If the queues were created correctly then setup the serial port\r
88         hardware. */\r
89         if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) )\r
90         {\r
91                 portENTER_CRITICAL();\r
92                 {\r
93                         /* Enable the UART0 Clock. */\r
94                         MRCC_PeripheralClockConfig( MRCC_Peripheral_UART0, ENABLE );\r
95                         \r
96                         /* Configure the UART0_Tx as alternate function */\r
97                         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;\r
98                         GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;\r
99                         GPIO_Init(GPIO0, &GPIO_InitStructure);\r
100                         \r
101                         /* Configure the UART0_Rx as input floating */\r
102                         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;\r
103                         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;\r
104                         GPIO_Init(GPIO0, &GPIO_InitStructure);\r
105                         \r
106                         /* Configure UART0. */\r
107                         UART_InitStructure.UART_WordLength = UART_WordLength_8D;\r
108                         UART_InitStructure.UART_StopBits = UART_StopBits_1;\r
109                         UART_InitStructure.UART_Parity = UART_Parity_No;\r
110                         UART_InitStructure.UART_BaudRate = ulWantedBaud;\r
111                         UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;\r
112                         UART_InitStructure.UART_Mode = UART_Mode_Tx_Rx;\r
113                         UART_InitStructure.UART_TxFIFOLevel = UART_FIFOLevel_1_2; /* FIFO size 16 bytes, FIFO level 8 bytes */\r
114                         UART_InitStructure.UART_RxFIFOLevel = UART_FIFOLevel_1_2; /* FIFO size 16 bytes, FIFO level 8 bytes */\r
115                         UART_Init(UART0, &UART_InitStructure);\r
116 \r
117                         /* Enable the UART0 */\r
118                         UART_Cmd(UART0, ENABLE);\r
119 \r
120                         /* Configure the IEC for the UART interrupts. */                        \r
121                         EIC_IRQInitStructure.EIC_IRQChannelCmd = ENABLE;\r
122                         EIC_IRQInitStructure.EIC_IRQChannel = UART0_IRQChannel;\r
123                         EIC_IRQInitStructure.EIC_IRQChannelPriority = 1;\r
124                         EIC_IRQInit(&EIC_IRQInitStructure);\r
125                         \r
126                         xQueueEmpty = pdTRUE;\r
127                         UART_ITConfig( UART0, UART_IT_Transmit | UART_IT_Receive, ENABLE );\r
128                 }\r
129                 portEXIT_CRITICAL();\r
130         }\r
131         else\r
132         {\r
133                 xReturn = ( xComPortHandle ) 0;\r
134         }\r
135 \r
136         /* This demo file only supports a single port but we have to return\r
137         something to comply with the standard demo header file. */\r
138         return xReturn;\r
139 }\r
140 /*-----------------------------------------------------------*/\r
141 \r
142 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime )\r
143 {\r
144         /* The port handle is not required as this driver only supports one port. */\r
145         ( void ) pxPort;\r
146 \r
147         /* Get the next character from the buffer.  Return false if no characters\r
148         are available, or arrive before xBlockTime expires. */\r
149         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
150         {\r
151                 return pdTRUE;\r
152         }\r
153         else\r
154         {\r
155                 return pdFALSE;\r
156         }\r
157 }\r
158 /*-----------------------------------------------------------*/\r
159 \r
160 void vSerialPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength )\r
161 {\r
162 signed portCHAR *pxNext;\r
163 \r
164         /* A couple of parameters that this port does not use. */\r
165         ( void ) usStringLength;\r
166         ( void ) pxPort;\r
167 \r
168         /* NOTE: This implementation does not handle the queue being full as no\r
169         block time is used! */\r
170 \r
171         /* The port handle is not required as this driver only supports UART0. */\r
172         ( void ) pxPort;\r
173 \r
174         /* Send each character in the string, one at a time. */\r
175         pxNext = ( signed portCHAR * ) pcString;\r
176         while( *pxNext )\r
177         {\r
178                 xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );\r
179                 pxNext++;\r
180         }\r
181 }\r
182 /*-----------------------------------------------------------*/\r
183 \r
184 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime )\r
185 {\r
186 portBASE_TYPE xReturn;\r
187 \r
188         /* Place the character in the queue of characters to be transmitted. */\r
189         portENTER_CRITICAL();\r
190         {\r
191                 if( xQueueEmpty == pdTRUE )\r
192                 {\r
193                         UART0->DR = cOutChar;\r
194                         xReturn = pdPASS;\r
195                 }\r
196                 else\r
197                 {\r
198                         if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )\r
199                         {\r
200                                 xReturn = pdFAIL;\r
201                         }                       \r
202                         else\r
203                         {\r
204                                 xReturn = pdPASS;                               \r
205                         }\r
206                 }\r
207                 \r
208                 xQueueEmpty = pdFALSE;\r
209         }\r
210         portEXIT_CRITICAL();\r
211 \r
212         return xReturn;\r
213 }\r
214 /*-----------------------------------------------------------*/\r
215 \r
216 void vSerialClose( xComPortHandle xPort )\r
217 {\r
218         /* Not supported as not required by the demo application. */\r
219 }\r
220 /*-----------------------------------------------------------*/\r
221 \r
222 __arm void vSerialISR( void )\r
223 {\r
224 signed portCHAR cChar;\r
225 portBASE_TYPE xTaskWokenByTx = pdFALSE, xTaskWokenByPost = pdFALSE;\r
226 \r
227         do\r
228         {\r
229                 if( UART0->MIS & UART_IT_Transmit )\r
230                 {\r
231                         /* The interrupt was caused by the THR becoming empty.  Are there any\r
232                         more characters to transmit? */\r
233                         if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xTaskWokenByTx ) == pdTRUE )\r
234                         {\r
235                                 /* A character was retrieved from the queue so can be sent to the\r
236                                 THR now. */\r
237                                 UART0->DR = cChar;\r
238                         }\r
239                         else\r
240                         {\r
241                                 xQueueEmpty = pdTRUE;           \r
242                         }               \r
243 \r
244                         UART_ClearITPendingBit( UART0, UART_IT_Transmit );\r
245                 }\r
246         \r
247                 if( UART0->MIS & UART_IT_Receive )\r
248                 {\r
249                         /* The interrupt was caused by a character being received.  Grab the\r
250                         character from the RHR and place it in the queue of received\r
251                         characters. */\r
252                         cChar = UART0->DR;\r
253                         xTaskWokenByPost = xQueueSendFromISR( xRxedChars, &cChar, xTaskWokenByPost );\r
254                         UART_ClearITPendingBit( UART0, UART_IT_Receive );\r
255                 }\r
256         } while( UART0->MIS );\r
257 \r
258         /* If a task was woken by either a character being received or a character\r
259         being transmitted then we may need to switch to another task. */\r
260         portEND_SWITCHING_ISR( ( xTaskWokenByPost || xTaskWokenByTx ) );\r
261 }\r
262 \r
263 \r
264 \r
265 \r
266 \r
267         \r