1 /* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
\r
3 /*This file is prepared for Doxygen automatic documentation generation.*/
\r
4 /*! \file *********************************************************************
\r
6 * \brief USART driver for AVR32 UC3.
\r
8 * This file contains basic functions for the AVR32 USART, with support for all
\r
9 * modes, settings and clock speeds.
\r
11 * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
\r
12 * - Supported devices: All AVR32 devices with a USART module can be used.
\r
15 * \author Atmel Corporation: http://www.atmel.com \n
\r
16 * Support and FAQ: http://support.atmel.no/
\r
18 ******************************************************************************/
\r
20 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
\r
22 * Redistribution and use in source and binary forms, with or without
\r
23 * modification, are permitted provided that the following conditions are met:
\r
25 * 1. Redistributions of source code must retain the above copyright notice, this
\r
26 * list of conditions and the following disclaimer.
\r
28 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
29 * this list of conditions and the following disclaimer in the documentation
\r
30 * and/or other materials provided with the distribution.
\r
32 * 3. The name of Atmel may not be used to endorse or promote products derived
\r
33 * from this software without specific prior written permission.
\r
35 * 4. This software may only be redistributed and used in connection with an Atmel
\r
38 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
\r
39 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
40 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
41 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
\r
42 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
\r
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
47 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
\r
51 #include "compiler.h"
\r
55 //------------------------------------------------------------------------------
\r
56 /*! \name Private Functions
\r
61 /*! \brief Checks if the USART is in multidrop mode.
\r
63 * \param usart Base address of the USART instance.
\r
65 * \return \c 1 if the USART is in multidrop mode, otherwise \c 0.
\r
67 #if (defined __GNUC__)
\r
68 __attribute__((__always_inline__))
\r
70 static __inline__ int usart_mode_is_multidrop(volatile avr32_usart_t *usart)
\r
72 return ((usart->mr >> AVR32_USART_MR_PAR_OFFSET) & AVR32_USART_MR_PAR_MULTI) == AVR32_USART_MR_PAR_MULTI;
\r
76 /*! \brief Calculates a clock divider (\e CD) and a fractional part (\e FP) for
\r
77 * the USART asynchronous modes to generate a baud rate as close as
\r
78 * possible to the baud rate set point.
\r
80 * Baud rate calculation:
\r
81 * \f$ Baudrate = \frac{SelectedClock}{Over \times (CD + \frac{FP}{8})} \f$, \e Over being 16 or 8.
\r
82 * The maximal oversampling is selected if it allows to generate a baud rate close to the set point.
\r
84 * \param usart Base address of the USART instance.
\r
85 * \param baudrate Baud rate set point.
\r
86 * \param pba_hz USART module input clock frequency (PBA clock, Hz).
\r
88 * \retval USART_SUCCESS Baud rate successfully initialized.
\r
89 * \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
\r
91 static int usart_set_async_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
\r
93 unsigned int over = (pba_hz >= 16 * baudrate) ? 16 : 8;
\r
94 unsigned int cd_fp = ((1 << AVR32_USART_BRGR_FP_SIZE) * pba_hz + (over * baudrate) / 2) / (over * baudrate);
\r
95 unsigned int cd = cd_fp >> AVR32_USART_BRGR_FP_SIZE;
\r
96 unsigned int fp = cd_fp & ((1 << AVR32_USART_BRGR_FP_SIZE) - 1);
\r
98 if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
\r
99 return USART_INVALID_INPUT;
\r
101 usart->mr = (usart->mr & ~(AVR32_USART_MR_USCLKS_MASK |
\r
102 AVR32_USART_MR_SYNC_MASK |
\r
103 AVR32_USART_MR_OVER_MASK)) |
\r
104 AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
\r
105 ((over == 16) ? AVR32_USART_MR_OVER_X16 : AVR32_USART_MR_OVER_X8) << AVR32_USART_MR_OVER_OFFSET;
\r
107 usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET |
\r
108 fp << AVR32_USART_BRGR_FP_OFFSET;
\r
110 return USART_SUCCESS;
\r
114 /*! \brief Calculates a clock divider (\e CD) for the USART synchronous master
\r
115 * modes to generate a baud rate as close as possible to the baud rate
\r
118 * Baud rate calculation:
\r
119 * \f$ Baudrate = \frac{SelectedClock}{CD} \f$.
\r
121 * \param usart Base address of the USART instance.
\r
122 * \param baudrate Baud rate set point.
\r
123 * \param pba_hz USART module input clock frequency (PBA clock, Hz).
\r
125 * \retval USART_SUCCESS Baud rate successfully initialized.
\r
126 * \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
\r
128 static int usart_set_sync_master_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
\r
130 unsigned int cd = (pba_hz + baudrate / 2) / baudrate;
\r
132 if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
\r
133 return USART_INVALID_INPUT;
\r
135 usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
\r
136 AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
\r
137 AVR32_USART_MR_SYNC_MASK;
\r
139 usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
\r
141 return USART_SUCCESS;
\r
145 /*! \brief Selects the SCK pin as the source of baud rate for the USART
\r
146 * synchronous slave modes.
\r
148 * \param usart Base address of the USART instance.
\r
150 * \retval USART_SUCCESS Baud rate successfully initialized.
\r
152 static int usart_set_sync_slave_baudrate(volatile avr32_usart_t *usart)
\r
154 usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
\r
155 AVR32_USART_MR_USCLKS_SCK << AVR32_USART_MR_USCLKS_OFFSET |
\r
156 AVR32_USART_MR_SYNC_MASK;
\r
158 return USART_SUCCESS;
\r
162 /*! \brief Calculates a clock divider (\e CD) for the USART ISO7816 mode to
\r
163 * generate an ISO7816 clock as close as possible to the clock set point.
\r
165 * ISO7816 clock calculation:
\r
166 * \f$ Clock = \frac{SelectedClock}{CD} \f$.
\r
168 * \param usart Base address of the USART instance.
\r
169 * \param clock ISO7816 clock set point.
\r
170 * \param pba_hz USART module input clock frequency (PBA clock, Hz).
\r
172 * \retval USART_SUCCESS ISO7816 clock successfully initialized.
\r
173 * \retval USART_INVALID_INPUT ISO7816 clock set point is out of range for the given input clock frequency.
\r
175 static int usart_set_iso7816_clock(volatile avr32_usart_t *usart, unsigned int clock, unsigned long pba_hz)
\r
177 unsigned int cd = (pba_hz + clock / 2) / clock;
\r
179 if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
\r
180 return USART_INVALID_INPUT;
\r
182 usart->mr = (usart->mr & ~(AVR32_USART_MR_USCLKS_MASK |
\r
183 AVR32_USART_MR_SYNC_MASK |
\r
184 AVR32_USART_MR_OVER_MASK)) |
\r
185 AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
\r
186 AVR32_USART_MR_OVER_X16 << AVR32_USART_MR_OVER_OFFSET;
\r
188 usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
\r
190 return USART_SUCCESS;
\r
194 #if defined(AVR32_USART_400_H_INCLUDED) || \
\r
195 defined(AVR32_USART_410_H_INCLUDED) || \
\r
196 defined(AVR32_USART_420_H_INCLUDED) || \
\r
197 defined(AVR32_USART_440_H_INCLUDED) || \
\r
198 defined(AVR32_USART_602_H_INCLUDED)
\r
201 /*! \brief Calculates a clock divider (\e CD) for the USART SPI master mode to
\r
202 * generate a baud rate as close as possible to the baud rate set point.
\r
204 * Baud rate calculation:
\r
205 * \f$ Baudrate = \frac{SelectedClock}{CD} \f$.
\r
207 * \param usart Base address of the USART instance.
\r
208 * \param baudrate Baud rate set point.
\r
209 * \param pba_hz USART module input clock frequency (PBA clock, Hz).
\r
211 * \retval USART_SUCCESS Baud rate successfully initialized.
\r
212 * \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
\r
214 static int usart_set_spi_master_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
\r
216 unsigned int cd = (pba_hz + baudrate / 2) / baudrate;
\r
218 if (cd < 4 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
\r
219 return USART_INVALID_INPUT;
\r
221 usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
\r
222 AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET;
\r
224 usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
\r
226 return USART_SUCCESS;
\r
230 /*! \brief Selects the SCK pin as the source of baud rate for the USART SPI
\r
233 * \param usart Base address of the USART instance.
\r
235 * \retval USART_SUCCESS Baud rate successfully initialized.
\r
237 static int usart_set_spi_slave_baudrate(volatile avr32_usart_t *usart)
\r
239 usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
\r
240 AVR32_USART_MR_USCLKS_SCK << AVR32_USART_MR_USCLKS_OFFSET;
\r
242 return USART_SUCCESS;
\r
246 #endif // USART rev. >= 4.0.0
\r
252 //------------------------------------------------------------------------------
\r
253 /*! \name Initialization Functions
\r
258 void usart_reset(volatile avr32_usart_t *usart)
\r
260 Bool global_interrupt_enabled = Is_global_interrupt_enabled();
\r
262 // Disable all USART interrupts.
\r
263 // Interrupts needed should be set explicitly on every reset.
\r
264 if (global_interrupt_enabled) Disable_global_interrupt();
\r
265 usart->idr = 0xFFFFFFFF;
\r
267 if (global_interrupt_enabled) Enable_global_interrupt();
\r
269 // Reset mode and other registers that could cause unpredictable behavior after reset.
\r
274 // Shutdown TX and RX (will be re-enabled when setup has successfully completed),
\r
275 // reset status bits and turn off DTR and RTS.
\r
276 usart->cr = AVR32_USART_CR_RSTRX_MASK |
\r
277 AVR32_USART_CR_RSTTX_MASK |
\r
278 AVR32_USART_CR_RSTSTA_MASK |
\r
279 AVR32_USART_CR_RSTIT_MASK |
\r
280 AVR32_USART_CR_RSTNACK_MASK |
\r
281 #ifndef AVR32_USART_440_H_INCLUDED
\r
282 // Note: Modem Signal Management DTR-DSR-DCD-RI are not included in USART rev.440.
\r
283 AVR32_USART_CR_DTRDIS_MASK |
\r
285 AVR32_USART_CR_RTSDIS_MASK;
\r
289 int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
\r
291 // Reset the USART and shutdown TX and RX.
\r
292 usart_reset(usart);
\r
294 // Check input values.
\r
295 if (!opt || // Null pointer.
\r
296 opt->charlength < 5 || opt->charlength > 9 ||
\r
297 opt->paritytype > 7 ||
\r
298 opt->stopbits > 2 + 255 ||
\r
299 opt->channelmode > 3 ||
\r
300 usart_set_async_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
\r
301 return USART_INVALID_INPUT;
\r
303 if (opt->charlength == 9)
\r
305 // Character length set to 9 bits. MODE9 dominates CHRL.
\r
306 usart->mr |= AVR32_USART_MR_MODE9_MASK;
\r
310 // CHRL gives the character length (- 5) when MODE9 = 0.
\r
311 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
\r
314 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
\r
315 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
\r
317 if (opt->stopbits > USART_2_STOPBITS)
\r
319 // Set two stop bits
\r
320 usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
\r
321 // and a timeguard period gives the rest.
\r
322 usart->ttgr = opt->stopbits - USART_2_STOPBITS;
\r
325 // Insert 1, 1.5 or 2 stop bits.
\r
326 usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
\r
328 // Set normal mode.
\r
329 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
\r
330 AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
\r
332 // Setup complete; enable communication.
\r
333 // Enable input and output.
\r
334 usart->cr = AVR32_USART_CR_RXEN_MASK |
\r
335 AVR32_USART_CR_TXEN_MASK;
\r
337 return USART_SUCCESS;
\r
341 int usart_init_rs232_tx_only(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
\r
343 // Reset the USART and shutdown TX and RX.
\r
344 usart_reset(usart);
\r
346 // Check input values.
\r
347 if (!opt || // Null pointer.
\r
348 opt->charlength < 5 || opt->charlength > 9 ||
\r
349 opt->paritytype > 7 ||
\r
350 opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
\r
351 opt->channelmode > 3 ||
\r
352 usart_set_sync_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
\r
353 return USART_INVALID_INPUT;
\r
355 if (opt->charlength == 9)
\r
357 // Character length set to 9 bits. MODE9 dominates CHRL.
\r
358 usart->mr |= AVR32_USART_MR_MODE9_MASK;
\r
362 // CHRL gives the character length (- 5) when MODE9 = 0.
\r
363 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
\r
366 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
\r
367 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
\r
369 if (opt->stopbits > USART_2_STOPBITS)
\r
371 // Set two stop bits
\r
372 usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
\r
373 // and a timeguard period gives the rest.
\r
374 usart->ttgr = opt->stopbits - USART_2_STOPBITS;
\r
377 // Insert 1 or 2 stop bits.
\r
378 usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
\r
380 // Set normal mode.
\r
381 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
\r
382 AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
\r
384 // Setup complete; enable communication.
\r
385 // Enable only output as input is not possible in synchronous mode without
\r
386 // transferring clock.
\r
387 usart->cr = AVR32_USART_CR_TXEN_MASK;
\r
389 return USART_SUCCESS;
\r
393 int usart_init_hw_handshaking(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
\r
395 // First: Setup standard RS232.
\r
396 if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
\r
397 return USART_INVALID_INPUT;
\r
399 // Set hardware handshaking mode.
\r
400 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
\r
401 AVR32_USART_MR_MODE_HARDWARE << AVR32_USART_MR_MODE_OFFSET;
\r
403 return USART_SUCCESS;
\r
407 int usart_init_modem(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
\r
409 // First: Setup standard RS232.
\r
410 if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
\r
411 return USART_INVALID_INPUT;
\r
414 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
\r
415 AVR32_USART_MR_MODE_MODEM << AVR32_USART_MR_MODE_OFFSET;
\r
417 return USART_SUCCESS;
\r
421 int usart_init_sync_master(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
\r
423 // Reset the USART and shutdown TX and RX.
\r
424 usart_reset(usart);
\r
426 // Check input values.
\r
427 if (!opt || // Null pointer.
\r
428 opt->charlength < 5 || opt->charlength > 9 ||
\r
429 opt->paritytype > 7 ||
\r
430 opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
\r
431 opt->channelmode > 3 ||
\r
432 usart_set_sync_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
\r
433 return USART_INVALID_INPUT;
\r
435 if (opt->charlength == 9)
\r
437 // Character length set to 9 bits. MODE9 dominates CHRL.
\r
438 usart->mr |= AVR32_USART_MR_MODE9_MASK;
\r
442 // CHRL gives the character length (- 5) when MODE9 = 0.
\r
443 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
\r
446 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
\r
447 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
\r
449 if (opt->stopbits > USART_2_STOPBITS)
\r
451 // Set two stop bits
\r
452 usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
\r
453 // and a timeguard period gives the rest.
\r
454 usart->ttgr = opt->stopbits - USART_2_STOPBITS;
\r
457 // Insert 1 or 2 stop bits.
\r
458 usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
\r
460 // Set normal mode.
\r
461 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
\r
462 AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET |
\r
463 AVR32_USART_MR_CLKO_MASK;
\r
465 // Setup complete; enable communication.
\r
466 // Enable input and output.
\r
467 usart->cr = AVR32_USART_CR_RXEN_MASK |
\r
468 AVR32_USART_CR_TXEN_MASK;
\r
470 return USART_SUCCESS;
\r
474 int usart_init_sync_slave(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
\r
476 // Reset the USART and shutdown TX and RX.
\r
477 usart_reset(usart);
\r
479 // Check input values.
\r
480 if (!opt || // Null pointer.
\r
481 opt->charlength < 5 || opt->charlength > 9 ||
\r
482 opt->paritytype > 7 ||
\r
483 opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
\r
484 opt->channelmode > 3 ||
\r
485 usart_set_sync_slave_baudrate(usart) == USART_INVALID_INPUT)
\r
486 return USART_INVALID_INPUT;
\r
488 if (opt->charlength == 9)
\r
490 // Character length set to 9 bits. MODE9 dominates CHRL.
\r
491 usart->mr |= AVR32_USART_MR_MODE9_MASK;
\r
495 // CHRL gives the character length (- 5) when MODE9 = 0.
\r
496 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
\r
499 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
\r
500 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
\r
502 if (opt->stopbits > USART_2_STOPBITS)
\r
504 // Set two stop bits
\r
505 usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
\r
506 // and a timeguard period gives the rest.
\r
507 usart->ttgr = opt->stopbits - USART_2_STOPBITS;
\r
510 // Insert 1 or 2 stop bits.
\r
511 usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
\r
513 // Set normal mode.
\r
514 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
\r
515 AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
\r
517 // Setup complete; enable communication.
\r
518 // Enable input and output.
\r
519 usart->cr = AVR32_USART_CR_RXEN_MASK |
\r
520 AVR32_USART_CR_TXEN_MASK;
\r
522 return USART_SUCCESS;
\r
526 int usart_init_rs485(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
\r
528 // First: Setup standard RS232.
\r
529 if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
\r
530 return USART_INVALID_INPUT;
\r
533 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
\r
534 AVR32_USART_MR_MODE_RS485 << AVR32_USART_MR_MODE_OFFSET;
\r
536 return USART_SUCCESS;
\r
540 int usart_init_IrDA(volatile avr32_usart_t *usart, const usart_options_t *opt,
\r
541 long pba_hz, unsigned char irda_filter)
\r
543 // First: Setup standard RS232.
\r
544 if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
\r
545 return USART_INVALID_INPUT;
\r
547 // Set IrDA filter.
\r
548 usart->ifr = irda_filter;
\r
550 // Set IrDA mode and activate filtering of input.
\r
551 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
\r
552 AVR32_USART_MODE_IRDA << AVR32_USART_MR_MODE_OFFSET |
\r
553 AVR32_USART_MR_FILTER_MASK;
\r
555 return USART_SUCCESS;
\r
559 int usart_init_iso7816(volatile avr32_usart_t *usart, const usart_iso7816_options_t *opt, int t, long pba_hz)
\r
561 // Reset the USART and shutdown TX and RX.
\r
562 usart_reset(usart);
\r
564 // Check input values.
\r
565 if (!opt || // Null pointer.
\r
566 opt->paritytype > 1)
\r
567 return USART_INVALID_INPUT;
\r
571 // Set USART mode to ISO7816, T=0.
\r
572 // The T=0 protocol always uses 2 stop bits.
\r
573 usart->mr = AVR32_USART_MR_MODE_ISO7816_T0 << AVR32_USART_MR_MODE_OFFSET |
\r
574 AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET |
\r
575 opt->bit_order << AVR32_USART_MR_MSBF_OFFSET; // Allow MSBF in T=0.
\r
579 // Only LSB first in the T=1 protocol.
\r
580 // max_iterations field is only used in T=0 mode.
\r
581 if (opt->bit_order != 0 ||
\r
582 opt->max_iterations != 0)
\r
583 return USART_INVALID_INPUT;
\r
585 // Set USART mode to ISO7816, T=1.
\r
586 // The T=1 protocol always uses 1 stop bit.
\r
587 usart->mr = AVR32_USART_MR_MODE_ISO7816_T1 << AVR32_USART_MR_MODE_OFFSET |
\r
588 AVR32_USART_MR_NBSTOP_1 << AVR32_USART_MR_NBSTOP_OFFSET;
\r
591 return USART_INVALID_INPUT;
\r
593 if (usart_set_iso7816_clock(usart, opt->iso7816_hz, pba_hz) == USART_INVALID_INPUT)
\r
594 return USART_INVALID_INPUT;
\r
596 // Set FIDI register: bit rate = selected clock/FI_DI_ratio/16.
\r
597 usart->fidi = opt->fidi_ratio;
\r
599 // Set ISO7816 spesific options in the MODE register.
\r
600 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
\r
601 AVR32_USART_MR_CLKO_MASK | // Enable clock output.
\r
602 opt->inhibit_nack << AVR32_USART_MR_INACK_OFFSET |
\r
603 opt->dis_suc_nack << AVR32_USART_MR_DSNACK_OFFSET |
\r
604 opt->max_iterations << AVR32_USART_MR_MAX_ITERATION_OFFSET;
\r
606 // Setup complete; enable the receiver by default.
\r
607 usart_iso7816_enable_receiver(usart);
\r
609 return USART_SUCCESS;
\r
613 #if defined(AVR32_USART_400_H_INCLUDED) || \
\r
614 defined(AVR32_USART_410_H_INCLUDED) || \
\r
615 defined(AVR32_USART_420_H_INCLUDED) || \
\r
616 defined(AVR32_USART_440_H_INCLUDED) || \
\r
617 defined(AVR32_USART_602_H_INCLUDED)
\r
620 int usart_init_lin_master(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz)
\r
622 // Reset the USART and shutdown TX and RX.
\r
623 usart_reset(usart);
\r
625 // Check input values.
\r
626 if (usart_set_async_baudrate(usart, baudrate, pba_hz) == USART_INVALID_INPUT)
\r
627 return USART_INVALID_INPUT;
\r
629 usart->mr |= AVR32_USART_MR_MODE_LIN_MASTER << AVR32_USART_MR_MODE_OFFSET; // LIN master mode.
\r
631 // Setup complete; enable communication.
\r
632 // Enable input and output.
\r
633 usart->cr = AVR32_USART_CR_RXEN_MASK |
\r
634 AVR32_USART_CR_TXEN_MASK;
\r
636 return USART_SUCCESS;
\r
640 int usart_init_lin_slave(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz)
\r
642 // Reset the USART and shutdown TX and RX.
\r
643 usart_reset(usart);
\r
645 // Check input values.
\r
646 if (usart_set_async_baudrate(usart, baudrate, pba_hz) == USART_INVALID_INPUT)
\r
647 return USART_INVALID_INPUT;
\r
649 usart->mr |= AVR32_USART_MR_MODE_LIN_SLAVE << AVR32_USART_MR_MODE_OFFSET; // LIN slave mode.
\r
651 // Setup complete; enable communication.
\r
652 // Enable input and output.
\r
653 usart->cr = AVR32_USART_CR_RXEN_MASK |
\r
654 AVR32_USART_CR_TXEN_MASK;
\r
656 return USART_SUCCESS;
\r
660 int usart_init_spi_master(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz)
\r
662 // Reset the USART and shutdown TX and RX.
\r
663 usart_reset(usart);
\r
665 // Check input values.
\r
666 if (!opt || // Null pointer.
\r
667 opt->charlength < 5 || opt->charlength > 9 ||
\r
668 opt->spimode > 3 ||
\r
669 opt->channelmode > 3 ||
\r
670 usart_set_spi_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
\r
671 return USART_INVALID_INPUT;
\r
673 if (opt->charlength == 9)
\r
675 // Character length set to 9 bits. MODE9 dominates CHRL.
\r
676 usart->mr |= AVR32_USART_MR_MODE9_MASK;
\r
680 // CHRL gives the character length (- 5) when MODE9 = 0.
\r
681 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
\r
684 usart->mr |= AVR32_USART_MR_MODE_SPI_MASTER << AVR32_USART_MR_MODE_OFFSET | // SPI master mode.
\r
685 ((opt->spimode & 0x1) ^ 0x1) << AVR32_USART_MR_SYNC_OFFSET | // SPI clock phase.
\r
686 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET | // Channel mode.
\r
687 (opt->spimode >> 1) << AVR32_USART_MR_MSBF_OFFSET | // SPI clock polarity.
\r
688 AVR32_USART_MR_CLKO_MASK; // Drive SCK pin.
\r
690 // Setup complete; enable communication.
\r
691 // Enable input and output.
\r
692 usart->cr = AVR32_USART_CR_RXEN_MASK |
\r
693 AVR32_USART_CR_TXEN_MASK;
\r
695 return USART_SUCCESS;
\r
699 int usart_init_spi_slave(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz)
\r
701 // Reset the USART and shutdown TX and RX.
\r
702 usart_reset(usart);
\r
704 // Check input values.
\r
705 if (!opt || // Null pointer.
\r
706 opt->charlength < 5 || opt->charlength > 9 ||
\r
707 opt->spimode > 3 ||
\r
708 opt->channelmode > 3 ||
\r
709 usart_set_spi_slave_baudrate(usart) == USART_INVALID_INPUT)
\r
710 return USART_INVALID_INPUT;
\r
712 if (opt->charlength == 9)
\r
714 // Character length set to 9 bits. MODE9 dominates CHRL.
\r
715 usart->mr |= AVR32_USART_MR_MODE9_MASK;
\r
719 // CHRL gives the character length (- 5) when MODE9 = 0.
\r
720 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
\r
723 usart->mr |= AVR32_USART_MR_MODE_SPI_SLAVE << AVR32_USART_MR_MODE_OFFSET | // SPI slave mode.
\r
724 ((opt->spimode & 0x1) ^ 0x1) << AVR32_USART_MR_SYNC_OFFSET | // SPI clock phase.
\r
725 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET | // Channel mode.
\r
726 (opt->spimode >> 1) << AVR32_USART_MR_MSBF_OFFSET; // SPI clock polarity.
\r
728 // Setup complete; enable communication.
\r
729 // Enable input and output.
\r
730 usart->cr = AVR32_USART_CR_RXEN_MASK |
\r
731 AVR32_USART_CR_TXEN_MASK;
\r
733 return USART_SUCCESS;
\r
737 #endif // USART rev. >= 4.0.0
\r
743 //------------------------------------------------------------------------------
\r
744 #if defined(AVR32_USART_400_H_INCLUDED) || \
\r
745 defined(AVR32_USART_410_H_INCLUDED) || \
\r
746 defined(AVR32_USART_420_H_INCLUDED) || \
\r
747 defined(AVR32_USART_440_H_INCLUDED) || \
\r
748 defined(AVR32_USART_602_H_INCLUDED)
\r
751 /*! \name SPI Control Functions
\r
756 int usart_spi_selectChip(volatile avr32_usart_t *usart)
\r
758 // Force the SPI chip select.
\r
759 usart->cr = AVR32_USART_CR_RTSEN_MASK;
\r
761 return USART_SUCCESS;
\r
765 int usart_spi_unselectChip(volatile avr32_usart_t *usart)
\r
767 int timeout = USART_DEFAULT_TIMEOUT;
\r
771 if (!timeout--) return USART_FAILURE;
\r
772 } while (!usart_tx_empty(usart));
\r
774 // Release the SPI chip select.
\r
775 usart->cr = AVR32_USART_CR_RTSDIS_MASK;
\r
777 return USART_SUCCESS;
\r
784 #endif // USART rev. >= 4.0.0
\r
787 //------------------------------------------------------------------------------
\r
788 /*! \name Transmit/Receive Functions
\r
793 int usart_send_address(volatile avr32_usart_t *usart, int address)
\r
795 // Check if USART is in multidrop / RS485 mode.
\r
796 if (!usart_mode_is_multidrop(usart)) return USART_MODE_FAULT;
\r
798 // Prepare to send an address.
\r
799 usart->cr = AVR32_USART_CR_SENDA_MASK;
\r
801 // Write the address to TX.
\r
802 usart_bw_write_char(usart, address);
\r
804 return USART_SUCCESS;
\r
808 int usart_write_char(volatile avr32_usart_t *usart, int c)
\r
810 if (usart_tx_ready(usart))
\r
812 usart->thr = (c << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
\r
813 return USART_SUCCESS;
\r
816 return USART_TX_BUSY;
\r
820 int usart_putchar(volatile avr32_usart_t *usart, int c)
\r
822 int timeout = USART_DEFAULT_TIMEOUT;
\r
828 if (!timeout--) return USART_FAILURE;
\r
829 } while (usart_write_char(usart, '\r') != USART_SUCCESS);
\r
831 timeout = USART_DEFAULT_TIMEOUT;
\r
836 if (!timeout--) return USART_FAILURE;
\r
837 } while (usart_write_char(usart, c) != USART_SUCCESS);
\r
839 return USART_SUCCESS;
\r
843 int usart_read_char(volatile avr32_usart_t *usart, int *c)
\r
845 // Check for errors: frame, parity and overrun. In RS485 mode, a parity error
\r
846 // would mean that an address char has been received.
\r
847 if (usart->csr & (AVR32_USART_CSR_OVRE_MASK |
\r
848 AVR32_USART_CSR_FRAME_MASK |
\r
849 AVR32_USART_CSR_PARE_MASK))
\r
850 return USART_RX_ERROR;
\r
852 // No error; if we really did receive a char, read it and return SUCCESS.
\r
853 if (usart_test_hit(usart))
\r
855 *c = (usart->rhr & AVR32_USART_RHR_RXCHR_MASK) >> AVR32_USART_RHR_RXCHR_OFFSET;
\r
856 return USART_SUCCESS;
\r
859 return USART_RX_EMPTY;
\r
863 int usart_getchar(volatile avr32_usart_t *usart)
\r
867 while ((ret = usart_read_char(usart, &c)) == USART_RX_EMPTY);
\r
869 if (ret == USART_RX_ERROR)
\r
870 return USART_FAILURE;
\r
876 void usart_write_line(volatile avr32_usart_t *usart, const char *string)
\r
878 while (*string != '\0')
\r
879 usart_putchar(usart, *string++);
\r
883 int usart_get_echo_line(volatile avr32_usart_t *usart)
\r
886 int retval = USART_SUCCESS;
\r
890 rx_char = usart_getchar(usart);
\r
891 if (rx_char == USART_FAILURE)
\r
893 usart_write_line(usart, "Error!!!\n");
\r
894 retval = USART_FAILURE;
\r
897 if (rx_char == '\x03')
\r
899 retval = USART_FAILURE;
\r
902 usart_putchar(usart, rx_char);
\r
903 if (rx_char == '\r')
\r
905 usart_putchar(usart, '\n');
\r