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