]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/MB91460_Softune/SRC/serial/serial.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / MB91460_Softune / SRC / serial / serial.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 \r
30 /* \r
31  * BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER.   \r
32  * \r
33  * This file only supports UART 2\r
34  */\r
35 \r
36 /* Standard includes. */\r
37 #include <stdlib.h>\r
38 \r
39 /* Scheduler includes. */\r
40 #include "FreeRTOS.h"\r
41 #include "queue.h"\r
42 #include "task.h"\r
43 \r
44 /* Demo application includes. */\r
45 #include "serial.h"\r
46 \r
47 /* The queue used to hold received characters. */\r
48 static QueueHandle_t xRxedChars; \r
49 \r
50 /* The queue used to hold characters waiting transmission. */\r
51 static QueueHandle_t xCharsForTx; \r
52 \r
53 static volatile short sTHREEmpty;\r
54 \r
55 /*-----------------------------------------------------------*/\r
56 \r
57 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )\r
58 {\r
59         portENTER_CRITICAL();\r
60         {\r
61                 /* Create the queues used by the com test task. */\r
62                 xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );\r
63                 xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );\r
64 \r
65                  /* Initialize UART asynchronous mode */\r
66                 BGR02 = configPER_CLOCK_HZ / ulWantedBaud;\r
67                   \r
68                 SCR02 = 0x17;   /* 8N1 */\r
69                 SMR02 = 0x0d;   /* enable SOT3, Reset, normal mode */\r
70                 SSR02 = 0x02;   /* LSB first, enable receive interrupts */\r
71 \r
72                 PFR20_D0 = 1;   /* enable UART */\r
73                 PFR20_D1 = 1;   /* enable UART */\r
74 \r
75                 EPFR20_D1 = 0;  /* enable UART */\r
76         }\r
77         portEXIT_CRITICAL();\r
78         \r
79         /* Unlike other ports, this serial code does not allow for more than one\r
80         com port.  We therefore don't return a pointer to a port structure and can\r
81         instead just return NULL. */\r
82         return NULL;\r
83 }\r
84 /*-----------------------------------------------------------*/\r
85 \r
86 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )\r
87 {\r
88         /* Get the next character from the buffer.  Return false if no characters\r
89         are available, or arrive before xBlockTime expires. */\r
90         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
91         {\r
92                 return pdTRUE;\r
93         }\r
94         else\r
95         {\r
96                 return pdFALSE;\r
97         }\r
98 }\r
99 /*-----------------------------------------------------------*/\r
100 \r
101 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )\r
102 {\r
103 signed portBASE_TYPE xReturn;\r
104 \r
105         /* Transmit a character. */\r
106         portENTER_CRITICAL();\r
107         {\r
108                 if( sTHREEmpty == pdTRUE )\r
109                 {\r
110                         /* If sTHREEmpty is true then the UART Tx ISR has indicated that \r
111                         there are no characters queued to be transmitted - so we can\r
112                         write the character directly to the shift Tx register. */\r
113                         sTHREEmpty = pdFALSE;\r
114                         TDR02 = cOutChar;\r
115                         xReturn = pdPASS;\r
116                 }\r
117                 else\r
118                 {\r
119                         /* sTHREEmpty is false, so there are still characters waiting to be\r
120                         transmitted.  We have to queue this character so it gets \r
121                         transmitted     in turn. */\r
122 \r
123                         /* Return false if after the block time there is no room on the Tx \r
124                         queue.  It is ok to block inside a critical section as each task\r
125                         maintains it's own critical section status. */\r
126                         if (xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdTRUE)\r
127                         {\r
128                                 xReturn = pdPASS;\r
129                         }\r
130                         else\r
131                         {\r
132                                 xReturn = pdFAIL;\r
133                         }\r
134                 }\r
135                 \r
136                 if (pdPASS == xReturn)\r
137                 {\r
138                         /* Turn on the Tx interrupt so the ISR will remove the character from the\r
139                         queue and send it.   This does not need to be in a critical section as\r
140                         if the interrupt has already removed the character the next interrupt\r
141                         will simply turn off the Tx interrupt again. */\r
142                         SSR02_TIE = 1;\r
143                 }\r
144                 \r
145         }\r
146         portEXIT_CRITICAL();\r
147 \r
148         return pdPASS;\r
149 }\r
150 /*-----------------------------------------------------------*/\r
151 \r
152 /*\r
153  * UART RX interrupt service routine.\r
154  */\r
155  __interrupt void UART2_RxISR (void)\r
156 {\r
157         signed char cChar;\r
158         portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
159 \r
160         /* Get the character from the UART and post it on the queue of Rxed \r
161         characters. */\r
162         cChar = RDR02;\r
163 \r
164         xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );\r
165 \r
166         if( xHigherPriorityTaskWoken )\r
167         {\r
168                 /*If the post causes a task to wake force a context switch \r
169                 as the woken task may have a higher priority than the task we have \r
170                 interrupted. */\r
171                 portYIELD_FROM_ISR();\r
172         }\r
173 }\r
174 \r
175 /*-----------------------------------------------------------*/\r
176 \r
177 /*\r
178  * UART Tx interrupt service routine.\r
179  */\r
180 __interrupt void UART2_TxISR (void)\r
181 {\r
182         signed char cChar;\r
183         signed portBASE_TYPE xTaskWoken = pdFALSE;\r
184 \r
185         /* The previous character has been transmitted.  See if there are any\r
186         further characters waiting transmission. */\r
187         if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xTaskWoken ) == pdTRUE )\r
188         {\r
189                 /* There was another character queued - transmit it now. */\r
190                 TDR02 = cChar;\r
191         }\r
192         else\r
193         {\r
194                 /* There were no other characters to transmit. */\r
195                 sTHREEmpty = pdTRUE;\r
196                 \r
197                 /* Disable transmit interrupts */\r
198                 SSR02_TIE = 0;\r
199         }\r
200 }\r
201 \r