]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/ARM9_STR91X_IAR/serial/serial.c
6af9c126576c0227cf292cb3fd147663597aee02
[freertos] / FreeRTOS / Demo / ARM9_STR91X_IAR / serial / serial.c
1 /*\r
2     FreeRTOS V8.2.0rc1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
12 \r
13     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
14     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
15     >>!   obliged to provide the source code for proprietary components     !<<\r
16     >>!   outside of the FreeRTOS kernel.                                   !<<\r
17 \r
18     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
19     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
20     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
21     link: http://www.freertos.org/a00114.html\r
22 \r
23     1 tab == 4 spaces!\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    Having a problem?  Start by reading the FAQ "My application does   *\r
28      *    not run, what could be wrong?".  Have you defined configASSERT()?  *\r
29      *                                                                       *\r
30      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
31      *                                                                       *\r
32     ***************************************************************************\r
33 \r
34     ***************************************************************************\r
35      *                                                                       *\r
36      *    FreeRTOS provides completely free yet professionally developed,    *\r
37      *    robust, strictly quality controlled, supported, and cross          *\r
38      *    platform software that is more than just the market leader, it     *\r
39      *    is the industry's de facto standard.                               *\r
40      *                                                                       *\r
41      *    Help yourself get started quickly while simultaneously helping     *\r
42      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
43      *    tutorial book, reference manual, or both:                          *\r
44      *    http://www.FreeRTOS.org/Documentation                              *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     ***************************************************************************\r
49      *                                                                       *\r
50      *   Investing in training allows your team to be as productive as       *\r
51      *   possible as early as possible, lowering your overall development    *\r
52      *   cost, and enabling you to bring a more robust product to market     *\r
53      *   earlier than would otherwise be possible.  Richard Barry is both    *\r
54      *   the architect and key author of FreeRTOS, and so also the world's   *\r
55      *   leading authority on what is the world's most popular real time     *\r
56      *   kernel for deeply embedded MCU designs.  Obtaining your training    *\r
57      *   from Richard ensures your team will gain directly from his in-depth *\r
58      *   product knowledge and years of usage experience.  Contact Real Time *\r
59      *   Engineers Ltd to enquire about the FreeRTOS Masterclass, presented  *\r
60      *   by Richard Barry:  http://www.FreeRTOS.org/contact\r
61      *                                                                       *\r
62     ***************************************************************************\r
63 \r
64     ***************************************************************************\r
65      *                                                                       *\r
66      *    You are receiving this top quality software for free.  Please play *\r
67      *    fair and reciprocate by reporting any suspected issues and         *\r
68      *    participating in the community forum:                              *\r
69      *    http://www.FreeRTOS.org/support                                    *\r
70      *                                                                       *\r
71      *    Thank you!                                                         *\r
72      *                                                                       *\r
73     ***************************************************************************\r
74 \r
75     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
76     license and Real Time Engineers Ltd. contact details.\r
77 \r
78     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
79     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
80     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
81 \r
82     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
83     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
84 \r
85     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
86     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
87     licenses offer ticketed support, indemnification and commercial middleware.\r
88 \r
89     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
90     engineered and independently SIL3 certified version for use in safety and\r
91     mission critical applications that require provable dependability.\r
92 \r
93     1 tab == 4 spaces!\r
94 */\r
95 \r
96 /*\r
97         BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART1.\r
98 */\r
99 \r
100 /* Library includes. */\r
101 #include "91x_lib.h"\r
102 \r
103 /* Scheduler includes. */\r
104 #include "FreeRTOS.h"\r
105 #include "queue.h"\r
106 #include "semphr.h"\r
107 \r
108 /* Demo application includes. */\r
109 #include "serial.h"\r
110 /*-----------------------------------------------------------*/\r
111 \r
112 /* Misc defines. */\r
113 #define serINVALID_QUEUE                                ( ( QueueHandle_t ) 0 )\r
114 #define serNO_BLOCK                                             ( ( TickType_t ) 0 )\r
115 #define serTX_BLOCK_TIME                                ( 40 / portTICK_PERIOD_MS )\r
116 \r
117 /* Interrupt and status bit definitions. */\r
118 #define mainTXRIS 0x20  \r
119 #define mainRXRIS 0x50\r
120 #define serTX_FIFO_FULL 0x20\r
121 #define serCLEAR_ALL_INTERRUPTS 0x3ff\r
122 /*-----------------------------------------------------------*/\r
123 \r
124 /* The queue used to hold received characters. */\r
125 static QueueHandle_t xRxedChars;\r
126 \r
127 /* The semaphore used to wake a task waiting for space to become available\r
128 in the FIFO. */\r
129 static SemaphoreHandle_t xTxFIFOSemaphore;\r
130 \r
131 /*-----------------------------------------------------------*/\r
132 \r
133 /* UART interrupt handler. */\r
134 void UART1_IRQHandler( void );\r
135 \r
136 /* The interrupt service routine - called from the assembly entry point. */\r
137 __arm void UART1_IRQHandler( void );\r
138 \r
139 /*-----------------------------------------------------------*/\r
140 \r
141 /* Flag to indicate whether or not a task is blocked waiting for space on\r
142 the FIFO. */\r
143 static long lTaskWaiting = pdFALSE;\r
144 \r
145 /*\r
146  * See the serial2.h header file.\r
147  */\r
148 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )\r
149 {\r
150 xComPortHandle xReturn;\r
151 UART_InitTypeDef xUART1_Init;\r
152 GPIO_InitTypeDef GPIO_InitStructure;\r
153         \r
154         /* Create the queues used to hold Rx characters. */\r
155         xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );\r
156         \r
157         /* Create the semaphore used to wake a task waiting for space to become\r
158         available in the FIFO. */\r
159         vSemaphoreCreateBinary( xTxFIFOSemaphore );\r
160 \r
161         /* If the queue/semaphore was created correctly then setup the serial port\r
162         hardware. */\r
163         if( ( xRxedChars != serINVALID_QUEUE ) && ( xTxFIFOSemaphore != serINVALID_QUEUE ) )\r
164         {\r
165                 /* Pre take the semaphore so a task will block if it tries to access\r
166                 it. */\r
167                 xSemaphoreTake( xTxFIFOSemaphore, 0 );\r
168                 \r
169                 /* Configure the UART. */\r
170                 xUART1_Init.UART_WordLength = UART_WordLength_8D;\r
171                 xUART1_Init.UART_StopBits = UART_StopBits_1;\r
172                 xUART1_Init.UART_Parity = UART_Parity_No;\r
173                 xUART1_Init.UART_BaudRate = ulWantedBaud;\r
174                 xUART1_Init.UART_HardwareFlowControl = UART_HardwareFlowControl_None;\r
175                 xUART1_Init.UART_Mode = UART_Mode_Tx_Rx;\r
176                 xUART1_Init.UART_FIFO = UART_FIFO_Enable;\r
177 \r
178                 /* Enable the UART1 Clock */\r
179                 SCU_APBPeriphClockConfig( __UART1, ENABLE );\r
180                 \r
181                 /* Enable the GPIO3 Clock */\r
182                 SCU_APBPeriphClockConfig( __GPIO3, ENABLE );\r
183                 \r
184                 /* Configure UART1_Rx pin GPIO3.2 */\r
185                 GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;\r
186                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;\r
187                 GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;\r
188                 GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;\r
189                 GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1 ;\r
190                 GPIO_Init( GPIO3, &GPIO_InitStructure );\r
191                 \r
192                 /* Configure UART1_Tx pin GPIO3.3 */\r
193                 GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;\r
194                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;\r
195                 GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;\r
196                 GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;\r
197                 GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2 ;\r
198                 GPIO_Init( GPIO3, &GPIO_InitStructure );\r
199                 \r
200                 \r
201                 portENTER_CRITICAL();\r
202                 {               \r
203                         /* Configure the UART itself. */\r
204                         UART_DeInit( UART1 );           \r
205                         UART_Init( UART1, &xUART1_Init );\r
206                         UART_ITConfig( UART1, UART_IT_Receive | UART_IT_Transmit, ENABLE );\r
207                         UART1->ICR = serCLEAR_ALL_INTERRUPTS;\r
208                         UART_LoopBackConfig( UART1, DISABLE );\r
209                         UART_IrDACmd( IrDA1, DISABLE );\r
210 \r
211                         /* Configure the VIC for the UART interrupts. */                        \r
212                         VIC_Config( UART1_ITLine, VIC_IRQ, 9 );\r
213                         VIC_ITCmd( UART1_ITLine, ENABLE );\r
214 \r
215                         UART_Cmd( UART1, ENABLE );                      \r
216                         lTaskWaiting = pdFALSE;\r
217                 }\r
218                 portEXIT_CRITICAL();\r
219         }\r
220         else\r
221         {\r
222                 xReturn = ( xComPortHandle ) 0;\r
223         }\r
224 \r
225         /* This demo file only supports a single port but we have to return\r
226         something to comply with the standard demo header file. */\r
227         return xReturn;\r
228 }\r
229 /*-----------------------------------------------------------*/\r
230 \r
231 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )\r
232 {\r
233         /* The port handle is not required as this driver only supports one port. */\r
234         ( void ) pxPort;\r
235 \r
236         /* Get the next character from the buffer.  Return false if no characters\r
237         are available, or arrive before xBlockTime expires. */\r
238         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
239         {\r
240                 return pdTRUE;\r
241         }\r
242         else\r
243         {\r
244                 return pdFALSE;\r
245         }\r
246 }\r
247 /*-----------------------------------------------------------*/\r
248 \r
249 void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )\r
250 {\r
251 signed char *pxNext;\r
252 \r
253         /* A couple of parameters that this port does not use. */\r
254         ( void ) usStringLength;\r
255         ( void ) pxPort;\r
256 \r
257         /* NOTE: This implementation does not handle the queue being full as no\r
258         block time is used! */\r
259 \r
260         /* The port handle is not required as this driver only supports UART1. */\r
261         ( void ) pxPort;\r
262 \r
263         /* Send each character in the string, one at a time. */\r
264         pxNext = ( signed char * ) pcString;\r
265         while( *pxNext )\r
266         {\r
267                 xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );\r
268                 pxNext++;\r
269         }\r
270 }\r
271 /*-----------------------------------------------------------*/\r
272 \r
273 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )\r
274 {\r
275 portBASE_TYPE xReturn;\r
276 \r
277         portENTER_CRITICAL();\r
278         {\r
279                 /* Can we write to the FIFO? */\r
280                 if( UART1->FR & serTX_FIFO_FULL )\r
281                 {\r
282                         /* Wait for the interrupt letting us know there is space on the\r
283                         FIFO.  It is ok to block in a critical section, interrupts will be\r
284                         enabled for other tasks once we force a switch. */\r
285                         lTaskWaiting = pdTRUE;\r
286                         \r
287                         /* Just to be a bit different this driver uses a semaphore to\r
288                         block the sending task when the FIFO is full.  The standard COMTest\r
289                         task assumes a queue of adequate length exists so does not use\r
290                         a block time.  For this demo the block time is therefore hard\r
291                         coded. */\r
292                         xReturn = xSemaphoreTake( xTxFIFOSemaphore, serTX_BLOCK_TIME );\r
293                         if( xReturn )\r
294                         {\r
295                                 UART1->DR = cOutChar;\r
296                         }\r
297                 }\r
298                 else\r
299                 {\r
300                         UART1->DR = cOutChar;\r
301                         xReturn = pdPASS;\r
302                 }\r
303         }\r
304         portEXIT_CRITICAL();\r
305 \r
306         return xReturn;\r
307 }\r
308 /*-----------------------------------------------------------*/\r
309 \r
310 void vSerialClose( xComPortHandle xPort )\r
311 {\r
312         /* Not supported as not required by the demo application. */\r
313 }\r
314 /*-----------------------------------------------------------*/\r
315 \r
316 void UART1_IRQHandler( void )\r
317 {\r
318 signed char cChar;\r
319 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
320 \r
321         while( UART1->RIS &     mainRXRIS )\r
322         {\r
323                 /* The interrupt was caused by a character being received.  Grab the\r
324                 character from the DR and place it in the queue of received\r
325                 characters. */\r
326                 cChar = UART1->DR;\r
327                 xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );\r
328         }       \r
329         \r
330         if( UART1->RIS & mainTXRIS )\r
331         {\r
332                 if( lTaskWaiting == pdTRUE )\r
333                 {\r
334                         /* This interrupt was caused by space becoming available on the Tx\r
335                         FIFO, wake any task that is waiting to post (if any). */\r
336                         xSemaphoreGiveFromISR( xTxFIFOSemaphore, &xHigherPriorityTaskWoken );\r
337                         lTaskWaiting = pdFALSE;\r
338                 }\r
339                 \r
340                 UART1->ICR = mainTXRIS;\r
341         }\r
342 \r
343         /* If a task was woken by either a character being received or a character\r
344         being transmitted then we may need to switch to another task. */\r
345         portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );\r
346 }\r
347 \r
348 \r
349 \r
350 \r
351 \r
352         \r