00001
00014
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 #include "gpio.h"
00049
00050
00051 #include "FreeRTOS.h"
00052 #include "queue.h"
00053 #include "task.h"
00054
00055
00056 #include "serial.h"
00057 #include <avr32/io.h>
00058 #include "board.h"
00059 #include "usart.h"
00060
00061
00062
00063
00064 #define serINVALID_COMPORT_HANDLER ( ( xComPortHandle ) 0 )
00065 #define serINVALID_QUEUE ( ( xQueueHandle ) 0 )
00066 #define serHANDLE ( ( xComPortHandle ) 1 )
00067 #define serNO_BLOCK ( ( portTickType ) 0 )
00068
00069
00070
00071
00072 typedef struct usartPrivateData
00073 {
00074 volatile avr32_usart_t *usart;
00075 xQueueHandle xRxedChars;
00076 xQueueHandle xCharsForTx;
00077 } xUsartPrivateData;
00078
00079 xUsartPrivateData xUsart0 = {&AVR32_USART0, NULL, NULL};
00080 xUsartPrivateData xUsart1 = {&AVR32_USART1, NULL, NULL};
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 static int iprvSerialCreateQueues( unsigned portBASE_TYPE uxRxQueueLength,
00094 xQueueHandle *pxRxedChars, unsigned portBASE_TYPE uxTxQueueLength,
00095 xQueueHandle *pxCharsForTx );
00096
00097
00098
00099 #if defined(__GNUC__)
00100 __attribute__((__noinline__))
00101 #elif defined(__ICCAVR32__)
00102 #pragma optimize = no_inline
00103 #endif
00104 static portBASE_TYPE prvUSART_ISR_NonNakedBehaviour( xUsartPrivateData *pxUsart )
00105 {
00106
00107 signed portCHAR cChar;
00108 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
00109 unsigned portLONG ulStatus;
00110 portBASE_TYPE retstatus;
00111
00112
00113 ulStatus = pxUsart->usart->csr & pxUsart->usart->imr;
00114
00115 if (ulStatus & AVR32_USART_CSR_TXRDY_MASK)
00116 {
00117
00118
00119
00120
00121 portENTER_CRITICAL();
00122 retstatus = xQueueReceiveFromISR(pxUsart->xCharsForTx, &cChar, &xHigherPriorityTaskWoken);
00123 portEXIT_CRITICAL();
00124 if (retstatus == pdTRUE)
00125 {
00126
00127
00128 pxUsart->usart->thr = cChar;
00129 }
00130 else
00131 {
00132
00133 pxUsart->usart->idr = AVR32_USART_IDR_TXRDY_MASK;
00134 }
00135 }
00136
00137 if (ulStatus & AVR32_USART_CSR_RXRDY_MASK)
00138 {
00139
00140 cChar = pxUsart->usart->rhr;
00141
00142
00143
00144 portENTER_CRITICAL();
00145 xQueueSendFromISR(pxUsart->xRxedChars, &cChar, &xHigherPriorityTaskWoken);
00146 portEXIT_CRITICAL();
00147 }
00148
00149
00150
00151 return ( xHigherPriorityTaskWoken );
00152 }
00153
00154
00155
00156
00157
00158 #if defined(__GNUC__)
00159 __attribute__((__naked__))
00160 #elif defined(__ICCAVR32__)
00161 #pragma shadow_registers = full // Naked.
00162 #endif
00163 void vUSART0_ISR( void )
00164 {
00165
00166
00167
00168
00169 portENTER_SWITCHING_ISR();
00170 prvUSART_ISR_NonNakedBehaviour(&xUsart0);
00171
00172
00173 portEXIT_SWITCHING_ISR();
00174 }
00175
00176
00177
00178
00179 #if defined(__GNUC__)
00180 __attribute__((__naked__))
00181 #elif defined(__ICCAVR32__)
00182 #pragma shadow_registers = full // Naked.
00183 #endif
00184 static void vUSART1_ISR( void )
00185 {
00186
00187
00188
00189
00190 portENTER_SWITCHING_ISR();
00191 prvUSART_ISR_NonNakedBehaviour(&xUsart1);
00192
00193
00194 portEXIT_SWITCHING_ISR();
00195 }
00196
00197
00206 xComPortHandle xUsartInit( eCOMPort UsartId, unsigned portLONG ulWantedBaud,
00207 unsigned portBASE_TYPE uxRxQueueLength,
00208 unsigned portBASE_TYPE uxTxQueueLength)
00209 {
00210 xComPortHandle xReturn;
00211 xUsartPrivateData *pxUsart;
00212 int UsartRxEnMask = ((uxRxQueueLength==0) ? 0 : AVR32_USART_CR_RXEN_MASK);
00213 int UsartTxEnMask = ((uxTxQueueLength==0) ? 0 : AVR32_USART_CR_TXEN_MASK);
00214 int iTempoStatus;
00215
00216 usart_options_t USART_OPTIONS =
00217 {
00218 .baudrate = 57600,
00219 .charlength = 8,
00220 .paritytype = USART_NO_PARITY,
00221 .stopbits = USART_1_STOPBIT,
00222 .channelmode = USART_NORMAL_CHMODE
00223 };
00224
00225 USART_OPTIONS.baudrate = ulWantedBaud;
00226
00227 xReturn = pxUsart = (UsartId == serCOM1 ? &xUsart0 : &xUsart1);
00228
00229
00230 iTempoStatus = iprvSerialCreateQueues( uxRxQueueLength, &(pxUsart->xRxedChars),
00231 uxTxQueueLength, &(pxUsart->xCharsForTx) );
00232
00233
00234 if( ( iTempoStatus != pdFAIL ) &&
00235 ( ulWantedBaud != ( unsigned portLONG ) 0 ) )
00236 {
00237 portENTER_CRITICAL();
00238 {
00242
00243 if(UsartId == serCOM1)
00244 {
00245 if(uxRxQueueLength)
00246 gpio_enable_module_pin(AVR32_USART0_RXD_0_0_PIN, AVR32_USART0_RXD_0_0_FUNCTION);
00247 if(uxTxQueueLength)
00248 gpio_enable_module_pin(AVR32_USART0_TXD_0_0_PIN, AVR32_USART0_TXD_0_0_FUNCTION);
00249 }
00250 else
00251 {
00252 if(uxRxQueueLength)
00253 gpio_enable_module_pin(AVR32_USART1_RXD_0_0_PIN, AVR32_USART1_RXD_0_0_FUNCTION);
00254 if(uxTxQueueLength)
00255 gpio_enable_module_pin(AVR32_USART1_TXD_0_0_PIN, AVR32_USART1_TXD_0_0_FUNCTION);
00256 }
00257
00258
00259 usart_init_rs232(pxUsart->usart, &USART_OPTIONS, CP_PBA_SPEED);
00260
00261
00262 pxUsart->usart->cr |= AVR32_USART_CR_RXDIS_MASK | AVR32_USART_CR_TXDIS_MASK;
00263
00264
00265
00266 if(UsartId == serCOM1)
00267 INTC_register_interrupt((__int_handler)&vUSART0_ISR, AVR32_USART0_IRQ, AVR32_INTC_INT1);
00268 else
00269 INTC_register_interrupt((__int_handler)&vUSART1_ISR, AVR32_USART1_IRQ, AVR32_INTC_INT1);
00270
00271
00272 if(uxRxQueueLength)
00273 pxUsart->usart->ier = AVR32_USART_IER_RXRDY_MASK;
00274
00275
00276 pxUsart->usart->cr |= UsartTxEnMask | UsartRxEnMask;
00277 }
00278 portEXIT_CRITICAL();
00279 }
00280 else
00281 {
00282 xReturn = serINVALID_COMPORT_HANDLER;
00283 }
00284
00285 return xReturn;
00286 }
00287
00288
00289
00290
00297 signed portBASE_TYPE xUsartGetChar( xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime )
00298 {
00299 xUsartPrivateData *pxUsart = (xUsartPrivateData *)pxPort;
00300
00301
00302
00303 if( xQueueReceive( pxUsart->xRxedChars, pcRxedChar, xBlockTime ) )
00304 {
00305 return pdTRUE;
00306 }
00307 else
00308 {
00309 return pdFALSE;
00310 }
00311 }
00312
00313
00314
00321 signed portBASE_TYPE xUsartPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime )
00322 {
00323 xUsartPrivateData *pxUsart = (xUsartPrivateData *)pxPort;
00324
00325
00326 if( xQueueSend( pxUsart->xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
00327 {
00328 return pdFAIL;
00329 }
00330
00331
00332
00333
00334
00335 pxUsart->usart->ier = (1 << AVR32_USART_IER_TXRDY_OFFSET);
00336
00337 return pdPASS;
00338 }
00339
00340
00341
00342 unsigned portSHORT usUsartPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength )
00343 {
00344 signed portCHAR *pxNext;
00345
00346
00347 pxNext = ( signed portCHAR * ) pcString;
00348 do
00349 {
00350 if(xUsartPutChar( pxPort, *pxNext, serNO_BLOCK ) != pdPASS)
00351 break;
00352 pxNext++;
00353 } while( --usStringLength );
00354
00355 return( usStringLength );
00356 }
00357
00358
00359
00364 void vSerialClose( xComPortHandle xPort )
00365 {
00366 xUsartPrivateData *pxUsart = (xUsartPrivateData *)xPort;
00367
00368 pxUsart->usart->idr = 0xFFFFFFFF;
00369 }
00370
00371
00372
00373
00374
00375
00376
00377 static int iprvSerialCreateQueues( unsigned portBASE_TYPE uxRxQueueLength, xQueueHandle *pxRxedChars,
00378 unsigned portBASE_TYPE uxTxQueueLength, xQueueHandle *pxCharsForTx )
00379 {
00380 int iRet = pdPASS;
00381
00382
00383
00384 *pxRxedChars = xQueueCreate( uxRxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
00385 *pxCharsForTx = xQueueCreate( uxTxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
00386 if( ( ( uxRxQueueLength ) && (*pxRxedChars == NULL) ) ||
00387 ( ( uxTxQueueLength ) && (*pxCharsForTx == NULL) ) )
00388 iRet = pdFAIL;
00389
00390 return(iRet);
00391 }
00392