]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/HCS12_GCC_banked/serial.c
Update version number in readiness for V10.3.0 release. Sync SVN with reviewed releas...
[freertos] / FreeRTOS / Demo / HCS12_GCC_banked / serial.c
1 /*\r
2         serial.c  for using FreeRTOS\r
3         Copyright (C) 2005  Robotronics Inc.\r
4 */\r
5 \r
6 \r
7 /* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER for port 1.\r
8 \r
9    GCC demo modifications by Jeff Smith, Robotronics Inc. 2005\r
10 */\r
11 \r
12 #include "cpu.h"\r
13 #include <sys/sio.h>\r
14 \r
15 /* Scheduler include files. */\r
16 #include "FreeRTOS.h"\r
17 #include "queue.h"\r
18 #include "task.h"\r
19 \r
20 /* Demo application include files. */\r
21 #include "sci.h"\r
22 #include "serial.h"\r
23 \r
24 /* The queues used to communicate between the task code and the interrupt\r
25 service routines. */\r
26 static QueueHandle_t xRxedChars; \r
27 static QueueHandle_t xCharsForTx; \r
28 \r
29 /* Interrupt identification bits. */\r
30 #define serOVERRUN_INTERRUPT            ( '\x08' )\r
31 #define serRX_INTERRUPT                         ( 0x20 )\r
32 #define serTX_INTERRUPT                         ( 0x80 )\r
33 \r
34 /*-----------------------------------------------------------*/\r
35 \r
36 \r
37 /*\r
38  * Initialise port for interrupt driven communications.\r
39  */\r
40 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )\r
41 {\r
42         /* Hardware setup is performed by the Processor Expert generated code.  \r
43         This function just creates the queues used to communicate between the \r
44         interrupt code and the task code - then sets the required baud rate. */\r
45 \r
46         xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );\r
47         xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );\r
48 \r
49         SCI_SetBaudRateMode( ( char ) ulWantedBaud );\r
50 \r
51         return NULL;\r
52 }\r
53 /*-----------------------------------------------------------*/\r
54 \r
55 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )\r
56 {\r
57         /* Get the next character from the buffer queue.  Return false if no characters\r
58         are available, or arrive before xBlockTime expires. */\r
59         if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )\r
60         {\r
61                 return pdTRUE;\r
62         }\r
63         else\r
64         {\r
65                 return pdFALSE;\r
66         }\r
67 }\r
68 /*-----------------------------------------------------------*/\r
69 \r
70 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )\r
71 {\r
72         /* Place the character in the queue of characters to be transmitted. */\r
73         if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )\r
74         {\r
75                 return pdFAIL;\r
76         }\r
77 \r
78         /* Turn on the Tx interrupt so the ISR will remove the character from the\r
79         queue and send it.   This does not need to be in a critical section as\r
80         if the interrupt has already removed the character the next interrupt\r
81         will simply turn off the Tx interrupt again. */\r
82         SCICR2 |= 0x80;                         // TIE\r
83 \r
84         return pdPASS;\r
85 }\r
86 /*-----------------------------------------------------------*/\r
87 \r
88 void vSerialClose( xComPortHandle xPort )\r
89 {       \r
90         /* Not supported. */\r
91         //( void ) xPort;\r
92 }\r
93 /*-----------------------------------------------------------*/\r
94 \r
95 \r
96 /* \r
97  * Interrupt service routine for the serial port.  Must be in non-banked\r
98  * memory. \r
99  */\r
100 \r
101 void ATTR_INT ATTR_NEAR vCOM_ISR( void );\r
102 \r
103 void vCOM_ISR( void )\r
104 {\r
105 volatile unsigned char ucByte, ucStatus;\r
106 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
107 \r
108         /* What caused the interrupt? */\r
109         ucStatus = SCISR1;\r
110         \r
111         if( ucStatus & serOVERRUN_INTERRUPT )\r
112         {\r
113                 /* The interrupt was caused by an overrun.  Clear the error by reading\r
114                 the data register. */\r
115                 ucByte = SCIDRL;\r
116         }\r
117         else\r
118         if( ucStatus & serRX_INTERRUPT )\r
119         {\r
120                 /* The interrupt was caused by a character being received.\r
121                 Read the received byte. */\r
122                 ucByte = SCIDRL;\r
123 \r
124                 /* Post the character onto the queue of received characters - noting\r
125                 whether or not this wakes a task. */\r
126                 xQueueSendFromISR( xRxedChars, ( void * ) &ucByte, &xHigherPriorityTaskWoken );\r
127         }\r
128         \r
129         if( ( ucStatus & serTX_INTERRUPT ) && ( SCICR2 & 0x80 ) )\r
130         {       \r
131                 /* The interrupt was caused by a character being transmitted. */\r
132                 if( xQueueReceiveFromISR( xCharsForTx, ( void * ) &ucByte, &xHigherPriorityTaskWoken ) == pdTRUE )\r
133                 {\r
134                         /* Clear the SCRF bit. */\r
135                         SCIDRL = ucByte;\r
136                 }\r
137                 else\r
138                 {\r
139                         /* Disable transmit interrupt */\r
140                         SCICR2 &= ~0x80;                        // TIE\r
141                 }\r
142         }\r
143 \r
144         if( xHigherPriorityTaskWoken )\r
145         {\r
146                 portYIELD();\r
147         }\r
148 }\r
149 \r