usart.c File Reference


Detailed Description

USART driver library.

This file contains basic drivers for the AVR32 USART, with support for all all modes, settings and clock speeds.

Author:
Atmel Corporation: http://www.atmel.com
Support email: avr32@atmel.com
Name
Revision
1.7
RCSfile
usart.c,v
Date
2006/05/10 13:00:07

Definition in file usart.c.

#include "usart.h"

Include dependency graph for usart.c:

Go to the source code of this file.

Functions

void usart_bw_write_char (volatile struct avr32_usart_t *usart, int c)
int usart_framing_error (volatile struct avr32_usart_t *usart)
int usart_getchar (volatile struct avr32_usart_t *usart)
int usart_init_handshaking (volatile struct avr32_usart_t *usart, struct usart_options_t *opt, long cpu_hz, int software_handshaking, char xon_char, char xoff_char)
int usart_init_IrDA (volatile struct avr32_usart_t *usart, struct usart_options_t *opt, long cpu_hz, unsigned char irda_filter)
int usart_init_iso7816 (volatile struct avr32_usart_t *usart, const struct iso7816_options_t *opt, int t, const long cpu_hz)
int usart_init_modem (volatile struct avr32_usart_t *usart, struct usart_options_t *opt, long cpu_hz)
int usart_init_rs232 (volatile struct avr32_usart_t *usart, struct usart_options_t *opt, long cpu_hz)
int usart_init_rs485 (volatile struct avr32_usart_t *usart, struct usart_options_t *opt, long cpu_hz)
static int usart_mode_is_multidrop (volatile struct avr32_usart_t *usart)
int usart_overrun_error (volatile struct avr32_usart_t *usart)
int usart_parity_error (volatile struct avr32_usart_t *usart)
int usart_putchar (volatile struct avr32_usart_t *usart, int c)
int usart_read_char (volatile struct avr32_usart_t *usart, int *c)
void usart_reset (volatile struct avr32_usart_t *usart)
void usart_reset_status (volatile struct avr32_usart_t *usart)
 Reset error status.
int usart_send_address (volatile struct avr32_usart_t *usart, int address)
static int usart_set_baudrate (volatile struct avr32_usart_t *usart, unsigned int baudrate, long cpu_hz)
int usart_write_char (volatile struct avr32_usart_t *usart, int c)


Function Documentation

void usart_bw_write_char ( volatile struct avr32_usart_t *  usart,
int  c 
) [inline]

A busy wait for writing a character to the usart. Use with *caution*

Parameters:
*usart Base address of the usart
c The character (up to 9 bits) to transmit
Returns:
None

Definition at line 484 of file usart.c.

References USART_SUCCESS, and usart_write_char().

Referenced by usart_send_address().

00485 {
00486         while (usart_write_char(usart, c) != USART_SUCCESS) {
00487         }
00488 
00489         return;
00490 }

Here is the call graph for this function:

int usart_framing_error ( volatile struct avr32_usart_t *  usart  ) 

Definition at line 426 of file usart.c.

00427 {
00428         return ((usart->csr & (1<<AVR32_USART_CSR_FRAME_OFFSET)) != 0);
00429 }

int usart_getchar ( volatile struct avr32_usart_t *  usart  ) 

Wait until a character is recevied, and return this.

Parameters:
*usart Base address of the usart
Returns:
The received character, or -1 upon error

Definition at line 524 of file usart.c.

References usart_read_char(), USART_RX_EMPTY, and USART_RX_ERROR.

00525 {
00526         int c, ret;
00527 
00528         while (((ret = usart_read_char(usart, &c)) == USART_RX_EMPTY)) {
00529         }
00530 
00531         if (ret == USART_RX_ERROR)
00532                 return -1;
00533         else
00534                 return c;
00535 }

Here is the call graph for this function:

int usart_init_handshaking ( volatile struct avr32_usart_t *  usart,
struct usart_options_t opt,
long  cpu_hz,
int  software_handshaking,
char  xon_char,
char  xoff_char 
)

Definition at line 220 of file usart.c.

References usart_init_rs232(), USART_INVALID_INPUT, USART_MODE_HW_HSH, USART_MODE_SW_HSH, and USART_SUCCESS.

