This file contains basic drivers for the AVR32 USART, with support for all all modes, settings and clock speeds.
Definition in file usart.c.
#include "usart.h"
#include "errno.h"
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) |
| 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*
| *usart | Base address of the usart | |
| c | The character (up to 9 bits) to transmit |
Definition at line 475 of file usart.c.
References SUCCESS, and usart_write_char().
Referenced by usart_send_address().
00476 { 00477 while (usart_write_char(usart, c) != SUCCESS) { 00478 } 00479 00480 return; 00481 }
| int usart_framing_error | ( | volatile struct avr32_usart_t * | usart | ) |
| int usart_getchar | ( | volatile struct avr32_usart_t * | usart | ) |
Wait until a character is recevied, and return this.
| *usart | Base address of the usart |
Definition at line 515 of file usart.c.
References usart_read_char(), USART_RX_EMPTY, and USART_RX_ERROR.
00516 { 00517 int c, ret; 00518 00519 while (((ret = usart_read_char(usart, &c)) == USART_RX_EMPTY)) { 00520 } 00521 00522 if (ret == USART_RX_ERROR) 00523 return -1; 00524 else 00525 return c; 00526 }
| 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 221 of file usart.c.
References INVALID_ARGUMENT, SUCCESS, usart_init_rs232(), and USART_MODE_HW_HSH.
00224 { 00225 int retval; 00226 00227 /* First: Setup standard RS323 */ 00228 if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != SUCCESS) 00229 return retval; 00230 00231 if (software_handshaking == 0) 00232 { 00233 /* Clear previous mode */ 00234 usart-> mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET); 00235 /* Hardware handshaking */ 00236 usart-> mr |= (USART_MODE_HW_HSH << AVR32_USART_MR_MODE_OFFSET); 00237 } 00238 else 00239 return INVALID_ARGUMENT; 00240 00241 return SUCCESS; 00242 }
| 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 252 of file usart.c.
References SUCCESS, and usart_init_rs232().
00254 { 00255 int retval; 00256 00257 /* First: Setup standard RS323 */ 00258 if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != SUCCESS) 00259 return retval; 00260 00261 /* Set IrDA counter */ 00262 usart->ifr = irda_filter; 00263 00264 /* Activate "low-pass filtering" of input */ 00265 usart->mr |= (1 << AVR32_USART_MR_FILTER_OFFSET); 00266 return SUCCESS; 00267 }
| 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 324 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, INVALID_ARGUMENT, iso7816_options_t::iso7816_hz, iso7816_options_t::max_iterations, SUCCESS, USART_MODE_ISO7816_T0, USART_MODE_ISO7816_T1, usart_reset(), and usart_set_baudrate().
00325 { 00326 int retval; 00327 00328 /* Reset the usart and shutdown RX and TX */ 00329 usart_reset(usart); 00330 00331 if (opt == 0) 00332 /* Null pointer */ 00333 return INVALID_ARGUMENT; 00334 00335 /* Don't care about charlength, parity or channelmode; All these fields 00336 are ignored in iso7816 mode. 8bit characters and even parity is always 00337 used */ 00338 00339 if (t == 0) 00340 { 00341 /* Set USART mode to ISO7816, T=0 */ 00342 /* The T=0 protocol always use 2 stop bits */ 00343 usart->mr = (USART_MODE_ISO7816_T0 << AVR32_USART_MR_MODE_OFFSET) | 00344 (2 << AVR32_USART_MR_NBSTOP_OFFSET) | 00345 (opt->bit_order << AVR32_USART_MR_MSBF_OFFSET); /* Allow MSBF in T=0 */ 00346 } 00347 else if (t == 1) 00348 { 00349 /* Only LSB first in the T=1 protocol */ 00350 if (opt->bit_order != 0) 00351 return INVALID_ARGUMENT; 00352 /* max_iterations field is only used in T=0 mode */ 00353 if (opt->max_iterations != 0) 00354 return INVALID_ARGUMENT; 00355 /* Set USART mode to ISO7816, T=1 */ 00356 usart->mr = (USART_MODE_ISO7816_T1 << AVR32_USART_MR_MODE_OFFSET); 00357 /* The T=1 protocol always use 1 stop bit (no change needed) */ 00358 } 00359 else 00360 return INVALID_ARGUMENT; 00361 00362 if ((retval = usart_set_baudrate(usart, opt->iso7816_hz, cpu_hz)) != SUCCESS) 00363 return retval; 00364 00365 /* Set FIDI register: bit rate = selected clock/FI_DI_ratio/16 */ 00366 usart->fidi = opt->fidi_ratio; 00367 /* Set ISO7816 spesific options in the MODE register */ 00368 usart->mr |= (opt->inhibit_nack << AVR32_USART_MR_INACK_OFFSET) | 00369 (opt->dis_suc_nack << AVR32_USART_MR_DSNACK_OFFSET) | 00370 (opt->max_iterations << AVR32_USART_MR_MAX_ITERATION_OFFSET) | 00371 (1 << AVR32_USART_MR_CLKO_OFFSET); /* Enable clock output */ 00372 00373 /* Setup complete; enable input */ 00374 /* Leave TX disabled for now */ 00375 usart->cr |= (1<<AVR32_USART_CR_RXEN_OFFSET); 00376 00377 return SUCCESS; 00378 }
| int usart_init_modem | ( | volatile struct avr32_usart_t * | usart, | |
| struct usart_options_t * | opt, | |||
| long | cpu_hz | |||
| ) |
Definition at line 276 of file usart.c.
References SUCCESS, usart_init_rs232(), and USART_MODE_MODEM.
00277 { 00278 int retval; 00279 00280 /* First: Setup standard RS323 */ 00281 if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != SUCCESS) 00282 return retval; 00283 00284 /* Clear previous mode */ 00285 usart-> mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET); 00286 /* Set Modem mode */ 00287 usart-> mr |= (USART_MODE_MODEM << AVR32_USART_MR_MODE_OFFSET); 00288 return SUCCESS; 00289 }
| 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
| *usart | Base address of the usart | |
| *opt | Options needed to set up RS232 communcation (see usart_options_t) | |
| cpu_hz | The usart clk frequency |
Definition at line 153 of file usart.c.
References usart_options_t::baudrate, usart_options_t::channelmode, usart_options_t::charlength, INVALID_ARGUMENT, usart_options_t::paritytype, usart_options_t::stopbits, SUCCESS, usart_reset(), and usart_set_baudrate().
Referenced by init_uart_a(), usart_init_handshaking(), usart_init_IrDA(), usart_init_modem(), and usart_init_rs485().
00154 { 00155 int retval; 00156 00157 /* Reset the usart and shutdown RX and TX */ 00158 usart_reset(usart); 00159 00160 /* Control input values */ 00161 if (opt == 0) /* Null pointer */ 00162 return INVALID_ARGUMENT; 00163 if (opt->charlength < 5 || opt->charlength > 9) 00164 return INVALID_ARGUMENT; 00165 if (opt->paritytype > 7) 00166 return INVALID_ARGUMENT; 00167 if (opt->stopbits > 2+255) 00168 return INVALID_ARGUMENT; 00169 if (opt->channelmode > 3) 00170 return INVALID_ARGUMENT; 00171 00172 if ((retval = usart_set_baudrate(usart, opt->baudrate, cpu_hz)) != \ 00173 SUCCESS) 00174 return retval; 00175 00176 if (opt->charlength == 9) { 00177 /* Charlength set to 9 bits; MODE9 dominates CHRL */ 00178 usart->mr |= (1<<AVR32_USART_MR_MODE9_OFFSET); 00179 } else { 00180 /* CHRL gives the charlength( - 5) when USART_MODE9=0 */ 00181 usart->mr |= 00182 ((opt->charlength-5) << AVR32_USART_MR_CHRL_OFFSET); 00183 } 00184 00185 usart->mr |= (opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET) | 00186 (opt->paritytype << AVR32_USART_MR_PAR_OFFSET); 00187 00188 if (opt->stopbits > 2) 00189 { 00190 /* Set two stop bits */ 00191 usart->mr |= (2 << AVR32_USART_MR_NBSTOP_OFFSET); 00192 /* And a timeguard period gives the rest */ 00193 usart->ttgr = (opt->stopbits-2); 00194 } 00195 else 00196 /* Insert 1, 1.5 or 2 stop bits */ 00197 usart->mr |= (opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET); 00198 00199 /* Setup complete; enable communication */ 00200 /* Enable input and output */ 00201 usart->cr |= (1<<AVR32_USART_CR_TXEN_OFFSET) | 00202 (1<<AVR32_USART_CR_RXEN_OFFSET); 00203 00204 return SUCCESS; 00205 }
| int usart_init_rs485 | ( | volatile struct avr32_usart_t * | usart, | |
| struct usart_options_t * | opt, | |||
| long | cpu_hz | |||
| ) |
Definition at line 301 of file usart.c.
References SUCCESS, usart_init_rs232(), and USART_MODE_RS485.
00302 { 00303 int retval; 00304 00305 /* First: Setup standard RS323 */ 00306 if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != SUCCESS) 00307 return retval; 00308 00309 /* Clear previous mode */ 00310 usart->mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET); 00311 /* Set Modem mode */ 00312 usart->mr |= (USART_MODE_RS485 << AVR32_USART_MR_MODE_OFFSET); 00313 return SUCCESS; 00314 }
| static int usart_mode_is_multidrop | ( | volatile struct avr32_usart_t * | usart | ) | [static] |
Definition at line 66 of file usart.c.
Referenced by usart_send_address().
00067 { 00068 return ( (usart->mr & 0x00000600) >> AVR32_USART_MR_PAR_OFFSET ); 00069 }
| 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 | |||
| ) |
Send a character with the usart
| *usart | Base address of the usart | |
| c | Character to write |
Definition at line 529 of file usart.c.
References SUCCESS, USART_DEFAULT_TIMEOUT, and usart_write_char().
Referenced by print(), and usart_print().
00530 { 00531 int timeout = USART_DEFAULT_TIMEOUT; 00532 00533 if (c == '\n'){ 00534 while ((usart_write_char(usart, '\r') != SUCCESS) && (timeout>0) ){ 00535 timeout--; 00536 } 00537 00538 if (timeout == 0) 00539 return -1; 00540 timeout = USART_DEFAULT_TIMEOUT; 00541 } 00542 00543 while ((usart_write_char(usart, c) != SUCCESS) && ( timeout>0 )){ 00544 timeout--; 00545 } 00546 if (timeout == 0) 00547 return -1; 00548 else 00549 return 0; 00550 }
| 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.
| *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) |
Definition at line 495 of file usart.c.
References SUCCESS, USART_RX_EMPTY, and USART_RX_ERROR.
Referenced by usart_getchar().
00496 { 00497 /* Check for errors; Frame, parity and overrun In RS485 mode a parity 00498 error would mean that we received an address char */ 00499 if (usart->csr & 00500 ((1 << AVR32_USART_CSR_OVRE_OFFSET) | 00501 (1 << AVR32_USART_CSR_FRAME_OFFSET) | 00502 (1 << AVR32_USART_CSR_PARE_OFFSET))) { 00503 return USART_RX_ERROR; 00504 } 00505 /* No error; if we really did receive a char, read it and return SUCCESS */ 00506 else if ((usart->csr & (1<<AVR32_USART_CSR_RXRDY_OFFSET)) != 0) { 00507 *c = (unsigned short)usart->rhr; 00508 return SUCCESS; 00509 } else { 00510 return USART_RX_EMPTY; 00511 } 00512 } /* usart_read */
| void usart_reset | ( | volatile struct avr32_usart_t * | usart | ) |
This function will reset the USART, and disable TX and RX
| *usart | Base address of the usart |
Definition at line 71 of file usart.c.
Referenced by board_init(), usart_init_iso7816(), and usart_init_rs232().
00072 { 00073 /* Disable all usart interrupts, interrupts needed should be set 00074 explicitly on every reset */ 00075 usart->idr = 0xFFFFffff; 00076 00077 /* Reset mode and other registers that could cause unpredictable 00078 behaviour after reset */ 00079 usart->mr = 0; 00080 usart->rtor = 0; 00081 usart->ttgr = 0; 00082 00083 /* Shutdown RX and TX (will be reenabled when setup 00084 is completed successfully), reset status bits and turn 00085 off DTR and RTS */ 00086 usart->cr = (1 << AVR32_USART_CR_RSTRX_OFFSET) | 00087 (1 << AVR32_USART_CR_RSTTX_OFFSET) | 00088 (1 << AVR32_USART_CR_RSTSTA_OFFSET) | 00089 (1 << AVR32_USART_CR_RSTIT_OFFSET) | 00090 (1 << AVR32_USART_CR_RSTNACK_OFFSET) | 00091 (1 << AVR32_USART_CR_DTRDIS_OFFSET) | 00092 (1 << AVR32_USART_CR_RTSDIS_OFFSET); 00093 }
| 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.
| *usart | Base address of the usart |
Definition at line 396 of file usart.c.
00397 { 00398 usart->cr |= (1<<AVR32_USART_CR_RSTSTA_OFFSET); 00399 }
| int usart_send_address | ( | volatile struct avr32_usart_t * | usart, | |
| int | address | |||
| ) |
Definition at line 452 of file usart.c.
References SUCCESS, usart_bw_write_char(), USART_MODE_FAULT, and usart_mode_is_multidrop().
00453 { 00454 /* Check if usart is in multidrop / RS485 mode */ 00455 if ( usart_mode_is_multidrop(usart) ) 00456 { 00457 /* Prepare to send an address */ 00458 usart->cr |= (1<<AVR32_USART_CR_SENDA_OFFSET); 00459 00460 /* Write the address to TX */ 00461 usart_bw_write_char(usart, address); 00462 return SUCCESS; 00463 } else { 00464 return USART_MODE_FAULT; 00465 } 00466 }
| 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
| *usart | Base address of the usart | |
| baudrate | Wanted baudrate | |
| cpu_hz | Frequency of the selected clock |
Definition at line 106 of file usart.c.
References INVALID_ARGUMENT, and SUCCESS.
Referenced by usart_init_iso7816(), and usart_init_rs232().
00107 { 00108 int cd; /* Clock divider */ 00109 00110 /* 00111 * ** BAUDRATE CALCULATION ** 00112 * 00113 * Selected Clock Selected Clock 00114 * baudrate = ---------------- or baudrate = ---------------- 00115 * 16 x CD 8 x CD 00116 * 00117 * (with 16x oversampling) (with 8x oversampling) 00118 */ 00119 00120 if ( baudrate < (cpu_hz/16) ){ 00121 /* Use 8x oversampling */ 00122 usart->mr |= (1<<AVR32_USART_MR_OVER_OFFSET); 00123 cd = cpu_hz / (8*baudrate); 00124 00125 if (cd < 2) { 00126 return INVALID_ARGUMENT; 00127 } 00128 usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET); 00129 } else { 00130 /* Use 16x oversampling */ 00131 usart->mr &= ~(1<<AVR32_USART_MR_OVER_OFFSET); 00132 cd = cpu_hz / (16*baudrate); 00133 00134 if (cd > 65535) { 00135 /* Baudrate is too low */ 00136 return INVALID_ARGUMENT; 00137 } 00138 } 00139 usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET); 00140 return SUCCESS; 00141 }
| 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
| *usart | Base address of the usart | |
| c | The character (up to 9 bits) to transmit |
Definition at line 483 of file usart.c.
References SUCCESS, and USART_TX_BUSY.
Referenced by usart_bw_write_char(), and usart_putchar().
00484 { 00485 00486 if ((usart->csr & (1<<AVR32_USART_CSR_TXRDY_OFFSET)) != 0) { 00487 usart->thr = c; 00488 return SUCCESS; 00489 } 00490 else 00491 return USART_TX_BUSY; 00492 }
1.5.3-20071008