2 FreeRTOS V9.0.0 - Copyright (C) 2016 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 ***************************************************************************
\r
14 >>! NOTE: The modification to the GPL is included to allow you to !<<
\r
15 >>! distribute a combined work that includes FreeRTOS without being !<<
\r
16 >>! obliged to provide the source code for proprietary components !<<
\r
17 >>! outside of the FreeRTOS kernel. !<<
\r
18 ***************************************************************************
\r
20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
\r
23 link: http://www.freertos.org/a00114.html
\r
25 ***************************************************************************
\r
27 * FreeRTOS provides completely free yet professionally developed, *
\r
28 * robust, strictly quality controlled, supported, and cross *
\r
29 * platform software that is more than just the market leader, it *
\r
30 * is the industry's de facto standard. *
\r
32 * Help yourself get started quickly while simultaneously helping *
\r
33 * to support the FreeRTOS project by purchasing a FreeRTOS *
\r
34 * tutorial book, reference manual, or both: *
\r
35 * http://www.FreeRTOS.org/Documentation *
\r
37 ***************************************************************************
\r
39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
\r
40 the FAQ page "My application does not run, what could be wrong?". Have you
\r
41 defined configASSERT()?
\r
43 http://www.FreeRTOS.org/support - In return for receiving this top quality
\r
44 embedded software for free we request you assist our global community by
\r
45 participating in the support forum.
\r
47 http://www.FreeRTOS.org/training - Investing in training allows your team to
\r
48 be as productive as possible as early as possible. Now you can receive
\r
49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
\r
50 Ltd, and the world's leading authority on the world's leading RTOS.
\r
52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
\r
54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
\r
56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
\r
57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
\r
59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
\r
60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
\r
61 licenses offer ticketed support, indemnification and commercial middleware.
\r
63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
\r
64 engineered and independently SIL3 certified version for use in safety and
\r
65 mission critical applications that require provable dependability.
\r
71 BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART1.
\r
74 /* Library includes. */
\r
75 #include "91x_lib.h"
\r
77 /* Scheduler includes. */
\r
78 #include "FreeRTOS.h"
\r
82 /* Demo application includes. */
\r
84 /*-----------------------------------------------------------*/
\r
87 #define serINVALID_QUEUE ( ( QueueHandle_t ) 0 )
\r
88 #define serNO_BLOCK ( ( TickType_t ) 0 )
\r
89 #define serTX_BLOCK_TIME ( 40 / portTICK_PERIOD_MS )
\r
91 /* Interrupt and status bit definitions. */
\r
92 #define mainTXRIS 0x20
\r
93 #define mainRXRIS 0x50
\r
94 #define serTX_FIFO_FULL 0x20
\r
95 #define serCLEAR_ALL_INTERRUPTS 0x3ff
\r
96 /*-----------------------------------------------------------*/
\r
98 /* The queue used to hold received characters. */
\r
99 static QueueHandle_t xRxedChars;
\r
101 /* The semaphore used to wake a task waiting for space to become available
\r
103 static SemaphoreHandle_t xTxFIFOSemaphore;
\r
105 /*-----------------------------------------------------------*/
\r
107 /* UART interrupt handler. */
\r
108 void UART1_IRQHandler( void );
\r
110 /* The interrupt service routine - called from the assembly entry point. */
\r
111 __arm void UART1_IRQHandler( void );
\r
113 /*-----------------------------------------------------------*/
\r
115 /* Flag to indicate whether or not a task is blocked waiting for space on
\r
117 static long lTaskWaiting = pdFALSE;
\r
120 * See the serial2.h header file.
\r
122 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
\r
124 xComPortHandle xReturn;
\r
125 UART_InitTypeDef xUART1_Init;
\r
126 GPIO_InitTypeDef GPIO_InitStructure;
\r
128 /* Create the queues used to hold Rx characters. */
\r
129 xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
\r
131 /* Create the semaphore used to wake a task waiting for space to become
\r
132 available in the FIFO. */
\r
133 vSemaphoreCreateBinary( xTxFIFOSemaphore );
\r
135 /* If the queue/semaphore was created correctly then setup the serial port
\r
137 if( ( xRxedChars != serINVALID_QUEUE ) && ( xTxFIFOSemaphore != serINVALID_QUEUE ) )
\r
139 /* Pre take the semaphore so a task will block if it tries to access
\r
141 xSemaphoreTake( xTxFIFOSemaphore, 0 );
\r
143 /* Configure the UART. */
\r
144 xUART1_Init.UART_WordLength = UART_WordLength_8D;
\r
145 xUART1_Init.UART_StopBits = UART_StopBits_1;
\r
146 xUART1_Init.UART_Parity = UART_Parity_No;
\r
147 xUART1_Init.UART_BaudRate = ulWantedBaud;
\r
148 xUART1_Init.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
\r
149 xUART1_Init.UART_Mode = UART_Mode_Tx_Rx;
\r
150 xUART1_Init.UART_FIFO = UART_FIFO_Enable;
\r
152 /* Enable the UART1 Clock */
\r
153 SCU_APBPeriphClockConfig( __UART1, ENABLE );
\r
155 /* Enable the GPIO3 Clock */
\r
156 SCU_APBPeriphClockConfig( __GPIO3, ENABLE );
\r
158 /* Configure UART1_Rx pin GPIO3.2 */
\r
159 GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
\r
160 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
\r
161 GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
\r
162 GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
\r
163 GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1 ;
\r
164 GPIO_Init( GPIO3, &GPIO_InitStructure );
\r
166 /* Configure UART1_Tx pin GPIO3.3 */
\r
167 GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
\r
168 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
\r
169 GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
\r
170 GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
\r
171 GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2 ;
\r
172 GPIO_Init( GPIO3, &GPIO_InitStructure );
\r
175 portENTER_CRITICAL();
\r
177 /* Configure the UART itself. */
\r
178 UART_DeInit( UART1 );
\r
179 UART_Init( UART1, &xUART1_Init );
\r
180 UART_ITConfig( UART1, UART_IT_Receive | UART_IT_Transmit, ENABLE );
\r
181 UART1->ICR = serCLEAR_ALL_INTERRUPTS;
\r
182 UART_LoopBackConfig( UART1, DISABLE );
\r
183 UART_IrDACmd( IrDA1, DISABLE );
\r
185 /* Configure the VIC for the UART interrupts. */
\r
186 VIC_Config( UART1_ITLine, VIC_IRQ, 9 );
\r
187 VIC_ITCmd( UART1_ITLine, ENABLE );
\r
189 UART_Cmd( UART1, ENABLE );
\r
190 lTaskWaiting = pdFALSE;
\r
192 portEXIT_CRITICAL();
\r
196 xReturn = ( xComPortHandle ) 0;
\r
199 /* This demo file only supports a single port but we have to return
\r
200 something to comply with the standard demo header file. */
\r
203 /*-----------------------------------------------------------*/
\r
205 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )
\r
207 /* The port handle is not required as this driver only supports one port. */
\r
210 /* Get the next character from the buffer. Return false if no characters
\r
211 are available, or arrive before xBlockTime expires. */
\r
212 if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
\r
221 /*-----------------------------------------------------------*/
\r
223 void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )
\r
225 signed char *pxNext;
\r
227 /* A couple of parameters that this port does not use. */
\r
228 ( void ) usStringLength;
\r
231 /* NOTE: This implementation does not handle the queue being full as no
\r
232 block time is used! */
\r
234 /* The port handle is not required as this driver only supports UART1. */
\r
237 /* Send each character in the string, one at a time. */
\r
238 pxNext = ( signed char * ) pcString;
\r
241 xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );
\r
245 /*-----------------------------------------------------------*/
\r
247 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
\r
249 portBASE_TYPE xReturn;
\r
251 portENTER_CRITICAL();
\r
253 /* Can we write to the FIFO? */
\r
254 if( UART1->FR & serTX_FIFO_FULL )
\r
256 /* Wait for the interrupt letting us know there is space on the
\r
257 FIFO. It is ok to block in a critical section, interrupts will be
\r
258 enabled for other tasks once we force a switch. */
\r
259 lTaskWaiting = pdTRUE;
\r
261 /* Just to be a bit different this driver uses a semaphore to
\r
262 block the sending task when the FIFO is full. The standard COMTest
\r
263 task assumes a queue of adequate length exists so does not use
\r
264 a block time. For this demo the block time is therefore hard
\r
266 xReturn = xSemaphoreTake( xTxFIFOSemaphore, serTX_BLOCK_TIME );
\r
269 UART1->DR = cOutChar;
\r
274 UART1->DR = cOutChar;
\r
278 portEXIT_CRITICAL();
\r
282 /*-----------------------------------------------------------*/
\r
284 void vSerialClose( xComPortHandle xPort )
\r
286 /* Not supported as not required by the demo application. */
\r
288 /*-----------------------------------------------------------*/
\r
290 void UART1_IRQHandler( void )
\r
293 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
\r
295 while( UART1->RIS & mainRXRIS )
\r
297 /* The interrupt was caused by a character being received. Grab the
\r
298 character from the DR and place it in the queue of received
\r
301 xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
\r
304 if( UART1->RIS & mainTXRIS )
\r
306 if( lTaskWaiting == pdTRUE )
\r
308 /* This interrupt was caused by space becoming available on the Tx
\r
309 FIFO, wake any task that is waiting to post (if any). */
\r
310 xSemaphoreGiveFromISR( xTxFIFOSemaphore, &xHigherPriorityTaskWoken );
\r
311 lTaskWaiting = pdFALSE;
\r
314 UART1->ICR = mainTXRIS;
\r
317 /* If a task was woken by either a character being received or a character
\r
318 being transmitted then we may need to switch to another task. */
\r
319 portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
\r