usart.c

Go to the documentation of this file.
00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
00021 #include "usart.h"
00022 
00027 void usart_reset( volatile avr32_usart_t * usart )
00028 {
00029         /* Disable all usart interrupts, interrupts needed should be set
00030            explicitly on every reset */
00031         usart->idr = 0xFFFFffff;
00032 
00033         /* Reset mode and other registers that could cause unpredictable
00034            behaviour after reset */
00035         usart->mr = 0;
00036         usart->rtor = 0;
00037         usart->ttgr = 0;
00038 
00039         /* Shutdown RX and TX (will be reenabled when setup
00040            is completed successfully), reset status bits and turn
00041            off DTR and RTS */
00042         usart->cr = (1<<AVR32_USART_CR_RSTRX_OFFSET)|
00043                     (1<<AVR32_USART_CR_RSTTX_OFFSET)|
00044                     (1<<AVR32_USART_CR_RSTSTA_OFFSET)|
00045                     (1<<AVR32_USART_CR_RSTIT_OFFSET)|
00046                     (1<<AVR32_USART_CR_RSTNACK_OFFSET)|
00047                     (1<<AVR32_USART_CR_DTRDIS_OFFSET)|
00048                     (1<<AVR32_USART_CR_RTSDIS_OFFSET);
00049 }
00050 
00051 
00065 static int usart_set_baudrate( volatile avr32_usart_t * usart,
00066                 unsigned int baudrate,
00067                 long cpuHz)
00068 {
00069         int cd, fp; /* clock divider and fractional part */
00070 
00071         /*
00072          *             ** BAUDRATE CALCULATION **
00073          *
00074          *                 selected clock                       selected clock
00075          *     baudrate = ----------------   or     baudrate = ----------------
00076          *                16 x (CD + FP/8)                      8 x (CD + FP/8)
00077          *
00078          *       (with 16x oversampling)              (with 8x oversampling)
00079          */
00080         if( baudrate > (cpuHz/16) ) {
00081                 /* use 8x oversampling */
00082                 usart->mr |= (1<<AVR32_USART_MR_OVER_OFFSET);
00083                 cd = cpuHz / ( 8 * baudrate );
00084 
00085                 if( cd < 2 ) {
00086                         return USART_ERROR_ARGUMENT;
00087                 }
00088 
00089                 fp = cpuHz / baudrate - 8 * cd;
00090                 usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
00091         } else {
00092                 /* use 16x oversampling */
00093                 usart->mr &= ~(1<<AVR32_USART_MR_OVER_OFFSET);
00094                 cd = cpuHz / ( 16 * baudrate );
00095 
00096                 if( cd > 65535 ) {
00097                         /* wanted baudrate is too low */
00098                         return USART_ERROR_ARGUMENT;
00099                 }
00100 
00101                 fp = cpuHz / ( 2 * baudrate ) - 8 * cd;
00102                 usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
00103         }
00104 
00105         return USART_OK;
00106 }
00107 
00108 
00120 int usart_init2( volatile avr32_usart_t * usart,
00121                 struct usart_options_t * opt,
00122                 long cpuHz )
00123 {
00124         int retval;
00125 
00126         /* reset the usart and shutdown RX and TX */
00127         usart_reset(usart);
00128 
00129         /* control input values */
00130         if( opt == 0 ) {
00131                 return USART_ERROR_ARGUMENT;
00132         }
00133         if( opt->charlength < 5 || opt->charlength > 9 ) {
00134                 return USART_ERROR_ARGUMENT;
00135         }
00136         if( opt->paritytype > 7 ) {
00137                 return USART_ERROR_ARGUMENT;
00138         }
00139         if( opt->stopbits > 2+255 ) {
00140                 return USART_ERROR_ARGUMENT;
00141         }
00142         if( opt->channelmode > 3 ) {
00143                 return USART_ERROR_ARGUMENT;
00144         }
00145 
00146         retval = usart_set_baudrate( usart, opt->baudrate, cpuHz );
00147 
00148         if( retval != USART_OK ) {
00149                 return retval;
00150         }
00151 
00152         if( opt->charlength == 9 ) {
00153                 /* charlength set to 9 bits; MODE9 dominates CHRL */
00154                 usart->mr |= (1<<AVR32_USART_MR_MODE9_OFFSET);
00155         } else {
00156                 /* CHRL gives the charlength( - 5) when USART_MODE9=0 */
00157                 usart->mr |=
00158                         ((opt->charlength-5) << AVR32_USART_MR_CHRL_OFFSET);
00159         }
00160 
00161         usart->mr |= (opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET) |
00162                      (opt->paritytype << AVR32_USART_MR_PAR_OFFSET);
00163 
00164         if( opt->stopbits > 2 ) {
00165                 /* set two stop bits */
00166                 usart->mr |= (2 << AVR32_USART_MR_NBSTOP_OFFSET);
00167                 /* and a timeguard period gives the rest */
00168                 usart->ttgr = (opt->stopbits-2);
00169         } else {
00170                 /* insert 1, 1.5 or 2 stop bits */
00171                 usart->mr |= (opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET);
00172         }
00173 
00174         /* enable TX and RX */
00175         usart->cr |= (1<<AVR32_USART_CR_TXEN_OFFSET) |
00176                      (1<<AVR32_USART_CR_RXEN_OFFSET);
00177 
00178         return USART_OK;
00179 }
00180 
00181 
00191 int usart_putchar( volatile avr32_usart_t * usart, int character )
00192 {
00193         int timeout = USART_DEFAULT_TIMEOUT;
00194 
00195         do {
00196                 --timeout;
00197         } while( (usart->csr & (1<<AVR32_USART_CSR_TXRDY_OFFSET)) == 0 && timeout > 0 );
00198 
00199         if( timeout == 0 ) {
00200                 return USART_TX_BUSY;
00201         }
00202 
00203         usart->thr = character;
00204 
00205         return USART_OK;
00206 }
00207 
00208 
00218 int usart_writeLine( volatile avr32_usart_t * usart, char * string )
00219 {
00220         int retVal = USART_OK;
00221 
00222         while( *string != '\0' ) {
00223                 retVal = usart_putchar( usart, *string++ );
00224         }
00225 
00226         if( retVal != USART_OK ) {
00227                 return retVal;
00228         }
00229 
00230         return USART_OK;
00231 }
00232 

Generated on Thu May 10 14:14:48 2007 for AVR321000 Communication with the AVR32 USART by  doxygen 1.5.1