00223 {
00224         int retval;
00225 
00226         /* First: Setup standard RS323 */
00227         if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS)
00228                 return retval;
00229 
00230         if (software_handshaking == 0)
00231         {
00232                 /* Clear previous mode */
00233                 usart-> mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET);
00234                 /* Hardware handshaking */
00235                 usart-> mr |= (USART_MODE_HW_HSH << AVR32_USART_MR_MODE_OFFSET);
00236         }
00237         else if (software_handshaking == 1)
00238         {
00239                 /* Clear previous mode */
00240                 usart-> mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET);
00241                 /* Software handshaking */
00242                 usart-> mr |= (USART_MODE_SW_HSH << AVR32_USART_MR_MODE_OFFSET);
00243                 /* Set XON and XOFF characters */
00244                 usart->xxr = (xon_char << AVR32_USART_XXR_XON_OFFSET) |
00245                              (xoff_char << AVR32_USART_XXR_XOFF_OFFSET);
00246         }
00247         else
00248                 return USART_INVALID_INPUT;
00249 
00250         return USART_SUCCESS;
00251 }

Here is the call graph for this function:

int usart_init_IrDA ( volatile struct avr32_usart_t *  usart,
struct usart_options_t opt,
long  cpu_hz,
unsigned char  irda_filter 
)

Definition at line 261 of file usart.c.

References usart_init_rs232(), and USART_SUCCESS.

00263 {
00264         int retval;
00265 
00266         /* First: Setup standard RS323 */
00267         if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS)
00268                 return retval;
00269 
00270         /* Set IrDA counter */
00271         usart->ifr = irda_filter;
00272 
00273         /* Activate "low-pass filtering" of input */
00274         usart->mr |= (1 << AVR32_USART_MR_FILTER_OFFSET);
00275         return USART_SUCCESS;
00276 }

Here is the call graph for this function:

int usart_init_iso7816 ( volatile struct avr32_usart_t *  usart,
const struct iso7816_options_t opt,
int  t,
const long  cpu_hz 
)

Definition at line 333 of file usart.c.

References iso7816_options_t::bit_order, iso7816_options_t::dis_suc_nack, iso7816_options_t::fidi_ratio, iso7816_options_t::inhibit_nack, iso7816_options_t::iso7816_hz, iso7816_options_t::max_iterations, USART_INVALID_INPUT, USART_MODE_ISO7816_T0, USART_MODE_ISO7816_T1, usart_reset(), usart_set_baudrate(), and USART_SUCCESS.

00334 {
00335         int retval;
00336 
00337         /* Reset the usart and shutdown RX and TX */
00338         usart_reset(usart);
00339 
00340         if (opt == 0)
00341                 /* Null pointer */
00342                 return USART_INVALID_INPUT;
00343 
00344         /* Don't care about charlength, parity or channelmode; All these fields
00345            are ignored in iso7816 mode. 8bit characters and even parity is always
00346            used */
00347 
00348         if (t == 0)
00349         {
00350                 /* Set USART mode to ISO7816, T=0 */
00351                 /* The T=0 protocol always use 2 stop bits */
00352                 usart->mr = (USART_MODE_ISO7816_T0 << AVR32_USART_MR_MODE_OFFSET) |
00353                             (2 << AVR32_USART_MR_NBSTOP_OFFSET) |
00354                             (opt->bit_order << AVR32_USART_MR_MSBF_OFFSET); /* Allow MSBF in T=0 */
00355         }
00356         else if (t == 1)
00357         {
00358                 /* Only LSB first in the T=1 protocol */
00359                 if (opt->bit_order != 0)
00360                         return USART_INVALID_INPUT;
00361                 /* max_iterations field is only used in T=0 mode */
00362                 if (opt->max_iterations != 0)
00363                         return USART_INVALID_INPUT;
00364                 /* Set USART mode to ISO7816, T=1 */
00365                 usart->mr = (USART_MODE_ISO7816_T1 << AVR32_USART_MR_MODE_OFFSET);
00366                 /* The T=1 protocol always use 1 stop bit (no change needed) */
00367         }
00368         else
00369                 return USART_INVALID_INPUT;
00370 
00371         if ((retval = usart_set_baudrate(usart, opt->iso7816_hz, cpu_hz)) != USART_SUCCESS)
00372                 return retval;
00373 
00374         /* Set FIDI register: bit rate = selected clock/FI_DI_ratio/16 */
00375         usart->fidi = opt->fidi_ratio;
00376         /* Set ISO7816 spesific options in the MODE register */
00377         usart->mr |= (opt->inhibit_nack << AVR32_USART_MR_INACK_OFFSET) |
00378                      (opt->dis_suc_nack << AVR32_USART_MR_DSNACK_OFFSET) |
00379                      (opt->max_iterations << AVR32_USART_MR_MAX_ITERATION_OFFSET) |
00380                      (1 << AVR32_USART_MR_CLKO_OFFSET); /* Enable clock output */
00381 
00382         /* Setup complete; enable input */
00383         /* Leave TX disabled for now */
00384         usart->cr |= (1<<AVR32_USART_CR_RXEN_OFFSET);
00385 
00386         return USART_SUCCESS;
00387 }

