]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/ARM7_AT91FR40008_GCC/serial/serial.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / ARM7_AT91FR40008_GCC / serial / serial.c
1 /*\r
2     FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.\r
3         \r
4 \r
5     ***************************************************************************\r
6      *                                                                       *\r
7      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
8      *    Complete, revised, and edited pdf reference manuals are also       *\r
9      *    available.                                                         *\r
10      *                                                                       *\r
11      *    Purchasing FreeRTOS documentation will not only help you, by       *\r
12      *    ensuring you get running as quickly as possible and with an        *\r
13      *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
14      *    the FreeRTOS project to continue with its mission of providing     *\r
15      *    professional grade, cross platform, de facto standard solutions    *\r
16      *    for microcontrollers - completely free of charge!                  *\r
17      *                                                                       *\r
18      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
19      *                                                                       *\r
20      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
21      *                                                                       *\r
22     ***************************************************************************\r
23 \r
24 \r
25     This file is part of the FreeRTOS distribution.\r
26 \r
27     FreeRTOS is free software; you can redistribute it and/or modify it under\r
28     the terms of the GNU General Public License (version 2) as published by the\r
29     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
30     >>>NOTE<<< The modification to the GPL is included to allow you to\r
31     distribute a combined work that includes FreeRTOS without being obliged to\r
32     provide the source code for proprietary components outside of the FreeRTOS\r
33     kernel.  FreeRTOS is distributed in the hope that it will be useful, but\r
34     WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
35     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
36     more details. You should have received a copy of the GNU General Public\r
37     License and the FreeRTOS license exception along with FreeRTOS; if not it\r
38     can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
39     by writing to Richard Barry, contact details for whom are available on the\r
40     FreeRTOS WEB site.\r
41 \r
42     1 tab == 4 spaces!\r
43     \r
44     ***************************************************************************\r
45      *                                                                       *\r
46      *    Having a problem?  Start by reading the FAQ "My application does   *\r
47      *    not run, what could be wrong?                                      *\r
48      *                                                                       *\r
49      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
50      *                                                                       *\r
51     ***************************************************************************\r
52 \r
53     \r
54     http://www.FreeRTOS.org - Documentation, training, latest information, \r
55     license and contact details.\r
56     \r
57     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
58     including FreeRTOS+Trace - an indispensable productivity tool.\r
59 \r
60     Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
61     the code with commercial support, indemnification, and middleware, under \r
62     the OpenRTOS brand: http://www.OpenRTOS.com.  High Integrity Systems also\r
63     provide a safety engineered and independently SIL3 certified version under \r
64     the SafeRTOS brand: http://www.SafeRTOS.com.\r
65 */\r
66 \r
67 /* \r
68         BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR USART0. \r
69 \r
70         This file contains all the serial port components that can be compiled to\r
71         either ARM or THUMB mode.  Components that must be compiled to ARM mode are\r
72         contained in serialISR.c.\r
73 */\r
74 \r
75 /* Standard includes. */\r
76 #include <stdlib.h>\r
77 \r
78 /* Scheduler includes. */\r
79 #include "FreeRTOS.h"\r
80 #include "queue.h"\r
81 #include "task.h"\r
82 \r
83 /* Demo application includes. */\r
84 #include "serial.h"\r
85 #include "AT91R40008.h"\r
86 #include "usart.h"\r
87 #include "pio.h"\r
88 #include "aic.h"\r
89 \r
90 /*-----------------------------------------------------------*/\r
91 \r
92 /* Constants to setup and access the UART. */\r
93 #define portUSART0_AIC_CHANNEL  ( ( unsigned long ) 2 )\r
94 \r
95 #define serINVALID_QUEUE                ( ( xQueueHandle ) 0 )\r
96 #define serHANDLE                               ( ( xComPortHandle ) 1 )\r
97 #define serNO_BLOCK                             ( ( portTickType ) 0 )\r
98 \r
99 /*-----------------------------------------------------------*/\r
100 \r
101 /* Queues used to hold received characters, and characters waiting to be\r
102 transmitted. */\r
103 static xQueueHandle xRxedChars; \r
104 static xQueueHandle xCharsForTx; \r
105 \r
106 /*-----------------------------------------------------------*/\r
107 \r
108 /* \r
109  * The queues are created in serialISR.c as they are used from the ISR.\r
110  * Obtain references to the queues and THRE Empty flag. \r
111  */\r
112 extern void vSerialISRCreateQueues(  unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxRxedChars, xQueueHandle *pxCharsForTx );\r
113 \r
114 /*-----------------------------------------------------------*/\r
115 \r
116 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )\r
117 {\r
118 unsigned long ulSpeed;\r
119 unsigned long ulCD;\r
120 xComPortHandle xReturn = serHANDLE;\r
121 extern void ( vUART_ISR_Wrapper )( void );\r
122 \r
123         /* The queues are used in the serial ISR routine, so are created from\r
124         serialISR.c (which is always compiled to ARM mode. */\r
125         vSerialISRCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx );\r
126 \r
127         if( \r
128                 ( xRxedChars != serINVALID_QUEUE ) && \r
129                 ( xCharsForTx != serINVALID_QUEUE ) && \r
130                 ( ulWantedBaud != ( unsigned long ) 0 ) \r
131           )\r
132         {\r
133                 portENTER_CRITICAL();\r
134                 {\r
135                         /* Enable clock to USART0... */\r
136                         AT91C_BASE_PS->PS_PCER = AT91C_PS_US0;\r
137 \r
138                         /* Disable all USART0 interrupt sources to begin... */\r
139                         AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;\r
140 \r
141                         /* Reset various status bits (just in case)... */\r
142                         AT91C_BASE_US0->US_CR = US_RSTSTA;\r
143 \r
144                         AT91C_BASE_PIO->PIO_PDR = TXD0 | RXD0;  /* Enable RXD and TXD pins */\r
145                         AT91C_BASE_US0->US_CR = US_RSTRX | US_RSTTX | US_RXDIS | US_TXDIS;\r
146 \r
147                         /* Clear Transmit and Receive Counters */\r
148                         AT91C_BASE_US0->US_RCR = 0;\r
149                         AT91C_BASE_US0->US_TCR = 0;\r
150 \r
151                         /* Input clock to baud rate generator is MCK */\r
152                         ulSpeed = configCPU_CLOCK_HZ * 10;  \r
153                         ulSpeed = ulSpeed / 16;\r
154                         ulSpeed = ulSpeed / ulWantedBaud;\r
155                         \r
156                         /* compute the error */\r
157                         ulCD  = ulSpeed / 10;\r
158                         if ((ulSpeed - (ulCD * 10)) >= 5)\r
159                         ulCD++;\r
160 \r
161                         /* Define the baud rate divisor register */\r
162                         AT91C_BASE_US0->US_BRGR = ulCD;\r
163 \r
164                         /* Define the USART mode */\r
165                         AT91C_BASE_US0->US_MR = US_CLKS_MCK | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1 | US_CHMODE_NORMAL;\r
166 \r
167                         /* Write the Timeguard Register */\r
168                         AT91C_BASE_US0->US_TTGR = 0;\r
169 \r
170                         /* Setup the interrupt for USART0.\r
171 \r
172                         Store interrupt handler function address in USART0 vector register... */\r
173                         AT91C_BASE_AIC->AIC_SVR[ portUSART0_AIC_CHANNEL ] = (unsigned long)vUART_ISR_Wrapper;\r
174                         \r
175                         /* USART0 interrupt level-sensitive, priority 1... */\r
176                         AT91C_BASE_AIC->AIC_SMR[ portUSART0_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 1;\r
177                         \r
178                         /* Clear some pending USART0 interrupts (just in case)... */\r
179                         AT91C_BASE_US0->US_CR = US_RSTSTA;\r
180 \r
181                         /* Enable USART0 interrupt sources (but not Tx for now)... */\r
182                         AT91C_BASE_US0->US_IER = US_RXRDY;\r
183 \r
184                         /* Enable USART0 interrupts in the AIC... */\r
185                         AT91C_BASE_AIC->AIC_IECR = ( 1 << portUSART0_AIC_CHANNEL );\r
186 \r
187                         /* Enable receiver and transmitter... */\r
188                         AT91C_BASE_US0->US_CR = US_RXEN | US_TXEN;\r
189                 }\r
190                 portEXIT_CRITICAL();\r
191         }\r
192         else\r
193         {\r
194                 xReturn = ( xComPortHandle ) 0;\r
195         }\r
196 \r
197         return xReturn;\r
198 }\r
199 /*-----------------------------------------------------------*/\r
200 \r
201 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime )\r
202 {\r
203         /* The port handle is not required as this driver only supports UART0. */\r
204         ( void ) pxPort;\r
205 \r
206         /* Get the next character from the buffer.  Return false if no characters\r
207         are available, or arrive before xBlockTime expires. */\r
208         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
209         {\r
210                 return pdTRUE;\r
211         }\r
212         else\r
213         {\r
214                 return pdFALSE;\r
215         }\r
216 }\r
217 /*-----------------------------------------------------------*/\r
218 \r
219 void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )\r
220 {\r
221 signed char *pxNext;\r
222 \r
223         /* NOTE: This implementation does not handle the queue being full as no\r
224         block time is used! */\r
225 \r
226         /* The port handle is not required as this driver only supports UART0. */\r
227         ( void ) pxPort;\r
228         ( void ) usStringLength;\r
229 \r
230         /* Send each character in the string, one at a time. */\r
231         pxNext = ( signed char * ) pcString;\r
232         while( *pxNext )\r
233         {\r
234                 xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );\r
235                 pxNext++;\r
236         }\r
237 }\r
238 /*-----------------------------------------------------------*/\r
239 \r
240 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime )\r
241 {\r
242         ( void ) pxPort;\r
243 \r
244         /* Place the character in the queue of characters to be transmitted. */\r
245         if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )\r
246         {\r
247                 return pdFAIL;\r
248         }\r
249 \r
250         /* Turn on the Tx interrupt so the ISR will remove the character from the\r
251         queue and send it.   This does not need to be in a critical section as\r
252         if the interrupt has already removed the character the next interrupt\r
253         will simply turn off the Tx interrupt again. */\r
254         AT91C_BASE_US0->US_IER = US_TXRDY;\r
255 \r
256         return pdPASS;\r
257 }\r
258 /*-----------------------------------------------------------*/\r
259 \r
260 void vSerialClose( xComPortHandle xPort )\r
261 {\r
262         /* Not supported as not required by the demo application. */\r
263         ( void ) xPort;\r
264 }\r
265 /*-----------------------------------------------------------*/\r
266 \r