]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/H8S/RTOSDemo/serial/serial.c
Update version numbers to V7.4.1.
[freertos] / FreeRTOS / Demo / H8S / RTOSDemo / serial / serial.c
1 /*\r
2     FreeRTOS V7.4.1 - Copyright (C) 2013 Real Time Engineers Ltd.\r
3 \r
4     FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT\r
5     http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
10      *    Complete, revised, and edited pdf reference manuals are also       *\r
11      *    available.                                                         *\r
12      *                                                                       *\r
13      *    Purchasing FreeRTOS documentation will not only help you, by       *\r
14      *    ensuring you get running as quickly as possible and with an        *\r
15      *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
16      *    the FreeRTOS project to continue with its mission of providing     *\r
17      *    professional grade, cross platform, de facto standard solutions    *\r
18      *    for microcontrollers - completely free of charge!                  *\r
19      *                                                                       *\r
20      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
21      *                                                                       *\r
22      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
23      *                                                                       *\r
24     ***************************************************************************\r
25 \r
26 \r
27     This file is part of the FreeRTOS distribution.\r
28 \r
29     FreeRTOS is free software; you can redistribute it and/or modify it under\r
30     the terms of the GNU General Public License (version 2) as published by the\r
31     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
32 \r
33     >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
34     distribute a combined work that includes FreeRTOS without being obliged to\r
35     provide the source code for proprietary components outside of the FreeRTOS\r
36     kernel.\r
37 \r
38     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
39     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
40     FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\r
41     details. You should have received a copy of the GNU General Public License\r
42     and the FreeRTOS license exception along with FreeRTOS; if not it can be\r
43     viewed here: http://www.freertos.org/a00114.html and also obtained by\r
44     writing to Real Time Engineers Ltd., contact details for whom are available\r
45     on the FreeRTOS WEB site.\r
46 \r
47     1 tab == 4 spaces!\r
48 \r
49     ***************************************************************************\r
50      *                                                                       *\r
51      *    Having a problem?  Start by reading the FAQ "My application does   *\r
52      *    not run, what could be wrong?"                                     *\r
53      *                                                                       *\r
54      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
55      *                                                                       *\r
56     ***************************************************************************\r
57 \r
58 \r
59     http://www.FreeRTOS.org - Documentation, books, training, latest versions, \r
60     license and Real Time Engineers Ltd. contact details.\r
61 \r
62     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
63     including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
64     fully thread aware and reentrant UDP/IP stack.\r
65 \r
66     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High \r
67     Integrity Systems, who sell the code with commercial support, \r
68     indemnification and middleware, under the OpenRTOS brand.\r
69     \r
70     http://www.SafeRTOS.com - High Integrity Systems also provide a safety \r
71     engineered and independently SIL3 certified version for use in safety and \r
72     mission critical applications that require provable dependability.\r
73 */\r
74 \r
75 \r
76 /* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER for port 1.\r
77 \r
78 Note that this driver is written to test the RTOS port and is not intended\r
79 to represent an optimised solution.  In particular no use is made of the DMA\r
80 peripheral. */\r
81 \r
82 /* Standard include files. */\r
83 #include <stdlib.h>\r
84 \r
85 /* Scheduler include files. */\r
86 #include "FreeRTOS.h"\r
87 #include "queue.h"\r
88 #include "task.h"\r
89 \r
90 /* Demo application include files. */\r
91 #include "serial.h"\r
92 \r
93 /* The queues used to communicate between the task code and the interrupt\r
94 service routines. */\r
95 static xQueueHandle xRxedChars; \r
96 static xQueueHandle xCharsForTx; \r
97 \r
98 /* Hardware specific constants. */\r
99 #define serTX_INTERRUPT                         ( ( unsigned char ) 0x80 )\r
100 #define serRX_INTERRUPT                         ( ( unsigned char ) 0x40 )\r
101 #define serTX_ENABLE                            ( ( unsigned char ) 0x20 )\r
102 #define serRX_ENABLE                            ( ( unsigned char ) 0x10 )\r
103 \r
104 /* Macros to turn on and off the serial port THRE interrupt while leaving the\r
105 other register bits in their correct state.   The Rx interrupt is always \r
106 enabled. */\r
107 #define serTX_INTERRUPT_ON()            SCR1 = serTX_INTERRUPT | serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;                                                                 \r
108 #define serTX_INTERRUPT_OFF()           SCR1 =                                   serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;\r
109 \r
110 /* Bit used to switch on the channel 1 serial port in the module stop \r
111 register. */\r
112 #define serMSTP6                                        ( ( unsigned short ) 0x0040 )\r
113 \r
114 /* Interrupt service routines.  Note that the Rx and Tx service routines can \r
115 cause a context switch and are therefore defined with the saveall attribute in\r
116 addition to the interrupt_handler attribute.  See the FreeRTOS.org WEB site \r
117 documentation for a full explanation.*/\r
118 void vCOM_1_Rx_ISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );\r
119 void vCOM_1_Tx_ISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );\r
120 void vCOM_1_Error_ISR( void ) __attribute__ ( ( interrupt_handler ) );\r
121 \r
122 /*-----------------------------------------------------------*/\r
123 \r
124 /*\r
125  * Initialise port 1 for interrupt driven communications.\r
126  */\r
127 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )\r
128 {\r
129         /* Create the queues used to communicate between the tasks and the\r
130         interrupt service routines. */\r
131         xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );\r
132         xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );\r
133 \r
134         /* No parity, 8 data bits and 1 stop bit is the default so does not require \r
135         configuration - setup the remains of the hardware. */\r
136         portENTER_CRITICAL();\r
137         {\r
138                 /* Turn channel 1 on. */\r
139                 MSTPCR &= ~serMSTP6;\r
140 \r
141                 /* Enable the channels and the Rx interrupt.  The Tx interrupt is only \r
142                 enabled when data is being transmitted. */\r
143                 SCR1 = serRX_INTERRUPT | serTX_ENABLE | serRX_ENABLE;\r
144 \r
145                 /* Bit rate settings for 22.1184MHz clock only!. */\r
146                 switch( ulWantedBaud )\r
147                 {\r
148                         case 4800       :       BRR1 = 143;\r
149                                                         break;\r
150                         case 9600       :       BRR1 = 71;\r
151                                                         break;\r
152                         case 19200      :       BRR1 = 35;\r
153                                                         break;\r
154                         case 38400      :       BRR1 = 17;\r
155                                                         break;\r
156                         case 57600      :       BRR1 = 11;\r
157                                                         break;\r
158                         case 115200     :       BRR1 = 5;\r
159                                                         break;\r
160                         default         :       BRR1 = 5;\r
161                                                         break;\r
162                 }\r
163         }\r
164         portEXIT_CRITICAL();    \r
165 \r
166         /* Unlike some ports, this driver code does not allow for more than one\r
167         com port.  We therefore don't return a pointer to a port structure and can\r
168         instead just return NULL. */\r
169         return NULL;\r
170 }\r
171 /*-----------------------------------------------------------*/\r
172 \r
173 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime )\r
174 {\r
175         /* Get the next character from the buffer queue.  Return false if no characters\r
176         are available, or arrive before xBlockTime expires. */\r
177         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
178         {\r
179                 return pdTRUE;\r
180         }\r
181         else\r
182         {\r
183                 return pdFALSE;\r
184         }\r
185 }\r
186 /*-----------------------------------------------------------*/\r
187 \r
188 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime )\r
189 {\r
190 signed portBASE_TYPE xReturn = pdPASS;\r
191 \r
192         /* Return false if after the block time there is no room on the Tx queue. */\r
193         portENTER_CRITICAL();\r
194         {\r
195                 /* Send a character to the queue of characters waiting transmission.\r
196                 The queue is serviced by the Tx ISR. */\r
197                 if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )\r
198                 {\r
199                         /* Could not post onto the queue. */\r
200                         xReturn = pdFAIL;\r
201                 }\r
202                 else\r
203                 {\r
204                         /* The message was posted onto the queue so we turn on the Tx\r
205                         interrupt to allow the Tx ISR to remove the character from the\r
206                         queue. */\r
207                         serTX_INTERRUPT_ON();\r
208                 }\r
209         }\r
210         portEXIT_CRITICAL();\r
211 \r
212         return xReturn;\r
213 }\r
214 /*-----------------------------------------------------------*/\r
215 \r
216 void vSerialClose( xComPortHandle xPort )\r
217 {       \r
218         /* Not supported. */\r
219         ( void ) xPort;\r
220 }\r
221 /*-----------------------------------------------------------*/\r
222 \r
223 void vCOM_1_Rx_ISR( void )\r
224 {\r
225         /* This can cause a context switch so this macro must be the first line\r
226         in the function. */\r
227         portENTER_SWITCHING_ISR();\r
228 \r
229         /* As this is a switching ISR the local variables must be declared as \r
230         static. */\r
231         static char cRxByte;\r
232         static portBASE_TYPE xHigherPriorityTaskWoken;\r
233 \r
234                 xHigherPriorityTaskWoken = pdFALSE;\r
235 \r
236                 /* Get the character. */\r
237                 cRxByte = RDR1;\r
238 \r
239                 /* Post the character onto the queue of received characters - noting\r
240                 whether or not this wakes a task. */\r
241                 xQueueSendFromISR( xRxedChars, &cRxByte, &xHigherPriorityTaskWoken );\r
242 \r
243                 /* Clear the interrupt. */\r
244                 SSR1 &= ~serRX_INTERRUPT;\r
245 \r
246         /* This must be the last line in the function.  We pass cTaskWokenByPost so \r
247         a context switch will occur if the received character woke a task that has\r
248         a priority higher than the task we interrupted. */\r
249         portEXIT_SWITCHING_ISR( xHigherPriorityTaskWoken );\r
250 }\r
251 /*-----------------------------------------------------------*/\r
252 \r
253 void vCOM_1_Tx_ISR( void )\r
254 {\r
255         /* This can cause a context switch so this macro must be the first line\r
256         in the function. */\r
257         portENTER_SWITCHING_ISR();\r
258 \r
259         /* As this is a switching ISR the local variables must be declared as \r
260         static. */\r
261         static char cTxByte;\r
262         static signed portBASE_TYPE xTaskWokenByTx;\r
263 \r
264                 /* This variable is static so must be explicitly reinitialised each\r
265                 time the function executes. */\r
266                 xTaskWokenByTx = pdFALSE;\r
267 \r
268                 /* The interrupt was caused by the THR becoming empty.  Are there any\r
269                 more characters to transmit?  Note whether or not the Tx interrupt has\r
270                 woken a task. */\r
271                 if( xQueueReceiveFromISR( xCharsForTx, &cTxByte, &xTaskWokenByTx ) == pdTRUE )\r
272                 {\r
273                         /* A character was retrieved from the queue so can be sent to the\r
274                         THR now. */                                                     \r
275                         TDR1 = cTxByte;\r
276 \r
277                         /* Clear the interrupt. */\r
278                         SSR1 &= ~serTX_INTERRUPT;\r
279                 }\r
280                 else\r
281                 {\r
282                         /* Queue empty, nothing to send so turn off the Tx interrupt. */\r
283                         serTX_INTERRUPT_OFF();\r
284                 }               \r
285 \r
286         /* This must be the last line in the function.  We pass cTaskWokenByTx so \r
287         a context switch will occur if the Tx'ed character woke a task that has\r
288         a priority higher than the task we interrupted. */\r
289         portEXIT_SWITCHING_ISR( xTaskWokenByTx );\r
290 }\r
291 /*-----------------------------------------------------------*/\r
292 \r
293 /*\r
294  * This ISR cannot cause a context switch so requires no special \r
295  * considerations. \r
296  */\r
297 void vCOM_1_Error_ISR( void )\r
298 {\r
299 volatile unsigned char ucIn;\r
300 \r
301         ucIn = SSR1;\r
302         SSR1 = 0;\r
303 }\r
304 \r