Here is the call graph for this function:

int usart_init_modem ( volatile struct avr32_usart_t *  usart,
struct usart_options_t opt,
long  cpu_hz 
)

Definition at line 285 of file usart.c.

References usart_init_rs232(), USART_MODE_MODEM, and USART_SUCCESS.

00286 {
00287         int retval;
00288 
00289         /* First: Setup standard RS323 */
00290         if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS)
00291                 return retval;
00292 
00293         /* Clear previous mode */
00294         usart-> mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET);
00295         /* Set Modem mode */
00296         usart-> mr |= (USART_MODE_MODEM << AVR32_USART_MR_MODE_OFFSET);
00297         return USART_SUCCESS;
00298 }

Here is the call graph for this function:

int usart_init_rs232 ( volatile struct avr32_usart_t *  usart,
struct usart_options_t opt,
long  cpu_hz 
)

Setup the usart to use the standard RS232 protocol

Parameters:
*usart Base address of the usart
*opt Options needed to set up RS232 communcation (see usart_options_t)
cpu_hz The usart clk frequency
Returns:
USART_SUCCESS or USART_INVALID_INPUT

Definition at line 152 of file usart.c.

References usart_options_t::baudrate, usart_options_t::channelmode, usart_options_t::charlength, usart_options_t::paritytype, usart_options_t::stopbits, USART_INVALID_INPUT, usart_reset(), usart_set_baudrate(), and USART_SUCCESS.

Referenced by main(), usart_init_handshaking(), usart_init_IrDA(), usart_init_modem(), and usart_init_rs485().

00153 {
00154         int retval;
00155 
00156         /* Reset the usart and shutdown RX and TX */
00157         usart_reset(usart);
00158 
00159         /* Control input values */
00160         if (opt == 0) /* Null pointer */
00161                 return USART_INVALID_INPUT;
00162         if (opt->charlength < 5 || opt->charlength > 9)
00163                 return USART_INVALID_INPUT;
00164         if (opt->paritytype > 7)
00165                 return USART_INVALID_INPUT;
00166         if (opt->stopbits > 2+255)
00167                 return USART_INVALID_INPUT;
00168         if (opt->channelmode > 3)
00169                 return USART_INVALID_INPUT;
00170 
00171         if ((retval = usart_set_baudrate(usart, opt->baudrate, cpu_hz)) != \
00172              USART_SUCCESS)
00173                 return retval;
00174 
00175         if (opt->charlength == 9) {
00176                 /* Charlength set to 9 bits; MODE9 dominates CHRL */
00177                 usart->mr |= (1<<AVR32_USART_MR_MODE9_OFFSET);
00178         } else {
00179                 /* CHRL gives the charlength( - 5) when USART_MODE9=0 */
00180                 usart->mr |=
00181                         ((opt->charlength-5) << AVR32_USART_MR_CHRL_OFFSET);
00182         }
00183 
00184         usart->mr |= (opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET) |
00185                      (opt->paritytype << AVR32_USART_MR_PAR_OFFSET);
00186 
00187         if (opt->stopbits > 2)
00188         {
00189                 /* Set two stop bits */
00190                 usart->mr |= (2 << AVR32_USART_MR_NBSTOP_OFFSET);
00191                 /* And a timeguard period gives the rest */
00192                 usart->ttgr = (opt->stopbits-2);
00193         }
00194         else
00195                 /* Insert 1, 1.5 or 2 stop bits */
00196                 usart->mr |= (opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET);
00197 
00198         /* Setup complete; enable communication */
00199         /* Enable input and output */
00200         usart->cr |= (1<<AVR32_USART_CR_TXEN_OFFSET) |
00201                      (1<<AVR32_USART_CR_RXEN_OFFSET);
00202 
00203         return USART_SUCCESS;
00204 }

Here is the call graph for this function:

int usart_init_rs485 ( volatile struct avr32_usart_t *  usart,
struct usart_options_t opt,
long  cpu_hz 
)

Definition at line 310 of file usart.c.

References usart_init_rs232(), USART_MODE_RS485, and USART_SUCCESS.

00311 {
00312         int retval;
00313 
00314         /* First: Setup standard RS323 */
00315         if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS)
00316                 return retval;
00317 
00318         /* Clear previous mode */
00319         usart->mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET);
00320         /* Set Modem mode */
00321         usart->mr |= (USART_MODE_RS485 << AVR32_USART_MR_MODE_OFFSET);
00322         return USART_SUCCESS;
00323 }

