serial.c File Reference


Detailed Description

Control Panel USART driver module.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

Definition in file serial.c.

#include "gpio.h"
#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"
#include "serial.h"
#include <avr32/io.h>
#include "board.h"
#include "usart.h"

Go to the source code of this file.

Data Structures

struct  usartPrivateData

Defines

#define serHANDLE   ( ( xComPortHandle ) 1 )
#define serINVALID_COMPORT_HANDLER   ( ( xComPortHandle ) 0 )
#define serINVALID_QUEUE   ( ( xQueueHandle ) 0 )
#define serNO_BLOCK   ( ( portTickType ) 0 )

Typedefs

typedef struct usartPrivateData xUsartPrivateData

Functions

static int iprvSerialCreateQueues (unsigned portBASE_TYPE uxRxQueueLength, xQueueHandle *pxRxedChars, unsigned portBASE_TYPE uxTxQueueLength, xQueueHandle *pxCharsForTx)
static portBASE_TYPE prvUSART_ISR_NonNakedBehaviour (xUsartPrivateData *pxUsart)
unsigned portSHORT usUsartPutString (xComPortHandle pxPort, const signed portCHAR *const pcString, unsigned portSHORT usStringLength)
 Put a string to Usart.
void vSerialClose (xComPortHandle xPort)
 Close the serial port.
void vUSART0_ISR (void)
static void vUSART1_ISR (void)
signed portBASE_TYPE xUsartGetChar (xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime)
 Get char from Usart.
xComPortHandle xUsartInit (eCOMPort UsartId, unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxRxQueueLength, unsigned portBASE_TYPE uxTxQueueLength)
 Init the serial port.
signed portBASE_TYPE xUsartPutChar (xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime)
 Put char to Usart.

Variables

xUsartPrivateData xUsart0 = {&AVR32_USART0, NULL, NULL}
xUsartPrivateData xUsart1 = {&AVR32_USART1, NULL, NULL}


Define Documentation

#define serHANDLE   ( ( xComPortHandle ) 1 )

Definition at line 66 of file serial.c.

#define serINVALID_COMPORT_HANDLER   ( ( xComPortHandle ) 0 )

Definition at line 64 of file serial.c.

Referenced by xUsartInit().

#define serINVALID_QUEUE   ( ( xQueueHandle ) 0 )

Definition at line 65 of file serial.c.

#define serNO_BLOCK   ( ( portTickType ) 0 )

Definition at line 67 of file serial.c.

Referenced by usUsartPutString().


Typedef Documentation


Function Documentation

static int iprvSerialCreateQueues ( unsigned portBASE_TYPE  uxRxQueueLength,
xQueueHandle *  pxRxedChars,
unsigned portBASE_TYPE  uxTxQueueLength,
xQueueHandle *  pxCharsForTx 
) [static]

Definition at line 377 of file serial.c.

Referenced by xUsartInit().

00379 {
00380   int iRet = pdPASS;
00381 
00382   /* Create the queues used to hold Rx and Tx characters. */
00383   // NOTE: xQueueCreate() will return NULL if the required length is 0.
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 }

static portBASE_TYPE prvUSART_ISR_NonNakedBehaviour ( xUsartPrivateData pxUsart  )  [static]

Definition at line 104 of file serial.c.

References usartPrivateData::usart, usartPrivateData::xCharsForTx, and usartPrivateData::xRxedChars.

Referenced by vUSART0_ISR(), and vUSART1_ISR().

