usart.c

Go to the documentation of this file.
00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
00022 /* Copyright (c) 2006, Atmel Corporation All rights reserved.
00023  *
00024  * Redistribution and use in source and binary forms, with or without
00025  * modification, are permitted provided that the following conditions are met:
00026  *
00027  * 1. Redistributions of source code must retain the above copyright notice,
00028  * this list of conditions and the following disclaimer.
00029  *
00030  * 2. Redistributions in binary form must reproduce the above copyright notice,
00031  * this list of conditions and the following disclaimer in the documentation
00032  * and/or other materials provided with the distribution.
00033  *
00034  * 3. The name of ATMEL may not be used to endorse or promote products derived
00035  * from this software without specific prior written permission.
00036  *
00037  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
00038  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00039  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
00040  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00041  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00042  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00043  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00044  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00045  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00046  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00047  */
00048 
00049 #include "usart.h"
00050 
00055 void usart_reset(volatile struct avr32_usart_t * usart)
00056 {
00057     /* Disable all usart interrupts, interrupts needed should be set
00058        explicitly on every reset */
00059     usart->idr = 0xFFFFffff;
00060 
00061     /* Reset mode and other registers that could cause unpredictable
00062        behaviour after reset */
00063     usart->mr = 0;
00064     usart->rtor = 0;
00065     usart->ttgr = 0;
00066 
00067     /* Shutdown RX and TX (will be reenabled when setup
00068        is completed successfully), reset status bits and turn
00069        off DTR and RTS */
00070     usart->cr = AVR32_USART_CR_RSTRX_MASK|
00071                 AVR32_USART_CR_RSTTX_MASK|
00072                 AVR32_USART_CR_RSTSTA_MASK|
00073                 AVR32_USART_CR_RSTIT_MASK|
00074                 AVR32_USART_CR_RSTNACK_MASK|
00075                 AVR32_USART_CR_DTRDIS_MASK|
00076                 AVR32_USART_CR_RTSDIS_MASK;
00077 }
00078 
00079 
00093 static int usart_set_baudrate(volatile struct avr32_usart_t * usart,
00094         unsigned int baudrate,
00095         const long cpuHz)
00096 {
00097     int cd; /* clock divider */
00098 
00099     /*
00100      *             ** BAUDRATE CALCULATION **
00101      *
00102      *                 selected clock                       selected clock
00103      *     baudrate = ----------------   or     baudrate = ----------------
00104      *                16 x (CD + FP/8)                      8 x (CD + FP/8)
00105      *
00106      *       (with 16x oversampling)              (with 8x oversampling)
00107      */
00108     if (baudrate > (cpuHz/16)) {
00109         /* use 8x oversampling */
00110         usart->mr |= (AVR32_USART_MR_OVER_MASK);
00111         cd = cpuHz / (8 * baudrate);
00112 
00113         if (cd < 2) {
00114             /* wanted baudrate is too high */
00115             return USART_ERROR_ARGUMENT;
00116         }
00117 
00118         usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
00119     } else {
00120         /* use 16x oversampling */
00121         usart->mr &= ~(AVR32_USART_MR_OVER_MASK);
00122         cd = cpuHz / (16 * baudrate);
00123 
00124         if (cd > 65535) {
00125             /* wanted baudrate is too low */
00126             return USART_ERROR_ARGUMENT;
00127         }
00128 
00129         usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
00130     }
00131 
00132     return USART_OK;
00133 }
00134 
00135 
00147 int usart_linit(volatile struct avr32_usart_t * usart,
00148         const struct usart_options_t * opt,
00149         const long cpuHz)
00150 {
00151     int retval;
00152 
00153     /* reset the usart and shutdown RX and TX */
00154     usart_reset(usart);
00155 
00156     /* control input values */
00157     if (opt == 0) {
00158         return USART_ERROR_ARGUMENT;
00159     }
00160     if (opt->charlength < 5 || opt->charlength > 9) {
00161         return USART_ERROR_ARGUMENT;
00162     }
00163     if (opt->paritytype > 7) {
00164         return USART_ERROR_ARGUMENT;
00165     }
00166     if (opt->stopbits > 2+255) {
00167         return USART_ERROR_ARGUMENT;
00168     }
00169     if (opt->channelmode > 3) {
00170         return USART_ERROR_ARGUMENT;
00171     }
00172 
00173     retval = usart_set_baudrate(usart, opt->baudrate, cpuHz);
00174 
00175     if (retval != USART_OK) {
00176         return retval;
00177     }
00178 
00179     if (opt->charlength == 9) {
00180         /* charlength set to 9 bits; MODE9 dominates CHRL */
00181         usart->mr |= AVR32_USART_MR_MODE9_MASK;
00182     } else {
00183         /* CHRL gives the charlength(- 5) when USART_MODE9=0 */
00184         usart->mr |=
00185             ((opt->charlength-5)<<AVR32_USART_MR_CHRL_OFFSET);
00186     }
00187 
00188     usart->mr |= (opt->channelmode<<AVR32_USART_MR_CHMODE_OFFSET)|
00189                  (opt->paritytype<<AVR32_USART_MR_PAR_OFFSET);
00190 
00191     if (opt->stopbits > 2) {
00192         /* set two stop bits */
00193         usart->mr |= (2<<AVR32_USART_MR_NBSTOP_OFFSET);
00194         /* and a timeguard period gives the rest */
00195         usart->ttgr = (opt->stopbits-2);
00196     } else {
00197         /* insert 1, 1.5 or 2 stop bits */
00198         usart->mr |= (opt->stopbits<<AVR32_USART_MR_NBSTOP_OFFSET);
00199     }
00200 
00201     /* enable TX and RX */
00202     usart->cr |= AVR32_USART_CR_TXEN_MASK|AVR32_USART_CR_RXEN_MASK;
00203 
00204     return USART_OK;
00205 }
00206 
00207 
00217 int usart_putchar(volatile struct avr32_usart_t * usart, const int character)
00218 {
00219     int timeout = USART_DEFAULT_TIMEOUT;
00220 
00221     do {
00222         --timeout;
00223     } while ((usart->csr & AVR32_USART_CSR_TXRDY_MASK) == 0 && timeout > 0);
00224 
00225     if (timeout == 0) {
00226         return USART_TX_BUSY;
00227     }
00228 
00229     usart->thr = character;
00230 
00231     return USART_OK;
00232 }
00233 
00234 
00244 int usart_lwriteLine(volatile struct avr32_usart_t * usart, const char * string)
00245 {
00246     int retVal = USART_OK;
00247 
00248     while (*string != '\0') {
00249         retVal = usart_putchar(usart, *string++);
00250 
00251         if (retVal != USART_OK) {
00252             return retVal;
00253         }
00254     }
00255 
00256     return USART_OK;
00257 }
00258 

Generated on Wed May 10 15:03:12 2006 for AVR32108 - Peripheral Direct Memory Access Driver by  doxygen 1.4.6-NO