Here is the call graph for this function:

static int usart_mode_is_multidrop ( volatile struct avr32_usart_t *  usart  )  [static]

Definition at line 65 of file usart.c.

Referenced by usart_send_address().

00066 {
00067   return ( (usart->mr & 0x00000600) >> AVR32_USART_MR_PAR_OFFSET );
00068 }

int usart_overrun_error ( volatile struct avr32_usart_t *  usart  ) 

Definition at line 437 of file usart.c.

00438 {
00439         return ((usart->csr & AVR32_USART_CSR_OVRE_OFFSET)) != 0;
00440 }

int usart_parity_error ( volatile struct avr32_usart_t *  usart  ) 

Definition at line 415 of file usart.c.

00416 {
00417         return ((usart->csr & (1<<AVR32_USART_CSR_PARE_OFFSET)) != 0);
00418 }

int usart_putchar ( volatile struct avr32_usart_t *  usart,
int  c 
)

Send a character with the usart

Parameters:
*usart Base address of the usart
c Character to write
Returns:
0 if char was written, -1 if the function timed out before the usart transmitter became ready to send

Definition at line 538 of file usart.c.

References USART_DEFAULT_TIMEOUT, USART_SUCCESS, and usart_write_char().

Referenced by print().

00539 {
00540         int timeout = USART_DEFAULT_TIMEOUT;
00541 
00542         if (c == '\n'){
00543           while ((usart_write_char(usart, '\r') != USART_SUCCESS) && (timeout>0) ){
00544             timeout--;
00545           }
00546         
00547           if (timeout == 0)
00548             return -1;
00549           timeout = USART_DEFAULT_TIMEOUT;
00550         }
00551 
00552         while ((usart_write_char(usart, c) != USART_SUCCESS) && ( timeout>0 )){
00553           timeout--;
00554         }
00555         if (timeout == 0)
00556                 return -1;
00557         else
00558                 return 0;
00559 }

Here is the call graph for this function:

int usart_read_char ( volatile struct avr32_usart_t *  usart,
int *  c 
)

Checks the RX buffer for a received character, and puts this at the memory location given.

Parameters:
*usart Base address of the usart
*c Pointer to the where the read charcter should be writen (must be short in order to accept 9 bit characters)
Returns:
USART_SUCCESS if the character was read successfully
USART_RX_EMPTY if the RX buffer was empty
USART_RX_ERROR if an error was deteceted
USART_ADDR_RECEIVED if an address is received while in multidrop mode

Definition at line 504 of file usart.c.

References USART_RX_EMPTY, USART_RX_ERROR, and USART_SUCCESS.

Referenced by usart_getchar().

00505 {
00506         /* Check for errors; Frame, parity and overrun In RS485 mode a parity
00507                 error would mean that we received an address char */
00508         if (usart->csr &
00509                         ((1 << AVR32_USART_CSR_OVRE_OFFSET) |
00510                         (1 << AVR32_USART_CSR_FRAME_OFFSET) |
00511                         (1 << AVR32_USART_CSR_PARE_OFFSET))) {
00512                 return USART_RX_ERROR;
00513         }
00514         /* No error; if we really did receive a char, read it and return SUCCESS */
00515         else if ((usart->csr & (1<<AVR32_USART_CSR_RXRDY_OFFSET)) != 0) {
00516                 *c = (unsigned short)usart->rhr;
00517                 return USART_SUCCESS;
00518         } else {
00519                 return USART_RX_EMPTY;
00520         }
00521 } /* usart_read */

void usart_reset ( volatile struct avr32_usart_t *  usart  ) 

This function will reset the USART, and disable TX and RX

Parameters:
*usart Base address of the usart
Returns:
nothing

Definition at line 70 of file usart.c.

Referenced by usart_init_iso7816(), and usart_init_rs232().

00071 {
00072         /* Disable all usart interrupts, interrupts needed should be set
00073            explicitly on every reset */
00074         usart->idr = 0xFFFFffff;
00075 
00076         /* Reset mode and other registers that could cause unpredictable
00077            behaviour after reset */
00078         usart->mr = 0;
00079         usart->rtor = 0;
00080         usart->ttgr = 0;
00081 
00082         /* Shutdown RX and TX (will be reenabled when setup
00083            is completed successfully), reset status bits and turn
00084            off DTR and RTS */
00085         usart->cr = (1 << AVR32_USART_CR_RSTRX_OFFSET) |
00086                     (1 << AVR32_USART_CR_RSTTX_OFFSET) |
00087                     (1 << AVR32_USART_CR_RSTSTA_OFFSET) |
00088                     (1 << AVR32_USART_CR_RSTIT_OFFSET) |
00089                     (1 << AVR32_USART_CR_RSTNACK_OFFSET) |
00090                     (1 << AVR32_USART_CR_DTRDIS_OFFSET) |
00091                     (1 << AVR32_USART_CR_RTSDIS_OFFSET);
00092 }

