2 FreeRTOS V8.2.0rc1 - Copyright (C) 2014 Real Time Engineers Ltd.
\r
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 This file is part of the FreeRTOS distribution.
\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
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
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
25 ***************************************************************************
\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
30 * http://www.FreeRTOS.org/FAQHelp.html *
\r
32 ***************************************************************************
\r
34 ***************************************************************************
\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
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
46 ***************************************************************************
\r
48 ***************************************************************************
\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
62 ***************************************************************************
\r
64 ***************************************************************************
\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
73 ***************************************************************************
\r
75 http://www.FreeRTOS.org - Documentation, books, training, latest versions,
\r
76 license and Real Time Engineers Ltd. contact details.
\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
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
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
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
97 BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART1.
\r
100 /* Library includes. */
\r
101 #include "91x_lib.h"
\r
103 /* Scheduler includes. */
\r
104 #include "FreeRTOS.h"
\r
106 #include "semphr.h"
\r
108 /* Demo application includes. */
\r
109 #include "serial.h"
\r
110 /*-----------------------------------------------------------*/
\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
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
124 /* The queue used to hold received characters. */
\r
125 static QueueHandle_t xRxedChars;
\r
127 /* The semaphore used to wake a task waiting for space to become available
\r
129 static SemaphoreHandle_t xTxFIFOSemaphore;
\r
131 /*-----------------------------------------------------------*/
\r
133 /* UART interrupt handler. */
\r
134 void UART1_IRQHandler( void );
\r
136 /* The interrupt service routine - called from the assembly entry point. */
\r
137 __arm void UART1_IRQHandler( void );
\r
139 /*-----------------------------------------------------------*/
\r
141 /* Flag to indicate whether or not a task is blocked waiting for space on
\r
143 static long lTaskWaiting = pdFALSE;
\r
146 * See the serial2.h header file.
\r
148 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
\r
150 xComPortHandle xReturn;
\r
151 UART_InitTypeDef xUART1_Init;
\r
152 GPIO_InitTypeDef GPIO_InitStructure;
\r
154 /* Create the queues used to hold Rx characters. */
\r
155 xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
\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
161 /* If the queue/semaphore was created correctly then setup the serial port
\r
163 if( ( xRxedChars != serINVALID_QUEUE ) && ( xTxFIFOSemaphore != serINVALID_QUEUE ) )
\r
165 /* Pre take the semaphore so a task will block if it tries to access
\r
167 xSemaphoreTake( xTxFIFOSemaphore, 0 );
\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
178 /* Enable the UART1 Clock */
\r
179 SCU_APBPeriphClockConfig( __UART1, ENABLE );
\r
181 /* Enable the GPIO3 Clock */
\r
182 SCU_APBPeriphClockConfig( __GPIO3, ENABLE );
\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
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
201 portENTER_CRITICAL();
\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
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
215 UART_Cmd( UART1, ENABLE );
\r
216 lTaskWaiting = pdFALSE;
\r
218 portEXIT_CRITICAL();
\r
222 xReturn = ( xComPortHandle ) 0;
\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
229 /*-----------------------------------------------------------*/
\r
231 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )
\r
233 /* The port handle is not required as this driver only supports one port. */
\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
247 /*-----------------------------------------------------------*/
\r
249 void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )
\r
251 signed char *pxNext;
\r
253 /* A couple of parameters that this port does not use. */
\r
254 ( void ) usStringLength;
\r
257 /* NOTE: This implementation does not handle the queue being full as no
\r
258 block time is used! */
\r
260 /* The port handle is not required as this driver only supports UART1. */
\r
263 /* Send each character in the string, one at a time. */
\r
264 pxNext = ( signed char * ) pcString;
\r
267 xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );
\r
271 /*-----------------------------------------------------------*/
\r
273 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
\r
275 portBASE_TYPE xReturn;
\r
277 portENTER_CRITICAL();
\r
279 /* Can we write to the FIFO? */
\r
280 if( UART1->FR & serTX_FIFO_FULL )
\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
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
292 xReturn = xSemaphoreTake( xTxFIFOSemaphore, serTX_BLOCK_TIME );
\r
295 UART1->DR = cOutChar;
\r
300 UART1->DR = cOutChar;
\r
304 portEXIT_CRITICAL();
\r
308 /*-----------------------------------------------------------*/
\r
310 void vSerialClose( xComPortHandle xPort )
\r
312 /* Not supported as not required by the demo application. */
\r
314 /*-----------------------------------------------------------*/
\r
316 void UART1_IRQHandler( void )
\r
319 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
\r
321 while( UART1->RIS & mainRXRIS )
\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
327 xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
\r
330 if( UART1->RIS & mainTXRIS )
\r
332 if( lTaskWaiting == pdTRUE )
\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
340 UART1->ICR = mainTXRIS;
\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