]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Cygnal/serial/serial.c
Update license information text files for the CLI, TCP and UDP products to be correct...
[freertos] / FreeRTOS / Demo / Cygnal / 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 /* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR DEMO PURPOSES */\r
31 #include <stdlib.h>\r
32 #include "FreeRTOS.h"\r
33 #include "queue.h"\r
34 #include "task.h"\r
35 #include "serial.h"\r
36 \r
37 /* Constants required to setup the serial control register. */\r
38 #define ser8_BIT_MODE                   ( ( unsigned char ) 0x40 )\r
39 #define serRX_ENABLE                    ( ( unsigned char ) 0x10 )\r
40 \r
41 /* Constants to setup the timer used to generate the baud rate. */\r
42 #define serCLOCK_DIV_48                 ( ( unsigned char ) 0x03 )\r
43 #define serUSE_PRESCALED_CLOCK  ( ( unsigned char ) 0x10 )\r
44 #define ser8BIT_WITH_RELOAD             ( ( unsigned char ) 0x20 )\r
45 #define serSMOD                                 ( ( unsigned char ) 0x10 )\r
46 \r
47 static QueueHandle_t xRxedChars; \r
48 static QueueHandle_t xCharsForTx; \r
49 \r
50 data static unsigned portBASE_TYPE uxTxEmpty;\r
51 \r
52 /*-----------------------------------------------------------*/\r
53 \r
54 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )\r
55 {\r
56 unsigned long ulReloadValue;\r
57 const portFLOAT fBaudConst = ( portFLOAT ) configCPU_CLOCK_HZ * ( portFLOAT ) 2.0;\r
58 unsigned char ucOriginalSFRPage;\r
59 \r
60         portENTER_CRITICAL();\r
61         {\r
62                 ucOriginalSFRPage = SFRPAGE;\r
63                 SFRPAGE = 0;\r
64 \r
65                 uxTxEmpty = pdTRUE;\r
66 \r
67                 /* Create the queues used by the com test task. */\r
68                 xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( char ) );\r
69                 xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( char ) );\r
70         \r
71                 /* Calculate the baud rate to use timer 1. */\r
72                 ulReloadValue = ( unsigned long ) ( ( ( portFLOAT ) 256 - ( fBaudConst / ( portFLOAT ) ( 32 * ulWantedBaud ) ) ) + ( portFLOAT ) 0.5 );\r
73 \r
74                 /* Set timer one for desired mode of operation. */\r
75                 TMOD &= 0x08;\r
76                 TMOD |= ser8BIT_WITH_RELOAD;\r
77                 SSTA0 |= serSMOD;\r
78 \r
79                 /* Set the reload and start values for the time. */\r
80                 TL1 = ( unsigned char ) ulReloadValue;\r
81                 TH1 = ( unsigned char ) ulReloadValue;\r
82 \r
83                 /* Setup the control register for standard n, 8, 1 - variable baud rate. */\r
84                 SCON = ser8_BIT_MODE | serRX_ENABLE;\r
85 \r
86                 /* Enable the serial port interrupts */\r
87                 ES = 1;\r
88 \r
89                 /* Start the timer. */\r
90                 TR1 = 1;\r
91 \r
92                 SFRPAGE = ucOriginalSFRPage;\r
93         }\r
94         portEXIT_CRITICAL();\r
95         \r
96         /* Unlike some ports, this serial code does not allow for more than one\r
97         com port.  We therefore don't return a pointer to a port structure and can\r
98         instead just return NULL. */\r
99         return NULL;\r
100 }\r
101 /*-----------------------------------------------------------*/\r
102 \r
103 void vSerialISR( void ) interrupt 4\r
104 {\r
105 char cChar;\r
106 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
107 \r
108         /* 8051 port interrupt routines MUST be placed within a critical section\r
109         if taskYIELD() is used within the ISR! */\r
110 \r
111         portENTER_CRITICAL();\r
112         {\r
113                 if( RI ) \r
114                 {\r
115                         /* Get the character and post it on the queue of Rxed characters.\r
116                         If the post causes a task to wake force a context switch if the woken task\r
117                         has a higher priority than the task we have interrupted. */\r
118                         cChar = SBUF;\r
119                         RI = 0;\r
120 \r
121                         xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );\r
122                 }\r
123 \r
124                 if( TI ) \r
125                 {\r
126                         if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == ( portBASE_TYPE ) pdTRUE )\r
127                         {\r
128                                 /* Send the next character queued for Tx. */\r
129                                 SBUF = cChar;\r
130                         }\r
131                         else\r
132                         {\r
133                                 /* Queue empty, nothing to send. */\r
134                                 uxTxEmpty = pdTRUE;\r
135                         }\r
136 \r
137                         TI = 0;\r
138                 }\r
139         \r
140                 if( xHigherPriorityTaskWoken )\r
141                 {\r
142                         portYIELD();\r
143                 }\r
144         }\r
145         portEXIT_CRITICAL();\r
146 }\r
147 /*-----------------------------------------------------------*/\r
148 \r
149 portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )\r
150 {\r
151         /* There is only one port supported. */\r
152         ( void ) pxPort;\r
153 \r
154         /* Get the next character from the buffer.  Return false if no characters\r
155         are available, or arrive before xBlockTime expires. */\r
156         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
157         {\r
158                 return ( portBASE_TYPE ) pdTRUE;\r
159         }\r
160         else\r
161         {\r
162                 return ( portBASE_TYPE ) pdFALSE;\r
163         }\r
164 }\r
165 /*-----------------------------------------------------------*/\r
166 \r
167 portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )\r
168 {\r
169 portBASE_TYPE xReturn;\r
170 \r
171         /* There is only one port supported. */\r
172         ( void ) pxPort;\r
173 \r
174         portENTER_CRITICAL();\r
175         {\r
176                 if( uxTxEmpty == pdTRUE )\r
177                 {\r
178                         SBUF = cOutChar;\r
179                         uxTxEmpty = pdFALSE;\r
180                         xReturn = ( portBASE_TYPE ) pdTRUE;\r
181                 }\r
182                 else\r
183                 {\r
184                         xReturn = xQueueSend( xCharsForTx, &cOutChar, xBlockTime );\r
185 \r
186                         if( xReturn == ( portBASE_TYPE ) pdFALSE )\r
187                         {\r
188                                 xReturn = ( portBASE_TYPE ) pdTRUE;\r
189                         }\r
190                 }\r
191         }\r
192         portEXIT_CRITICAL();\r
193 \r
194         return xReturn;\r
195 }\r
196 /*-----------------------------------------------------------*/\r
197 \r
198 void vSerialClose( xComPortHandle xPort )\r
199 {\r
200         /* Not implemented in this port. */\r
201         ( void ) xPort;\r
202 }\r
203 /*-----------------------------------------------------------*/\r
204 \r
205 \r
206 \r
207 \r
208 \r