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 port 1.
\r
73 Note that this driver is written to test the RTOS port and is not intended
\r
74 to represent an optimised solution. In particular no use is made of the DMA
\r
77 /* Standard include files. */
\r
80 /* Scheduler include files. */
\r
81 #include "FreeRTOS.h"
\r
85 /* Demo application include files. */
\r
88 /* The queues used to communicate between the task code and the interrupt
\r
89 service routines. */
\r
90 static QueueHandle_t xRxedChars;
\r
91 static QueueHandle_t xCharsForTx;
\r
93 /* Hardware specific constants. */
\r
94 #define serTX_INTERRUPT ( ( unsigned char ) 0x80 )
\r
95 #define serRX_INTERRUPT ( ( unsigned char ) 0x40 )
\r
96 #define serTX_ENABLE ( ( unsigned char ) 0x20 )
\r
97 #define serRX_ENABLE ( ( unsigned char ) 0x10 )
\r
99 /* Macros to turn on and off the serial port THRE interrupt while leaving the
\r
100 other register bits in their correct state. The Rx interrupt is always
\r
102 #define serTX_INTERRUPT_ON() SCR1 = serTX_INTERRUPT | serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;
\r
103 #define serTX_INTERRUPT_OFF() SCR1 = serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;
\r
105 /* Bit used to switch on the channel 1 serial port in the module stop
\r
107 #define serMSTP6 ( ( unsigned short ) 0x0040 )
\r
109 /* Interrupt service routines. Note that the Rx and Tx service routines can
\r
110 cause a context switch and are therefore defined with the saveall attribute in
\r
111 addition to the interrupt_handler attribute. See the FreeRTOS.org WEB site
\r
112 documentation for a full explanation.*/
\r
113 void vCOM_1_Rx_ISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );
\r
114 void vCOM_1_Tx_ISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );
\r
115 void vCOM_1_Error_ISR( void ) __attribute__ ( ( interrupt_handler ) );
\r
117 /*-----------------------------------------------------------*/
\r
120 * Initialise port 1 for interrupt driven communications.
\r
122 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
\r
124 /* Create the queues used to communicate between the tasks and the
\r
125 interrupt service routines. */
\r
126 xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
\r
127 xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
\r
129 /* No parity, 8 data bits and 1 stop bit is the default so does not require
\r
130 configuration - setup the remains of the hardware. */
\r
131 portENTER_CRITICAL();
\r
133 /* Turn channel 1 on. */
\r
134 MSTPCR &= ~serMSTP6;
\r
136 /* Enable the channels and the Rx interrupt. The Tx interrupt is only
\r
137 enabled when data is being transmitted. */
\r
138 SCR1 = serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;
\r
140 /* Bit rate settings for 22.1184MHz clock only!. */
\r
141 switch( ulWantedBaud )
\r
143 case 4800 : BRR1 = 143;
\r
145 case 9600 : BRR1 = 71;
\r
147 case 19200 : BRR1 = 35;
\r
149 case 38400 : BRR1 = 17;
\r
151 case 57600 : BRR1 = 11;
\r
153 case 115200 : BRR1 = 5;
\r
155 default : BRR1 = 5;
\r
159 portEXIT_CRITICAL();
\r
161 /* Unlike some ports, this driver code does not allow for more than one
\r
162 com port. We therefore don't return a pointer to a port structure and can
\r
163 instead just return NULL. */
\r
166 /*-----------------------------------------------------------*/
\r
168 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )
\r
170 /* Get the next character from the buffer queue. Return false if no characters
\r
171 are available, or arrive before xBlockTime expires. */
\r
172 if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
\r
181 /*-----------------------------------------------------------*/
\r
183 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
\r
185 signed portBASE_TYPE xReturn = pdPASS;
\r
187 /* Return false if after the block time there is no room on the Tx queue. */
\r
188 portENTER_CRITICAL();
\r
190 /* Send a character to the queue of characters waiting transmission.
\r
191 The queue is serviced by the Tx ISR. */
\r
192 if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
\r
194 /* Could not post onto the queue. */
\r
199 /* The message was posted onto the queue so we turn on the Tx
\r
200 interrupt to allow the Tx ISR to remove the character from the
\r
202 serTX_INTERRUPT_ON();
\r
205 portEXIT_CRITICAL();
\r
209 /*-----------------------------------------------------------*/
\r
211 void vSerialClose( xComPortHandle xPort )
\r
213 /* Not supported. */
\r
216 /*-----------------------------------------------------------*/
\r
218 void vCOM_1_Rx_ISR( void )
\r
220 /* This can cause a context switch so this macro must be the first line
\r
221 in the function. */
\r
222 portENTER_SWITCHING_ISR();
\r
224 /* As this is a switching ISR the local variables must be declared as
\r
226 static char cRxByte;
\r
227 static portBASE_TYPE xHigherPriorityTaskWoken;
\r
229 xHigherPriorityTaskWoken = pdFALSE;
\r
231 /* Get the character. */
\r
234 /* Post the character onto the queue of received characters - noting
\r
235 whether or not this wakes a task. */
\r
236 xQueueSendFromISR( xRxedChars, &cRxByte, &xHigherPriorityTaskWoken );
\r
238 /* Clear the interrupt. */
\r
239 SSR1 &= ~serRX_INTERRUPT;
\r
241 /* This must be the last line in the function. We pass cTaskWokenByPost so
\r
242 a context switch will occur if the received character woke a task that has
\r
243 a priority higher than the task we interrupted. */
\r
244 portEXIT_SWITCHING_ISR( xHigherPriorityTaskWoken );
\r
246 /*-----------------------------------------------------------*/
\r
248 void vCOM_1_Tx_ISR( void )
\r
250 /* This can cause a context switch so this macro must be the first line
\r
251 in the function. */
\r
252 portENTER_SWITCHING_ISR();
\r
254 /* As this is a switching ISR the local variables must be declared as
\r
256 static char cTxByte;
\r
257 static signed portBASE_TYPE xTaskWokenByTx;
\r
259 /* This variable is static so must be explicitly reinitialised each
\r
260 time the function executes. */
\r
261 xTaskWokenByTx = pdFALSE;
\r
263 /* The interrupt was caused by the THR becoming empty. Are there any
\r
264 more characters to transmit? Note whether or not the Tx interrupt has
\r
266 if( xQueueReceiveFromISR( xCharsForTx, &cTxByte, &xTaskWokenByTx ) == pdTRUE )
\r
268 /* A character was retrieved from the queue so can be sent to the
\r
272 /* Clear the interrupt. */
\r
273 SSR1 &= ~serTX_INTERRUPT;
\r
277 /* Queue empty, nothing to send so turn off the Tx interrupt. */
\r
278 serTX_INTERRUPT_OFF();
\r
281 /* This must be the last line in the function. We pass cTaskWokenByTx so
\r
282 a context switch will occur if the Tx'ed character woke a task that has
\r
283 a priority higher than the task we interrupted. */
\r
284 portEXIT_SWITCHING_ISR( xTaskWokenByTx );
\r
286 /*-----------------------------------------------------------*/
\r
289 * This ISR cannot cause a context switch so requires no special
\r
292 void vCOM_1_Error_ISR( void )
\r
294 volatile unsigned char ucIn;
\r