00001
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include <avr32/io.h>
00051 #include "board.h"
00052 #include "gpio.h"
00053 #include "usart.h"
00054
00055
00056 #include "FreeRTOS.h"
00057 #include "queue.h"
00058 #include "task.h"
00059
00060
00061 #include "serial.h"
00062
00063
00064
00065
00066 #define serINVALID_COMPORT_HANDLER ( ( xComPortHandle ) 0 )
00067 #define serINVALID_QUEUE ( ( xQueueHandle ) 0 )
00068 #define serHANDLE ( ( xComPortHandle ) 1 )
00069 #define serNO_BLOCK ( ( portTickType ) 0 )
00070
00071
00072
00073
00074
00075 static xQueueHandle xRxedChars;
00076 static xQueueHandle xCharsForTx;
00077
00078
00079
00080
00081 static void vprvSerialCreateQueues( unsigned portBASE_TYPE uxQueueLength,
00082 xQueueHandle *pxRxedChars,
00083 xQueueHandle *pxCharsForTx );
00084
00085
00086
00087 #if __GNUC__
00088 __attribute__((__noinline__))
00089 #elif __ICCAVR32__
00090 #pragma optimize = no_inline
00091 #endif
00092
00093 static portBASE_TYPE prvUSART_ISR_NonNakedBehaviour( void )
00094 {
00095
00096 signed portCHAR cChar;
00097 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
00098 unsigned portLONG ulStatus;
00099 volatile avr32_usart_t *usart = serialPORT_USART;
00100 portBASE_TYPE retstatus;
00101
00102
00103 ulStatus = usart->csr & usart->imr;
00104
00105 if (ulStatus & AVR32_USART_CSR_TXRDY_MASK)
00106 {
00107
00108
00109
00110
00111 portENTER_CRITICAL();
00112 retstatus = xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken );
00113 portEXIT_CRITICAL();
00114
00115 if (retstatus == pdTRUE)
00116 {
00117
00118
00119 usart->thr = cChar;
00120 }
00121 else
00122 {
00123
00124 usart->idr = AVR32_USART_IDR_TXRDY_MASK;
00125 }
00126 }
00127
00128 if (ulStatus & AVR32_USART_CSR_RXRDY_MASK)
00129 {
00130
00131 cChar = usart->rhr;
00132
00133
00134
00135 portENTER_CRITICAL();
00136 xQueueSendFromISR(xRxedChars, &cChar, &xHigherPriorityTaskWoken);
00137 portEXIT_CRITICAL();
00138 }
00139
00140
00141
00142 return ( xHigherPriorityTaskWoken );
00143 }
00144
00145
00146
00147
00148
00149 #if __GNUC__
00150 __attribute__((__naked__))
00151 #elif __ICCAVR32__
00152 #pragma shadow_registers = full // Naked.
00153 #endif
00154
00155 static void vUSART_ISR( void )
00156 {
00157
00158
00159
00160 portENTER_SWITCHING_ISR();
00161
00162 prvUSART_ISR_NonNakedBehaviour();
00163
00164
00165
00166 portEXIT_SWITCHING_ISR();
00167 }
00168
00169
00170
00171
00172
00173
00174 xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
00175 {
00176 static const gpio_map_t USART_GPIO_MAP =
00177 {
00178 { serialPORT_USART_RX_PIN, serialPORT_USART_RX_FUNCTION },
00179 { serialPORT_USART_TX_PIN, serialPORT_USART_TX_FUNCTION }
00180 };
00181
00182 xComPortHandle xReturn = serHANDLE;
00183 volatile avr32_usart_t *usart = serialPORT_USART;
00184
00185
00186 usart_options_t USART_OPTIONS =
00187 {
00188 .baudrate = 57600,
00189 .charlength = 8,
00190 .paritytype = USART_NO_PARITY,
00191 .stopbits = USART_1_STOPBIT,
00192 .channelmode = USART_NORMAL_CHMODE
00193 };
00194
00195 USART_OPTIONS.baudrate = ulWantedBaud;
00196
00197
00198 vprvSerialCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx );
00199
00200
00201 if( ( xRxedChars != serINVALID_QUEUE ) &&
00202 ( xCharsForTx != serINVALID_QUEUE ) &&
00203 ( ulWantedBaud != ( unsigned portLONG ) 0 ) )
00204 {
00205 portENTER_CRITICAL();
00206 {
00210
00211 gpio_enable_module( USART_GPIO_MAP, sizeof( USART_GPIO_MAP ) / sizeof( USART_GPIO_MAP[0] ) );
00212
00213
00214 usart_init_rs232(usart, &USART_OPTIONS, configPBA_CLOCK_HZ);
00215
00216
00217 usart->cr |= AVR32_USART_CR_RXDIS_MASK | AVR32_USART_CR_TXDIS_MASK;
00218
00219
00220
00221 INTC_register_interrupt((__int_handler)&vUSART_ISR, serialPORT_USART_IRQ, AVR32_INTC_INT1);
00222
00223
00224 usart->ier = AVR32_USART_IER_RXRDY_MASK;
00225
00226
00227 usart->cr |= AVR32_USART_CR_TXEN_MASK | AVR32_USART_CR_RXEN_MASK;
00228 }
00229 portEXIT_CRITICAL();
00230 }
00231 else
00232 {
00233 xReturn = serINVALID_COMPORT_HANDLER;
00234 }
00235
00236 return xReturn;
00237 }
00238
00239
00240 signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime )
00241 {
00242
00243 ( void ) pxPort;
00244
00245
00246
00247 if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
00248 {
00249 return pdTRUE;
00250 }
00251 else
00252 {
00253 return pdFALSE;
00254 }
00255 }
00256
00257
00258 void vSerialPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength )
00259 {
00260 signed portCHAR *pxNext;
00261
00262
00263
00264
00265
00266 ( void ) pxPort;
00267
00268
00269 pxNext = ( signed portCHAR * ) pcString;
00270 while( *pxNext )
00271 {
00272 xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );
00273 pxNext++;
00274 }
00275 }
00276
00277
00278 signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime )
00279 {
00280 volatile avr32_usart_t *usart = serialPORT_USART;
00281
00282
00283 if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
00284 {
00285 return pdFAIL;
00286 }
00287
00288
00289
00290
00291
00292 usart->ier = (1 << AVR32_USART_IER_TXRDY_OFFSET);
00293
00294 return pdPASS;
00295 }
00296
00297
00298 void vSerialClose( xComPortHandle xPort )
00299 {
00300
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 static void vprvSerialCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxRxedChars, xQueueHandle *pxCharsForTx )
00310 {
00311
00312 xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
00313 xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
00314
00315
00316
00317 *pxRxedChars = xRxedChars;
00318 *pxCharsForTx = xCharsForTx;
00319 }
00320