00105 {
00106   /* Now we can declare the local variables. */
00107   signed portCHAR     cChar;
00108   portBASE_TYPE     xHigherPriorityTaskWoken = pdFALSE;
00109   unsigned portLONG     ulStatus;
00110   portBASE_TYPE retstatus;
00111 
00112   /* What caused the interrupt? */
00113   ulStatus = pxUsart->usart->csr & pxUsart->usart->imr;
00114 
00115   if (ulStatus & AVR32_USART_CSR_TXRDY_MASK)
00116   {
00117     /* The interrupt was caused by the THR becoming empty.  Are there any
00118        more characters to transmit? */
00119     /* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
00120       calls in a critical section . */
00121     portENTER_CRITICAL();
00122     retstatus = xQueueReceiveFromISR(pxUsart->xCharsForTx, &cChar, &xHigherPriorityTaskWoken);
00123     portEXIT_CRITICAL();
00124     if (retstatus == pdTRUE)
00125     {
00126       /* A character was retrieved from the queue so can be sent to the
00127          THR now. */
00128       pxUsart->usart->thr = cChar;
00129     }
00130     else
00131     {
00132       /* Queue empty, nothing to send so turn off the Tx interrupt. */
00133       pxUsart->usart->idr = AVR32_USART_IDR_TXRDY_MASK;
00134     }
00135   }
00136 
00137   if (ulStatus & AVR32_USART_CSR_RXRDY_MASK)
00138   {
00139     /* The interrupt was caused by the receiver getting data. */
00140     cChar = pxUsart->usart->rhr; //TODO
00141 
00142     /* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
00143       calls in a critical section . */
00144     portENTER_CRITICAL();
00145     xQueueSendFromISR(pxUsart->xRxedChars, &cChar, &xHigherPriorityTaskWoken);
00146     portEXIT_CRITICAL();
00147   }
00148 
00149   /* The return value will be used by portEXIT_SWITCHING_ISR() to know if it
00150   should perform a vTaskSwitchContext(). */
00151   return ( xHigherPriorityTaskWoken );
00152 }

unsigned portSHORT usUsartPutString ( xComPortHandle  pxPort,
const signed portCHAR *const   pcString,
unsigned portSHORT  usStringLength 
)

Put a string to Usart.

Parameters:
pxPort The Usart handle to put the string to
pcString The string to transmit
usStringLength The number of char to transmit.

Definition at line 342 of file serial.c.

References serNO_BLOCK, and xUsartPutChar().

Referenced by ustracedump_Print(), vcom1shell_PrintMsg(), and vtracedump_PrintBlocking().

00343 {
00344 signed portCHAR *pxNext;
00345 
00346   /* Send each character in the string, one at a time. */
00347   pxNext = ( signed portCHAR * ) pcString;
00348   do
00349   {
00350     if(xUsartPutChar( pxPort, *pxNext, serNO_BLOCK ) != pdPASS)
00351       break; // The queue is full.
00352     pxNext++;
00353   } while( --usStringLength );
00354 
00355   return( usStringLength ); // Return the number of remaining characters.
00356 }

void vSerialClose ( xComPortHandle  xPort  ) 

Close the serial port.

Parameters:
xPort The handle of the usart to close

Definition at line 364 of file serial.c.

References usartPrivateData::usart.

Referenced by v_com1shell_stopResources(), and v_tracedump_stopResources().

00365 {
00366   xUsartPrivateData *pxUsart = (xUsartPrivateData *)xPort;
00367   /* Disable all USART interrupt sources */
00368   pxUsart->usart->idr = 0xFFFFFFFF;
00369 }

void vUSART0_ISR ( void   ) 

Definition at line 163 of file serial.c.

References prvUSART_ISR_NonNakedBehaviour().

Referenced by xUsartInit().

00164 {
00165 
00166  /* This ISR can cause a context switch, so the first statement must be a
00167   call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any
00168   variable declarations. */
00169   portENTER_SWITCHING_ISR();
00170   prvUSART_ISR_NonNakedBehaviour(&xUsart0);
00171  /* Exit the ISR.  If a task was woken by either a character being received
00172   or transmitted then a context switch will occur. */
00173   portEXIT_SWITCHING_ISR();
00174 }

static void vUSART1_ISR ( void   )  [static]

Definition at line 184 of file serial.c.

References prvUSART_ISR_NonNakedBehaviour().

Referenced by xUsartInit().

00185 {
00186 
00187  /* This ISR can cause a context switch, so the first statement must be a
00188   call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any
00189   variable declarations. */
00190   portENTER_SWITCHING_ISR();
00191   prvUSART_ISR_NonNakedBehaviour(&xUsart1);
00192  /* Exit the ISR.  If a task was woken by either a character being received
00193   or transmitted then a context switch will occur. */
00194   portEXIT_SWITCHING_ISR();
00195 }

signed portBASE_TYPE xUsartGetChar ( xComPortHandle  pxPort,
signed portCHAR *  pcRxedChar,
portTickType  xBlockTime 
)

Get char from Usart.

Parameters:
pxPort The Usart handle to get the char from
pcRxedChar The rxed char(output)
xBlockTime The max time to wait for a rxed char

Definition at line 297 of file serial.c.

References usartPrivateData::xRxedChars.

Referenced by com1shell_GetChar(), and prvGetChar().

