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 #ifndef _USART_H_
43 #define _USART_H_
44 
45 /**
46  * \defgroup group_avr32_drivers_usart USART - Univ. Sync/Async Serial Rec/Trans
47  *
48  * Driver for the USART (Universal Synchronous Asynchronous Receiver Transmitter).
49  * The driver supports the following  modes: RS232, RS485, SPI, LIN and ISO7816.
50  *
51  * \{
52  */
53 
54 #include <avr32/io.h>
55 #include "compiler.h"
56 
57 
58 /*! \name Return Values
59  */
60 //! @{
61 #define USART_SUCCESS                 0 //!< Successful completion.
62 #define USART_FAILURE                -1 //!< Failure because of some unspecified reason.
63 #define USART_INVALID_INPUT           1 //!< Input value out of range.
64 #define USART_INVALID_ARGUMENT       -1 //!< Argument value out of range.
65 #define USART_TX_BUSY                 2 //!< Transmitter was busy.
66 #define USART_RX_EMPTY                3 //!< Nothing was received.
67 #define USART_RX_ERROR                4 //!< Transmission error occurred.
68 #define USART_MODE_FAULT              5 //!< USART not in the appropriate mode.
69 //! @}
70 
71 //! Default time-out value (number of attempts).
72 #define USART_DEFAULT_TIMEOUT         10000
73 
74 /*! \name Parity Settings
75  */
76 //! @{
77 #define USART_EVEN_PARITY             AVR32_USART_MR_PAR_EVEN   //!< Use even parity on character transmission.
78 #define USART_ODD_PARITY              AVR32_USART_MR_PAR_ODD    //!< Use odd parity on character transmission.
79 #define USART_SPACE_PARITY            AVR32_USART_MR_PAR_SPACE  //!< Use a space as parity bit.
80 #define USART_MARK_PARITY             AVR32_USART_MR_PAR_MARK   //!< Use a mark as parity bit.
81 #define USART_NO_PARITY               AVR32_USART_MR_PAR_NONE   //!< Don't use a parity bit.
82 #define USART_MULTIDROP_PARITY        AVR32_USART_MR_PAR_MULTI  //!< Parity bit is used to flag address characters.
83 //! @}
84 
85 /*! \name Stop Bits Settings
86  */
87 //! @{
88 #define USART_1_STOPBIT               AVR32_USART_MR_NBSTOP_1   //!< Use 1 stop bit.
89 #define USART_1_5_STOPBITS            AVR32_USART_MR_NBSTOP_1_5 //!< Use 1.5 stop bits.
90 #define USART_2_STOPBITS              AVR32_USART_MR_NBSTOP_2   //!< Use 2 stop bits (for more, just give the number of bits).
91 //! @}
92 
93 /*! \name Channel Modes
94  */
95 //! @{
96 #define USART_NORMAL_CHMODE           AVR32_USART_MR_CHMODE_NORMAL      //!< Normal communication.
97 #define USART_AUTO_ECHO               AVR32_USART_MR_CHMODE_ECHO        //!< Echo data.
98 #define USART_LOCAL_LOOPBACK          AVR32_USART_MR_CHMODE_LOCAL_LOOP  //!< Local loopback.
99 #define USART_REMOTE_LOOPBACK         AVR32_USART_MR_CHMODE_REMOTE_LOOP //!< Remote loopback.
100 //! @}
101 
102 #if defined(AVR32_USART_400_H_INCLUDED) || \
103     defined(AVR32_USART_410_H_INCLUDED) || \
104     defined(AVR32_USART_420_H_INCLUDED) || \
105     defined(AVR32_USART_440_H_INCLUDED) || \
106     defined(AVR32_USART_602_H_INCLUDED)
107 
108 /*! \name LIN Node Actions
109  */
110 //! @{
111 #define USART_LIN_PUBLISH_ACTION      AVR32_USART_LINMR_NACT_PUBLISH    //!< The USART transmits the response.
112 #define USART_LIN_SUBSCRIBE_ACTION    AVR32_USART_LINMR_NACT_SUBSCRIBE  //!< The USART receives the response.
113 #define USART_LIN_IGNORE_ACTION       AVR32_USART_LINMR_NACT_IGNORE     //!< The USART does not transmit and does not receive the response.
114 //! @}
115 
116 /*! \name LIN Checksum Types
117  */
118 //! @{
119 #define USART_LIN_ENHANCED_CHECKSUM   0 //!< LIN 2.0 "enhanced" checksum.
120 #define USART_LIN_CLASSIC_CHECKSUM    1 //!< LIN 1.3 "classic" checksum.
121 //! @}
122 
123 #endif  // USART rev. >= 4.0.0
124 
125 
126 //! Input parameters when initializing RS232 and similar modes.
127 typedef struct
128 {
129   //! Set baud rate of the USART (unused in slave modes).
130   unsigned long baudrate;
131 
132   //! Number of bits to transmit as a character (5 to 9).
133   unsigned char charlength;
134 
135   //! How to calculate the parity bit: \ref USART_EVEN_PARITY, \ref USART_ODD_PARITY,
136   //! \ref USART_SPACE_PARITY, \ref USART_MARK_PARITY, \ref USART_NO_PARITY or
137   //! \ref USART_MULTIDROP_PARITY.
138   unsigned char paritytype;
139 
140   //! Number of stop bits between two characters: \ref USART_1_STOPBIT,
141   //! \ref USART_1_5_STOPBITS, \ref USART_2_STOPBITS or any number from 3 to 257
142   //! which will result in a time guard period of that length between characters.
143   //! \note \ref USART_1_5_STOPBITS is supported in asynchronous modes only.
144   unsigned short stopbits;
145 
146   //! Run the channel in testmode: \ref USART_NORMAL_CHMODE, \ref USART_AUTO_ECHO,
147   //! \ref USART_LOCAL_LOOPBACK or \ref USART_REMOTE_LOOPBACK.
148   unsigned char channelmode;
149 } usart_options_t;
150 
151 //! Input parameters when initializing ISO7816 mode.
152 typedef struct
153 {
154   //! Set the frequency of the ISO7816 clock.
155   unsigned long iso7816_hz;
156 
157   //! The number of ISO7816 clock ticks in every bit period (1 to 2047, 0 = disable clock).
158   //! Bit rate = \ref iso7816_hz / \ref fidi_ratio.
159   unsigned short fidi_ratio;
160 
161   //! How to calculate the parity bit: \ref USART_EVEN_PARITY for normal mode or
162   //! \ref USART_ODD_PARITY for inverse mode.
163   unsigned char paritytype;
164 
165   //! Inhibit Non Acknowledge:\n
166   //!   - 0: the NACK is generated;\n
167   //!   - 1: the NACK is not generated.
168   //!
169   //! \note This bit will be used only in ISO7816 mode, protocol T = 0 receiver.
170   int inhibit_nack;
171 
172   //! Disable successive NACKs.
173   //! Successive parity errors are counted up to the value in the \ref max_iterations field.
174   //! These parity errors generate a NACK on the ISO line. As soon as this value is reached,
175   //! no additional NACK is sent on the ISO line. The ITERATION flag is asserted.
176   int dis_suc_nack;
177 
178   //! Max number of repetitions (0 to 7).
179   unsigned char max_iterations;
180 
181   //! Bit order in transmitted characters:\n
182   //!   - 0: LSB first;\n
183   //!   - 1: MSB first.
184   int bit_order;
185 } usart_iso7816_options_t;
186 
187 #if defined(AVR32_USART_400_H_INCLUDED) || \
188     defined(AVR32_USART_410_H_INCLUDED) || \
189     defined(AVR32_USART_420_H_INCLUDED) || \
190     defined(AVR32_USART_440_H_INCLUDED) || \
191     defined(AVR32_USART_602_H_INCLUDED)
192 
193 //! Input parameters when initializing SPI mode.
194 typedef struct
195 {
196   //! Set the frequency of the SPI clock (unused in slave mode).
197   unsigned long baudrate;
198 
199   //! Number of bits to transmit as a character (5 to 9).
200   unsigned char charlength;
201 
202   //! Which SPI mode to use.
203   unsigned char spimode;
204 
205   //! Run the channel in testmode: \ref USART_NORMAL_CHMODE, \ref USART_AUTO_ECHO,
206   //! \ref USART_LOCAL_LOOPBACK or \ref USART_REMOTE_LOOPBACK.
207   unsigned char channelmode;
208 } usart_spi_options_t;
209 
210 #endif  // USART rev. >= 4.0.0
211 
212 
213 //------------------------------------------------------------------------------
214 /*! \name Initialization Functions
215  */
216 //! @{
217 
218 /*! \brief Resets the USART and disables TX and RX.
219  *
220  * \param usart   Base address of the USART instance.
221  */
222 extern void usart_reset(volatile avr32_usart_t *usart);
223 
224 /*! \brief Sets up the USART to use the standard RS232 protocol.
225  *
226  * \param usart   Base address of the USART instance.
227  * \param opt     Options needed to set up RS232 communication (see \ref usart_options_t).
228  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
229  *
230  * \retval USART_SUCCESS        Mode successfully initialized.
231  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
232  */
233 extern int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
234 
235 /*! \brief Sets up the USART to use the standard RS232 protocol in TX-only mode.
236  *
237  * Compared to \ref usart_init_rs232, this function allows very high baud rates
238  * (up to \a pba_hz instead of \a pba_hz / \c 8) at the expense of full duplex.
239  *
240  * \param usart   Base address of the USART instance.
241  * \param opt     Options needed to set up RS232 communication (see \ref usart_options_t).
242  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
243  *
244  * \retval USART_SUCCESS        Mode successfully initialized.
245  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
246  *
247  * \note The \c 1.5 stop bit is not supported in this mode.
248  */
249 extern int usart_init_rs232_tx_only(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
250 
251 /*! \brief Sets up the USART to use hardware handshaking.
252  *
253  * \param usart   Base address of the USART instance.
254  * \param opt     Options needed to set up RS232 communication (see \ref usart_options_t).
255  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
256  *
257  * \retval USART_SUCCESS        Mode successfully initialized.
258  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
259  *
260  * \note \ref usart_init_rs232 does not need to be invoked before this function.
261  */
262 extern int usart_init_hw_handshaking(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
263 
264 /*! \brief Sets up the USART to use the modem protocol, activating dedicated inputs/outputs.
265  *
266  * \param usart   Base address of the USART instance.
267  * \param opt     Options needed to set up RS232 communication (see \ref usart_options_t).
268  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
269  *
270  * \retval USART_SUCCESS        Mode successfully initialized.
271  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
272  */
273 extern int usart_init_modem(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
274 
275 /*! \brief Sets up the USART to use a synchronous RS232-like protocol in master mode.
276  *
277  * \param usart   Base address of the USART instance.
278  * \param opt     Options needed to set up RS232 communication (see \ref usart_options_t).
279  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
280  *
281  * \retval USART_SUCCESS        Mode successfully initialized.
282  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
283  */
284 extern int usart_init_sync_master(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
285 
286 /*! \brief Sets up the USART to use a synchronous RS232-like protocol in slave mode.
287  *
288  * \param usart   Base address of the USART instance.
289  * \param opt     Options needed to set up RS232 communication (see \ref usart_options_t).
290  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
291  *
292  * \retval USART_SUCCESS        Mode successfully initialized.
293  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
294  */
295 extern int usart_init_sync_slave(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
296 
297 /*! \brief Sets up the USART to use the RS485 protocol.
298  *
299  * \param usart   Base address of the USART instance.
300  * \param opt     Options needed to set up RS232 communication (see \ref usart_options_t).
301  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
302  *
303  * \retval USART_SUCCESS        Mode successfully initialized.
304  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
305  */
306 extern int usart_init_rs485(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
307 
308 /*! \brief Sets up the USART to use the IrDA protocol.
309  *
310  * \param usart         Base address of the USART instance.
311  * \param opt           Options needed to set up RS232 communication (see \ref usart_options_t).
312  * \param pba_hz        USART module input clock frequency (PBA clock, Hz).
313  * \param irda_filter   Counter used to distinguish received ones from zeros.
314  *
315  * \retval USART_SUCCESS        Mode successfully initialized.
316  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
317  */
318 extern int usart_init_IrDA(volatile avr32_usart_t *usart, const usart_options_t *opt,
319                            long pba_hz, unsigned char irda_filter);
320 
321 /*! \brief Sets up the USART to use the ISO7816 T=0 or T=1 smartcard protocols.
322  *
323  * The receiver is enabled by default. \ref usart_iso7816_enable_receiver and
324  * \ref usart_iso7816_enable_transmitter can be called to change the half-duplex
325  * communication direction.
326  *
327  * \param usart   Base address of the USART instance.
328  * \param opt     Options needed to set up ISO7816 communication (see \ref usart_iso7816_options_t).
329  * \param t       ISO7816 mode to use (T=0 or T=1).
330  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
331  *
332  * \retval USART_SUCCESS        Mode successfully initialized.
333  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
334  */
335 extern int usart_init_iso7816(volatile avr32_usart_t *usart, const usart_iso7816_options_t *opt, int t, long pba_hz);
336 
337 #if defined(AVR32_USART_400_H_INCLUDED) || \
338     defined(AVR32_USART_410_H_INCLUDED) || \
339     defined(AVR32_USART_420_H_INCLUDED) || \
340     defined(AVR32_USART_440_H_INCLUDED) || \
341     defined(AVR32_USART_602_H_INCLUDED)
342 
343 /*! \brief Sets up the USART to use the LIN master mode.
344  *
345  * \param usart     Base address of the USART instance.
346  * \param baudrate  Baud rate.
347  * \param pba_hz    USART module input clock frequency (PBA clock, Hz).
348  *
349  */
350 extern int usart_init_lin_master(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz);
351 
352 /*! \brief Sets up the USART to use the LIN slave mode.
353  *
354  * \param usart     Base address of the USART instance.
355  * \param baudrate  Baud rate.
356  * \param pba_hz    USART module input clock frequency (PBA clock, Hz).
357  *
358  */
359 extern int usart_init_lin_slave(volatile avr32_usart_t *usart, unsigned long baudrate, long pba_hz);
360 
361 /*! \brief Sets up the USART to use the SPI master mode.
362  *
363  * \ref usart_spi_selectChip and \ref usart_spi_unselectChip can be called to
364  * select or unselect the SPI slave chip.
365  *
366  * \param usart   Base address of the USART instance.
367  * \param opt     Options needed to set up SPI mode (see \ref usart_spi_options_t).
368  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
369  *
370  * \retval USART_SUCCESS        Mode successfully initialized.
371  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
372  */
373 extern int usart_init_spi_master(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz);
374 
375 /*! \brief Sets up the USART to use the SPI slave mode.
376  *
377  * \param usart   Base address of the USART instance.
378  * \param opt     Options needed to set up SPI mode (see \ref usart_spi_options_t).
379  * \param pba_hz  USART module input clock frequency (PBA clock, Hz).
380  *
381  * \retval USART_SUCCESS        Mode successfully initialized.
382  * \retval USART_INVALID_INPUT  One or more of the arguments is out of valid range.
383  */
384 extern int usart_init_spi_slave(volatile avr32_usart_t *usart, const usart_spi_options_t *opt, long pba_hz);
385 
386 #endif  // USART rev. >= 4.0.0
387 
388 //! @}
389 
390 
391 //------------------------------------------------------------------------------
392 /*! \name Read and Reset Error Status Bits
393  */
394 //! @{
395 
396 /*! \brief Resets the error status.
397  *
398  * This function resets the status bits indicating that a parity error,
399  * framing error or overrun has occurred. The RXBRK bit, indicating
400  * a start/end of break condition on the RX line, is also reset.
401  *
402  * \param usart   Base address of the USART instance.
403  */
usart_reset_status(volatile avr32_usart_t * usart)404 __always_inline static void usart_reset_status(volatile avr32_usart_t *usart)
405 {
406   usart->cr = AVR32_USART_CR_RSTSTA_MASK;
407 }
408 
409 /*! \brief Checks if a parity error has occurred since last status reset.
410  *
411  * \param usart   Base address of the USART instance.
412  *
413  * \return \c 1 if a parity error has been detected, otherwise \c 0.
414  */
usart_parity_error(volatile avr32_usart_t * usart)415 __always_inline static int usart_parity_error(volatile avr32_usart_t *usart)
416 {
417   return (usart->csr & AVR32_USART_CSR_PARE_MASK) != 0;
418 }
419 
420 /*! \brief Checks if a framing error has occurred since last status reset.
421  *
422  * \param usart   Base address of the USART instance.
423  *
424  * \return \c 1 if a framing error has been detected, otherwise \c 0.
425  */
usart_framing_error(volatile avr32_usart_t * usart)426 __always_inline static int usart_framing_error(volatile avr32_usart_t *usart)
427 {
428   return (usart->csr & AVR32_USART_CSR_FRAME_MASK) != 0;
429 }
430 
431 /*! \brief Checks if an overrun error has occurred since last status reset.
432  *
433  * \param usart   Base address of the USART instance.
434  *
435  * \return \c 1 if a overrun error has been detected, otherwise \c 0.
436  */
usart_overrun_error(volatile avr32_usart_t * usart)437 __always_inline static int usart_overrun_error(volatile avr32_usart_t *usart)
438 {
439   return (usart->csr & AVR32_USART_CSR_OVRE_MASK) != 0;
440 }
441 
442 #if defined(AVR32_USART_400_H_INCLUDED) || \
443     defined(AVR32_USART_410_H_INCLUDED) || \
444     defined(AVR32_USART_420_H_INCLUDED) || \
445     defined(AVR32_USART_440_H_INCLUDED) || \
446     defined(AVR32_USART_602_H_INCLUDED)
447 
448 /*! \brief Get LIN Error Status
449  *
450  * \param usart   Base address of the USART instance.
451  *
452  * \retval The binary value of the error field.
453  */
usart_lin_get_error(volatile avr32_usart_t * usart)454 __always_inline static int usart_lin_get_error(volatile avr32_usart_t *usart)
455 {
456   return (usart->csr & (AVR32_USART_CSR_LINSNRE_MASK |
457                         AVR32_USART_CSR_LINCE_MASK |
458                         AVR32_USART_CSR_LINIPE_MASK |
459                         AVR32_USART_CSR_LINISFE_MASK |
460                         AVR32_USART_CSR_LINBE_MASK)) >> AVR32_USART_CSR_LINBE_OFFSET;
461 }
462 
463 #endif  // USART rev. >= 4.0.0
464 
465 //! @}
466 
467 
468 //------------------------------------------------------------------------------
469 /*! \name ISO7816 Control Functions
470  */
471 //! @{
472 
473 /*! \brief Enables the ISO7816 receiver.
474  *
475  * The ISO7816 transmitter is disabled.
476  *
477  * \param usart   Base address of the USART instance.
478  */
usart_iso7816_enable_receiver(volatile avr32_usart_t * usart)479 __always_inline static void usart_iso7816_enable_receiver(volatile avr32_usart_t *usart)
480 {
481   usart->cr = AVR32_USART_CR_TXDIS_MASK | AVR32_USART_CR_RXEN_MASK;
482 }
483 
484 /*! \brief Enables the ISO7816 transmitter.
485  *
486  * The ISO7816 receiver is disabled.
487  *
488  * \param usart   Base address of the USART instance.
489  */
usart_iso7816_enable_transmitter(volatile avr32_usart_t * usart)490 __always_inline static void usart_iso7816_enable_transmitter(volatile avr32_usart_t *usart)
491 {
492   usart->cr = AVR32_USART_CR_RXDIS_MASK | AVR32_USART_CR_TXEN_MASK;
493 }
494 
495 //! @}
496 
497 
498 //------------------------------------------------------------------------------
499 #if defined(AVR32_USART_400_H_INCLUDED) || \
500     defined(AVR32_USART_410_H_INCLUDED) || \
501     defined(AVR32_USART_420_H_INCLUDED) || \
502     defined(AVR32_USART_440_H_INCLUDED) || \
503     defined(AVR32_USART_602_H_INCLUDED)
504 
505 /*! \name LIN Control Functions
506  */
507 //! @{
508 
509 /*! \brief Sets the node action.
510  *
511  * \param usart   Base address of the USART instance.
512  * \param action  The node action: \ref USART_LIN_PUBLISH_ACTION,
513  *                \ref USART_LIN_SUBSCRIBE_ACTION or
514  *                \ref USART_LIN_IGNORE_ACTION.
515  */
usart_lin_set_node_action(volatile avr32_usart_t * usart,unsigned char action)516 __always_inline static void usart_lin_set_node_action(volatile avr32_usart_t *usart, unsigned char action)
517 {
518   usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_NACT_MASK) |
519                  action << AVR32_USART_LINMR_NACT_OFFSET;
520 }
521 
522 /*! \brief Enables or disables the Identifier parity.
523  *
524  * \param usart   Base address of the USART instance.
525  * \param parity  Whether to enable the Identifier parity: \c true or \c false.
526  */
usart_lin_enable_parity(volatile avr32_usart_t * usart,unsigned char parity)527 __always_inline static void usart_lin_enable_parity(volatile avr32_usart_t *usart, unsigned char parity)
528 {
529   usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_PARDIS_MASK) |
530                  !parity << AVR32_USART_LINMR_PARDIS_OFFSET;
531 }
532 
533 /*! \brief Enables or disables the checksum.
534  *
535  * \param usart   Base address of the USART instance.
536  * \param parity  Whether to enable the checksum: \c true or \c false.
537  */
usart_lin_enable_checksum(volatile avr32_usart_t * usart,unsigned char checksum)538 __always_inline static void usart_lin_enable_checksum(volatile avr32_usart_t *usart, unsigned char checksum)
539 {
540   usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_CHKDIS_MASK) |
541                  !checksum << AVR32_USART_LINMR_CHKDIS_OFFSET;
542 }
543 
544 /*! \brief Sets the checksum type.
545  *
546  * \param usart   Base address of the USART instance.
547  * \param chktyp  The checksum type: \ref USART_LIN_ENHANCED_CHEKSUM or
548  *                \ref USART_LIN_CLASSIC_CHECKSUM.
549  */
usart_lin_set_checksum(volatile avr32_usart_t * usart,unsigned char chktyp)550 __always_inline static void usart_lin_set_checksum(volatile avr32_usart_t *usart, unsigned char chktyp)
551 {
552   usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_CHKTYP_MASK) |
553                  chktyp << AVR32_USART_LINMR_CHKTYP_OFFSET;
554 }
555 
556 /*! \brief Gets the response data length.
557  *
558  * \param usart   Base address of the USART instance.
559  *
560  * \return The response data length.
561  */
usart_lin_get_data_length(volatile avr32_usart_t * usart)562 __always_inline static unsigned char usart_lin_get_data_length(volatile avr32_usart_t *usart)
563 {
564   if (usart->linmr & AVR32_USART_LINMR_DLM_MASK)
565   {
566     unsigned char data_length = 1 << ((usart->linir >> (AVR32_USART_LINIR_IDCHR_OFFSET + 4)) & 0x03);
567     if (data_length == 1)
568       data_length = 2;
569     return data_length;
570   }
571   else
572     return ((usart->linmr & AVR32_USART_LINMR_DLC_MASK) >> AVR32_USART_LINMR_DLC_OFFSET) + 1;
573 }
574 
575 /*! \brief Sets the response data length for LIN 1.x.
576  *
577  * \param usart   Base address of the USART instance.
578  */
usart_lin_set_data_length_lin1x(volatile avr32_usart_t * usart)579 __always_inline static void usart_lin_set_data_length_lin1x(volatile avr32_usart_t *usart)
580 {
581   usart->linmr |= AVR32_USART_LINMR_DLM_MASK;
582 }
583 
584 /*! \brief Sets the response data length for LIN 2.x.
585  *
586  * \param usart         Base address of the USART instance.
587  * \param data_length   The response data length.
588  */
usart_lin_set_data_length_lin2x(volatile avr32_usart_t * usart,unsigned char data_length)589 __always_inline static void usart_lin_set_data_length_lin2x(volatile avr32_usart_t *usart, unsigned char data_length)
590 {
591   usart->linmr = (usart->linmr & ~(AVR32_USART_LINMR_DLC_MASK |
592                                    AVR32_USART_LINMR_DLM_MASK)) |
593                  (data_length - 1) << AVR32_USART_LINMR_DLC_OFFSET;
594 }
595 
596 /*! \brief Enables or disables the frame slot mode.
597  *
598  * \param usart       Base address of the USART instance.
599  * \param frameslot   Whether to enable the frame slot mode: \c true or
600  *                    \c false.
601  */
usart_lin_enable_frameslot(volatile avr32_usart_t * usart,unsigned char frameslot)602 __always_inline static void usart_lin_enable_frameslot(volatile avr32_usart_t *usart, unsigned char frameslot)
603 {
604   usart->linmr = (usart->linmr & ~AVR32_USART_LINMR_FSDIS_MASK) |
605                  !frameslot << AVR32_USART_LINMR_FSDIS_OFFSET;
606 }
607 
608 /*! \brief Gets the Identifier character.
609  *
610  * \param usart   Base address of the USART instance.
611  *
612  * \return The Identifier character.
613  */
usart_lin_get_id_char(volatile avr32_usart_t * usart)614 __always_inline static unsigned char usart_lin_get_id_char(volatile avr32_usart_t *usart)
615 {
616   return (usart->linir & AVR32_USART_LINIR_IDCHR_MASK) >> AVR32_USART_LINIR_IDCHR_OFFSET;
617 }
618 
619 /*! \brief Sets the Identifier character.
620  *
621  * \param usart     Base address of the USART instance.
622  * \param id_char   The Identifier character.
623  */
usart_lin_set_id_char(volatile avr32_usart_t * usart,unsigned char id_char)624 __always_inline static void usart_lin_set_id_char(volatile avr32_usart_t *usart, unsigned char id_char)
625 {
626   usart->linir = (usart->linir & ~AVR32_USART_LINIR_IDCHR_MASK) |
627                  id_char << AVR32_USART_LINIR_IDCHR_OFFSET;
628 }
629 
630 //! @}
631 
632 #endif  // USART rev. >= 4.0.0
633 
634 
635 //------------------------------------------------------------------------------
636 #if defined(AVR32_USART_400_H_INCLUDED) || \
637     defined(AVR32_USART_410_H_INCLUDED) || \
638     defined(AVR32_USART_420_H_INCLUDED) || \
639     defined(AVR32_USART_440_H_INCLUDED) || \
640     defined(AVR32_USART_602_H_INCLUDED)
641 
642 /*! \name SPI Control Functions
643  */
644 //! @{
645 
646 /*! \brief Selects SPI slave chip.
647  *
648  * \param usart   Base address of the USART instance.
649  *
650  * \retval USART_SUCCESS        Success.
651  */
652 extern int usart_spi_selectChip(volatile avr32_usart_t *usart);
653 
654 /*! \brief Unselects SPI slave chip.
655  *
656  * \param usart   Base address of the USART instance.
657  *
658  * \retval USART_SUCCESS        Success.
659  * \retval USART_FAILURE        Time-out.
660  */
661 extern int usart_spi_unselectChip(volatile avr32_usart_t *usart);
662 
663 //! @}
664 
665 #endif  // USART rev. >= 4.0.0
666 
667 
668 //------------------------------------------------------------------------------
669 /*! \name Transmit/Receive Functions
670  */
671 //! @{
672 
673 /*! \brief Addresses a receiver.
674  *
675  * While in RS485 mode, receivers only accept data addressed to them.
676  * A packet/char with the address tag set has to precede any data.
677  * This function is used to address a receiver. This receiver should read
678  * all the following data, until an address packet addresses another receiver.
679  *
680  * \param usart     Base address of the USART instance.
681  * \param address   Address of the target device.
682  *
683  * \retval USART_SUCCESS    Address successfully sent (if current mode is RS485).
684  * \retval USART_MODE_FAULT Wrong operating mode.
685  */
686 extern int usart_send_address(volatile avr32_usart_t *usart, int address);
687 
688 /*! \brief Tests if the USART is ready to transmit a character.
689  *
690  * \param usart   Base address of the USART instance.
691  *
692  * \return \c 1 if the USART Transmit Holding Register is free, otherwise \c 0.
693  */
usart_tx_ready(volatile avr32_usart_t * usart)694 __always_inline static int usart_tx_ready(volatile avr32_usart_t *usart)
695 {
696   return (usart->csr & AVR32_USART_CSR_TXRDY_MASK) != 0;
697 }
698 
699 /*! \brief Writes the given character to the TX buffer if the transmitter is ready.
700  *
701  * \param usart   Base address of the USART instance.
702  * \param c       The character (up to 9 bits) to transmit.
703  *
704  * \retval USART_SUCCESS  The transmitter was ready.
705  * \retval USART_TX_BUSY  The transmitter was busy.
706  */
707 extern int usart_write_char(volatile avr32_usart_t *usart, int c);
708 
709 /*! \brief An active wait writing a character to the USART.
710  *
711  * \param usart   Base address of the USART instance.
712  * \param c       The character (up to 9 bits) to transmit.
713  */
usart_bw_write_char(volatile avr32_usart_t * usart,int c)714 __always_inline static void usart_bw_write_char(volatile avr32_usart_t *usart, int c)
715 {
716   while (usart_write_char(usart, c) != USART_SUCCESS);
717 }
718 
719 /*! \brief Sends a character with the USART.
720  *
721  * \param usart   Base address of the USART instance.
722  * \param c       Character to write.
723  *
724  * \retval USART_SUCCESS  The character was written.
725  * \retval USART_FAILURE  The function timed out before the USART transmitter became ready to send.
726  */
727 extern int usart_putchar(volatile avr32_usart_t *usart, int c);
728 
729 /*! \brief Tests if all requested USART transmissions are over.
730  *
731  * \param usart   Base address of the USART instance.
732  *
733  * \return \c 1 if the USART Transmit Shift Register and the USART Transmit
734  *         Holding Register are free, otherwise \c 0.
735  */
usart_tx_empty(volatile avr32_usart_t * usart)736 __always_inline static int usart_tx_empty(volatile avr32_usart_t *usart)
737 {
738   return (usart->csr & AVR32_USART_CSR_TXEMPTY_MASK) != 0;
739 }
740 
741 /*! \brief Tests if the USART contains a received character.
742  *
743  * \param usart   Base address of the USART instance.
744  *
745  * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0.
746  */
usart_test_hit(volatile avr32_usart_t * usart)747 __always_inline static int usart_test_hit(volatile avr32_usart_t *usart)
748 {
749   return (usart->csr & AVR32_USART_CSR_RXRDY_MASK) != 0;
750 }
751 
752 /*! \brief Checks the RX buffer for a received character, and stores it at the
753  *         given memory location.
754  *
755  * \param usart   Base address of the USART instance.
756  * \param c       Pointer to the where the read character should be stored
757  *                (must be at least short in order to accept 9-bit characters).
758  *
759  * \retval USART_SUCCESS  The character was read successfully.
760  * \retval USART_RX_EMPTY The RX buffer was empty.
761  * \retval USART_RX_ERROR An error was detected.
762  */
763 extern int usart_read_char(volatile avr32_usart_t *usart, int *c);
764 
765 /*! \brief Waits until a character is received, and returns it.
766  *
767  * \param usart   Base address of the USART instance.
768  *
769  * \return The received character, or \ref USART_FAILURE upon error.
770  */
771 extern int usart_getchar(volatile avr32_usart_t *usart);
772 
773 /*! \brief Writes one character string to the USART.
774  *
775  * \param usart   Base address of the USART instance.
776  * \param string  String to be written.
777  */
778 extern void usart_write_line(volatile avr32_usart_t *usart, const char *string);
779 
780 /*! \brief Gets and echoes characters until end of line (detected by a CR character).
781  *
782  * \param usart   Base address of the USART instance.
783  *
784  * \retval USART_SUCCESS  Success.
785  * \retval USART_FAILURE  Low-level error detected or ETX character received.
786  */
787 extern int usart_get_echo_line(volatile avr32_usart_t *usart);
788 
789 #if defined(AVR32_USART_400_H_INCLUDED) || \
790     defined(AVR32_USART_410_H_INCLUDED) || \
791     defined(AVR32_USART_420_H_INCLUDED) || \
792     defined(AVR32_USART_440_H_INCLUDED) || \
793     defined(AVR32_USART_602_H_INCLUDED)
794 
795 /*! \brief Abort LIN transmission.
796  *
797  * \param usart   Base address of the USART instance.
798  */
usart_lin_abort(volatile avr32_usart_t * usart)799 __always_inline static void usart_lin_abort(volatile avr32_usart_t *usart)
800 {
801   usart->cr = AVR32_USART_LINABT_MASK;
802 }
803 
804 /*! \brief Tests if a LIN transfer has been completed.
805  *
806  * \param usart   Base address of the USART instance.
807  *
808  * \return \c 1 if a LIN transfer has been completed, otherwise \c 0.
809  */
usart_lin_transfer_completed(volatile avr32_usart_t * usart)810 __always_inline static int usart_lin_transfer_completed(volatile avr32_usart_t *usart)
811 {
812   return (usart->csr & AVR32_USART_CSR_LINTC_MASK) != 0;
813 }
814 
815 #endif  // USART rev. >= 4.0.0
816 
817 //! @}
818 
819 /**
820  * \}
821  */
822 
823 #endif  // _USART_H_
824