void usart_reset_status ( volatile struct avr32_usart_t *  usart  ) 

Reset error status.

This function resets the status bits indicating that a parity error, framing error or overrun has occured. The rxbreak bit, indicating a start/end of break condition on the rx-line, is also reset.

Parameters:
*usart Base address of the usart
Returns:
nothing

Definition at line 405 of file usart.c.

00406 {
00407         usart->cr |= (1<<AVR32_USART_CR_RSTSTA_OFFSET);
00408 }

int usart_send_address ( volatile struct avr32_usart_t *  usart,
int  address 
)

Definition at line 461 of file usart.c.

References usart_bw_write_char(), USART_MODE_FAULT, usart_mode_is_multidrop(), and USART_SUCCESS.

00462 {
00463         /* Check if usart is in multidrop / RS485 mode */
00464         if ( usart_mode_is_multidrop(usart) )
00465         {
00466                 /* Prepare to send an address */
00467                 usart->cr |= (1<<AVR32_USART_CR_SENDA_OFFSET);
00468 
00469                 /* Write the address to TX */
00470                 usart_bw_write_char(usart, address);
00471                 return USART_SUCCESS;
00472         } else {
00473                 return USART_MODE_FAULT;
00474         }
00475 }

Here is the call graph for this function:

static int usart_set_baudrate ( volatile struct avr32_usart_t *  usart,
unsigned int  baudrate,
long  cpu_hz 
) [static]

This function will calculate a clock divider(CD) and fractional part(FP) that gets the usart as close to a wanted baudrate as possible

Parameters:
*usart Base address of the usart
baudrate Wanted baudrate
cpu_hz Frequency of the selected clock
Returns:
USART_SUCCESS or USART_INVALID_INPUT if wanted baudrate is impossible with given clockspeed

Definition at line 105 of file usart.c.

References USART_INVALID_INPUT, and USART_SUCCESS.

Referenced by usart_init_iso7816(), and usart_init_rs232().

00106 {
00107         int cd; /* Clock divider */
00108 
00109         /*
00110          *             ** BAUDRATE CALCULATION **
00111          *
00112          *                 Selected Clock                       Selected Clock
00113          *     baudrate = ----------------   or     baudrate = ----------------
00114          *                             16 x CD                                        8 x CD
00115          *
00116          *       (with 16x oversampling)              (with 8x oversampling)
00117          */
00118 
00119         if ( baudrate < (cpu_hz/16)  ){
00120                 /* Use 8x oversampling */
00121                 usart->mr |= (1<<AVR32_USART_MR_OVER_OFFSET);
00122                 cd = cpu_hz / (8*baudrate);
00123 
00124                 if (cd < 2) {
00125                         return USART_INVALID_INPUT;
00126                 }
00127                 usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
00128         } else {
00129                 /* Use 16x oversampling */
00130                 usart->mr &= ~(1<<AVR32_USART_MR_OVER_OFFSET);
00131                 cd =  cpu_hz / (16*baudrate);
00132 
00133                 if (cd > 65535) {
00134                   /* Baudrate is too low */
00135                   return USART_INVALID_INPUT;
00136                 }
00137         }
00138         usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
00139         return USART_SUCCESS;
00140 }

int usart_write_char ( volatile struct avr32_usart_t *  usart,
int  c 
)

If the transmitter is ready; write the given character to the TX buffer

Parameters:
*usart Base address of the usart
c The character (up to 9 bits) to transmit
Returns:
USART_SUCCESS when the transmitter is ready USART_TX_BUSY when the transmitter is busy

Definition at line 492 of file usart.c.

References USART_SUCCESS, and USART_TX_BUSY.

Referenced by usart_bw_write_char(), and usart_putchar().

00493 {
00494 
00495         if ((usart->csr & (1<<AVR32_USART_CSR_TXRDY_OFFSET)) != 0) {
00496                 usart->thr = c;
00497                 return USART_SUCCESS;
00498         }
00499         else
00500                 return USART_TX_BUSY;
00501 }


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