1 /*****************************************************************************
2 *
3 * \file
4 *
5 * \brief USART driver for AVR32 UC3.
6 *
7 * This file contains basic functions for the AVR32 USART, with support for all
8 * modes, settings and clock speeds.
9 *
10 * Copyright (c) 2009-2018 Microchip Technology Inc. and its subsidiaries.
11 *
12 * \asf_license_start
13 *
14 * \page License
15 *
16 * Subject to your compliance with these terms, you may use Microchip
17 * software and any derivatives exclusively with Microchip products.
18 * It is your responsibility to comply with third party license terms applicable
19 * to your use of third party software (including open source software) that
20 * may accompany Microchip software.
21 *
22 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
23 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
24 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
25 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
26 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
27 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
28 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
29 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
30 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
31 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
32 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
33 *
34 * \asf_license_stop
35 *
36 ******************************************************************************/
37 /*
38 * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
39 */
40
41
42 #include "compiler.h"
43 #include "usart.h"
44
45
46 //------------------------------------------------------------------------------
47 /*! \name Private Functions
48 */
49 //! @{
50
51
52 /*! \brief Checks if the USART is in multidrop mode.
53 *
54 * \param usart Base address of the USART instance.
55 *
56 * \return \c 1 if the USART is in multidrop mode, otherwise \c 0.
57 */
usart_mode_is_multidrop(volatile avr32_usart_t * usart)58 __always_inline static int usart_mode_is_multidrop(volatile avr32_usart_t *usart)
59 {
60 return ((usart->mr >> AVR32_USART_MR_PAR_OFFSET) & AVR32_USART_MR_PAR_MULTI) == AVR32_USART_MR_PAR_MULTI;
61 }
62
63
64 /*! \brief Calculates a clock divider (\e CD) and a fractional part (\e FP) for
65 * the USART asynchronous modes to generate a baud rate as close as
66 * possible to the baud rate set point.
67 *
68 * Baud rate calculation:
69 * \f$ Baudrate = \frac{SelectedClock}{Over \times (CD + \frac{FP}{8})} \f$, \e Over being 16 or 8.
70 * The maximal oversampling is selected if it allows to generate a baud rate close to the set point.
71 *
72 * \param usart Base address of the USART instance.
73 * \param baudrate Baud rate set point.
74 * \param pba_hz USART module input clock frequency (PBA clock, Hz).
75 *
76 * \retval USART_SUCCESS Baud rate successfully initialized.
77 * \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
78 */
usart_set_async_baudrate(volatile avr32_usart_t * usart,unsigned int baudrate,unsigned long pba_hz)79 static int usart_set_async_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
80 {
81 unsigned int over = (pba_hz >= 16 * baudrate) ? 16 : 8;
82 unsigned int cd_fp = ((1 << AVR32_USART_BRGR_FP_SIZE) * pba_hz + (over * baudrate) / 2) / (over * baudrate);
83 unsigned int cd = cd_fp >> AVR32_USART_BRGR_FP_SIZE;
84 unsigned int fp = cd_fp & ((1 << AVR32_USART_BRGR_FP_SIZE) - 1);
85
86 if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
87 return USART_INVALID_INPUT;
88
89 usart->mr = (usart->mr & ~(AVR32_USART_MR_USCLKS_MASK |
90 AVR32_USART_MR_SYNC_MASK |
91 AVR32_USART_MR_OVER_MASK)) |
92 AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
93 ((over == 16) ? AVR32_USART_MR_OVER_X16 : AVR32_USART_MR_OVER_X8) << AVR32_USART_MR_OVER_OFFSET;
94
95 usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET |
96 fp << AVR32_USART_BRGR_FP_OFFSET;
97
98 return USART_SUCCESS;
99 }
100
101
102 /*! \brief Calculates a clock divider (\e CD) for the USART synchronous master
103 * modes to generate a baud rate as close as possible to the baud rate
104 * set point.
105 *
106 * Baud rate calculation:
107 * \f$ Baudrate = \frac{SelectedClock}{CD} \f$.
108 *
109 * \param usart Base address of the USART instance.
110 * \param baudrate Baud rate set point.
111 * \param pba_hz USART module input clock frequency (PBA clock, Hz).
112 *
113 * \retval USART_SUCCESS Baud rate successfully initialized.
114 * \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
115 */
usart_set_sync_master_baudrate(volatile avr32_usart_t * usart,unsigned int baudrate,unsigned long pba_hz)116 static int usart_set_sync_master_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
117 {
118 unsigned int cd = (pba_hz + baudrate / 2) / baudrate;
119
120 if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
121 return USART_INVALID_INPUT;
122
123 usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
124 AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
125 AVR32_USART_MR_SYNC_MASK;
126
127 usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
128
129 return USART_SUCCESS;
130 }
131
132
133 /*! \brief Selects the SCK pin as the source of baud rate for the USART
134 * synchronous slave modes.
135 *
136 * \param usart Base address of the USART instance.
137 *
138 * \retval USART_SUCCESS Baud rate successfully initialized.
139 */
usart_set_sync_slave_baudrate(volatile avr32_usart_t * usart)140 static int usart_set_sync_slave_baudrate(volatile avr32_usart_t *usart)
141 {
142 usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
143 AVR32_USART_MR_USCLKS_SCK << AVR32_USART_MR_USCLKS_OFFSET |
144 AVR32_USART_MR_SYNC_MASK;
145
146 return USART_SUCCESS;
147 }
148
149
150 /*! \brief Calculates a clock divider (\e CD) for the USART ISO7816 mode to
151 * generate an ISO7816 clock as close as possible to the clock set point.
152 *
153 * ISO7816 clock calculation:
154 * \f$ Clock = \frac{SelectedClock}{CD} \f$.
155 *
156 * \param usart Base address of the USART instance.
157 * \param clock ISO7816 clock set point.
158 * \param pba_hz USART module input clock frequency (PBA clock, Hz).
159 *
160 * \retval USART_SUCCESS ISO7816 clock successfully initialized.
161 * \retval USART_INVALID_INPUT ISO7816 clock set point is out of range for the given input clock frequency.
162 */
usart_set_iso7816_clock(volatile avr32_usart_t * usart,unsigned int clock,unsigned long pba_hz)163 static int usart_set_iso7816_clock(volatile avr32_usart_t *usart, unsigned int clock, unsigned long pba_hz)
164 {
165 unsigned int cd = (pba_hz + clock / 2) / clock;
166
167 if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
168 return USART_INVALID_INPUT;
169
170 usart->mr = (usart->mr & ~(AVR32_USART_MR_USCLKS_MASK |
171 AVR32_USART_MR_SYNC_MASK |
172 AVR32_USART_MR_OVER_MASK)) |
173 AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
174 AVR32_USART_MR_OVER_X16 << AVR32_USART_MR_OVER_OFFSET;
175
176 usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
177
178 return USART_SUCCESS;
179 }
180
181
182 #if defined(AVR32_USART_400_H_INCLUDED) || \
183 defined(AVR32_USART_410_H_INCLUDED) || \
184 defined(AVR32_USART_420_H_INCLUDED) || \
185 defined(AVR32_USART_440_H_INCLUDED) || \
186 defined(AVR32_USART_602_H_INCLUDED)
187
188
189 /*! \brief Calculates a clock divider (\e CD) for the USART SPI master mode to
190 * generate a baud rate as close as possible to the baud rate set point.
191 *
192 * Baud rate calculation:
193 * \f$ Baudrate = \frac{SelectedClock}{CD} \f$.
194 *
195 * \param usart Base address of the USART instance.
196 * \param baudrate Baud rate set point.
197 * \param pba_hz USART module input clock frequency (PBA clock, Hz).
198 *
199 * \retval USART_SUCCESS Baud rate successfully initialized.
200 * \retval USART_INVALID_INPUT Baud rate set point is out of range for the given input clock frequency.
201 */
usart_set_spi_master_baudrate(volatile avr32_usart_t * usart,unsigned int baudrate,unsigned long pba_hz)202 static int usart_set_spi_master_baudrate(volatile avr32_usart_t *usart, unsigned int baudrate, unsigned long pba_hz)
203 {
204 unsigned int cd = (pba_hz + baudrate / 2) / baudrate;
205
206 if (cd < 4 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
207 return USART_INVALID_INPUT;
208
209 usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
210 AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET;
211
212 usart->brgr = cd << AVR32_USART_BRGR_CD_OFFSET;
213
214 return USART_SUCCESS;
215 }
216
217
218 /*! \brief Selects the SCK pin as the source of baud rate for the USART SPI
219 * slave mode.
220 *
221 * \param usart Base address of the USART instance.
222 *
223 * \retval USART_SUCCESS Baud rate successfully initialized.
224 */
usart_set_spi_slave_baudrate(volatile avr32_usart_t * usart)225 static int usart_set_spi_slave_baudrate(volatile avr32_usart_t *usart)
226 {
227 usart->mr = (usart->mr & ~AVR32_USART_MR_USCLKS_MASK) |
228 AVR32_USART_MR_USCLKS_SCK << AVR32_USART_MR_USCLKS_OFFSET;
229
230 return USART_SUCCESS;
231 }
232
233
234 #endif // USART rev. >= 4.0.0
235
236
237 //! @}
238
239
240 //------------------------------------------------------------------------------
241 /*! \name Initialization Functions
242 */
243 //! @{
244
245
usart_reset(volatile avr32_usart_t * usart)246 void usart_reset(volatile avr32_usart_t *usart)
247 {
248 bool global_interrupt_enabled = cpu_irq_is_enabled();
249
250 // Disable all USART interrupts.
251 // Interrupts needed should be set explicitly on every reset.
252 if (global_interrupt_enabled) cpu_irq_disable();
253 usart->idr = 0xFFFFFFFF;
254 usart->csr;
255 if (global_interrupt_enabled) cpu_irq_enable();
256
257 // Reset mode and other registers that could cause unpredictable behavior after reset.
258 usart->mr = 0;
259 usart->rtor = 0;
260 usart->ttgr = 0;
261
262 // Shutdown TX and RX (will be re-enabled when setup has successfully completed),
263 // reset status bits and turn off DTR and RTS.
264 usart->cr = AVR32_USART_CR_RSTRX_MASK |
265 AVR32_USART_CR_RSTTX_MASK |
266 AVR32_USART_CR_RSTSTA_MASK |
267 AVR32_USART_CR_RSTIT_MASK |
268 AVR32_USART_CR_RSTNACK_MASK |
269 #ifndef AVR32_USART_440_H_INCLUDED
270 // Note: Modem Signal Management DTR-DSR-DCD-RI are not included in USART rev.440.
271 AVR32_USART_CR_DTRDIS_MASK |
272 #endif
273 AVR32_USART_CR_RTSDIS_MASK;
274 }
275
276
usart_init_rs232(volatile avr32_usart_t * usart,const usart_options_t * opt,long pba_hz)277 int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
278 {
279 // Reset the USART and shutdown TX and RX.
280 usart_reset(usart);
281
282 // Check input values.
283 if (!opt || // Null pointer.
284 opt->charlength < 5 || opt->charlength > 9 ||
285 opt->paritytype > 7 ||
286 opt->stopbits > 2 + 255 ||
287 opt->channelmode > 3 ||
288 usart_set_async_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
289 return USART_INVALID_INPUT;
290
291 if (opt->charlength == 9)
292 {
293 // Character length set to 9 bits. MODE9 dominates CHRL.
294 usart->mr |= AVR32_USART_MR_MODE9_MASK;
295 }
296 else
297 {
298 // CHRL gives the character length (- 5) when MODE9 = 0.
299 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
300 }
301
302 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
303 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
304
305 if (opt->stopbits > USART_2_STOPBITS)
306 {
307 // Set two stop bits
308 usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
309 // and a timeguard period gives the rest.
310 usart->ttgr = opt->stopbits - USART_2_STOPBITS;
311 }
312 else
313 // Insert 1, 1.5 or 2 stop bits.
314 usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
315
316 // Set normal mode.
317 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
318 AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
319
320 // Setup complete; enable communication.
321 // Enable input and output.
322 usart->cr = AVR32_USART_CR_RXEN_MASK |
323 AVR32_USART_CR_TXEN_MASK;
324
325 return USART_SUCCESS;
326 }
327
328
usart_init_rs232_tx_only(volatile avr32_usart_t * usart,const usart_options_t * opt,long pba_hz)329 int usart_init_rs232_tx_only(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
330 {
331 // Reset the USART and shutdown TX and RX.
332 usart_reset(usart);
333
334 // Check input values.
335 if (!opt || // Null pointer.
336 opt->charlength < 5 || opt->charlength > 9 ||
337 opt->paritytype > 7 ||
338 opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
339 opt->channelmode > 3 ||
340 usart_set_sync_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
341 return USART_INVALID_INPUT;
342
343 if (opt->charlength == 9)
344 {
345 // Character length set to 9 bits. MODE9 dominates CHRL.
346 usart->mr |= AVR32_USART_MR_MODE9_MASK;
347 }
348 else
349 {
350 // CHRL gives the character length (- 5) when MODE9 = 0.
351 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
352 }
353
354 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
355 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
356
357 if (opt->stopbits > USART_2_STOPBITS)
358 {
359 // Set two stop bits
360 usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
361 // and a timeguard period gives the rest.
362 usart->ttgr = opt->stopbits - USART_2_STOPBITS;
363 }
364 else
365 // Insert 1 or 2 stop bits.
366 usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
367
368 // Set normal mode.
369 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
370 AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
371
372 // Setup complete; enable communication.
373 // Enable only output as input is not possible in synchronous mode without
374 // transferring clock.
375 usart->cr = AVR32_USART_CR_TXEN_MASK;
376
377 return USART_SUCCESS;
378 }
379
380
usart_init_hw_handshaking(volatile avr32_usart_t * usart,const usart_options_t * opt,long pba_hz)381 int usart_init_hw_handshaking(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
382 {
383 // First: Setup standard RS232.
384 if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
385 return USART_INVALID_INPUT;
386
387 // Set hardware handshaking mode.
388 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
389 AVR32_USART_MR_MODE_HARDWARE << AVR32_USART_MR_MODE_OFFSET;
390
391 return USART_SUCCESS;
392 }
393
394
usart_init_modem(volatile avr32_usart_t * usart,const usart_options_t * opt,long pba_hz)395 int usart_init_modem(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
396 {
397 // First: Setup standard RS232.
398 if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
399 return USART_INVALID_INPUT;
400
401 // Set modem mode.
402 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
403 AVR32_USART_MR_MODE_MODEM << AVR32_USART_MR_MODE_OFFSET;
404
405 return USART_SUCCESS;
406 }
407
408
usart_init_sync_master(volatile avr32_usart_t * usart,const usart_options_t * opt,long pba_hz)409 int usart_init_sync_master(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
410 {
411 // Reset the USART and shutdown TX and RX.
412 usart_reset(usart);
413
414 // Check input values.
415 if (!opt || // Null pointer.
416 opt->charlength < 5 || opt->charlength > 9 ||
417 opt->paritytype > 7 ||
418 opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
419 opt->channelmode > 3 ||
420 usart_set_sync_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
421 return USART_INVALID_INPUT;
422
423 if (opt->charlength == 9)
424 {
425 // Character length set to 9 bits. MODE9 dominates CHRL.
426 usart->mr |= AVR32_USART_MR_MODE9_MASK;
427 }
428 else
429 {
430 // CHRL gives the character length (- 5) when MODE9 = 0.
431 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
432 }
433
434 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
435 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
436
437 if (opt->stopbits > USART_2_STOPBITS)
438 {
439 // Set two stop bits
440 usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
441 // and a timeguard period gives the rest.
442 usart->ttgr = opt->stopbits - USART_2_STOPBITS;
443 }
444 else
445 // Insert 1 or 2 stop bits.
446 usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
447
448 // Set normal mode.
449 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
450 AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET |
451 AVR32_USART_MR_CLKO_MASK;
452
453 // Setup complete; enable communication.
454 // Enable input and output.
455 usart->cr = AVR32_USART_CR_RXEN_MASK |
456 AVR32_USART_CR_TXEN_MASK;
457
458 return USART_SUCCESS;
459 }
460
461
usart_init_sync_slave(volatile avr32_usart_t * usart,const usart_options_t * opt,long pba_hz)462 int usart_init_sync_slave(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
463 {
464 // Reset the USART and shutdown TX and RX.
465 usart_reset(usart);
466
467 // Check input values.
468 if (!opt || // Null pointer.
469 opt->charlength < 5 || opt->charlength > 9 ||
470 opt->paritytype > 7 ||
471 opt->stopbits == 1 || opt->stopbits > 2 + 255 ||
472 opt->channelmode > 3 ||
473 usart_set_sync_slave_baudrate(usart) == USART_INVALID_INPUT)
474 return USART_INVALID_INPUT;
475
476 if (opt->charlength == 9)
477 {
478 // Character length set to 9 bits. MODE9 dominates CHRL.
479 usart->mr |= AVR32_USART_MR_MODE9_MASK;
480 }
481 else
482 {
483 // CHRL gives the character length (- 5) when MODE9 = 0.
484 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
485 }
486
487 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
488 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET;
489
490 if (opt->stopbits > USART_2_STOPBITS)
491 {
492 // Set two stop bits
493 usart->mr |= AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET;
494 // and a timeguard period gives the rest.
495 usart->ttgr = opt->stopbits - USART_2_STOPBITS;
496 }
497 else
498 // Insert 1 or 2 stop bits.
499 usart->mr |= opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET;
500
501 // Set normal mode.
502 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
503 AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
504
505 // Setup complete; enable communication.
506 // Enable input and output.
507 usart->cr = AVR32_USART_CR_RXEN_MASK |
508 AVR32_USART_CR_TXEN_MASK;
509
510 return USART_SUCCESS;
511 }
512
513
usart_init_rs485(volatile avr32_usart_t * usart,const usart_options_t * opt,long pba_hz)514 int usart_init_rs485(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
515 {
516 // First: Setup standard RS232.
517 if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
518 return USART_INVALID_INPUT;
519
520 // Set RS485 mode.
521 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
522 AVR32_USART_MR_MODE_RS485 << AVR32_USART_MR_MODE_OFFSET;
523
524 return USART_SUCCESS;
525 }
526
527
usart_init_IrDA(volatile avr32_usart_t * usart,const usart_options_t * opt,long pba_hz,unsigned char irda_filter)528 int usart_init_IrDA(volatile avr32_usart_t *usart, const usart_options_t *opt,
529 long pba_hz, unsigned char irda_filter)
530 {
531 // First: Setup standard RS232.
532 if (usart_init_rs232(usart, opt, pba_hz) == USART_INVALID_INPUT)
533 return USART_INVALID_INPUT;
534
535 // Set IrDA filter.
536 usart->ifr = irda_filter;
537
538 // Set IrDA mode and activate filtering of input.
539 usart->mr = (usart->mr & ~AVR32_USART_MR_MODE_MASK) |
540 AVR32_USART_MODE_IRDA << AVR32_USART_MR_MODE_OFFSET |
541 AVR32_USART_MR_FILTER_MASK;
542
543 return USART_SUCCESS;
544 }
545
546
usart_init_iso7816(volatile avr32_usart_t * usart,const usart_iso7816_options_t * opt,int t,long pba_hz)547 int usart_init_iso7816(volatile avr32_usart_t *usart, const usart_iso7816_options_t *opt, int t, long pba_hz)
548 {
549 // Reset the USART and shutdown TX and RX.
550 usart_reset(usart);
551
552 // Check input values.
553 if (!opt || // Null pointer.
554 opt->paritytype > 1)
555 return USART_INVALID_INPUT;
556
557 if (t == 0)
558 {
559 // Set USART mode to ISO7816, T=0.
560 // The T=0 protocol always uses 2 stop bits.
561 usart->mr = AVR32_USART_MR_MODE_ISO7816_T0 << AVR32_USART_MR_MODE_OFFSET |
562 AVR32_USART_MR_NBSTOP_2 << AVR32_USART_MR_NBSTOP_OFFSET |
563 opt->bit_order << AVR32_USART_MR_MSBF_OFFSET; // Allow MSBF in T=0.
564 }
565 else if (t == 1)
566 {
567 // Only LSB first in the T=1 protocol.
568 // max_iterations field is only used in T=0 mode.
569 if (opt->bit_order != 0 ||
570 opt->max_iterations != 0)
571 return USART_INVALID_INPUT;
572
573 // Set USART mode to ISO7816, T=1.
574 // The T=1 protocol always uses 1 stop bit.
575 usart->mr = AVR32_USART_MR_MODE_ISO7816_T1 << AVR32_USART_MR_MODE_OFFSET |
576 AVR32_USART_MR_NBSTOP_1 << AVR32_USART_MR_NBSTOP_OFFSET;
577 }
578 else
579 return USART_INVALID_INPUT;
580
581 if (usart_set_iso7816_clock(usart, opt->iso7816_hz, pba_hz) == USART_INVALID_INPUT)
582 return USART_INVALID_INPUT;
583
584 // Set FIDI register: bit rate = selected clock/FI_DI_ratio/16.
585 usart->fidi = opt->fidi_ratio;
586
587 // Set ISO7816 specific options in the MODE register.
588 usart->mr |= opt->paritytype << AVR32_USART_MR_PAR_OFFSET |
589 AVR32_USART_MR_CLKO_MASK | // Enable clock output.
590 opt->inhibit_nack << AVR32_USART_MR_INACK_OFFSET |
591 opt->dis_suc_nack << AVR32_USART_MR_DSNACK_OFFSET |
592 opt->max_iterations << AVR32_USART_MR_MAX_ITERATION_OFFSET;
593
594 // Setup complete; enable the receiver by default.
595 usart_iso7816_enable_receiver(usart);
596
597 return USART_SUCCESS;
598 }
599
600
601 #if defined(AVR32_USART_400_H_INCLUDED) || \
602 defined(AVR32_USART_410_H_INCLUDED) || \
603 defined(AVR32_USART_420_H_INCLUDED) || \
604 defined(AVR32_USART_440_H_INCLUDED) || \
605 defined(AVR32_USART_602_H_INCLUDED)
606
607
usart_init_lin_master(volatile avr32_usart_t * usart,unsigned long baudrate,long pba_hz)608 int usart_init_lin_master(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz)
609 {
610 // Reset the USART and shutdown TX and RX.
611 usart_reset(usart);
612
613 // Check input values.
614 if (usart_set_async_baudrate(usart, baudrate, pba_hz) == USART_INVALID_INPUT)
615 return USART_INVALID_INPUT;
616
617 usart->mr |= AVR32_USART_MR_MODE_LIN_MASTER << AVR32_USART_MR_MODE_OFFSET; // LIN master mode.
618
619 // Setup complete; enable communication.
620 // Enable input and output.
621 usart->cr = AVR32_USART_CR_RXEN_MASK |
622 AVR32_USART_CR_TXEN_MASK;
623
624 return USART_SUCCESS;
625 }
626
627
usart_init_lin_slave(volatile avr32_usart_t * usart,unsigned long baudrate,long pba_hz)628 int usart_init_lin_slave(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz)
629 {
630 // Reset the USART and shutdown TX and RX.
631 usart_reset(usart);
632
633 // Check input values.
634 if (usart_set_async_baudrate(usart, baudrate, pba_hz) == USART_INVALID_INPUT)
635 return USART_INVALID_INPUT;
636
637 usart->mr |= AVR32_USART_MR_MODE_LIN_SLAVE << AVR32_USART_MR_MODE_OFFSET; // LIN slave mode.
638
639 // Setup complete; enable communication.
640 // Enable input and output.
641 usart->cr = AVR32_USART_CR_RXEN_MASK |
642 AVR32_USART_CR_TXEN_MASK;
643
644 return USART_SUCCESS;
645 }
646
647
usart_init_spi_master(volatile avr32_usart_t * usart,const usart_spi_options_t * opt,long pba_hz)648 int usart_init_spi_master(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz)
649 {
650 // Reset the USART and shutdown TX and RX.
651 usart_reset(usart);
652
653 // Check input values.
654 if (!opt || // Null pointer.
655 opt->charlength < 5 || opt->charlength > 9 ||
656 opt->spimode > 3 ||
657 opt->channelmode > 3 ||
658 usart_set_spi_master_baudrate(usart, opt->baudrate, pba_hz) == USART_INVALID_INPUT)
659 return USART_INVALID_INPUT;
660
661 if (opt->charlength == 9)
662 {
663 // Character length set to 9 bits. MODE9 dominates CHRL.
664 usart->mr |= AVR32_USART_MR_MODE9_MASK;
665 }
666 else
667 {
668 // CHRL gives the character length (- 5) when MODE9 = 0.
669 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
670 }
671
672 usart->mr |= AVR32_USART_MR_MODE_SPI_MASTER << AVR32_USART_MR_MODE_OFFSET | // SPI master mode.
673 ((opt->spimode & 0x1) ^ 0x1) << AVR32_USART_MR_SYNC_OFFSET | // SPI clock phase.
674 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET | // Channel mode.
675 (opt->spimode >> 1) << AVR32_USART_MR_MSBF_OFFSET | // SPI clock polarity.
676 AVR32_USART_MR_CLKO_MASK; // Drive SCK pin.
677
678 // Setup complete; enable communication.
679 // Enable input and output.
680 usart->cr = AVR32_USART_CR_RXEN_MASK |
681 AVR32_USART_CR_TXEN_MASK;
682
683 return USART_SUCCESS;
684 }
685
686
usart_init_spi_slave(volatile avr32_usart_t * usart,const usart_spi_options_t * opt,long pba_hz)687 int usart_init_spi_slave(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz)
688 {
689 // Reset the USART and shutdown TX and RX.
690 usart_reset(usart);
691
692 // Check input values.
693 if (!opt || // Null pointer.
694 opt->charlength < 5 || opt->charlength > 9 ||
695 opt->spimode > 3 ||
696 opt->channelmode > 3 ||
697 usart_set_spi_slave_baudrate(usart) == USART_INVALID_INPUT)
698 return USART_INVALID_INPUT;
699
700 if (opt->charlength == 9)
701 {
702 // Character length set to 9 bits. MODE9 dominates CHRL.
703 usart->mr |= AVR32_USART_MR_MODE9_MASK;
704 }
705 else
706 {
707 // CHRL gives the character length (- 5) when MODE9 = 0.
708 usart->mr |= (opt->charlength - 5) << AVR32_USART_MR_CHRL_OFFSET;
709 }
710
711 usart->mr |= AVR32_USART_MR_MODE_SPI_SLAVE << AVR32_USART_MR_MODE_OFFSET | // SPI slave mode.
712 ((opt->spimode & 0x1) ^ 0x1) << AVR32_USART_MR_SYNC_OFFSET | // SPI clock phase.
713 opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET | // Channel mode.
714 (opt->spimode >> 1) << AVR32_USART_MR_MSBF_OFFSET; // SPI clock polarity.
715
716 // Setup complete; enable communication.
717 // Enable input and output.
718 usart->cr = AVR32_USART_CR_RXEN_MASK |
719 AVR32_USART_CR_TXEN_MASK;
720
721 return USART_SUCCESS;
722 }
723
724
725 #endif // USART rev. >= 4.0.0
726
727
728 //! @}
729
730
731 //------------------------------------------------------------------------------
732 #if defined(AVR32_USART_400_H_INCLUDED) || \
733 defined(AVR32_USART_410_H_INCLUDED) || \
734 defined(AVR32_USART_420_H_INCLUDED) || \
735 defined(AVR32_USART_440_H_INCLUDED) || \
736 defined(AVR32_USART_602_H_INCLUDED)
737
738
739 /*! \name SPI Control Functions
740 */
741 //! @{
742
743
usart_spi_selectChip(volatile avr32_usart_t * usart)744 int usart_spi_selectChip(volatile avr32_usart_t *usart)
745 {
746 // Force the SPI chip select.
747 usart->cr = AVR32_USART_CR_RTSEN_MASK;
748
749 return USART_SUCCESS;
750 }
751
752
usart_spi_unselectChip(volatile avr32_usart_t * usart)753 int usart_spi_unselectChip(volatile avr32_usart_t *usart)
754 {
755 int timeout = USART_DEFAULT_TIMEOUT;
756
757 do
758 {
759 if (!timeout--) return USART_FAILURE;
760 } while (!usart_tx_empty(usart));
761
762 // Release the SPI chip select.
763 usart->cr = AVR32_USART_CR_RTSDIS_MASK;
764
765 return USART_SUCCESS;
766 }
767
768
769 //! @}
770
771
772 #endif // USART rev. >= 4.0.0
773
774
775 //------------------------------------------------------------------------------
776 /*! \name Transmit/Receive Functions
777 */
778 //! @{
779
780
usart_send_address(volatile avr32_usart_t * usart,int address)781 int usart_send_address(volatile avr32_usart_t *usart, int address)
782 {
783 // Check if USART is in multidrop / RS485 mode.
784 if (!usart_mode_is_multidrop(usart)) return USART_MODE_FAULT;
785
786 // Prepare to send an address.
787 usart->cr = AVR32_USART_CR_SENDA_MASK;
788
789 // Write the address to TX.
790 usart_bw_write_char(usart, address);
791
792 return USART_SUCCESS;
793 }
794
795
usart_write_char(volatile avr32_usart_t * usart,int c)796 int usart_write_char(volatile avr32_usart_t *usart, int c)
797 {
798 if (usart_tx_ready(usart))
799 {
800 usart->thr = (c << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
801 return USART_SUCCESS;
802 }
803 else
804 return USART_TX_BUSY;
805 }
806
807
usart_putchar(volatile avr32_usart_t * usart,int c)808 int usart_putchar(volatile avr32_usart_t *usart, int c)
809 {
810 int timeout = USART_DEFAULT_TIMEOUT;
811
812 do
813 {
814 if (!timeout--) return USART_FAILURE;
815 } while (usart_write_char(usart, c) != USART_SUCCESS);
816
817 return USART_SUCCESS;
818 }
819
820
usart_read_char(volatile avr32_usart_t * usart,int * c)821 int usart_read_char(volatile avr32_usart_t *usart, int *c)
822 {
823 // Check for errors: frame, parity and overrun. In RS485 mode, a parity error
824 // would mean that an address char has been received.
825 if (usart->csr & (AVR32_USART_CSR_OVRE_MASK |
826 AVR32_USART_CSR_FRAME_MASK |
827 AVR32_USART_CSR_PARE_MASK))
828 return USART_RX_ERROR;
829
830 // No error; if we really did receive a char, read it and return SUCCESS.
831 if (usart_test_hit(usart))
832 {
833 *c = (usart->rhr & AVR32_USART_RHR_RXCHR_MASK) >> AVR32_USART_RHR_RXCHR_OFFSET;
834 return USART_SUCCESS;
835 }
836 else
837 return USART_RX_EMPTY;
838 }
839
840
usart_getchar(volatile avr32_usart_t * usart)841 int usart_getchar(volatile avr32_usart_t *usart)
842 {
843 int c, ret;
844
845 while ((ret = usart_read_char(usart, &c)) == USART_RX_EMPTY);
846
847 if (ret == USART_RX_ERROR)
848 return USART_FAILURE;
849
850 return c;
851 }
852
853
usart_write_line(volatile avr32_usart_t * usart,const char * string)854 void usart_write_line(volatile avr32_usart_t *usart, const char *string)
855 {
856 while (*string != '\0')
857 usart_putchar(usart, *string++);
858 }
859
860
usart_get_echo_line(volatile avr32_usart_t * usart)861 int usart_get_echo_line(volatile avr32_usart_t *usart)
862 {
863 int rx_char;
864 int retval = USART_SUCCESS;
865
866 while (1)
867 {
868 rx_char = usart_getchar(usart);
869 if (rx_char == USART_FAILURE)
870 {
871 usart_write_line(usart, "Error!!!\r\n");
872 retval = USART_FAILURE;
873 break;
874 }
875 if (rx_char == '\x03')
876 {
877 retval = USART_FAILURE;
878 break;
879 }
880 usart_putchar(usart, rx_char);
881 if (rx_char == '\r')
882 { // Add a LF and consider this as the end of the line.
883 usart_putchar(usart, '\n');
884 break;
885 }
886 }
887
888 return retval;
889 }
890
891
892 //! @}
893