- Main Page
- Related Pages
- Data Structures
- Files

# usart.c

Go to the documentation of this file.

    00001 /*This file is prepared for Doxygen automatic documentation generation.*/
    00018 /* Copyright (C) 2006-2008, Atmel Corporation All rights reserved.
    00019  *
    00020  * Redistribution and use in source and binary forms, with or without
    00021  * modification, are permitted provided that the following conditions are met:
    00022  *
    00023  * 1. Redistributions of source code must retain the above copyright notice,
    00024  * this list of conditions and the following disclaimer.
    00025  *
    00026  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00027  * this list of conditions and the following disclaimer in the documentation
    00028  * and/or other materials provided with the distribution.
    00029  *
    00030  * 3. The name of ATMEL may not be used to endorse or promote products derived
    00031  * from this software without specific prior written permission.
    00032  *
    00033  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
    00034  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00035  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
    00036  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
    00037  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00038  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00039  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00040  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00041  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    00042  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00043  */
    00044
    00045
    00046 #include "compiler.h"
    00047 #include "usart.h"
    00048
    00049
    00050 //------------------------------------------------------------------------------
    00053
    00054
    00055
    00062 #if __GNUC__
    00063 __attribute__((__always_inline__))
    00064 #endif
    00065 static __inline__ int usart_mode_is_multidrop(volatile avr32_usart_t *usart)
    00066 {
    00067   return ((usart->mr >> AVR32_USART_MR_PAR_OFFSET) & AVR32_USART_MR_PAR_MULTI) == AVR32_USART_MR_PAR_MULTI;
    00068 }
    00069
    00070
    00086 static int usart_set_async_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
    00087 {
    00088   unsigned int over = (pba_hz >= 16 * baudrate) ? 16 : 8;
    00089   unsigned int cd_fp = ((1 << AVR32_USART_BRGR_FP_SIZE) * pba_hz + (over * baudrate) / 2) / (over * baudrate);
    00090   unsigned int cd = cd_fp >> AVR32_USART_BRGR_FP_SIZE;
    00091   unsigned int fp = cd_fp & ((1 << AVR32_USART_BRGR_FP_SIZE) - 1);
    00092
    00093   if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
    00094     return USART_INVALID_INPUT;
    00095
    00096   usart->mr = (usart->mr & ~(AVR32_USART_MR_USCLKS_MASK |
    00097                              AVR32_USART_MR_SYNC_MASK |
    00098                              AVR32_USART_MR_OVER_MASK)) |
    00099               AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
    00100               ((over == 16) ? AVR32_USART_MR_OVER_X16 : AVR32_USART_MR_OVER_X8) << AVR32_USART_MR_OVER_OFFSET;
    00101
    00102   usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET |
    00103                 fp << AVR32_USART_BRGR_FP_OFFSET;
    00104
    00105   return USART_SUCCESS;
    00106 }
    00107
    00108
    00123 static int usart_set_sync_master_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
    00124 {
    00125   unsigned int cd = (pba_hz + baudrate / 2) / baudrate;
    00126
    00127   if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
    00128     return USART_INVALID_INPUT;
    00129
    00130   usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
    00131               AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
    00132               AVR32_USART_MR_SYNC_MASK;
    00133
    00134   usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
    00135
    00136   return USART_SUCCESS;
    00137 }
    00138
    00139
    00147 static int usart_set_sync_slave_baudrate(volatile avr32_usart_t *usart)
    00148 {
    00149   usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
    00150               AVR32_USART_MR_USCLKS_SCK << AVR32_USART_MR_USCLKS_OFFSET |
    00151               AVR32_USART_MR_SYNC_MASK;
    00152
    00153   return USART_SUCCESS;
    00154 }
    00155
    00156
    00170 static int usart_set_iso7816_clock(volatile avr32_usart_t *usart, unsigned int clock, unsigned long pba_hz)
    00171 {
    00172   unsigned int cd = (pba_hz + clock / 2) / clock;
    00173
    00174   if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
    00175     return USART_INVALID_INPUT;
    00176
    00177   usart->mr = (usart->mr & ~(AVR32_USART_MR_USCLKS_MASK |
    00178                              AVR32_USART_MR_SYNC_MASK |
    00179                              AVR32_USART_MR_OVER_MASK)) |
    00180               AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
    00181               AVR32_USART_MR_OVER_X16 << AVR32_USART_MR_OVER_OFFSET;
    00182
    00183   usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
    00184
    00185   return USART_SUCCESS;
    00186 }
    00187
    00188
    00189 #if defined(AVR32_USART_400_H_INCLUDED) || \
    00190     defined(AVR32_USART_410_H_INCLUDED) || \
    00191     defined(AVR32_USART_420_H_INCLUDED)
    00192
    00193
    00207 static int usart_set_spi_master_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
    00208 {
    00209   unsigned int cd = (pba_hz + baudrate / 2) / baudrate;
    00210
    00211   if (cd < 4 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
    00212     return USART_INVALID_INPUT;
    00213
    00214   usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
    00215               AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET;
    00216
    00217   usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
    00218
    00219   return USART_SUCCESS;
    00220 }
    00221
    00222
    00230 static int usart_set_spi_slave_baudrate(volatile avr32_usart_t *usart)
    00231 {
    00232   usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
    00233               AVR32_USART_MR_USCLKS_SCK << AVR32_USART_MR_USCLKS_OFFSET;
    00234
    00235   return USART_SUCCESS;
    00236 }
    00237
    00238
    00239 #endif  // USART rev. >= 4.0.0
    00240
    00241
    00243
    00244
    00245 //------------------------------------------------------------------------------
    00248
    00249
    00250
    00251 void usart_reset(volatile avr32_usart_t *usart)
    00252 {
    00253   Bool global_interrupt_enabled = Is_global_interrupt_enabled();
    00254
    00255   // Disable all USART interrupts.
    00256   // Interrupts needed should be set explicitly on every reset.
    00257   if (global_interrupt_enabled) Disable_global_interrupt();
    00258   usart->idr = 0xFFFFFFFF;
    00259   usart->csr;
    00260   if (global_interrupt_enabled) Enable_global_interrupt();
    00261
    00262   // Reset mode and other registers that could cause unpredictable behavior after reset.
    00263   usart->mr = 0;
    00264   usart->rtor = 0;
    00265   usart->ttgr = 0;
    00266
    00267   // Shutdown TX and RX (will be re-enabled when setup has successfully completed),
    00268   // reset status bits and turn off DTR and RTS.
    00269   usart->cr = AVR32_USART_CR_RSTRX_MASK   |
    00270               AVR32_USART_CR_RSTTX_MASK   |
    00271               AVR32_USART_CR_RSTSTA_MASK  |
    00272               AVR32_USART_CR_RSTIT_MASK   |
    00273               AVR32_USART_CR_RSTNACK_MASK |
    00274               AVR32_USART_CR_DTRDIS_MASK  |
    00275               AVR32_USART_CR_RTSDIS_MASK;
    00276 }
    00277
    00278
    00279 int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
    00280 {
    00281   // Reset the USART and shutdown TX and RX.
    00282   usart_reset(usart);
    00283
    00284   // Check input values.
    00285   if (!opt || // Null pointer.
    00286       opt->charlength < 5 || opt->charlength > 9 ||
    00287       opt->paritytype > 7 ||
    00288       opt->stopbits > 2 + 255 ||
    00289       opt->channelmode > 3 ||
    00290       usart_set_async_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
    00291     return USART_INVALID_INPUT;
    00292
    00293   if (opt->charlength == 9)
    00294   {
    00295     // Character length set to 9 bits. MODE9 dominates CHRL.
    00296     usart->mr |= AVR32_USART_MR_MODE9_MASK;
    00297   }
    00298   else
    00299   {
    00300     // CHRL gives the character length (- 5) when MODE9 = 0.
    00301     usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
    00302   }
    00303
    00304   usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
    00305                opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
    00306
    00307   if (opt->stopbits > USART_2_STOPBITS)
    00308   {
    00309     // Set two stop bits
    00310     usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
    00311     // and a timeguard period gives the rest.
    00312     usart->ttgr = opt->stopbits - USART_2_STOPBITS;
    00313   }
    00314   else
    00315     // Insert 1, 1.5 or 2 stop bits.
    00316     usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
    00317
    00318   // Set normal mode.
    00319   usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
    00320               AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
    00321
    00322   // Setup complete; enable communication.
    00323   // Enable input and output.
    00324   usart->cr = AVR32_USART_CR_RXEN_MASK |
    00325               AVR32_USART_CR_TXEN_MASK;
    00326
    00327   return USART_SUCCESS;
    00328 }
    00329
    00330
    00331 int usart_init_rs232_tx_only(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
    00332 {
    00333   // Reset the USART and shutdown TX and RX.
    00334   usart_reset(usart);
    00335
    00336   // Check input values.
    00337   if (!opt || // Null pointer.
    00338       opt->charlength < 5 || opt->charlength > 9 ||
    00339       opt->paritytype > 7 ||
    00340       opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
    00341       opt->channelmode > 3 ||
    00342       usart_set_sync_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
    00343     return USART_INVALID_INPUT;
    00344
    00345   if (opt->charlength == 9)
    00346   {
    00347     // Character length set to 9 bits. MODE9 dominates CHRL.
    00348     usart->mr |= AVR32_USART_MR_MODE9_MASK;
    00349   }
    00350   else
    00351   {
    00352     // CHRL gives the character length (- 5) when MODE9 = 0.
    00353     usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
    00354   }
    00355
    00356   usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
    00357                opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
    00358
    00359   if (opt->stopbits > USART_2_STOPBITS)
    00360   {
    00361     // Set two stop bits
    00362     usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
    00363     // and a timeguard period gives the rest.
    00364     usart->ttgr = opt->stopbits - USART_2_STOPBITS;
    00365   }
    00366   else
    00367     // Insert 1 or 2 stop bits.
    00368     usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
    00369
    00370   // Set normal mode.
    00371   usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
    00372               AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
    00373
    00374   // Setup complete; enable communication.
    00375   // Enable only output as input is not possible in synchronous mode without
    00376   // transferring clock.
    00377   usart->cr = AVR32_USART_CR_TXEN_MASK;
    00378
    00379   return USART_SUCCESS;
    00380 }
    00381
    00382
    00383 int usart_init_hw_handshaking(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
    00384 {
    00385   // First: Setup standard RS232.
    00386   if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
    00387     return USART_INVALID_INPUT;
    00388
    00389   // Set hardware handshaking mode.
    00390   usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
    00391               AVR32_USART_MR_MODE_HARDWARE << AVR32_USART_MR_MODE_OFFSET;
    00392
    00393   return USART_SUCCESS;
    00394 }
    00395
    00396
    00397 int usart_init_modem(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
    00398 {
    00399   // First: Setup standard RS232.
    00400   if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
    00401     return USART_INVALID_INPUT;
    00402
    00403   // Set modem mode.
    00404   usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
    00405               AVR32_USART_MR_MODE_MODEM << AVR32_USART_MR_MODE_OFFSET;
    00406
    00407   return USART_SUCCESS;
    00408 }
    00409
    00410
    00411 int usart_init_sync_master(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
    00412 {
    00413   // Reset the USART and shutdown TX and RX.
    00414   usart_reset(usart);
    00415
    00416   // Check input values.
    00417   if (!opt || // Null pointer.
    00418       opt->charlength < 5 || opt->charlength > 9 ||
    00419       opt->paritytype > 7 ||
    00420       opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
    00421       opt->channelmode > 3 ||
    00422       usart_set_sync_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
    00423     return USART_INVALID_INPUT;
    00424
    00425   if (opt->charlength == 9)
    00426   {
    00427     // Character length set to 9 bits. MODE9 dominates CHRL.
    00428     usart->mr |= AVR32_USART_MR_MODE9_MASK;
    00429   }
    00430   else
    00431   {
    00432     // CHRL gives the character length (- 5) when MODE9 = 0.
    00433     usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
    00434   }
    00435
    00436   usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
    00437                opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
    00438
    00439   if (opt->stopbits > USART_2_STOPBITS)
    00440   {
    00441     // Set two stop bits
    00442     usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
    00443     // and a timeguard period gives the rest.
    00444     usart->ttgr = opt->stopbits - USART_2_STOPBITS;
    00445   }
    00446   else
    00447     // Insert 1 or 2 stop bits.
    00448     usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
    00449
    00450   // Set normal mode.
    00451   usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
    00452               AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET |
    00453               AVR32_USART_MR_CLKO_MASK;
    00454
    00455   // Setup complete; enable communication.
    00456   // Enable input and output.
    00457   usart->cr = AVR32_USART_CR_RXEN_MASK |
    00458               AVR32_USART_CR_TXEN_MASK;
    00459
    00460   return USART_SUCCESS;
    00461 }
    00462
    00463
    00464 int usart_init_sync_slave(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
    00465 {
    00466   // Reset the USART and shutdown TX and RX.
    00467   usart_reset(usart);
    00468
    00469   // Check input values.
    00470   if (!opt || // Null pointer.
    00471       opt->charlength < 5 || opt->charlength > 9 ||
    00472       opt->paritytype > 7 ||
    00473       opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
    00474       opt->channelmode > 3 ||
    00475       usart_set_sync_slave_baudrate(usart) == USART_INVALID_INPUT)
    00476     return USART_INVALID_INPUT;
    00477
    00478   if (opt->charlength == 9)
    00479   {
    00480     // Character length set to 9 bits. MODE9 dominates CHRL.
    00481     usart->mr |= AVR32_USART_MR_MODE9_MASK;
    00482   }
    00483   else
    00484   {
    00485     // CHRL gives the character length (- 5) when MODE9 = 0.
    00486     usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
    00487   }
    00488
    00489   usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
    00490                opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
    00491
    00492   if (opt->stopbits > USART_2_STOPBITS)
    00493   {
    00494     // Set two stop bits
    00495     usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
    00496     // and a timeguard period gives the rest.
    00497     usart->ttgr = opt->stopbits - USART_2_STOPBITS;
    00498   }
    00499   else
    00500     // Insert 1 or 2 stop bits.
    00501     usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
    00502
    00503   // Set normal mode.
    00504   usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
    00505               AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
    00506
    00507   // Setup complete; enable communication.
    00508   // Enable input and output.
    00509   usart->cr = AVR32_USART_CR_RXEN_MASK |
    00510               AVR32_USART_CR_TXEN_MASK;
    00511
    00512   return USART_SUCCESS;
    00513 }
    00514
    00515
    00516 int usart_init_rs485(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
    00517 {
    00518   // First: Setup standard RS232.
    00519   if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
    00520     return USART_INVALID_INPUT;
    00521
    00522   // Set RS485 mode.
    00523   usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
    00524               AVR32_USART_MR_MODE_RS485 << AVR32_USART_MR_MODE_OFFSET;
    00525
    00526   return USART_SUCCESS;
    00527 }
    00528
    00529
    00530 int usart_init_IrDA(volatile avr32_usart_t *usart, const usart_options_t *opt,
    00531                     long pba_hz, unsigned char irda_filter)
    00532 {
    00533   // First: Setup standard RS232.
    00534   if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
    00535     return USART_INVALID_INPUT;
    00536
    00537   // Set IrDA filter.
    00538   usart->ifr = irda_filter;
    00539
    00540   // Set IrDA mode and activate filtering of input.
    00541   usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
    00542               AVR32_USART_MODE_IRDA << AVR32_USART_MR_MODE_OFFSET |
    00543               AVR32_USART_MR_FILTER_MASK;
    00544
    00545   return USART_SUCCESS;
    00546 }
    00547
    00548
    00549 int usart_init_iso7816(volatile avr32_usart_t *usart, const usart_iso7816_options_t *opt, int t, long pba_hz)
    00550 {
    00551   // Reset the USART and shutdown TX and RX.
    00552   usart_reset(usart);
    00553
    00554   // Check input values.
    00555   if (!opt || // Null pointer.
    00556       opt->paritytype > 1)
    00557     return USART_INVALID_INPUT;
    00558
    00559   if (t == 0)
    00560   {
    00561     // Set USART mode to ISO7816, T=0.
    00562     // The T=0 protocol always uses 2 stop bits.
    00563     usart->mr = AVR32_USART_MR_MODE_ISO7816_T0 << AVR32_USART_MR_MODE_OFFSET |
    00564                 AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET |
    00565                 opt->bit_order << AVR32_USART_MR_MSBF_OFFSET; // Allow MSBF in T=0.
    00566   }
    00567   else if (t == 1)
    00568   {
    00569     // Only LSB first in the T=1 protocol.
    00570     // max_iterations field is only used in T=0 mode.
    00571     if (opt->bit_order != 0 ||
    00572         opt->max_iterations != 0)
    00573       return USART_INVALID_INPUT;
    00574
    00575     // Set USART mode to ISO7816, T=1.
    00576     // The T=1 protocol always uses 1 stop bit.
    00577     usart->mr = AVR32_USART_MR_MODE_ISO7816_T1 << AVR32_USART_MR_MODE_OFFSET |
    00578                 AVR32_USART_MR_NBSTOP_1 << AVR32_USART_MR_NBSTOP_OFFSET;
    00579   }
    00580   else
    00581     return USART_INVALID_INPUT;
    00582
    00583   if (usart_set_iso7816_clock(usart, opt->iso7816_hz, pba_hz) == USART_INVALID_INPUT)
    00584     return USART_INVALID_INPUT;
    00585
    00586   // Set FIDI register: bit rate = selected clock/FI_DI_ratio/16.
    00587   usart->fidi = opt->fidi_ratio;
    00588
    00589   // Set ISO7816 spesific options in the MODE register.
    00590   usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
    00591                AVR32_USART_MR_CLKO_MASK | // Enable clock output.
    00592                opt->inhibit_nack << AVR32_USART_MR_INACK_OFFSET |
    00593                opt->dis_suc_nack << AVR32_USART_MR_DSNACK_OFFSET |
    00594                opt->max_iterations << AVR32_USART_MR_MAX_ITERATION_OFFSET;
    00595
    00596   // Setup complete; enable the receiver by default.
    00597   usart_iso7816_enable_receiver(usart);
    00598
    00599   return USART_SUCCESS;
    00600 }
    00601
    00602
    00603 #if defined(AVR32_USART_400_H_INCLUDED) || \
    00604     defined(AVR32_USART_410_H_INCLUDED) || \
    00605     defined(AVR32_USART_420_H_INCLUDED)
    00606
    00607
    00608 int usart_init_lin_master(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz)
    00609 {
    00610   // Reset the USART and shutdown TX and RX.
    00611   usart_reset(usart);
    00612
    00613   // Check input values.
    00614   if (usart_set_async_baudrate(usart, baudrate, pba_hz) == USART_INVALID_INPUT)
    00615     return USART_INVALID_INPUT;
    00616
    00617   usart->mr |= AVR32_USART_MR_MODE_LIN_MASTER << AVR32_USART_MR_MODE_OFFSET;  // LIN master mode.
    00618
    00619   // Setup complete; enable communication.
    00620   // Enable input and output.
    00621   usart->cr = AVR32_USART_CR_RXEN_MASK |
    00622               AVR32_USART_CR_TXEN_MASK;
    00623
    00624   return USART_SUCCESS;
    00625 }
    00626
    00627
    00628 int usart_init_lin_slave(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz)
    00629 {
    00630   // Reset the USART and shutdown TX and RX.
    00631   usart_reset(usart);
    00632
    00633   // Check input values.
    00634   if (usart_set_async_baudrate(usart, baudrate, pba_hz) == USART_INVALID_INPUT)
    00635     return USART_INVALID_INPUT;
    00636
    00637   usart->mr |= AVR32_USART_MR_MODE_LIN_SLAVE << AVR32_USART_MR_MODE_OFFSET; // LIN slave mode.
    00638
    00639   // Setup complete; enable communication.
    00640   // Enable input and output.
    00641   usart->cr = AVR32_USART_CR_RXEN_MASK |
    00642               AVR32_USART_CR_TXEN_MASK;
    00643
    00644   return USART_SUCCESS;
    00645 }
    00646
    00647
    00648 int usart_init_spi_master(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz)
    00649 {
    00650   // Reset the USART and shutdown TX and RX.
    00651   usart_reset(usart);
    00652
    00653   // Check input values.
    00654   if (!opt || // Null pointer.
    00655       opt->charlength < 5 || opt->charlength > 9 ||
    00656       opt->spimode > 3 ||
    00657       opt->channelmode > 3 ||
    00658       usart_set_spi_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
    00659     return USART_INVALID_INPUT;
    00660
    00661   if (opt->charlength == 9)
    00662   {
    00663     // Character length set to 9 bits. MODE9 dominates CHRL.
    00664     usart->mr |= AVR32_USART_MR_MODE9_MASK;
    00665   }
    00666   else
    00667   {
    00668     // CHRL gives the character length (- 5) when MODE9 = 0.
    00669     usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
    00670   }
    00671
    00672   usart->mr |= AVR32_USART_MR_MODE_SPI_MASTER << AVR32_USART_MR_MODE_OFFSET | // SPI master mode.
    00673                ((opt->spimode & 0x1) ^ 0x1) << AVR32_USART_MR_SYNC_OFFSET |   // SPI clock phase.
    00674                opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET |             // Channel mode.
    00675                (opt->spimode >> 1) << AVR32_USART_MR_MSBF_OFFSET |            // SPI clock polarity.
    00676                AVR32_USART_MR_CLKO_MASK;                                      // Drive SCK pin.
    00677
    00678   // Setup complete; enable communication.
    00679   // Enable input and output.
    00680   usart->cr = AVR32_USART_CR_RXEN_MASK |
    00681               AVR32_USART_CR_TXEN_MASK;
    00682
    00683   return USART_SUCCESS;
    00684 }
    00685
    00686
    00687 int usart_init_spi_slave(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz)
    00688 {
    00689   // Reset the USART and shutdown TX and RX.
    00690   usart_reset(usart);
    00691
    00692   // Check input values.
    00693   if (!opt || // Null pointer.
    00694       opt->charlength < 5 || opt->charlength > 9 ||
    00695       opt->spimode > 3 ||
    00696       opt->channelmode > 3 ||
    00697       usart_set_spi_slave_baudrate(usart) == USART_INVALID_INPUT)
    00698     return USART_INVALID_INPUT;
    00699
    00700   if (opt->charlength == 9)
    00701   {
    00702     // Character length set to 9 bits. MODE9 dominates CHRL.
    00703     usart->mr |= AVR32_USART_MR_MODE9_MASK;
    00704   }
    00705   else
    00706   {
    00707     // CHRL gives the character length (- 5) when MODE9 = 0.
    00708     usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
    00709   }
    00710
    00711   usart->mr |= AVR32_USART_MR_MODE_SPI_SLAVE << AVR32_USART_MR_MODE_OFFSET |  // SPI slave mode.
    00712                ((opt->spimode & 0x1) ^ 0x1) << AVR32_USART_MR_SYNC_OFFSET |   // SPI clock phase.
    00713                opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET |             // Channel mode.
    00714                (opt->spimode >> 1) << AVR32_USART_MR_MSBF_OFFSET;             // SPI clock polarity.
    00715
    00716   // Setup complete; enable communication.
    00717   // Enable input and output.
    00718   usart->cr = AVR32_USART_CR_RXEN_MASK |
    00719               AVR32_USART_CR_TXEN_MASK;
    00720
    00721   return USART_SUCCESS;
    00722 }
    00723
    00724
    00725 #endif  // USART rev. >= 4.0.0
    00726
    00727
    00729
    00730
    00731 //------------------------------------------------------------------------------
    00732 #if defined(AVR32_USART_400_H_INCLUDED) || \
    00733     defined(AVR32_USART_410_H_INCLUDED) || \
    00734     defined(AVR32_USART_420_H_INCLUDED)
    00735
    00736
    00739
    00740
    00741
    00742 int usart_spi_selectChip(volatile avr32_usart_t *usart)
    00743 {
    00744   // Force the SPI chip select.
    00745   usart->cr = AVR32_USART_CR_RTSEN_MASK;
    00746
    00747   return USART_SUCCESS;
    00748 }
    00749
    00750
    00751 int usart_spi_unselectChip(volatile avr32_usart_t *usart)
    00752 {
    00753   int timeout = USART_DEFAULT_TIMEOUT;
    00754
    00755   do
    00756   {
    00757     if (!timeout--) return USART_FAILURE;
    00758   } while (!usart_tx_empty(usart));
    00759
    00760   // Release the SPI chip select.
    00761   usart->cr = AVR32_USART_CR_RTSDIS_MASK;
    00762
    00763   return USART_SUCCESS;
    00764 }
    00765
    00766
    00768
    00769
    00770 #endif  // USART rev. >= 4.0.0
    00771
    00772
    00773 //------------------------------------------------------------------------------
    00776
    00777
    00778
    00779 int usart_send_address(volatile avr32_usart_t *usart, int address)
    00780 {
    00781   // Check if USART is in multidrop / RS485 mode.
    00782   if (!usart_mode_is_multidrop(usart)) return USART_MODE_FAULT;
    00783
    00784   // Prepare to send an address.
    00785   usart->cr = AVR32_USART_CR_SENDA_MASK;
    00786
    00787   // Write the address to TX.
    00788   usart_bw_write_char(usart, address);
    00789
    00790   return USART_SUCCESS;
    00791 }
    00792
    00793
    00794 int usart_write_char(volatile avr32_usart_t *usart, int c)
    00795 {
    00796   if (usart_tx_ready(usart))
    00797   {
    00798     usart->thr = (c << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
    00799     return USART_SUCCESS;
    00800   }
    00801   else
    00802     return USART_TX_BUSY;
    00803 }
    00804
    00805
    00806 int usart_putchar(volatile avr32_usart_t *usart, int c)
    00807 {
    00808   int timeout = USART_DEFAULT_TIMEOUT;
    00809
    00810   if (c == '\n')
    00811   {
    00812     do
    00813     {
    00814       if (!timeout--) return USART_FAILURE;
    00815     } while (usart_write_char(usart, '\r') != USART_SUCCESS);
    00816
    00817     timeout = USART_DEFAULT_TIMEOUT;
    00818   }
    00819
    00820   do
    00821   {
    00822     if (!timeout--) return USART_FAILURE;
    00823   } while (usart_write_char(usart, c) != USART_SUCCESS);
    00824
    00825   return USART_SUCCESS;
    00826 }
    00827
    00828
    00829 int usart_read_char(volatile avr32_usart_t *usart, int *c)
    00830 {
    00831   // Check for errors: frame, parity and overrun. In RS485 mode, a parity error
    00832   // would mean that an address char has been received.
    00833   if (usart->csr & (AVR32_USART_CSR_OVRE_MASK |
    00834                     AVR32_USART_CSR_FRAME_MASK |
    00835                     AVR32_USART_CSR_PARE_MASK))
    00836     return USART_RX_ERROR;
    00837
    00838   // No error; if we really did receive a char, read it and return SUCCESS.
    00839   if (usart_test_hit(usart))
    00840   {
    00841     *c = (usart->rhr & AVR32_USART_RHR_RXCHR_MASK) >> AVR32_USART_RHR_RXCHR_OFFSET;
    00842     return USART_SUCCESS;
    00843   }
    00844   else
    00845     return USART_RX_EMPTY;
    00846 }
    00847
    00848
    00849 int usart_getchar(volatile avr32_usart_t *usart)
    00850 {
    00851   int c, ret;
    00852
    00853   while ((ret = usart_read_char(usart, &c)) == USART_RX_EMPTY);
    00854
    00855   if (ret == USART_RX_ERROR)
    00856     return USART_FAILURE;
    00857
    00858   return c;
    00859 }
    00860
    00861
    00862 void usart_write_line(volatile avr32_usart_t *usart, const char *string)
    00863 {
    00864   while (*string != '\0')
    00865     usart_putchar(usart, *string++);
    00866 }
    00867
    00868
    00869 int usart_get_echo_line(volatile avr32_usart_t *usart)
    00870 {
    00871   int rx_char;
    00872   int retval = USART_SUCCESS;
    00873
    00874   while (1)
    00875   {
    00876     rx_char = usart_getchar(usart);
    00877     if (rx_char == USART_FAILURE)
    00878     {
    00879       usart_write_line(usart, "Error!!!\n");
    00880       break;
    00881     }
    00882     if (rx_char == '\x03')
    00883     {
    00884       retval = USART_FAILURE;
    00885       break;
    00886     }
    00887     usart_putchar(usart, rx_char);
    00888     if (rx_char == '\r')
    00889     {
    00890       usart_putchar(usart, '\n');
    00891       break;
    00892     }
    00893   }
    00894
    00895   return retval;
    00896 }
    00897
    00898