00298 {
00299   xUsartPrivateData *pxUsart = (xUsartPrivateData *)pxPort;
00300 
00301   /* Get the next character from the buffer.  Return false if no characters
00302   are available, or arrive before xBlockTime expires. */
00303   if( xQueueReceive( pxUsart->xRxedChars, pcRxedChar, xBlockTime ) )
00304   {
00305     return pdTRUE;
00306   }
00307   else
00308   {
00309     return pdFALSE;
00310   }
00311 }

xComPortHandle xUsartInit ( eCOMPort  UsartId,
unsigned portLONG  ulWantedBaud,
unsigned portBASE_TYPE  uxRxQueueLength,
unsigned portBASE_TYPE  uxTxQueueLength 
)

Init the serial port.

Parameters:
UsartId The identifier of the Usart to init.
ulWantedBaud The required baudrate.
uxRxQueueLength The length of the Rx buffer (if 0, rx is not supported).
uxTxQueueLength The length of the Tx buffer (if 0, tx is not supported).
Returns:
xComPortHandle Handler on the COM port.

Configure USART.

Definition at line 206 of file serial.c.

References CP_PBA_SPEED, iprvSerialCreateQueues(), serCOM1, serINVALID_COMPORT_HANDLER, usartPrivateData::usart, vUSART0_ISR(), vUSART1_ISR(), usartPrivateData::xCharsForTx, and usartPrivateData::xRxedChars.

Referenced by itracedump_Init(), and portTASK_FUNCTION().

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   // USART options.
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   /* Create the rx and tx queues. */
00230   iTempoStatus =  iprvSerialCreateQueues( uxRxQueueLength, &(pxUsart->xRxedChars),
00231                           uxTxQueueLength, &(pxUsart->xCharsForTx) );
00232 
00233   /* Configure USART. */
00234   if( ( iTempoStatus != pdFAIL ) &&
00235       ( ulWantedBaud != ( unsigned portLONG ) 0 ) )
00236   {
00237     portENTER_CRITICAL();
00238     {
00242       /* Enable USART RXD & TXD pins. */
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       // Initialize USART in RS232 mode.
00259       usart_init_rs232(pxUsart->usart, &USART_OPTIONS, CP_PBA_SPEED);
00260 
00261       /* We're not fully done yet: disable receiver and transmitter. */
00262       pxUsart->usart->cr |= AVR32_USART_CR_RXDIS_MASK | AVR32_USART_CR_TXDIS_MASK;
00263 
00264       // Register the USART interrupt handler to the interrupt controller and
00265       // enable the USART interrupt.
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       /* Enable USART interrupt sources (but not Tx for now)... */
00272       if(uxRxQueueLength)
00273         pxUsart->usart->ier = AVR32_USART_IER_RXRDY_MASK;
00274 
00275       /* Enable receiver and transmitter... */
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 }

signed portBASE_TYPE xUsartPutChar ( xComPortHandle  pxPort,
signed portCHAR  cOutChar,
portTickType  xBlockTime 
)

Put char to Usart.

Parameters:
pxPort The Usart handle to put the char to
cOutChar The char to transmit
xBlockTime The max time to wait for getting the right to transmit the char.

Definition at line 321 of file serial.c.

References usartPrivateData::usart, and usartPrivateData::xCharsForTx.

Referenced by usUsartPutString(), vcom1shell_PutChar(), vtracedump_Putchar(), and vtracedump_Putchar_Block().

00322 {
00323 xUsartPrivateData *pxUsart = (xUsartPrivateData *)pxPort;
00324 
00325   /* Place the character in the queue of characters to be transmitted. */
00326   if( xQueueSend( pxUsart->xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
00327   {
00328     return pdFAIL;
00329   }
00330 
00331   /* Turn on the Tx interrupt so the ISR will remove the character from the
00332   queue and send it.   This does not need to be in a critical section as
00333   if the interrupt has already removed the character the next interrupt
00334   will simply turn off the Tx interrupt again. */
00335   pxUsart->usart->ier = (1 << AVR32_USART_IER_TXRDY_OFFSET);
00336 
00337   return pdPASS;
00338 }


Variable Documentation

xUsartPrivateData xUsart0 = {&AVR32_USART0, NULL, NULL}

Definition at line 79 of file serial.c.

xUsartPrivateData xUsart1 = {&AVR32_USART1, NULL, NULL}

Definition at line 80 of file serial.c.


Generated on Fri Feb 19 02:22:47 2010 for AVR32 - Control Panel demonstration. by  doxygen 1.5.5