]> git.sur5r.net Git - freertos/blob - Demo/PIC18_WizC/serial/serial.c
First version under SVN is V4.0.1
[freertos] / Demo / PIC18_WizC / serial / serial.c
1 /*\r
2         FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS distribution.\r
5 \r
6         FreeRTOS is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section \r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26         ***************************************************************************\r
27         See http://www.FreeRTOS.org for documentation, latest information, license \r
28         and contact details.  Please ensure to read the configuration and relevant \r
29         port sections of the online documentation.\r
30         ***************************************************************************\r
31 */\r
32 \r
33 /*\r
34 Changes from V3.0.0\r
35         + ISRcode removed. Is now pulled inline to reduce stack-usage.\r
36 \r
37 Changes from V3.0.1\r
38 */\r
39 \r
40 /* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER. */\r
41 \r
42 /* Scheduler header files. */\r
43 #include "FreeRTOS.h"\r
44 #include "task.h"\r
45 #include "queue.h"\r
46 \r
47 #include "serial.h"\r
48 \r
49 /* Hardware pin definitions. */\r
50 #define serTX_PIN                               bTRC6\r
51 #define serRX_PIN                               bTRC7\r
52 \r
53 /* Bit/register definitions. */\r
54 #define serINPUT                                ( 1 )\r
55 #define serOUTPUT                               ( 0 )\r
56 #define serINTERRUPT_ENABLED    ( 1 )\r
57 \r
58 /* All ISR's use the PIC18 low priority interrupt. */\r
59 #define serLOW_PRIORITY                 ( 0 )\r
60 \r
61 /*-----------------------------------------------------------*/\r
62 \r
63 /* Queues to interface between comms API and interrupt routines. */\r
64 xQueueHandle xRxedChars; \r
65 xQueueHandle xCharsForTx;\r
66 \r
67 /*-----------------------------------------------------------*/\r
68 \r
69 xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portCHAR ucQueueLength )\r
70 {\r
71         unsigned portSHORT usSPBRG;\r
72         \r
73         /* Create the queues used by the ISR's to interface to tasks. */\r
74         xRxedChars = xQueueCreate( ucQueueLength, ( unsigned portBASE_TYPE ) sizeof( portCHAR ) );\r
75         xCharsForTx = xQueueCreate( ucQueueLength, ( unsigned portBASE_TYPE ) sizeof( portCHAR ) );\r
76 \r
77         portENTER_CRITICAL();\r
78 \r
79         /* Setup the IO pins to enable the USART IO. */\r
80         serTX_PIN       = serINPUT;             // YES really! See datasheet\r
81         serRX_PIN       = serINPUT;\r
82 \r
83         /* Set the TX config register. */\r
84         TXSTA = 0b00100000;\r
85                 //        ||||||||--bit0: TX9D  = n/a\r
86                 //        |||||||---bit1: TRMT  = ReadOnly\r
87                 //        ||||||----bit2: BRGH  = High speed\r
88                 //        |||||-----bit3: SENDB = n/a\r
89                 //        ||||------bit4: SYNC  = Asynchronous mode\r
90                 //        |||-------bit5: TXEN  = Transmit enable\r
91                 //        ||--------bit6: TX9   = 8-bit transmission\r
92                 //        |---------bit7: CSRC  = n/a\r
93 \r
94         /* Set the Receive config register. */\r
95         RCSTA = 0b10010000;\r
96                 //        ||||||||--bit0: RX9D  = ReadOnly\r
97                 //        |||||||---bit1: OERR  = ReadOnly\r
98                 //        ||||||----bit2: FERR  = ReadOnly\r
99                 //        |||||-----bit3: ADDEN = n/a\r
100                 //        ||||------bit4: CREN  = Enable receiver\r
101                 //        |||-------bit5: SREN  = n/a\r
102                 //        ||--------bit6: RX9   = 8-bit reception\r
103                 //        |---------bit7: SPEN  = Serial port enabled\r
104 \r
105         /* Calculate the baud rate generator value.\r
106            We use low-speed (BRGH=0), the formula is\r
107            SPBRG = ( ( FOSC / Desired Baud Rate ) / 64 ) - 1 */\r
108         usSPBRG = ( ( APROCFREQ / ulWantedBaud ) / 64 ) - 1;\r
109         if( usSPBRG > 255 )\r
110         {\r
111                 SPBRG = 255;\r
112         }\r
113         else\r
114         {\r
115                 SPBRG = usSPBRG;\r
116         }\r
117 \r
118         /* Set the serial interrupts to use the same priority as the tick. */\r
119         bTXIP = serLOW_PRIORITY;\r
120         bRCIP = serLOW_PRIORITY;\r
121 \r
122         /* Enable the Rx interrupt now, the Tx interrupt will get enabled when\r
123         we have data to send. */\r
124         bRCIE = serINTERRUPT_ENABLED;\r
125         \r
126         portEXIT_CRITICAL();\r
127 \r
128         /* Unlike other ports, this serial code does not allow for more than one\r
129         com port.  We therefore don't return a pointer to a port structure and \r
130         can     instead just return NULL. */\r
131         return NULL;\r
132 }\r
133 /*-----------------------------------------------------------*/\r
134 \r
135 xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portCHAR ucBufferLength )\r
136 {\r
137         /* This is not implemented in this port.\r
138         Use xSerialPortInitMinimal() instead. */\r
139         return NULL;\r
140 }\r
141 /*-----------------------------------------------------------*/\r
142 \r
143 portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, portCHAR *pcRxedChar, portTickType xBlockTime )\r
144 {\r
145         /* Get the next character from the buffer.  Return false if no characters\r
146         are available, or arrive before xBlockTime expires. */\r
147         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
148         {\r
149                 return ( portCHAR ) pdTRUE;\r
150         }\r
151 \r
152         return ( portCHAR ) pdFALSE;\r
153 }\r
154 /*-----------------------------------------------------------*/\r
155 \r
156 portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, portCHAR cOutChar, portTickType xBlockTime )\r
157 {\r
158         /* Return false if after the block time there is no room on the Tx queue. */\r
159         if( xQueueSend( xCharsForTx, ( const void * ) &cOutChar, xBlockTime ) != ( portCHAR ) pdPASS )\r
160         {\r
161                 return pdFAIL;\r
162         }\r
163 \r
164         /* Turn interrupt on - ensure the compiler only generates a single \r
165         instruction for this. */\r
166         bTXIE = serINTERRUPT_ENABLED;\r
167 \r
168         return pdPASS;\r
169 }\r
170 /*-----------------------------------------------------------*/\r
171 \r
172 void vSerialClose( xComPortHandle xPort )\r
173 {\r
174         /* Not implemented for this port.\r
175         To implement, turn off the interrupts and delete the memory\r
176         allocated to the queues. */\r
177 }\r