]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/PIC18_WizC/serial/serial.c
Update version number in readiness for V10.3.0 release. Sync SVN with reviewed releas...
[freertos] / FreeRTOS / Demo / PIC18_WizC / serial / serial.c
1 /*\r
2  * FreeRTOS Kernel V10.3.0\r
3  * Copyright (C) 2020 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 Changes from V3.0.0\r
30         + ISRcode removed. Is now pulled inline to reduce stack-usage.\r
31 \r
32 Changes from V3.0.1\r
33 */\r
34 \r
35 /* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER. */\r
36 \r
37 /* Scheduler header files. */\r
38 #include "FreeRTOS.h"\r
39 #include "task.h"\r
40 #include "queue.h"\r
41 \r
42 #include "serial.h"\r
43 \r
44 /* Hardware pin definitions. */\r
45 #define serTX_PIN                               bTRC6\r
46 #define serRX_PIN                               bTRC7\r
47 \r
48 /* Bit/register definitions. */\r
49 #define serINPUT                                ( 1 )\r
50 #define serOUTPUT                               ( 0 )\r
51 #define serINTERRUPT_ENABLED    ( 1 )\r
52 \r
53 /* All ISR's use the PIC18 low priority interrupt. */\r
54 #define serLOW_PRIORITY                 ( 0 )\r
55 \r
56 /*-----------------------------------------------------------*/\r
57 \r
58 /* Queues to interface between comms API and interrupt routines. */\r
59 QueueHandle_t xRxedChars; \r
60 QueueHandle_t xCharsForTx;\r
61 portBASE_TYPE xHigherPriorityTaskWoken;\r
62 \r
63 /*-----------------------------------------------------------*/\r
64 \r
65 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned char ucQueueLength )\r
66 {\r
67         unsigned short usSPBRG;\r
68         \r
69         /* Create the queues used by the ISR's to interface to tasks. */\r
70         xRxedChars = xQueueCreate( ucQueueLength, ( unsigned portBASE_TYPE ) sizeof( char ) );\r
71         xCharsForTx = xQueueCreate( ucQueueLength, ( unsigned portBASE_TYPE ) sizeof( char ) );\r
72 \r
73         portENTER_CRITICAL();\r
74 \r
75         /* Setup the IO pins to enable the USART IO. */\r
76         serTX_PIN       = serINPUT;             // YES really! See datasheet\r
77         serRX_PIN       = serINPUT;\r
78 \r
79         /* Set the TX config register. */\r
80         TXSTA = 0b00100000;\r
81                 //        ||||||||--bit0: TX9D  = n/a\r
82                 //        |||||||---bit1: TRMT  = ReadOnly\r
83                 //        ||||||----bit2: BRGH  = High speed\r
84                 //        |||||-----bit3: SENDB = n/a\r
85                 //        ||||------bit4: SYNC  = Asynchronous mode\r
86                 //        |||-------bit5: TXEN  = Transmit enable\r
87                 //        ||--------bit6: TX9   = 8-bit transmission\r
88                 //        |---------bit7: CSRC  = n/a\r
89 \r
90         /* Set the Receive config register. */\r
91         RCSTA = 0b10010000;\r
92                 //        ||||||||--bit0: RX9D  = ReadOnly\r
93                 //        |||||||---bit1: OERR  = ReadOnly\r
94                 //        ||||||----bit2: FERR  = ReadOnly\r
95                 //        |||||-----bit3: ADDEN = n/a\r
96                 //        ||||------bit4: CREN  = Enable receiver\r
97                 //        |||-------bit5: SREN  = n/a\r
98                 //        ||--------bit6: RX9   = 8-bit reception\r
99                 //        |---------bit7: SPEN  = Serial port enabled\r
100 \r
101         /* Calculate the baud rate generator value.\r
102            We use low-speed (BRGH=0), the formula is\r
103            SPBRG = ( ( FOSC / Desired Baud Rate ) / 64 ) - 1 */\r
104         usSPBRG = ( ( APROCFREQ / ulWantedBaud ) / 64 ) - 1;\r
105         if( usSPBRG > 255 )\r
106         {\r
107                 SPBRG = 255;\r
108         }\r
109         else\r
110         {\r
111                 SPBRG = usSPBRG;\r
112         }\r
113 \r
114         /* Set the serial interrupts to use the same priority as the tick. */\r
115         bTXIP = serLOW_PRIORITY;\r
116         bRCIP = serLOW_PRIORITY;\r
117 \r
118         /* Enable the Rx interrupt now, the Tx interrupt will get enabled when\r
119         we have data to send. */\r
120         bRCIE = serINTERRUPT_ENABLED;\r
121         \r
122         portEXIT_CRITICAL();\r
123 \r
124         /* Unlike other ports, this serial code does not allow for more than one\r
125         com port.  We therefore don't return a pointer to a port structure and \r
126         can     instead just return NULL. */\r
127         return NULL;\r
128 }\r
129 /*-----------------------------------------------------------*/\r
130 \r
131 xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned char ucBufferLength )\r
132 {\r
133         /* This is not implemented in this port.\r
134         Use xSerialPortInitMinimal() instead. */\r
135         return NULL;\r
136 }\r
137 /*-----------------------------------------------------------*/\r
138 \r
139 portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, char *pcRxedChar, TickType_t xBlockTime )\r
140 {\r
141         /* Get the next character from the buffer.  Return false if no characters\r
142         are available, or arrive before xBlockTime expires. */\r
143         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
144         {\r
145                 return ( char ) pdTRUE;\r
146         }\r
147 \r
148         return ( char ) pdFALSE;\r
149 }\r
150 /*-----------------------------------------------------------*/\r
151 \r
152 portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, char cOutChar, TickType_t xBlockTime )\r
153 {\r
154         /* Return false if after the block time there is no room on the Tx queue. */\r
155         if( xQueueSend( xCharsForTx, ( const void * ) &cOutChar, xBlockTime ) != ( char ) pdPASS )\r
156         {\r
157                 return pdFAIL;\r
158         }\r
159 \r
160         /* Turn interrupt on - ensure the compiler only generates a single \r
161         instruction for this. */\r
162         bTXIE = serINTERRUPT_ENABLED;\r
163 \r
164         return pdPASS;\r
165 }\r
166 /*-----------------------------------------------------------*/\r
167 \r
168 void vSerialClose( xComPortHandle xPort )\r
169 {\r
170         /* Not implemented for this port.\r
171         To implement, turn off the interrupts and delete the memory\r
172         allocated to the queues. */\r
173 }\r