2 serial.c for using FreeRTOS
3 Copyright (C) 2005 Robotronics Inc.
7 /* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER for port 1.
9 GCC demo modifications by Jeff Smith, Robotronics Inc. 2005
15 /* Scheduler include files. */
20 /* Demo application include files. */
24 /* The queues used to communicate between the task code and the interrupt
26 static QueueHandle_t xRxedChars;
27 static QueueHandle_t xCharsForTx;
29 /* Interrupt identification bits. */
30 #define serOVERRUN_INTERRUPT ( '\x08' )
31 #define serRX_INTERRUPT ( 0x20 )
32 #define serTX_INTERRUPT ( 0x80 )
34 /*-----------------------------------------------------------*/
38 * Initialise port for interrupt driven communications.
40 xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
42 /* Hardware setup is performed by the Processor Expert generated code.
43 This function just creates the queues used to communicate between the
44 interrupt code and the task code - then sets the required baud rate. */
46 xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
47 xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
49 SCI_SetBaudRateMode( ( char ) ulWantedBaud );
53 /*-----------------------------------------------------------*/
55 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )
57 /* Get the next character from the buffer queue. Return false if no characters
58 are available, or arrive before xBlockTime expires. */
59 if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
68 /*-----------------------------------------------------------*/
70 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
72 /* Place the character in the queue of characters to be transmitted. */
73 if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
78 /* Turn on the Tx interrupt so the ISR will remove the character from the
79 queue and send it. This does not need to be in a critical section as
80 if the interrupt has already removed the character the next interrupt
81 will simply turn off the Tx interrupt again. */
82 SCICR2 |= 0x80; // TIE
86 /*-----------------------------------------------------------*/
88 void vSerialClose( xComPortHandle xPort )
93 /*-----------------------------------------------------------*/
97 * Interrupt service routine for the serial port. Must be in non-banked
101 void ATTR_INT ATTR_NEAR vCOM_ISR( void );
103 void vCOM_ISR( void )
105 volatile unsigned char ucByte, ucStatus;
106 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
108 /* What caused the interrupt? */
111 if( ucStatus & serOVERRUN_INTERRUPT )
113 /* The interrupt was caused by an overrun. Clear the error by reading
114 the data register. */
118 if( ucStatus & serRX_INTERRUPT )
120 /* The interrupt was caused by a character being received.
121 Read the received byte. */
124 /* Post the character onto the queue of received characters - noting
125 whether or not this wakes a task. */
126 xQueueSendFromISR( xRxedChars, ( void * ) &ucByte, &xHigherPriorityTaskWoken );
129 if( ( ucStatus & serTX_INTERRUPT ) && ( SCICR2 & 0x80 ) )
131 /* The interrupt was caused by a character being transmitted. */
132 if( xQueueReceiveFromISR( xCharsForTx, ( void * ) &ucByte, &xHigherPriorityTaskWoken ) == pdTRUE )
134 /* Clear the SCRF bit. */
139 /* Disable transmit interrupt */
140 SCICR2 &= ~0x80; // TIE
144 if( xHigherPriorityTaskWoken )