xref: /btstack/port/samv71-xplained-atwilc3000/ASF/sam/drivers/usart/usart.c (revision 1b2596b5303dd8caeea8565532c93cca8dab8cc4)
1*1b2596b5SMatthias Ringwald /**
2*1b2596b5SMatthias Ringwald  * \file
3*1b2596b5SMatthias Ringwald  *
4*1b2596b5SMatthias Ringwald  * \brief Universal Synchronous Asynchronous Receiver Transmitter (USART) driver
5*1b2596b5SMatthias Ringwald  * for SAM.
6*1b2596b5SMatthias Ringwald  *
7*1b2596b5SMatthias Ringwald  * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
8*1b2596b5SMatthias Ringwald  *
9*1b2596b5SMatthias Ringwald  * \asf_license_start
10*1b2596b5SMatthias Ringwald  *
11*1b2596b5SMatthias Ringwald  * \page License
12*1b2596b5SMatthias Ringwald  *
13*1b2596b5SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
14*1b2596b5SMatthias Ringwald  * modification, are permitted provided that the following conditions are met:
15*1b2596b5SMatthias Ringwald  *
16*1b2596b5SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright notice,
17*1b2596b5SMatthias Ringwald  *    this list of conditions and the following disclaimer.
18*1b2596b5SMatthias Ringwald  *
19*1b2596b5SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright notice,
20*1b2596b5SMatthias Ringwald  *    this list of conditions and the following disclaimer in the documentation
21*1b2596b5SMatthias Ringwald  *    and/or other materials provided with the distribution.
22*1b2596b5SMatthias Ringwald  *
23*1b2596b5SMatthias Ringwald  * 3. The name of Atmel may not be used to endorse or promote products derived
24*1b2596b5SMatthias Ringwald  *    from this software without specific prior written permission.
25*1b2596b5SMatthias Ringwald  *
26*1b2596b5SMatthias Ringwald  * 4. This software may only be redistributed and used in connection with an
27*1b2596b5SMatthias Ringwald  *    Atmel microcontroller product.
28*1b2596b5SMatthias Ringwald  *
29*1b2596b5SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
30*1b2596b5SMatthias Ringwald  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31*1b2596b5SMatthias Ringwald  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
32*1b2596b5SMatthias Ringwald  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
33*1b2596b5SMatthias Ringwald  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34*1b2596b5SMatthias Ringwald  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35*1b2596b5SMatthias Ringwald  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36*1b2596b5SMatthias Ringwald  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37*1b2596b5SMatthias Ringwald  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38*1b2596b5SMatthias Ringwald  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39*1b2596b5SMatthias Ringwald  * POSSIBILITY OF SUCH DAMAGE.
40*1b2596b5SMatthias Ringwald  *
41*1b2596b5SMatthias Ringwald  * \asf_license_stop
42*1b2596b5SMatthias Ringwald  *
43*1b2596b5SMatthias Ringwald  */
44*1b2596b5SMatthias Ringwald /*
45*1b2596b5SMatthias Ringwald  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
46*1b2596b5SMatthias Ringwald  */
47*1b2596b5SMatthias Ringwald 
48*1b2596b5SMatthias Ringwald #include "usart.h"
49*1b2596b5SMatthias Ringwald 
50*1b2596b5SMatthias Ringwald /// @cond 0
51*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
52*1b2596b5SMatthias Ringwald #ifdef __cplusplus
53*1b2596b5SMatthias Ringwald extern "C" {
54*1b2596b5SMatthias Ringwald #endif
55*1b2596b5SMatthias Ringwald /**INDENT-ON**/
56*1b2596b5SMatthias Ringwald /// @endcond
57*1b2596b5SMatthias Ringwald 
58*1b2596b5SMatthias Ringwald /**
59*1b2596b5SMatthias Ringwald  * \defgroup sam_drivers_usart_group Universal Synchronous Asynchronous
60*1b2596b5SMatthias Ringwald  * Receiver Transmitter (USART)
61*1b2596b5SMatthias Ringwald  *
62*1b2596b5SMatthias Ringwald  * The Universal Synchronous Asynchronous Receiver Transceiver (USART)
63*1b2596b5SMatthias Ringwald  * provides one full duplex universal synchronous asynchronous serial link.
64*1b2596b5SMatthias Ringwald  * Data frame format is widely programmable (data length, parity, number of
65*1b2596b5SMatthias Ringwald  * stop bits) to support a maximum of standards. The receiver implements
66*1b2596b5SMatthias Ringwald  * parity error, framing error and overrun error detection. The receiver
67*1b2596b5SMatthias Ringwald  * time-out enables handling variable-length frames and the transmitter
68*1b2596b5SMatthias Ringwald  * timeguard facilitates communications with slow remote devices. Multidrop
69*1b2596b5SMatthias Ringwald  * communications are also supported through address bit handling in reception
70*1b2596b5SMatthias Ringwald  * and transmission. The driver supports the following modes:
71*1b2596b5SMatthias Ringwald  * RS232, RS485, SPI, IrDA, ISO7816, MODEM, Hardware handshaking and LIN.
72*1b2596b5SMatthias Ringwald  *
73*1b2596b5SMatthias Ringwald  * @{
74*1b2596b5SMatthias Ringwald  */
75*1b2596b5SMatthias Ringwald 
76*1b2596b5SMatthias Ringwald /* The write protect key value. */
77*1b2596b5SMatthias Ringwald #ifndef US_WPMR_WPKEY_PASSWD
78*1b2596b5SMatthias Ringwald #define US_WPMR_WPKEY_PASSWD    US_WPMR_WPKEY(0x555341U)
79*1b2596b5SMatthias Ringwald #endif
80*1b2596b5SMatthias Ringwald 
81*1b2596b5SMatthias Ringwald #ifndef US_WPMR_WPKEY_PASSWD
82*1b2596b5SMatthias Ringwald #  define US_WPMR_WPKEY_PASSWD US_WPMR_WPKEY(US_WPKEY_VALUE)
83*1b2596b5SMatthias Ringwald #endif
84*1b2596b5SMatthias Ringwald 
85*1b2596b5SMatthias Ringwald /* The CD value scope programmed in MR register. */
86*1b2596b5SMatthias Ringwald #define MIN_CD_VALUE                  0x01
87*1b2596b5SMatthias Ringwald #define MIN_CD_VALUE_SPI              0x04
88*1b2596b5SMatthias Ringwald #define MAX_CD_VALUE                  US_BRGR_CD_Msk
89*1b2596b5SMatthias Ringwald 
90*1b2596b5SMatthias Ringwald /* The receiver sampling divide of baudrate clock. */
91*1b2596b5SMatthias Ringwald #define HIGH_FRQ_SAMPLE_DIV           16
92*1b2596b5SMatthias Ringwald #define LOW_FRQ_SAMPLE_DIV            8
93*1b2596b5SMatthias Ringwald 
94*1b2596b5SMatthias Ringwald /* Max transmitter timeguard. */
95*1b2596b5SMatthias Ringwald #define MAX_TRAN_GUARD_TIME           US_TTGR_TG_Msk
96*1b2596b5SMatthias Ringwald 
97*1b2596b5SMatthias Ringwald /* The non-existent parity error number. */
98*1b2596b5SMatthias Ringwald #define USART_PARITY_ERROR            5
99*1b2596b5SMatthias Ringwald 
100*1b2596b5SMatthias Ringwald /* ISO7816 protocol type. */
101*1b2596b5SMatthias Ringwald #define ISO7816_T_0                   0
102*1b2596b5SMatthias Ringwald #define ISO7816_T_1                   1
103*1b2596b5SMatthias Ringwald 
104*1b2596b5SMatthias Ringwald /**
105*1b2596b5SMatthias Ringwald  * \brief Calculate a clock divider(CD) and a fractional part (FP) for the
106*1b2596b5SMatthias Ringwald  * USART asynchronous modes to generate a baudrate as close as possible to
107*1b2596b5SMatthias Ringwald  * the baudrate set point.
108*1b2596b5SMatthias Ringwald  *
109*1b2596b5SMatthias Ringwald  * \note Baud rate calculation: Baudrate = ul_mck/(Over * (CD + FP/8))
110*1b2596b5SMatthias Ringwald  * (Over being 16 or 8). The maximal oversampling is selected if it allows to
111*1b2596b5SMatthias Ringwald  * generate a baudrate close to the set point.
112*1b2596b5SMatthias Ringwald  *
113*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
114*1b2596b5SMatthias Ringwald  * \param baudrate Baud rate set point.
115*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
116*1b2596b5SMatthias Ringwald  *
117*1b2596b5SMatthias Ringwald  * \retval 0 Baud rate is successfully initialized.
118*1b2596b5SMatthias Ringwald  * \retval 1 Baud rate set point is out of range for the given input clock
119*1b2596b5SMatthias Ringwald  * frequency.
120*1b2596b5SMatthias Ringwald  */
usart_set_async_baudrate(Usart * p_usart,uint32_t baudrate,uint32_t ul_mck)121*1b2596b5SMatthias Ringwald uint32_t usart_set_async_baudrate(Usart *p_usart,
122*1b2596b5SMatthias Ringwald 		uint32_t baudrate, uint32_t ul_mck)
123*1b2596b5SMatthias Ringwald {
124*1b2596b5SMatthias Ringwald 	uint32_t over;
125*1b2596b5SMatthias Ringwald 	uint32_t cd_fp;
126*1b2596b5SMatthias Ringwald 	uint32_t cd;
127*1b2596b5SMatthias Ringwald 	uint32_t fp;
128*1b2596b5SMatthias Ringwald 
129*1b2596b5SMatthias Ringwald 	/* Calculate the receiver sampling divide of baudrate clock. */
130*1b2596b5SMatthias Ringwald 	if (ul_mck >= HIGH_FRQ_SAMPLE_DIV * baudrate) {
131*1b2596b5SMatthias Ringwald 		over = HIGH_FRQ_SAMPLE_DIV;
132*1b2596b5SMatthias Ringwald 	} else {
133*1b2596b5SMatthias Ringwald 		over = LOW_FRQ_SAMPLE_DIV;
134*1b2596b5SMatthias Ringwald 	}
135*1b2596b5SMatthias Ringwald 
136*1b2596b5SMatthias Ringwald 	/* Calculate clock divider according to the fraction calculated formula. */
137*1b2596b5SMatthias Ringwald 	cd_fp = (8 * ul_mck + (over * baudrate) / 2) / (over * baudrate);
138*1b2596b5SMatthias Ringwald 	cd = cd_fp >> 3;
139*1b2596b5SMatthias Ringwald 	fp = cd_fp & 0x07;
140*1b2596b5SMatthias Ringwald 	if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {
141*1b2596b5SMatthias Ringwald 		return 1;
142*1b2596b5SMatthias Ringwald 	}
143*1b2596b5SMatthias Ringwald 
144*1b2596b5SMatthias Ringwald 	/* Configure the OVER bit in MR register. */
145*1b2596b5SMatthias Ringwald 	if (over == 8) {
146*1b2596b5SMatthias Ringwald 		p_usart->US_MR |= US_MR_OVER;
147*1b2596b5SMatthias Ringwald 	}
148*1b2596b5SMatthias Ringwald 
149*1b2596b5SMatthias Ringwald 	/* Configure the baudrate generate register. */
150*1b2596b5SMatthias Ringwald 	p_usart->US_BRGR = (cd << US_BRGR_CD_Pos) | (fp << US_BRGR_FP_Pos);
151*1b2596b5SMatthias Ringwald 
152*1b2596b5SMatthias Ringwald 	return 0;
153*1b2596b5SMatthias Ringwald }
154*1b2596b5SMatthias Ringwald 
155*1b2596b5SMatthias Ringwald /**
156*1b2596b5SMatthias Ringwald  * \brief Calculate a clock divider for the USART synchronous master modes
157*1b2596b5SMatthias Ringwald  * to generate a baudrate as close as possible to the baudrate set point.
158*1b2596b5SMatthias Ringwald  *
159*1b2596b5SMatthias Ringwald  * \note Synchronous baudrate calculation: baudrate = ul_mck / cd
160*1b2596b5SMatthias Ringwald  *
161*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
162*1b2596b5SMatthias Ringwald  * \param baudrate Baud rate set point.
163*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
164*1b2596b5SMatthias Ringwald  *
165*1b2596b5SMatthias Ringwald  * \retval 0 Baud rate is successfully initialized.
166*1b2596b5SMatthias Ringwald  * \retval 1 Baud rate set point is out of range for the given input clock
167*1b2596b5SMatthias Ringwald  * frequency.
168*1b2596b5SMatthias Ringwald  */
usart_set_sync_master_baudrate(Usart * p_usart,uint32_t baudrate,uint32_t ul_mck)169*1b2596b5SMatthias Ringwald static uint32_t usart_set_sync_master_baudrate(Usart *p_usart,
170*1b2596b5SMatthias Ringwald 		uint32_t baudrate, uint32_t ul_mck)
171*1b2596b5SMatthias Ringwald {
172*1b2596b5SMatthias Ringwald 	uint32_t cd;
173*1b2596b5SMatthias Ringwald 
174*1b2596b5SMatthias Ringwald 	/* Calculate clock divider according to the formula in synchronous mode. */
175*1b2596b5SMatthias Ringwald 	cd = (ul_mck + baudrate / 2) / baudrate;
176*1b2596b5SMatthias Ringwald 
177*1b2596b5SMatthias Ringwald 	if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {
178*1b2596b5SMatthias Ringwald 		return 1;
179*1b2596b5SMatthias Ringwald 	}
180*1b2596b5SMatthias Ringwald 
181*1b2596b5SMatthias Ringwald 	/* Configure the baudrate generate register. */
182*1b2596b5SMatthias Ringwald 	p_usart->US_BRGR = cd << US_BRGR_CD_Pos;
183*1b2596b5SMatthias Ringwald 
184*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) |
185*1b2596b5SMatthias Ringwald 			US_MR_USCLKS_MCK | US_MR_SYNC;
186*1b2596b5SMatthias Ringwald 	return 0;
187*1b2596b5SMatthias Ringwald }
188*1b2596b5SMatthias Ringwald 
189*1b2596b5SMatthias Ringwald /**
190*1b2596b5SMatthias Ringwald  * \brief Select the SCK pin as the source of baud rate for the USART
191*1b2596b5SMatthias Ringwald  * synchronous slave modes.
192*1b2596b5SMatthias Ringwald  *
193*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
194*1b2596b5SMatthias Ringwald  */
usart_set_sync_slave_baudrate(Usart * p_usart)195*1b2596b5SMatthias Ringwald static void usart_set_sync_slave_baudrate(Usart *p_usart)
196*1b2596b5SMatthias Ringwald {
197*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) |
198*1b2596b5SMatthias Ringwald 			US_MR_USCLKS_SCK | US_MR_SYNC;
199*1b2596b5SMatthias Ringwald }
200*1b2596b5SMatthias Ringwald 
201*1b2596b5SMatthias Ringwald /**
202*1b2596b5SMatthias Ringwald  * \brief Calculate a clock divider (\e CD) for the USART SPI master mode to
203*1b2596b5SMatthias Ringwald  * generate a baud rate as close as possible to the baud rate set point.
204*1b2596b5SMatthias Ringwald  *
205*1b2596b5SMatthias Ringwald  * \note Baud rate calculation:
206*1b2596b5SMatthias Ringwald  * \f$ Baudrate = \frac{SelectedClock}{CD} \f$.
207*1b2596b5SMatthias Ringwald  *
208*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
209*1b2596b5SMatthias Ringwald  * \param baudrate Baud rate set point.
210*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
211*1b2596b5SMatthias Ringwald  *
212*1b2596b5SMatthias Ringwald  * \retval 0 Baud rate is successfully initialized.
213*1b2596b5SMatthias Ringwald  * \retval 1 Baud rate set point is out of range for the given input clock
214*1b2596b5SMatthias Ringwald  * frequency.
215*1b2596b5SMatthias Ringwald  */
usart_set_spi_master_baudrate(Usart * p_usart,uint32_t baudrate,uint32_t ul_mck)216*1b2596b5SMatthias Ringwald static uint32_t usart_set_spi_master_baudrate(Usart *p_usart,
217*1b2596b5SMatthias Ringwald 		uint32_t baudrate, uint32_t ul_mck)
218*1b2596b5SMatthias Ringwald {
219*1b2596b5SMatthias Ringwald 	uint32_t cd;
220*1b2596b5SMatthias Ringwald 
221*1b2596b5SMatthias Ringwald 	/* Calculate the clock divider according to the formula in SPI mode. */
222*1b2596b5SMatthias Ringwald 	cd = (ul_mck + baudrate / 2) / baudrate;
223*1b2596b5SMatthias Ringwald 
224*1b2596b5SMatthias Ringwald 	if (cd < MIN_CD_VALUE_SPI || cd > MAX_CD_VALUE) {
225*1b2596b5SMatthias Ringwald 		return 1;
226*1b2596b5SMatthias Ringwald 	}
227*1b2596b5SMatthias Ringwald 
228*1b2596b5SMatthias Ringwald 	p_usart->US_BRGR = cd << US_BRGR_CD_Pos;
229*1b2596b5SMatthias Ringwald 
230*1b2596b5SMatthias Ringwald 	return 0;
231*1b2596b5SMatthias Ringwald }
232*1b2596b5SMatthias Ringwald 
233*1b2596b5SMatthias Ringwald /**
234*1b2596b5SMatthias Ringwald  * \brief Select the SCK pin as the source of baudrate for the USART SPI slave
235*1b2596b5SMatthias Ringwald  * mode.
236*1b2596b5SMatthias Ringwald  *
237*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
238*1b2596b5SMatthias Ringwald  */
usart_set_spi_slave_baudrate(Usart * p_usart)239*1b2596b5SMatthias Ringwald static void usart_set_spi_slave_baudrate(Usart *p_usart)
240*1b2596b5SMatthias Ringwald {
241*1b2596b5SMatthias Ringwald 	p_usart->US_MR &= ~US_MR_USCLKS_Msk;
242*1b2596b5SMatthias Ringwald 	p_usart->US_MR |= US_MR_USCLKS_SCK;
243*1b2596b5SMatthias Ringwald }
244*1b2596b5SMatthias Ringwald 
245*1b2596b5SMatthias Ringwald /**
246*1b2596b5SMatthias Ringwald  * \brief Reset the USART and disable TX and RX.
247*1b2596b5SMatthias Ringwald  *
248*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
249*1b2596b5SMatthias Ringwald  */
usart_reset(Usart * p_usart)250*1b2596b5SMatthias Ringwald void usart_reset(Usart *p_usart)
251*1b2596b5SMatthias Ringwald {
252*1b2596b5SMatthias Ringwald 	/* Disable the Write Protect. */
253*1b2596b5SMatthias Ringwald 	usart_disable_writeprotect(p_usart);
254*1b2596b5SMatthias Ringwald 
255*1b2596b5SMatthias Ringwald 	/* Reset registers that could cause unpredictable behavior after reset. */
256*1b2596b5SMatthias Ringwald 	p_usart->US_MR = 0;
257*1b2596b5SMatthias Ringwald 	p_usart->US_RTOR = 0;
258*1b2596b5SMatthias Ringwald 	p_usart->US_TTGR = 0;
259*1b2596b5SMatthias Ringwald 
260*1b2596b5SMatthias Ringwald 	/* Disable TX and RX. */
261*1b2596b5SMatthias Ringwald 	usart_reset_tx(p_usart);
262*1b2596b5SMatthias Ringwald 	usart_reset_rx(p_usart);
263*1b2596b5SMatthias Ringwald 	/* Reset status bits. */
264*1b2596b5SMatthias Ringwald 	usart_reset_status(p_usart);
265*1b2596b5SMatthias Ringwald 	/* Turn off RTS and DTR if exist. */
266*1b2596b5SMatthias Ringwald 	usart_drive_RTS_pin_high(p_usart);
267*1b2596b5SMatthias Ringwald #if (SAM3S || SAM4S || SAM3U || SAM4L || SAM4E)
268*1b2596b5SMatthias Ringwald 	usart_drive_DTR_pin_high(p_usart);
269*1b2596b5SMatthias Ringwald #endif
270*1b2596b5SMatthias Ringwald }
271*1b2596b5SMatthias Ringwald 
272*1b2596b5SMatthias Ringwald /**
273*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in RS232 mode.
274*1b2596b5SMatthias Ringwald  *
275*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
276*1b2596b5SMatthias Ringwald  *
277*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
278*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
279*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
280*1b2596b5SMatthias Ringwald  *
281*1b2596b5SMatthias Ringwald  * \retval 0 on success.
282*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
283*1b2596b5SMatthias Ringwald  */
usart_init_rs232(Usart * p_usart,const sam_usart_opt_t * p_usart_opt,uint32_t ul_mck)284*1b2596b5SMatthias Ringwald uint32_t usart_init_rs232(Usart *p_usart,
285*1b2596b5SMatthias Ringwald 		const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
286*1b2596b5SMatthias Ringwald {
287*1b2596b5SMatthias Ringwald 	static uint32_t ul_reg_val;
288*1b2596b5SMatthias Ringwald 
289*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
290*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
291*1b2596b5SMatthias Ringwald 
292*1b2596b5SMatthias Ringwald 	ul_reg_val = 0;
293*1b2596b5SMatthias Ringwald 	/* Check whether the input values are legal. */
294*1b2596b5SMatthias Ringwald 	if (!p_usart_opt || usart_set_async_baudrate(p_usart,
295*1b2596b5SMatthias Ringwald 			p_usart_opt->baudrate, ul_mck)) {
296*1b2596b5SMatthias Ringwald 		return 1;
297*1b2596b5SMatthias Ringwald 	}
298*1b2596b5SMatthias Ringwald 
299*1b2596b5SMatthias Ringwald 	/* Configure the USART option. */
300*1b2596b5SMatthias Ringwald 	ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type |
301*1b2596b5SMatthias Ringwald 			p_usart_opt->channel_mode | p_usart_opt->stop_bits;
302*1b2596b5SMatthias Ringwald 
303*1b2596b5SMatthias Ringwald 	/* Configure the USART mode as normal mode. */
304*1b2596b5SMatthias Ringwald 	ul_reg_val |= US_MR_USART_MODE_NORMAL;
305*1b2596b5SMatthias Ringwald 
306*1b2596b5SMatthias Ringwald 	p_usart->US_MR |= ul_reg_val;
307*1b2596b5SMatthias Ringwald 
308*1b2596b5SMatthias Ringwald 	return 0;
309*1b2596b5SMatthias Ringwald }
310*1b2596b5SMatthias Ringwald 
311*1b2596b5SMatthias Ringwald /**
312*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in hardware handshaking mode.
313*1b2596b5SMatthias Ringwald  *
314*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
315*1b2596b5SMatthias Ringwald  *
316*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
317*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
318*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
319*1b2596b5SMatthias Ringwald  *
320*1b2596b5SMatthias Ringwald  * \retval 0 on success.
321*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
322*1b2596b5SMatthias Ringwald  */
usart_init_hw_handshaking(Usart * p_usart,const sam_usart_opt_t * p_usart_opt,uint32_t ul_mck)323*1b2596b5SMatthias Ringwald uint32_t usart_init_hw_handshaking(Usart *p_usart,
324*1b2596b5SMatthias Ringwald 		const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
325*1b2596b5SMatthias Ringwald {
326*1b2596b5SMatthias Ringwald 	/* Initialize the USART as standard RS232. */
327*1b2596b5SMatthias Ringwald 	if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {
328*1b2596b5SMatthias Ringwald 		return 1;
329*1b2596b5SMatthias Ringwald 	}
330*1b2596b5SMatthias Ringwald 
331*1b2596b5SMatthias Ringwald 	/* Set hardware handshaking mode. */
332*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
333*1b2596b5SMatthias Ringwald 			US_MR_USART_MODE_HW_HANDSHAKING;
334*1b2596b5SMatthias Ringwald 
335*1b2596b5SMatthias Ringwald 	return 0;
336*1b2596b5SMatthias Ringwald }
337*1b2596b5SMatthias Ringwald 
338*1b2596b5SMatthias Ringwald #if (SAM3S || SAM4S || SAM3U || SAM4L || SAM4E)
339*1b2596b5SMatthias Ringwald 
340*1b2596b5SMatthias Ringwald /**
341*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in modem mode.
342*1b2596b5SMatthias Ringwald  *
343*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
344*1b2596b5SMatthias Ringwald  *
345*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
346*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
347*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
348*1b2596b5SMatthias Ringwald  *
349*1b2596b5SMatthias Ringwald  * \retval 0 on success.
350*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
351*1b2596b5SMatthias Ringwald  */
usart_init_modem(Usart * p_usart,const sam_usart_opt_t * p_usart_opt,uint32_t ul_mck)352*1b2596b5SMatthias Ringwald uint32_t usart_init_modem(Usart *p_usart,
353*1b2596b5SMatthias Ringwald 		const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
354*1b2596b5SMatthias Ringwald {
355*1b2596b5SMatthias Ringwald 	/*
356*1b2596b5SMatthias Ringwald 	 * SAM3S, SAM4S and SAM4E series support MODEM mode only on USART1,
357*1b2596b5SMatthias Ringwald 	 * SAM3U and SAM4L series support MODEM mode only on USART0.
358*1b2596b5SMatthias Ringwald 	 */
359*1b2596b5SMatthias Ringwald #if (SAM3S || SAM4S || SAM4E)
360*1b2596b5SMatthias Ringwald #ifdef USART1
361*1b2596b5SMatthias Ringwald 	if (p_usart != USART1) {
362*1b2596b5SMatthias Ringwald 		return 1;
363*1b2596b5SMatthias Ringwald 	}
364*1b2596b5SMatthias Ringwald #endif
365*1b2596b5SMatthias Ringwald #elif (SAM3U || SAM4L)
366*1b2596b5SMatthias Ringwald 	if (p_usart != USART0) {
367*1b2596b5SMatthias Ringwald 		return 1;
368*1b2596b5SMatthias Ringwald 	}
369*1b2596b5SMatthias Ringwald #endif
370*1b2596b5SMatthias Ringwald 
371*1b2596b5SMatthias Ringwald 	/* Initialize the USART as standard RS232. */
372*1b2596b5SMatthias Ringwald 	if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {
373*1b2596b5SMatthias Ringwald 		return 1;
374*1b2596b5SMatthias Ringwald 	}
375*1b2596b5SMatthias Ringwald 
376*1b2596b5SMatthias Ringwald 	/* Set MODEM mode. */
377*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
378*1b2596b5SMatthias Ringwald 			US_MR_USART_MODE_MODEM;
379*1b2596b5SMatthias Ringwald 
380*1b2596b5SMatthias Ringwald 	return 0;
381*1b2596b5SMatthias Ringwald }
382*1b2596b5SMatthias Ringwald #endif
383*1b2596b5SMatthias Ringwald 
384*1b2596b5SMatthias Ringwald /**
385*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in SYNC mode and act as a master.
386*1b2596b5SMatthias Ringwald  *
387*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
388*1b2596b5SMatthias Ringwald  *
389*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
390*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
391*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
392*1b2596b5SMatthias Ringwald  *
393*1b2596b5SMatthias Ringwald  * \retval 0 on success.
394*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
395*1b2596b5SMatthias Ringwald  */
usart_init_sync_master(Usart * p_usart,const sam_usart_opt_t * p_usart_opt,uint32_t ul_mck)396*1b2596b5SMatthias Ringwald uint32_t usart_init_sync_master(Usart *p_usart,
397*1b2596b5SMatthias Ringwald 		const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
398*1b2596b5SMatthias Ringwald {
399*1b2596b5SMatthias Ringwald 	static uint32_t ul_reg_val;
400*1b2596b5SMatthias Ringwald 
401*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
402*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
403*1b2596b5SMatthias Ringwald 
404*1b2596b5SMatthias Ringwald 	ul_reg_val = 0;
405*1b2596b5SMatthias Ringwald 	/* Check whether the input values are legal. */
406*1b2596b5SMatthias Ringwald 	if (!p_usart_opt || usart_set_sync_master_baudrate(p_usart,
407*1b2596b5SMatthias Ringwald 			p_usart_opt->baudrate, ul_mck)) {
408*1b2596b5SMatthias Ringwald 		return 1;
409*1b2596b5SMatthias Ringwald 	}
410*1b2596b5SMatthias Ringwald 
411*1b2596b5SMatthias Ringwald 	/* Configure the USART option. */
412*1b2596b5SMatthias Ringwald 	ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type |
413*1b2596b5SMatthias Ringwald 			p_usart_opt->channel_mode | p_usart_opt->stop_bits;
414*1b2596b5SMatthias Ringwald 
415*1b2596b5SMatthias Ringwald 	/* Set normal mode and output clock as synchronous master. */
416*1b2596b5SMatthias Ringwald 	ul_reg_val |= US_MR_USART_MODE_NORMAL | US_MR_CLKO;
417*1b2596b5SMatthias Ringwald 	p_usart->US_MR |= ul_reg_val;
418*1b2596b5SMatthias Ringwald 
419*1b2596b5SMatthias Ringwald 	return 0;
420*1b2596b5SMatthias Ringwald }
421*1b2596b5SMatthias Ringwald 
422*1b2596b5SMatthias Ringwald /**
423*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in SYNC mode and act as a slave.
424*1b2596b5SMatthias Ringwald  *
425*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
426*1b2596b5SMatthias Ringwald  *
427*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
428*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
429*1b2596b5SMatthias Ringwald  *
430*1b2596b5SMatthias Ringwald  * \retval 0 on success.
431*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
432*1b2596b5SMatthias Ringwald  */
usart_init_sync_slave(Usart * p_usart,const sam_usart_opt_t * p_usart_opt)433*1b2596b5SMatthias Ringwald uint32_t usart_init_sync_slave(Usart *p_usart,
434*1b2596b5SMatthias Ringwald 		const sam_usart_opt_t *p_usart_opt)
435*1b2596b5SMatthias Ringwald {
436*1b2596b5SMatthias Ringwald 	static uint32_t ul_reg_val;
437*1b2596b5SMatthias Ringwald 
438*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
439*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
440*1b2596b5SMatthias Ringwald 
441*1b2596b5SMatthias Ringwald 	ul_reg_val = 0;
442*1b2596b5SMatthias Ringwald 	usart_set_sync_slave_baudrate(p_usart);
443*1b2596b5SMatthias Ringwald 
444*1b2596b5SMatthias Ringwald 	/* Check whether the input values are legal. */
445*1b2596b5SMatthias Ringwald 	if (!p_usart_opt) {
446*1b2596b5SMatthias Ringwald 		return 1;
447*1b2596b5SMatthias Ringwald 	}
448*1b2596b5SMatthias Ringwald 
449*1b2596b5SMatthias Ringwald 	/* Configure the USART option. */
450*1b2596b5SMatthias Ringwald 	ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type |
451*1b2596b5SMatthias Ringwald 			p_usart_opt->channel_mode | p_usart_opt->stop_bits;
452*1b2596b5SMatthias Ringwald 
453*1b2596b5SMatthias Ringwald 	/* Set normal mode. */
454*1b2596b5SMatthias Ringwald 	ul_reg_val |= US_MR_USART_MODE_NORMAL;
455*1b2596b5SMatthias Ringwald 	p_usart->US_MR |= ul_reg_val;
456*1b2596b5SMatthias Ringwald 
457*1b2596b5SMatthias Ringwald 	return 0;
458*1b2596b5SMatthias Ringwald }
459*1b2596b5SMatthias Ringwald 
460*1b2596b5SMatthias Ringwald /**
461*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in RS485 mode.
462*1b2596b5SMatthias Ringwald  *
463*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
464*1b2596b5SMatthias Ringwald  *
465*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
466*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
467*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
468*1b2596b5SMatthias Ringwald  *
469*1b2596b5SMatthias Ringwald  * \retval 0 on success.
470*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
471*1b2596b5SMatthias Ringwald  */
usart_init_rs485(Usart * p_usart,const sam_usart_opt_t * p_usart_opt,uint32_t ul_mck)472*1b2596b5SMatthias Ringwald uint32_t usart_init_rs485(Usart *p_usart,
473*1b2596b5SMatthias Ringwald 		const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
474*1b2596b5SMatthias Ringwald {
475*1b2596b5SMatthias Ringwald 	/* Initialize the USART as standard RS232. */
476*1b2596b5SMatthias Ringwald 	if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {
477*1b2596b5SMatthias Ringwald 		return 1;
478*1b2596b5SMatthias Ringwald 	}
479*1b2596b5SMatthias Ringwald 
480*1b2596b5SMatthias Ringwald 	/* Set RS485 mode. */
481*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
482*1b2596b5SMatthias Ringwald 			US_MR_USART_MODE_RS485;
483*1b2596b5SMatthias Ringwald 
484*1b2596b5SMatthias Ringwald 	return 0;
485*1b2596b5SMatthias Ringwald }
486*1b2596b5SMatthias Ringwald 
487*1b2596b5SMatthias Ringwald #if (!SAMG55 && !SAMV71 && !SAMV70 && !SAME70 && !SAMS70)
488*1b2596b5SMatthias Ringwald /**
489*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in IrDA mode.
490*1b2596b5SMatthias Ringwald  *
491*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
492*1b2596b5SMatthias Ringwald  *
493*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
494*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
495*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
496*1b2596b5SMatthias Ringwald  *
497*1b2596b5SMatthias Ringwald  * \retval 0 on success.
498*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
499*1b2596b5SMatthias Ringwald  */
usart_init_irda(Usart * p_usart,const sam_usart_opt_t * p_usart_opt,uint32_t ul_mck)500*1b2596b5SMatthias Ringwald uint32_t usart_init_irda(Usart *p_usart,
501*1b2596b5SMatthias Ringwald 		const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
502*1b2596b5SMatthias Ringwald {
503*1b2596b5SMatthias Ringwald 	/* Initialize the USART as standard RS232. */
504*1b2596b5SMatthias Ringwald 	if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {
505*1b2596b5SMatthias Ringwald 		return 1;
506*1b2596b5SMatthias Ringwald 	}
507*1b2596b5SMatthias Ringwald 
508*1b2596b5SMatthias Ringwald 	/* Set IrDA filter. */
509*1b2596b5SMatthias Ringwald 	p_usart->US_IF = p_usart_opt->irda_filter;
510*1b2596b5SMatthias Ringwald 
511*1b2596b5SMatthias Ringwald 	/* Set IrDA mode. */
512*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
513*1b2596b5SMatthias Ringwald 			US_MR_USART_MODE_IRDA;
514*1b2596b5SMatthias Ringwald 
515*1b2596b5SMatthias Ringwald 	return 0;
516*1b2596b5SMatthias Ringwald }
517*1b2596b5SMatthias Ringwald #endif
518*1b2596b5SMatthias Ringwald 
519*1b2596b5SMatthias Ringwald #if (!SAMV71 && !SAMV70 && !SAME70 && !SAMS70)
520*1b2596b5SMatthias Ringwald /**
521*1b2596b5SMatthias Ringwald  * \brief Calculate a clock divider (\e CD) for the USART ISO7816 mode to
522*1b2596b5SMatthias Ringwald  * generate an ISO7816 clock as close as possible to the clock set point.
523*1b2596b5SMatthias Ringwald  *
524*1b2596b5SMatthias Ringwald  * \note ISO7816 clock calculation: Clock = ul_mck / cd
525*1b2596b5SMatthias Ringwald  *
526*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
527*1b2596b5SMatthias Ringwald  * \param clock ISO7816 clock set point.
528*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
529*1b2596b5SMatthias Ringwald  *
530*1b2596b5SMatthias Ringwald  * \retval 0 ISO7816 clock is successfully initialized.
531*1b2596b5SMatthias Ringwald  * \retval 1 ISO7816 clock set point is out of range for the given input clock
532*1b2596b5SMatthias Ringwald  * frequency.
533*1b2596b5SMatthias Ringwald  */
usart_set_iso7816_clock(Usart * p_usart,uint32_t clock,uint32_t ul_mck)534*1b2596b5SMatthias Ringwald static uint32_t usart_set_iso7816_clock(Usart *p_usart,
535*1b2596b5SMatthias Ringwald 		uint32_t clock, uint32_t ul_mck)
536*1b2596b5SMatthias Ringwald {
537*1b2596b5SMatthias Ringwald 	uint32_t cd;
538*1b2596b5SMatthias Ringwald 
539*1b2596b5SMatthias Ringwald 	/* Calculate clock divider according to the formula in ISO7816 mode. */
540*1b2596b5SMatthias Ringwald 	cd = (ul_mck + clock / 2) / clock;
541*1b2596b5SMatthias Ringwald 
542*1b2596b5SMatthias Ringwald 	if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {
543*1b2596b5SMatthias Ringwald 		return 1;
544*1b2596b5SMatthias Ringwald 	}
545*1b2596b5SMatthias Ringwald 
546*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~(US_MR_USCLKS_Msk | US_MR_SYNC |
547*1b2596b5SMatthias Ringwald 			US_MR_OVER)) | US_MR_USCLKS_MCK | US_MR_CLKO;
548*1b2596b5SMatthias Ringwald 
549*1b2596b5SMatthias Ringwald 	/* Configure the baudrate generate register. */
550*1b2596b5SMatthias Ringwald 	p_usart->US_BRGR = cd << US_BRGR_CD_Pos;
551*1b2596b5SMatthias Ringwald 
552*1b2596b5SMatthias Ringwald 	return 0;
553*1b2596b5SMatthias Ringwald }
554*1b2596b5SMatthias Ringwald 
555*1b2596b5SMatthias Ringwald /**
556*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in ISO7816 mode.
557*1b2596b5SMatthias Ringwald  *
558*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
559*1b2596b5SMatthias Ringwald  *
560*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
561*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
562*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
563*1b2596b5SMatthias Ringwald  *
564*1b2596b5SMatthias Ringwald  * \retval 0 on success.
565*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
566*1b2596b5SMatthias Ringwald  */
usart_init_iso7816(Usart * p_usart,const usart_iso7816_opt_t * p_usart_opt,uint32_t ul_mck)567*1b2596b5SMatthias Ringwald uint32_t usart_init_iso7816(Usart *p_usart,
568*1b2596b5SMatthias Ringwald 		const usart_iso7816_opt_t *p_usart_opt, uint32_t ul_mck)
569*1b2596b5SMatthias Ringwald {
570*1b2596b5SMatthias Ringwald 	static uint32_t ul_reg_val;
571*1b2596b5SMatthias Ringwald 
572*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
573*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
574*1b2596b5SMatthias Ringwald 
575*1b2596b5SMatthias Ringwald 	ul_reg_val = 0;
576*1b2596b5SMatthias Ringwald 
577*1b2596b5SMatthias Ringwald 	/* Check whether the input values are legal. */
578*1b2596b5SMatthias Ringwald 	if (!p_usart_opt || ((p_usart_opt->parity_type != US_MR_PAR_EVEN) &&
579*1b2596b5SMatthias Ringwald 			(p_usart_opt->parity_type != US_MR_PAR_ODD))) {
580*1b2596b5SMatthias Ringwald 		return 1;
581*1b2596b5SMatthias Ringwald 	}
582*1b2596b5SMatthias Ringwald 
583*1b2596b5SMatthias Ringwald 	if (p_usart_opt->protocol_type == ISO7816_T_0) {
584*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_USART_MODE_IS07816_T_0 | US_MR_NBSTOP_2_BIT |
585*1b2596b5SMatthias Ringwald 				(p_usart_opt->max_iterations << US_MR_MAX_ITERATION_Pos);
586*1b2596b5SMatthias Ringwald 
587*1b2596b5SMatthias Ringwald 		if (p_usart_opt->bit_order) {
588*1b2596b5SMatthias Ringwald 			ul_reg_val |= US_MR_MSBF;
589*1b2596b5SMatthias Ringwald 		}
590*1b2596b5SMatthias Ringwald 	} else if (p_usart_opt->protocol_type == ISO7816_T_1) {
591*1b2596b5SMatthias Ringwald 		/*
592*1b2596b5SMatthias Ringwald 		 * Only LSBF is used in the T=1 protocol, and max_iterations field
593*1b2596b5SMatthias Ringwald 		 * is only used in T=0 mode.
594*1b2596b5SMatthias Ringwald 		 */
595*1b2596b5SMatthias Ringwald 		if (p_usart_opt->bit_order || p_usart_opt->max_iterations) {
596*1b2596b5SMatthias Ringwald 			return 1;
597*1b2596b5SMatthias Ringwald 		}
598*1b2596b5SMatthias Ringwald 
599*1b2596b5SMatthias Ringwald 		/* Set USART mode to ISO7816, T=1, and always uses 1 stop bit. */
600*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_USART_MODE_IS07816_T_1 | US_MR_NBSTOP_1_BIT;
601*1b2596b5SMatthias Ringwald 	} else {
602*1b2596b5SMatthias Ringwald 		return 1;
603*1b2596b5SMatthias Ringwald 	}
604*1b2596b5SMatthias Ringwald 
605*1b2596b5SMatthias Ringwald 	/* Set up the baudrate. */
606*1b2596b5SMatthias Ringwald 	if (usart_set_iso7816_clock(p_usart, p_usart_opt->iso7816_hz, ul_mck)) {
607*1b2596b5SMatthias Ringwald 		return 1;
608*1b2596b5SMatthias Ringwald 	}
609*1b2596b5SMatthias Ringwald 
610*1b2596b5SMatthias Ringwald 	/* Set FIDI register: bit rate = iso7816_hz / fidi_ratio. */
611*1b2596b5SMatthias Ringwald 	p_usart->US_FIDI = p_usart_opt->fidi_ratio;
612*1b2596b5SMatthias Ringwald 
613*1b2596b5SMatthias Ringwald 	/* Set ISO7816 parity type in the MODE register. */
614*1b2596b5SMatthias Ringwald 	ul_reg_val |= p_usart_opt->parity_type;
615*1b2596b5SMatthias Ringwald 
616*1b2596b5SMatthias Ringwald 	if (p_usart_opt->inhibit_nack) {
617*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_INACK;
618*1b2596b5SMatthias Ringwald 	}
619*1b2596b5SMatthias Ringwald 	if (p_usart_opt->dis_suc_nack) {
620*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_DSNACK;
621*1b2596b5SMatthias Ringwald 	}
622*1b2596b5SMatthias Ringwald 
623*1b2596b5SMatthias Ringwald 	p_usart->US_MR |= ul_reg_val;
624*1b2596b5SMatthias Ringwald 
625*1b2596b5SMatthias Ringwald 	return 0;
626*1b2596b5SMatthias Ringwald }
627*1b2596b5SMatthias Ringwald 
628*1b2596b5SMatthias Ringwald /**
629*1b2596b5SMatthias Ringwald  * \brief Reset the ITERATION in US_CSR when the ISO7816 mode is enabled.
630*1b2596b5SMatthias Ringwald  *
631*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
632*1b2596b5SMatthias Ringwald  */
usart_reset_iterations(Usart * p_usart)633*1b2596b5SMatthias Ringwald void usart_reset_iterations(Usart *p_usart)
634*1b2596b5SMatthias Ringwald {
635*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RSTIT;
636*1b2596b5SMatthias Ringwald }
637*1b2596b5SMatthias Ringwald 
638*1b2596b5SMatthias Ringwald /**
639*1b2596b5SMatthias Ringwald  * \brief Reset NACK in US_CSR.
640*1b2596b5SMatthias Ringwald  *
641*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
642*1b2596b5SMatthias Ringwald  */
usart_reset_nack(Usart * p_usart)643*1b2596b5SMatthias Ringwald void usart_reset_nack(Usart *p_usart)
644*1b2596b5SMatthias Ringwald {
645*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RSTNACK;
646*1b2596b5SMatthias Ringwald }
647*1b2596b5SMatthias Ringwald 
648*1b2596b5SMatthias Ringwald /**
649*1b2596b5SMatthias Ringwald  * \brief Check if one receive buffer is filled.
650*1b2596b5SMatthias Ringwald  *
651*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
652*1b2596b5SMatthias Ringwald  *
653*1b2596b5SMatthias Ringwald  * \retval 1 Receive is complete.
654*1b2596b5SMatthias Ringwald  * \retval 0 Receive is still pending.
655*1b2596b5SMatthias Ringwald  */
usart_is_rx_buf_end(Usart * p_usart)656*1b2596b5SMatthias Ringwald uint32_t usart_is_rx_buf_end(Usart *p_usart)
657*1b2596b5SMatthias Ringwald {
658*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_ENDRX) > 0;
659*1b2596b5SMatthias Ringwald }
660*1b2596b5SMatthias Ringwald 
661*1b2596b5SMatthias Ringwald /**
662*1b2596b5SMatthias Ringwald  * \brief Check if one transmit buffer is empty.
663*1b2596b5SMatthias Ringwald  *
664*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
665*1b2596b5SMatthias Ringwald  *
666*1b2596b5SMatthias Ringwald  * \retval 1 Transmit is complete.
667*1b2596b5SMatthias Ringwald  * \retval 0 Transmit is still pending.
668*1b2596b5SMatthias Ringwald  */
usart_is_tx_buf_end(Usart * p_usart)669*1b2596b5SMatthias Ringwald uint32_t usart_is_tx_buf_end(Usart *p_usart)
670*1b2596b5SMatthias Ringwald {
671*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_ENDTX) > 0;
672*1b2596b5SMatthias Ringwald }
673*1b2596b5SMatthias Ringwald 
674*1b2596b5SMatthias Ringwald /**
675*1b2596b5SMatthias Ringwald  * \brief Check if both receive buffers are full.
676*1b2596b5SMatthias Ringwald  *
677*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
678*1b2596b5SMatthias Ringwald  *
679*1b2596b5SMatthias Ringwald  * \retval 1 Receive buffers are full.
680*1b2596b5SMatthias Ringwald  * \retval 0 Receive buffers are not full.
681*1b2596b5SMatthias Ringwald  */
usart_is_rx_buf_full(Usart * p_usart)682*1b2596b5SMatthias Ringwald uint32_t usart_is_rx_buf_full(Usart *p_usart)
683*1b2596b5SMatthias Ringwald {
684*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_RXBUFF) > 0;
685*1b2596b5SMatthias Ringwald }
686*1b2596b5SMatthias Ringwald 
687*1b2596b5SMatthias Ringwald /**
688*1b2596b5SMatthias Ringwald  * \brief Check if both transmit buffers are empty.
689*1b2596b5SMatthias Ringwald  *
690*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
691*1b2596b5SMatthias Ringwald  *
692*1b2596b5SMatthias Ringwald  * \retval 1 Transmit buffers are empty.
693*1b2596b5SMatthias Ringwald  * \retval 0 Transmit buffers are not empty.
694*1b2596b5SMatthias Ringwald  */
usart_is_tx_buf_empty(Usart * p_usart)695*1b2596b5SMatthias Ringwald uint32_t usart_is_tx_buf_empty(Usart *p_usart)
696*1b2596b5SMatthias Ringwald {
697*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_TXBUFE) > 0;
698*1b2596b5SMatthias Ringwald }
699*1b2596b5SMatthias Ringwald 
700*1b2596b5SMatthias Ringwald /**
701*1b2596b5SMatthias Ringwald  * \brief Get the total number of errors that occur during an ISO7816 transfer.
702*1b2596b5SMatthias Ringwald  *
703*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
704*1b2596b5SMatthias Ringwald  *
705*1b2596b5SMatthias Ringwald  * \return The number of errors that occurred.
706*1b2596b5SMatthias Ringwald  */
usart_get_error_number(Usart * p_usart)707*1b2596b5SMatthias Ringwald uint8_t usart_get_error_number(Usart *p_usart)
708*1b2596b5SMatthias Ringwald {
709*1b2596b5SMatthias Ringwald 	return (p_usart->US_NER & US_NER_NB_ERRORS_Msk);
710*1b2596b5SMatthias Ringwald }
711*1b2596b5SMatthias Ringwald 
712*1b2596b5SMatthias Ringwald #endif
713*1b2596b5SMatthias Ringwald 
714*1b2596b5SMatthias Ringwald /**
715*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in SPI mode and act as a master.
716*1b2596b5SMatthias Ringwald  *
717*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
718*1b2596b5SMatthias Ringwald  *
719*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
720*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
721*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
722*1b2596b5SMatthias Ringwald  *
723*1b2596b5SMatthias Ringwald  * \retval 0 on success.
724*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
725*1b2596b5SMatthias Ringwald  */
usart_init_spi_master(Usart * p_usart,const usart_spi_opt_t * p_usart_opt,uint32_t ul_mck)726*1b2596b5SMatthias Ringwald uint32_t usart_init_spi_master(Usart *p_usart,
727*1b2596b5SMatthias Ringwald 		const usart_spi_opt_t *p_usart_opt, uint32_t ul_mck)
728*1b2596b5SMatthias Ringwald {
729*1b2596b5SMatthias Ringwald 	static uint32_t ul_reg_val;
730*1b2596b5SMatthias Ringwald 
731*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
732*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
733*1b2596b5SMatthias Ringwald 
734*1b2596b5SMatthias Ringwald 	ul_reg_val = 0;
735*1b2596b5SMatthias Ringwald 	/* Check whether the input values are legal. */
736*1b2596b5SMatthias Ringwald 	if (!p_usart_opt || (p_usart_opt->spi_mode > SPI_MODE_3) ||
737*1b2596b5SMatthias Ringwald 			usart_set_spi_master_baudrate(p_usart, p_usart_opt->baudrate,
738*1b2596b5SMatthias Ringwald 			ul_mck)) {
739*1b2596b5SMatthias Ringwald 		return 1;
740*1b2596b5SMatthias Ringwald 	}
741*1b2596b5SMatthias Ringwald 
742*1b2596b5SMatthias Ringwald 	/* Configure the character length bit in MR register. */
743*1b2596b5SMatthias Ringwald 	ul_reg_val |= p_usart_opt->char_length;
744*1b2596b5SMatthias Ringwald 
745*1b2596b5SMatthias Ringwald 	/* Set SPI master mode and channel mode. */
746*1b2596b5SMatthias Ringwald 	ul_reg_val |= US_MR_USART_MODE_SPI_MASTER | US_MR_CLKO |
747*1b2596b5SMatthias Ringwald 			p_usart_opt->channel_mode;
748*1b2596b5SMatthias Ringwald 
749*1b2596b5SMatthias Ringwald 	switch (p_usart_opt->spi_mode) {
750*1b2596b5SMatthias Ringwald 	case SPI_MODE_0:
751*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_CPHA;
752*1b2596b5SMatthias Ringwald 		ul_reg_val &= ~US_MR_CPOL;
753*1b2596b5SMatthias Ringwald 		break;
754*1b2596b5SMatthias Ringwald 
755*1b2596b5SMatthias Ringwald 	case SPI_MODE_1:
756*1b2596b5SMatthias Ringwald 		ul_reg_val &= ~US_MR_CPHA;
757*1b2596b5SMatthias Ringwald 		ul_reg_val &= ~US_MR_CPOL;
758*1b2596b5SMatthias Ringwald 		break;
759*1b2596b5SMatthias Ringwald 
760*1b2596b5SMatthias Ringwald 	case SPI_MODE_2:
761*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_CPHA;
762*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_CPOL;
763*1b2596b5SMatthias Ringwald 		break;
764*1b2596b5SMatthias Ringwald 
765*1b2596b5SMatthias Ringwald 	case SPI_MODE_3:
766*1b2596b5SMatthias Ringwald 		ul_reg_val &= ~US_MR_CPHA;
767*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_CPOL;
768*1b2596b5SMatthias Ringwald 		break;
769*1b2596b5SMatthias Ringwald 
770*1b2596b5SMatthias Ringwald 	default:
771*1b2596b5SMatthias Ringwald 		break;
772*1b2596b5SMatthias Ringwald 	}
773*1b2596b5SMatthias Ringwald 
774*1b2596b5SMatthias Ringwald 	p_usart->US_MR |= ul_reg_val;
775*1b2596b5SMatthias Ringwald 
776*1b2596b5SMatthias Ringwald 	return 0;
777*1b2596b5SMatthias Ringwald }
778*1b2596b5SMatthias Ringwald 
779*1b2596b5SMatthias Ringwald /**
780*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in SPI mode and act as a slave.
781*1b2596b5SMatthias Ringwald  *
782*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
783*1b2596b5SMatthias Ringwald  *
784*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
785*1b2596b5SMatthias Ringwald  * \param p_usart_opt Pointer to sam_usart_opt_t instance.
786*1b2596b5SMatthias Ringwald  *
787*1b2596b5SMatthias Ringwald  * \retval 0 on success.
788*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
789*1b2596b5SMatthias Ringwald  */
usart_init_spi_slave(Usart * p_usart,const usart_spi_opt_t * p_usart_opt)790*1b2596b5SMatthias Ringwald uint32_t usart_init_spi_slave(Usart *p_usart,
791*1b2596b5SMatthias Ringwald 		const usart_spi_opt_t *p_usart_opt)
792*1b2596b5SMatthias Ringwald {
793*1b2596b5SMatthias Ringwald 	static uint32_t ul_reg_val;
794*1b2596b5SMatthias Ringwald 
795*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
796*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
797*1b2596b5SMatthias Ringwald 
798*1b2596b5SMatthias Ringwald 	ul_reg_val = 0;
799*1b2596b5SMatthias Ringwald 	usart_set_spi_slave_baudrate(p_usart);
800*1b2596b5SMatthias Ringwald 
801*1b2596b5SMatthias Ringwald 	/* Check whether the input values are legal. */
802*1b2596b5SMatthias Ringwald 	if (!p_usart_opt || p_usart_opt->spi_mode > SPI_MODE_3) {
803*1b2596b5SMatthias Ringwald 		return 1;
804*1b2596b5SMatthias Ringwald 	}
805*1b2596b5SMatthias Ringwald 
806*1b2596b5SMatthias Ringwald 	/* Configure the character length bit in MR register. */
807*1b2596b5SMatthias Ringwald 	ul_reg_val |= p_usart_opt->char_length;
808*1b2596b5SMatthias Ringwald 
809*1b2596b5SMatthias Ringwald 	/* Set SPI slave mode and channel mode. */
810*1b2596b5SMatthias Ringwald 	ul_reg_val |= US_MR_USART_MODE_SPI_SLAVE | p_usart_opt->channel_mode;
811*1b2596b5SMatthias Ringwald 
812*1b2596b5SMatthias Ringwald 	switch (p_usart_opt->spi_mode) {
813*1b2596b5SMatthias Ringwald 	case SPI_MODE_0:
814*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_CPHA;
815*1b2596b5SMatthias Ringwald 		ul_reg_val &= ~US_MR_CPOL;
816*1b2596b5SMatthias Ringwald 		break;
817*1b2596b5SMatthias Ringwald 
818*1b2596b5SMatthias Ringwald 	case SPI_MODE_1:
819*1b2596b5SMatthias Ringwald 		ul_reg_val &= ~US_MR_CPHA;
820*1b2596b5SMatthias Ringwald 		ul_reg_val &= ~US_MR_CPOL;
821*1b2596b5SMatthias Ringwald 		break;
822*1b2596b5SMatthias Ringwald 
823*1b2596b5SMatthias Ringwald 	case SPI_MODE_2:
824*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_CPHA;
825*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_CPOL;
826*1b2596b5SMatthias Ringwald 		break;
827*1b2596b5SMatthias Ringwald 
828*1b2596b5SMatthias Ringwald 	case SPI_MODE_3:
829*1b2596b5SMatthias Ringwald 		ul_reg_val |= US_MR_CPOL;
830*1b2596b5SMatthias Ringwald 		ul_reg_val &= ~US_MR_CPHA;
831*1b2596b5SMatthias Ringwald 		break;
832*1b2596b5SMatthias Ringwald 
833*1b2596b5SMatthias Ringwald 	default:
834*1b2596b5SMatthias Ringwald 		break;
835*1b2596b5SMatthias Ringwald 	}
836*1b2596b5SMatthias Ringwald 
837*1b2596b5SMatthias Ringwald 	p_usart->US_MR |= ul_reg_val;
838*1b2596b5SMatthias Ringwald 
839*1b2596b5SMatthias Ringwald 	return 0;
840*1b2596b5SMatthias Ringwald }
841*1b2596b5SMatthias Ringwald 
842*1b2596b5SMatthias Ringwald #if (SAM3XA || SAM4L || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)
843*1b2596b5SMatthias Ringwald 
844*1b2596b5SMatthias Ringwald /**
845*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in LIN mode and act as a LIN master.
846*1b2596b5SMatthias Ringwald  *
847*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
848*1b2596b5SMatthias Ringwald  *
849*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
850*1b2596b5SMatthias Ringwald  * \param ul_baudrate Baudrate to be used.
851*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
852*1b2596b5SMatthias Ringwald  *
853*1b2596b5SMatthias Ringwald  * \retval 0 on success.
854*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
855*1b2596b5SMatthias Ringwald  */
usart_init_lin_master(Usart * p_usart,uint32_t ul_baudrate,uint32_t ul_mck)856*1b2596b5SMatthias Ringwald uint32_t usart_init_lin_master(Usart *p_usart,uint32_t ul_baudrate,
857*1b2596b5SMatthias Ringwald 		uint32_t ul_mck)
858*1b2596b5SMatthias Ringwald {
859*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
860*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
861*1b2596b5SMatthias Ringwald 
862*1b2596b5SMatthias Ringwald 	/* Set up the baudrate. */
863*1b2596b5SMatthias Ringwald 	if (usart_set_async_baudrate(p_usart, ul_baudrate, ul_mck)) {
864*1b2596b5SMatthias Ringwald 		return 1;
865*1b2596b5SMatthias Ringwald 	}
866*1b2596b5SMatthias Ringwald 
867*1b2596b5SMatthias Ringwald 	/* Set LIN master mode. */
868*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
869*1b2596b5SMatthias Ringwald 			US_MR_USART_MODE_LIN_MASTER;
870*1b2596b5SMatthias Ringwald 
871*1b2596b5SMatthias Ringwald 	usart_enable_rx(p_usart);
872*1b2596b5SMatthias Ringwald 	usart_enable_tx(p_usart);
873*1b2596b5SMatthias Ringwald 
874*1b2596b5SMatthias Ringwald 	return 0;
875*1b2596b5SMatthias Ringwald }
876*1b2596b5SMatthias Ringwald 
877*1b2596b5SMatthias Ringwald /**
878*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in LIN mode and act as a LIN slave.
879*1b2596b5SMatthias Ringwald  *
880*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
881*1b2596b5SMatthias Ringwald  *
882*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
883*1b2596b5SMatthias Ringwald  * \param ul_baudrate Baudrate to be used.
884*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
885*1b2596b5SMatthias Ringwald  *
886*1b2596b5SMatthias Ringwald  * \retval 0 on success.
887*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
888*1b2596b5SMatthias Ringwald  */
usart_init_lin_slave(Usart * p_usart,uint32_t ul_baudrate,uint32_t ul_mck)889*1b2596b5SMatthias Ringwald uint32_t usart_init_lin_slave(Usart *p_usart, uint32_t ul_baudrate,
890*1b2596b5SMatthias Ringwald 		uint32_t ul_mck)
891*1b2596b5SMatthias Ringwald {
892*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
893*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
894*1b2596b5SMatthias Ringwald 
895*1b2596b5SMatthias Ringwald 	usart_enable_rx(p_usart);
896*1b2596b5SMatthias Ringwald 	usart_enable_tx(p_usart);
897*1b2596b5SMatthias Ringwald 
898*1b2596b5SMatthias Ringwald 	/* Set LIN slave mode. */
899*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
900*1b2596b5SMatthias Ringwald 			US_MR_USART_MODE_LIN_SLAVE;
901*1b2596b5SMatthias Ringwald 
902*1b2596b5SMatthias Ringwald 	/* Set up the baudrate. */
903*1b2596b5SMatthias Ringwald 	if (usart_set_async_baudrate(p_usart, ul_baudrate, ul_mck)) {
904*1b2596b5SMatthias Ringwald 		return 1;
905*1b2596b5SMatthias Ringwald 	}
906*1b2596b5SMatthias Ringwald 
907*1b2596b5SMatthias Ringwald 	return 0;
908*1b2596b5SMatthias Ringwald }
909*1b2596b5SMatthias Ringwald 
910*1b2596b5SMatthias Ringwald /**
911*1b2596b5SMatthias Ringwald  * \brief Abort the current LIN transmission.
912*1b2596b5SMatthias Ringwald  *
913*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
914*1b2596b5SMatthias Ringwald  */
usart_lin_abort_tx(Usart * p_usart)915*1b2596b5SMatthias Ringwald void usart_lin_abort_tx(Usart *p_usart)
916*1b2596b5SMatthias Ringwald {
917*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_LINABT;
918*1b2596b5SMatthias Ringwald }
919*1b2596b5SMatthias Ringwald 
920*1b2596b5SMatthias Ringwald /**
921*1b2596b5SMatthias Ringwald  * \brief Send a wakeup signal on the LIN bus.
922*1b2596b5SMatthias Ringwald  *
923*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
924*1b2596b5SMatthias Ringwald  */
usart_lin_send_wakeup_signal(Usart * p_usart)925*1b2596b5SMatthias Ringwald void usart_lin_send_wakeup_signal(Usart *p_usart)
926*1b2596b5SMatthias Ringwald {
927*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_LINWKUP;
928*1b2596b5SMatthias Ringwald }
929*1b2596b5SMatthias Ringwald 
930*1b2596b5SMatthias Ringwald /**
931*1b2596b5SMatthias Ringwald  * \brief Configure the LIN node action, which should be one of PUBLISH,
932*1b2596b5SMatthias Ringwald  * SUBSCRIBE or IGNORE.
933*1b2596b5SMatthias Ringwald  *
934*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
935*1b2596b5SMatthias Ringwald  * \param uc_action 0 for PUBLISH, 1 for SUBSCRIBE, 2 for IGNORE.
936*1b2596b5SMatthias Ringwald  */
usart_lin_set_node_action(Usart * p_usart,uint8_t uc_action)937*1b2596b5SMatthias Ringwald void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action)
938*1b2596b5SMatthias Ringwald {
939*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_NACT_Msk) |
940*1b2596b5SMatthias Ringwald 			(uc_action << US_LINMR_NACT_Pos);
941*1b2596b5SMatthias Ringwald }
942*1b2596b5SMatthias Ringwald 
943*1b2596b5SMatthias Ringwald /**
944*1b2596b5SMatthias Ringwald  * \brief Disable the parity check during the LIN communication.
945*1b2596b5SMatthias Ringwald  *
946*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
947*1b2596b5SMatthias Ringwald  */
usart_lin_disable_parity(Usart * p_usart)948*1b2596b5SMatthias Ringwald void usart_lin_disable_parity(Usart *p_usart)
949*1b2596b5SMatthias Ringwald {
950*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR |= US_LINMR_PARDIS;
951*1b2596b5SMatthias Ringwald }
952*1b2596b5SMatthias Ringwald 
953*1b2596b5SMatthias Ringwald /**
954*1b2596b5SMatthias Ringwald  * \brief Enable the parity check during the LIN communication.
955*1b2596b5SMatthias Ringwald  *
956*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
957*1b2596b5SMatthias Ringwald  */
usart_lin_enable_parity(Usart * p_usart)958*1b2596b5SMatthias Ringwald void usart_lin_enable_parity(Usart *p_usart)
959*1b2596b5SMatthias Ringwald {
960*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR &= ~US_LINMR_PARDIS;
961*1b2596b5SMatthias Ringwald }
962*1b2596b5SMatthias Ringwald 
963*1b2596b5SMatthias Ringwald /**
964*1b2596b5SMatthias Ringwald  * \brief Disable the checksum during the LIN communication.
965*1b2596b5SMatthias Ringwald  *
966*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
967*1b2596b5SMatthias Ringwald  */
usart_lin_disable_checksum(Usart * p_usart)968*1b2596b5SMatthias Ringwald void usart_lin_disable_checksum(Usart *p_usart)
969*1b2596b5SMatthias Ringwald {
970*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR |= US_LINMR_CHKDIS;
971*1b2596b5SMatthias Ringwald }
972*1b2596b5SMatthias Ringwald 
973*1b2596b5SMatthias Ringwald /**
974*1b2596b5SMatthias Ringwald  * \brief Enable the checksum during the LIN communication.
975*1b2596b5SMatthias Ringwald  *
976*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
977*1b2596b5SMatthias Ringwald  */
usart_lin_enable_checksum(Usart * p_usart)978*1b2596b5SMatthias Ringwald void usart_lin_enable_checksum(Usart *p_usart)
979*1b2596b5SMatthias Ringwald {
980*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR &= ~US_LINMR_CHKDIS;
981*1b2596b5SMatthias Ringwald }
982*1b2596b5SMatthias Ringwald 
983*1b2596b5SMatthias Ringwald /**
984*1b2596b5SMatthias Ringwald  * \brief Configure the checksum type during the LIN communication.
985*1b2596b5SMatthias Ringwald  *
986*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
987*1b2596b5SMatthias Ringwald  * \param uc_type 0 for LIN 2.0 Enhanced checksum or 1 for LIN 1.3 Classic
988*1b2596b5SMatthias Ringwald  *  checksum.
989*1b2596b5SMatthias Ringwald  */
usart_lin_set_checksum_type(Usart * p_usart,uint8_t uc_type)990*1b2596b5SMatthias Ringwald void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type)
991*1b2596b5SMatthias Ringwald {
992*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_CHKTYP) |
993*1b2596b5SMatthias Ringwald 			(uc_type << 4);
994*1b2596b5SMatthias Ringwald }
995*1b2596b5SMatthias Ringwald 
996*1b2596b5SMatthias Ringwald /**
997*1b2596b5SMatthias Ringwald  * \brief Configure the data length mode during the LIN communication.
998*1b2596b5SMatthias Ringwald  *
999*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1000*1b2596b5SMatthias Ringwald  * \param uc_mode Indicate the data length type: 0 if the data length is
1001*1b2596b5SMatthias Ringwald  * defined by the DLC of LIN mode register or 1 if the data length is defined
1002*1b2596b5SMatthias Ringwald  * by the bit 5 and 6 of the identifier.
1003*1b2596b5SMatthias Ringwald  */
usart_lin_set_data_len_mode(Usart * p_usart,uint8_t uc_mode)1004*1b2596b5SMatthias Ringwald void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode)
1005*1b2596b5SMatthias Ringwald {
1006*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLM) |
1007*1b2596b5SMatthias Ringwald 			(uc_mode << 5);
1008*1b2596b5SMatthias Ringwald }
1009*1b2596b5SMatthias Ringwald 
1010*1b2596b5SMatthias Ringwald /**
1011*1b2596b5SMatthias Ringwald  * \brief Disable the frame slot mode during the LIN communication.
1012*1b2596b5SMatthias Ringwald  *
1013*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1014*1b2596b5SMatthias Ringwald  */
usart_lin_disable_frame_slot(Usart * p_usart)1015*1b2596b5SMatthias Ringwald void usart_lin_disable_frame_slot(Usart *p_usart)
1016*1b2596b5SMatthias Ringwald {
1017*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR |= US_LINMR_FSDIS;
1018*1b2596b5SMatthias Ringwald }
1019*1b2596b5SMatthias Ringwald 
1020*1b2596b5SMatthias Ringwald /**
1021*1b2596b5SMatthias Ringwald  * \brief Enable the frame slot mode during the LIN communication.
1022*1b2596b5SMatthias Ringwald  *
1023*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1024*1b2596b5SMatthias Ringwald  */
usart_lin_enable_frame_slot(Usart * p_usart)1025*1b2596b5SMatthias Ringwald void usart_lin_enable_frame_slot(Usart *p_usart)
1026*1b2596b5SMatthias Ringwald {
1027*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR &= ~US_LINMR_FSDIS;
1028*1b2596b5SMatthias Ringwald }
1029*1b2596b5SMatthias Ringwald 
1030*1b2596b5SMatthias Ringwald /**
1031*1b2596b5SMatthias Ringwald  * \brief Configure the wakeup signal type during the LIN communication.
1032*1b2596b5SMatthias Ringwald  *
1033*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1034*1b2596b5SMatthias Ringwald  * \param uc_type Indicate the checksum type: 0 if the wakeup signal is a
1035*1b2596b5SMatthias Ringwald  * LIN 2.0 wakeup signal; 1 if the wakeup signal is a LIN 1.3 wakeup signal.
1036*1b2596b5SMatthias Ringwald  */
usart_lin_set_wakeup_signal_type(Usart * p_usart,uint8_t uc_type)1037*1b2596b5SMatthias Ringwald void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type)
1038*1b2596b5SMatthias Ringwald {
1039*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_WKUPTYP) |
1040*1b2596b5SMatthias Ringwald 			(uc_type << 7);
1041*1b2596b5SMatthias Ringwald }
1042*1b2596b5SMatthias Ringwald 
1043*1b2596b5SMatthias Ringwald /**
1044*1b2596b5SMatthias Ringwald  * \brief Configure the response data length if the data length is defined by
1045*1b2596b5SMatthias Ringwald  * the DLC field during the LIN communication.
1046*1b2596b5SMatthias Ringwald  *
1047*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1048*1b2596b5SMatthias Ringwald  * \param uc_len Indicate the response data length.
1049*1b2596b5SMatthias Ringwald  */
usart_lin_set_response_data_len(Usart * p_usart,uint8_t uc_len)1050*1b2596b5SMatthias Ringwald void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len)
1051*1b2596b5SMatthias Ringwald {
1052*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLC_Msk) |
1053*1b2596b5SMatthias Ringwald 			((uc_len - 1) << US_LINMR_DLC_Pos);
1054*1b2596b5SMatthias Ringwald }
1055*1b2596b5SMatthias Ringwald 
1056*1b2596b5SMatthias Ringwald /**
1057*1b2596b5SMatthias Ringwald  * \brief The LIN mode register is not written by the PDC.
1058*1b2596b5SMatthias Ringwald  *
1059*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1060*1b2596b5SMatthias Ringwald  */
usart_lin_disable_pdc_mode(Usart * p_usart)1061*1b2596b5SMatthias Ringwald void usart_lin_disable_pdc_mode(Usart *p_usart)
1062*1b2596b5SMatthias Ringwald {
1063*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR &= ~US_LINMR_PDCM;
1064*1b2596b5SMatthias Ringwald }
1065*1b2596b5SMatthias Ringwald 
1066*1b2596b5SMatthias Ringwald /**
1067*1b2596b5SMatthias Ringwald  * \brief The LIN mode register (except this flag) is written by the PDC.
1068*1b2596b5SMatthias Ringwald  *
1069*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1070*1b2596b5SMatthias Ringwald  */
usart_lin_enable_pdc_mode(Usart * p_usart)1071*1b2596b5SMatthias Ringwald void usart_lin_enable_pdc_mode(Usart *p_usart)
1072*1b2596b5SMatthias Ringwald {
1073*1b2596b5SMatthias Ringwald 	p_usart->US_LINMR |= US_LINMR_PDCM;
1074*1b2596b5SMatthias Ringwald }
1075*1b2596b5SMatthias Ringwald 
1076*1b2596b5SMatthias Ringwald /**
1077*1b2596b5SMatthias Ringwald  * \brief Configure the LIN identifier when USART works in LIN master mode.
1078*1b2596b5SMatthias Ringwald  *
1079*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1080*1b2596b5SMatthias Ringwald  * \param uc_id The identifier to be transmitted.
1081*1b2596b5SMatthias Ringwald  */
usart_lin_set_tx_identifier(Usart * p_usart,uint8_t uc_id)1082*1b2596b5SMatthias Ringwald void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id)
1083*1b2596b5SMatthias Ringwald {
1084*1b2596b5SMatthias Ringwald 	p_usart->US_LINIR = (p_usart->US_LINIR & ~US_LINIR_IDCHR_Msk) |
1085*1b2596b5SMatthias Ringwald 			US_LINIR_IDCHR(uc_id);
1086*1b2596b5SMatthias Ringwald }
1087*1b2596b5SMatthias Ringwald 
1088*1b2596b5SMatthias Ringwald /**
1089*1b2596b5SMatthias Ringwald  * \brief Read the identifier when USART works in LIN mode.
1090*1b2596b5SMatthias Ringwald  *
1091*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1092*1b2596b5SMatthias Ringwald  *
1093*1b2596b5SMatthias Ringwald  * \return The last identifier received in LIN slave mode or the last
1094*1b2596b5SMatthias Ringwald  * identifier transmitted in LIN master mode.
1095*1b2596b5SMatthias Ringwald  */
usart_lin_read_identifier(Usart * p_usart)1096*1b2596b5SMatthias Ringwald uint8_t usart_lin_read_identifier(Usart *p_usart)
1097*1b2596b5SMatthias Ringwald {
1098*1b2596b5SMatthias Ringwald 	return (p_usart->US_LINIR & US_LINIR_IDCHR_Msk);
1099*1b2596b5SMatthias Ringwald }
1100*1b2596b5SMatthias Ringwald 
1101*1b2596b5SMatthias Ringwald /**
1102*1b2596b5SMatthias Ringwald  * \brief Get data length.
1103*1b2596b5SMatthias Ringwald  *
1104*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1105*1b2596b5SMatthias Ringwald  *
1106*1b2596b5SMatthias Ringwald  * \return Data length.
1107*1b2596b5SMatthias Ringwald  */
usart_lin_get_data_length(Usart * usart)1108*1b2596b5SMatthias Ringwald uint8_t usart_lin_get_data_length(Usart *usart)
1109*1b2596b5SMatthias Ringwald {
1110*1b2596b5SMatthias Ringwald 	if (usart->US_LINMR & US_LINMR_DLM) {
1111*1b2596b5SMatthias Ringwald 		uint8_t data_length = 1 << ((usart->US_LINIR >>
1112*1b2596b5SMatthias Ringwald 				(US_LINIR_IDCHR_Pos + 4)) & 0x03);
1113*1b2596b5SMatthias Ringwald 		return data_length;
1114*1b2596b5SMatthias Ringwald 	} else {
1115*1b2596b5SMatthias Ringwald 		return ((usart->US_LINMR & US_LINMR_DLC_Msk) >> US_LINMR_DLC_Pos) + 1;
1116*1b2596b5SMatthias Ringwald 	}
1117*1b2596b5SMatthias Ringwald }
1118*1b2596b5SMatthias Ringwald 
1119*1b2596b5SMatthias Ringwald #endif
1120*1b2596b5SMatthias Ringwald 
1121*1b2596b5SMatthias Ringwald #if (SAMV71 || SAMV70 || SAME70 || SAMS70)
1122*1b2596b5SMatthias Ringwald /**
1123*1b2596b5SMatthias Ringwald  * \brief Get identifier send status.
1124*1b2596b5SMatthias Ringwald  *
1125*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1126*1b2596b5SMatthias Ringwald  *
1127*1b2596b5SMatthias Ringwald  * \return
1128*1b2596b5SMatthias Ringwald  * 0:  No LIN identifier has been sent since the last RSTSTA.
1129*1b2596b5SMatthias Ringwald  * 1: :At least one LIN identifier has been sent since the last RSTSTA.
1130*1b2596b5SMatthias Ringwald  */
usart_lin_identifier_send_complete(Usart * usart)1131*1b2596b5SMatthias Ringwald uint8_t usart_lin_identifier_send_complete(Usart *usart)
1132*1b2596b5SMatthias Ringwald {
1133*1b2596b5SMatthias Ringwald 	return (usart->US_CSR & US_CSR_LINID) > 0;
1134*1b2596b5SMatthias Ringwald }
1135*1b2596b5SMatthias Ringwald 
1136*1b2596b5SMatthias Ringwald /**
1137*1b2596b5SMatthias Ringwald  * \brief Get identifier received status.
1138*1b2596b5SMatthias Ringwald  *
1139*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1140*1b2596b5SMatthias Ringwald  *
1141*1b2596b5SMatthias Ringwald  * \return
1142*1b2596b5SMatthias Ringwald  * 0:  No LIN identifier has been reveived since the last RSTSTA.
1143*1b2596b5SMatthias Ringwald  * 1: At least one LIN identifier has been received since the last RSTSTA.
1144*1b2596b5SMatthias Ringwald  */
usart_lin_identifier_reception_complete(Usart * usart)1145*1b2596b5SMatthias Ringwald uint8_t usart_lin_identifier_reception_complete(Usart *usart)
1146*1b2596b5SMatthias Ringwald {
1147*1b2596b5SMatthias Ringwald 	return (usart->US_CSR & US_CSR_LINID) > 0;
1148*1b2596b5SMatthias Ringwald }
1149*1b2596b5SMatthias Ringwald 
1150*1b2596b5SMatthias Ringwald /**
1151*1b2596b5SMatthias Ringwald  * \brief Get transmission status.
1152*1b2596b5SMatthias Ringwald  *
1153*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1154*1b2596b5SMatthias Ringwald  *
1155*1b2596b5SMatthias Ringwald  * \return
1156*1b2596b5SMatthias Ringwald  * 0: The USART is idle or a LIN transfer is ongoing.
1157*1b2596b5SMatthias Ringwald  * 1: A LIN transfer has been completed since the last RSTSTA.
1158*1b2596b5SMatthias Ringwald  */
usart_lin_tx_complete(Usart * usart)1159*1b2596b5SMatthias Ringwald uint8_t usart_lin_tx_complete(Usart *usart)
1160*1b2596b5SMatthias Ringwald {
1161*1b2596b5SMatthias Ringwald 	return (usart->US_CSR & US_CSR_LINTC) > 0;
1162*1b2596b5SMatthias Ringwald }
1163*1b2596b5SMatthias Ringwald 
1164*1b2596b5SMatthias Ringwald /**
1165*1b2596b5SMatthias Ringwald  * \brief Configure USART to work in LON mode.
1166*1b2596b5SMatthias Ringwald  *
1167*1b2596b5SMatthias Ringwald  * \note By default, the transmitter and receiver aren't enabled.
1168*1b2596b5SMatthias Ringwald  *
1169*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1170*1b2596b5SMatthias Ringwald  * \param ul_baudrate Baudrate to be used.
1171*1b2596b5SMatthias Ringwald  * \param ul_mck USART module input clock frequency.
1172*1b2596b5SMatthias Ringwald  *
1173*1b2596b5SMatthias Ringwald  * \retval 0 on success.
1174*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
1175*1b2596b5SMatthias Ringwald  */
usart_init_lon(Usart * p_usart,uint32_t ul_baudrate,uint32_t ul_mck)1176*1b2596b5SMatthias Ringwald uint32_t usart_init_lon(Usart *p_usart,uint32_t ul_baudrate,
1177*1b2596b5SMatthias Ringwald 		uint32_t ul_mck)
1178*1b2596b5SMatthias Ringwald {
1179*1b2596b5SMatthias Ringwald 	/* Reset the USART and shut down TX and RX. */
1180*1b2596b5SMatthias Ringwald 	usart_reset(p_usart);
1181*1b2596b5SMatthias Ringwald 
1182*1b2596b5SMatthias Ringwald 	/* Set up the baudrate. */
1183*1b2596b5SMatthias Ringwald 	if (usart_set_async_baudrate(p_usart, ul_baudrate, ul_mck)) {
1184*1b2596b5SMatthias Ringwald 		return 1;
1185*1b2596b5SMatthias Ringwald 	}
1186*1b2596b5SMatthias Ringwald 
1187*1b2596b5SMatthias Ringwald 	/* Set LIN master mode. */
1188*1b2596b5SMatthias Ringwald 	p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
1189*1b2596b5SMatthias Ringwald 			US_MR_USART_MODE_LON;
1190*1b2596b5SMatthias Ringwald 
1191*1b2596b5SMatthias Ringwald 	usart_enable_rx(p_usart);
1192*1b2596b5SMatthias Ringwald 	usart_enable_tx(p_usart);
1193*1b2596b5SMatthias Ringwald 
1194*1b2596b5SMatthias Ringwald 	return 0;
1195*1b2596b5SMatthias Ringwald }
1196*1b2596b5SMatthias Ringwald 
1197*1b2596b5SMatthias Ringwald /**
1198*1b2596b5SMatthias Ringwald  * \brief set LON parameter value.
1199*1b2596b5SMatthias Ringwald  *
1200*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1201*1b2596b5SMatthias Ringwald  * \param uc_type 0: LON comm_type = 1 mode,
1202*1b2596b5SMatthias Ringwald  *  1: LON comm_type = 2 mode
1203*1b2596b5SMatthias Ringwald  */
usart_lon_set_comm_type(Usart * p_usart,uint8_t uc_type)1204*1b2596b5SMatthias Ringwald void  usart_lon_set_comm_type(Usart *p_usart, uint8_t uc_type)
1205*1b2596b5SMatthias Ringwald {
1206*1b2596b5SMatthias Ringwald 	p_usart->US_LONMR = (p_usart->US_LONMR & ~US_LONMR_COMMT) |
1207*1b2596b5SMatthias Ringwald 			 (uc_type << 0);
1208*1b2596b5SMatthias Ringwald }
1209*1b2596b5SMatthias Ringwald 
1210*1b2596b5SMatthias Ringwald /**
1211*1b2596b5SMatthias Ringwald  * \brief Disable  LON Collision Detection Feature.
1212*1b2596b5SMatthias Ringwald  *
1213*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1214*1b2596b5SMatthias Ringwald  */
usart_lon_disable_coll_detection(Usart * p_usart)1215*1b2596b5SMatthias Ringwald void usart_lon_disable_coll_detection(Usart *p_usart)
1216*1b2596b5SMatthias Ringwald {
1217*1b2596b5SMatthias Ringwald 	p_usart->US_LONMR |= US_LONMR_COLDET;
1218*1b2596b5SMatthias Ringwald }
1219*1b2596b5SMatthias Ringwald 
1220*1b2596b5SMatthias Ringwald /**
1221*1b2596b5SMatthias Ringwald  * \brief Enable LON Collision Detection Feature.
1222*1b2596b5SMatthias Ringwald  *
1223*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1224*1b2596b5SMatthias Ringwald  */
usart_lon_enable_coll_detection(Usart * p_usart)1225*1b2596b5SMatthias Ringwald void usart_lon_enable_coll_detection(Usart *p_usart)
1226*1b2596b5SMatthias Ringwald {
1227*1b2596b5SMatthias Ringwald 	p_usart->US_LONMR &= ~US_LONMR_COLDET;
1228*1b2596b5SMatthias Ringwald }
1229*1b2596b5SMatthias Ringwald 
1230*1b2596b5SMatthias Ringwald /**
1231*1b2596b5SMatthias Ringwald  * \brief set Terminate Frame upon Collision Notification.
1232*1b2596b5SMatthias Ringwald  *
1233*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1234*1b2596b5SMatthias Ringwald  * \param uc_type 0:  Do not terminate the frame in LON comm_type = 1 mode upon collision detection.
1235*1b2596b5SMatthias Ringwald  * 1:Terminate the frame in LON comm_type = 1 mode upon collision detection if possible.
1236*1b2596b5SMatthias Ringwald  */
usart_lon_set_tcol(Usart * p_usart,uint8_t uc_type)1237*1b2596b5SMatthias Ringwald void  usart_lon_set_tcol(Usart *p_usart, uint8_t uc_type)
1238*1b2596b5SMatthias Ringwald {
1239*1b2596b5SMatthias Ringwald 	p_usart->US_LONMR = (p_usart->US_LONMR & ~US_LONMR_TCOL) |
1240*1b2596b5SMatthias Ringwald 			 (uc_type << 2);
1241*1b2596b5SMatthias Ringwald }
1242*1b2596b5SMatthias Ringwald 
1243*1b2596b5SMatthias Ringwald /**
1244*1b2596b5SMatthias Ringwald  * \brief set  LON Collision Detection on Frame Tail.
1245*1b2596b5SMatthias Ringwald  *
1246*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1247*1b2596b5SMatthias Ringwald  * \param uc_type 0: Detect collisions after CRC has been sent but prior end of transmission in LON comm_type = 1 mode.
1248*1b2596b5SMatthias Ringwald  * 1: Ignore collisions after CRC has been sent but prior end of transmission in LON comm_type = 1 mode.
1249*1b2596b5SMatthias Ringwald  */
usart_lon_set_cdtail(Usart * p_usart,uint8_t uc_type)1250*1b2596b5SMatthias Ringwald void  usart_lon_set_cdtail(Usart *p_usart, uint8_t uc_type)
1251*1b2596b5SMatthias Ringwald {
1252*1b2596b5SMatthias Ringwald 	p_usart->US_LONMR = (p_usart->US_LONMR & ~US_LONMR_CDTAIL) |
1253*1b2596b5SMatthias Ringwald 			 (uc_type << 3);
1254*1b2596b5SMatthias Ringwald }
1255*1b2596b5SMatthias Ringwald 
1256*1b2596b5SMatthias Ringwald /**
1257*1b2596b5SMatthias Ringwald  * \brief set  LON DMA Mode.
1258*1b2596b5SMatthias Ringwald  *
1259*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1260*1b2596b5SMatthias Ringwald  * \param uc_type 0: The LON data length register US_LONDL is not written by the DMA.
1261*1b2596b5SMatthias Ringwald  * 1: The LON data length register US_LONDL is written by the DMA.
1262*1b2596b5SMatthias Ringwald  */
usart_lon_set_dmam(Usart * p_usart,uint8_t uc_type)1263*1b2596b5SMatthias Ringwald void  usart_lon_set_dmam(Usart *p_usart, uint8_t uc_type)
1264*1b2596b5SMatthias Ringwald {
1265*1b2596b5SMatthias Ringwald 	p_usart->US_LONMR = (p_usart->US_LONMR & ~US_LONMR_DMAM) |
1266*1b2596b5SMatthias Ringwald 			 (uc_type << 4);
1267*1b2596b5SMatthias Ringwald }
1268*1b2596b5SMatthias Ringwald 
1269*1b2596b5SMatthias Ringwald /**
1270*1b2596b5SMatthias Ringwald  * \brief set LON Beta1 Length after Transmission.
1271*1b2596b5SMatthias Ringwald  *
1272*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1273*1b2596b5SMatthias Ringwald  * \param ul_len 1-16777215: LON beta1 length after transmission in tbit
1274*1b2596b5SMatthias Ringwald  */
usart_lon_set_beta1_tx_len(Usart * p_usart,uint32_t ul_len)1275*1b2596b5SMatthias Ringwald void  usart_lon_set_beta1_tx_len(Usart *p_usart, uint32_t ul_len)
1276*1b2596b5SMatthias Ringwald {
1277*1b2596b5SMatthias Ringwald 	p_usart->US_LONB1TX = US_LONB1TX_BETA1TX(ul_len);
1278*1b2596b5SMatthias Ringwald }
1279*1b2596b5SMatthias Ringwald 
1280*1b2596b5SMatthias Ringwald /**
1281*1b2596b5SMatthias Ringwald  * \brief set LON Beta1 Length after Reception.
1282*1b2596b5SMatthias Ringwald  *
1283*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1284*1b2596b5SMatthias Ringwald  * \param ul_len 1-16777215: LON beta1 length after reception in tbit.
1285*1b2596b5SMatthias Ringwald  */
usart_lon_set_beta1_rx_len(Usart * p_usart,uint32_t ul_len)1286*1b2596b5SMatthias Ringwald void  usart_lon_set_beta1_rx_len(Usart *p_usart, uint32_t ul_len)
1287*1b2596b5SMatthias Ringwald {
1288*1b2596b5SMatthias Ringwald 	p_usart->US_LONB1RX = US_LONB1RX_BETA1RX(ul_len);
1289*1b2596b5SMatthias Ringwald }
1290*1b2596b5SMatthias Ringwald 
1291*1b2596b5SMatthias Ringwald /**
1292*1b2596b5SMatthias Ringwald  * \brief set  LON Priority.
1293*1b2596b5SMatthias Ringwald  *
1294*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1295*1b2596b5SMatthias Ringwald  * \param uc_psnb 0 -127: LON Priority Slot Number.
1296*1b2596b5SMatthias Ringwald  * \param uc_nps  0 -127: LON Node Priority Slot.
1297*1b2596b5SMatthias Ringwald  */
usart_lon_set_priority(Usart * p_usart,uint8_t uc_psnb,uint8_t uc_nps)1298*1b2596b5SMatthias Ringwald void  usart_lon_set_priority(Usart *p_usart, uint8_t uc_psnb, uint8_t uc_nps)
1299*1b2596b5SMatthias Ringwald {
1300*1b2596b5SMatthias Ringwald 	p_usart->US_LONPRIO = US_LONPRIO_PSNB(uc_psnb) | US_LONPRIO_NPS(uc_nps);
1301*1b2596b5SMatthias Ringwald }
1302*1b2596b5SMatthias Ringwald 
1303*1b2596b5SMatthias Ringwald /**
1304*1b2596b5SMatthias Ringwald  * \brief set LON Indeterminate Time after Transmission.
1305*1b2596b5SMatthias Ringwald  *
1306*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1307*1b2596b5SMatthias Ringwald  * \param ul_time 1-16777215: LON Indeterminate Time after Transmission (comm_type = 1 mode only).
1308*1b2596b5SMatthias Ringwald  */
usart_lon_set_tx_idt(Usart * p_usart,uint32_t ul_time)1309*1b2596b5SMatthias Ringwald void  usart_lon_set_tx_idt(Usart *p_usart, uint32_t ul_time)
1310*1b2596b5SMatthias Ringwald {
1311*1b2596b5SMatthias Ringwald 	p_usart->US_IDTTX = US_IDTTX_IDTTX(ul_time);
1312*1b2596b5SMatthias Ringwald }
1313*1b2596b5SMatthias Ringwald 
1314*1b2596b5SMatthias Ringwald /**
1315*1b2596b5SMatthias Ringwald  * \brief set LON Indeterminate Time after Reception.
1316*1b2596b5SMatthias Ringwald  *
1317*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1318*1b2596b5SMatthias Ringwald  * \param ul_time 1-16777215: LON Indeterminate Time after Reception (comm_type = 1 mode only).
1319*1b2596b5SMatthias Ringwald  */
usart_lon_set_rx_idt(Usart * p_usart,uint32_t ul_time)1320*1b2596b5SMatthias Ringwald void  usart_lon_set_rx_idt(Usart *p_usart, uint32_t ul_time)
1321*1b2596b5SMatthias Ringwald {
1322*1b2596b5SMatthias Ringwald 	p_usart->US_IDTRX = US_IDTRX_IDTRX(ul_time);
1323*1b2596b5SMatthias Ringwald }
1324*1b2596b5SMatthias Ringwald 
1325*1b2596b5SMatthias Ringwald /**
1326*1b2596b5SMatthias Ringwald  * \brief set LON Preamble Length.
1327*1b2596b5SMatthias Ringwald  *
1328*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1329*1b2596b5SMatthias Ringwald  * \param ul_len 1-16383: LON preamble length in tbit(without byte-sync).
1330*1b2596b5SMatthias Ringwald  */
usart_lon_set_pre_len(Usart * p_usart,uint32_t ul_len)1331*1b2596b5SMatthias Ringwald void  usart_lon_set_pre_len(Usart *p_usart, uint32_t ul_len)
1332*1b2596b5SMatthias Ringwald {
1333*1b2596b5SMatthias Ringwald 	p_usart->US_LONPR = US_LONPR_LONPL(ul_len);
1334*1b2596b5SMatthias Ringwald }
1335*1b2596b5SMatthias Ringwald 
1336*1b2596b5SMatthias Ringwald /**
1337*1b2596b5SMatthias Ringwald  * \brief set LON  Data Length.
1338*1b2596b5SMatthias Ringwald  *
1339*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1340*1b2596b5SMatthias Ringwald  * \param uc_len 0-255: LON data length is LONDL+1 bytes.
1341*1b2596b5SMatthias Ringwald  */
usart_lon_set_data_len(Usart * p_usart,uint8_t uc_len)1342*1b2596b5SMatthias Ringwald void  usart_lon_set_data_len(Usart *p_usart, uint8_t uc_len)
1343*1b2596b5SMatthias Ringwald {
1344*1b2596b5SMatthias Ringwald 	p_usart->US_LONDL = US_LONDL_LONDL(uc_len);
1345*1b2596b5SMatthias Ringwald }
1346*1b2596b5SMatthias Ringwald 
1347*1b2596b5SMatthias Ringwald /**
1348*1b2596b5SMatthias Ringwald  * \brief set  LON Priority.
1349*1b2596b5SMatthias Ringwald  *
1350*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1351*1b2596b5SMatthias Ringwald  * \param uc_bli   LON Backlog Increment.
1352*1b2596b5SMatthias Ringwald  * \param uc_altp LON Alternate Path Bit.
1353*1b2596b5SMatthias Ringwald  * \param uc_pb   LON Priority Bit.
1354*1b2596b5SMatthias Ringwald  */
usart_lon_set_l2hdr(Usart * p_usart,uint8_t uc_bli,uint8_t uc_altp,uint8_t uc_pb)1355*1b2596b5SMatthias Ringwald void  usart_lon_set_l2hdr(Usart *p_usart, uint8_t uc_bli, uint8_t uc_altp, uint8_t uc_pb)
1356*1b2596b5SMatthias Ringwald {
1357*1b2596b5SMatthias Ringwald 	p_usart->US_LONL2HDR = US_LONL2HDR_BLI(uc_bli) | (uc_altp << 6) | (uc_pb << 7);
1358*1b2596b5SMatthias Ringwald }
1359*1b2596b5SMatthias Ringwald 
1360*1b2596b5SMatthias Ringwald /**
1361*1b2596b5SMatthias Ringwald  * \brief Check if LON Transmission End.
1362*1b2596b5SMatthias Ringwald  *
1363*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1364*1b2596b5SMatthias Ringwald  *
1365*1b2596b5SMatthias Ringwald  * \retval 1  At least one transmission has been performed since the last RSTSTA.
1366*1b2596b5SMatthias Ringwald  * \retval 0  Transmission on going or no transmission occurred since the last RSTSTA.
1367*1b2596b5SMatthias Ringwald  */
usart_lon_is_tx_end(Usart * p_usart)1368*1b2596b5SMatthias Ringwald uint32_t usart_lon_is_tx_end(Usart *p_usart)
1369*1b2596b5SMatthias Ringwald {
1370*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_LTXD) > 0;
1371*1b2596b5SMatthias Ringwald }
1372*1b2596b5SMatthias Ringwald 
1373*1b2596b5SMatthias Ringwald /**
1374*1b2596b5SMatthias Ringwald  * \brief Check if LON Reception End.
1375*1b2596b5SMatthias Ringwald  *
1376*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1377*1b2596b5SMatthias Ringwald  *
1378*1b2596b5SMatthias Ringwald  * \retval 1  At least one Reception has been performed since the last RSTSTA.
1379*1b2596b5SMatthias Ringwald  * \retval 0  Reception on going or no Reception occurred since the last RSTSTA.
1380*1b2596b5SMatthias Ringwald  */
usart_lon_is_rx_end(Usart * p_usart)1381*1b2596b5SMatthias Ringwald uint32_t usart_lon_is_rx_end(Usart *p_usart)
1382*1b2596b5SMatthias Ringwald {
1383*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_LRXD) > 0;
1384*1b2596b5SMatthias Ringwald }
1385*1b2596b5SMatthias Ringwald #endif
1386*1b2596b5SMatthias Ringwald 
1387*1b2596b5SMatthias Ringwald /**
1388*1b2596b5SMatthias Ringwald  * \brief Enable USART transmitter.
1389*1b2596b5SMatthias Ringwald  *
1390*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1391*1b2596b5SMatthias Ringwald  */
usart_enable_tx(Usart * p_usart)1392*1b2596b5SMatthias Ringwald void usart_enable_tx(Usart *p_usart)
1393*1b2596b5SMatthias Ringwald {
1394*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_TXEN;
1395*1b2596b5SMatthias Ringwald }
1396*1b2596b5SMatthias Ringwald 
1397*1b2596b5SMatthias Ringwald /**
1398*1b2596b5SMatthias Ringwald  * \brief Disable USART transmitter.
1399*1b2596b5SMatthias Ringwald  *
1400*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1401*1b2596b5SMatthias Ringwald  */
usart_disable_tx(Usart * p_usart)1402*1b2596b5SMatthias Ringwald void usart_disable_tx(Usart *p_usart)
1403*1b2596b5SMatthias Ringwald {
1404*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_TXDIS;
1405*1b2596b5SMatthias Ringwald }
1406*1b2596b5SMatthias Ringwald 
1407*1b2596b5SMatthias Ringwald /**
1408*1b2596b5SMatthias Ringwald  * \brief Immediately stop and disable USART transmitter.
1409*1b2596b5SMatthias Ringwald  *
1410*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1411*1b2596b5SMatthias Ringwald  */
usart_reset_tx(Usart * p_usart)1412*1b2596b5SMatthias Ringwald void usart_reset_tx(Usart *p_usart)
1413*1b2596b5SMatthias Ringwald {
1414*1b2596b5SMatthias Ringwald 	/* Reset transmitter */
1415*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RSTTX | US_CR_TXDIS;
1416*1b2596b5SMatthias Ringwald }
1417*1b2596b5SMatthias Ringwald 
1418*1b2596b5SMatthias Ringwald /**
1419*1b2596b5SMatthias Ringwald  * \brief Configure the transmit timeguard register.
1420*1b2596b5SMatthias Ringwald  *
1421*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1422*1b2596b5SMatthias Ringwald  * \param timeguard The value of transmit timeguard.
1423*1b2596b5SMatthias Ringwald  */
usart_set_tx_timeguard(Usart * p_usart,uint32_t timeguard)1424*1b2596b5SMatthias Ringwald void usart_set_tx_timeguard(Usart *p_usart, uint32_t timeguard)
1425*1b2596b5SMatthias Ringwald {
1426*1b2596b5SMatthias Ringwald 	p_usart->US_TTGR = timeguard;
1427*1b2596b5SMatthias Ringwald }
1428*1b2596b5SMatthias Ringwald 
1429*1b2596b5SMatthias Ringwald /**
1430*1b2596b5SMatthias Ringwald  * \brief Enable USART receiver.
1431*1b2596b5SMatthias Ringwald  *
1432*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1433*1b2596b5SMatthias Ringwald  */
usart_enable_rx(Usart * p_usart)1434*1b2596b5SMatthias Ringwald void usart_enable_rx(Usart *p_usart)
1435*1b2596b5SMatthias Ringwald {
1436*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RXEN;
1437*1b2596b5SMatthias Ringwald }
1438*1b2596b5SMatthias Ringwald 
1439*1b2596b5SMatthias Ringwald /**
1440*1b2596b5SMatthias Ringwald  * \brief Disable USART receiver.
1441*1b2596b5SMatthias Ringwald  *
1442*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1443*1b2596b5SMatthias Ringwald  */
usart_disable_rx(Usart * p_usart)1444*1b2596b5SMatthias Ringwald void usart_disable_rx(Usart *p_usart)
1445*1b2596b5SMatthias Ringwald {
1446*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RXDIS;
1447*1b2596b5SMatthias Ringwald }
1448*1b2596b5SMatthias Ringwald 
1449*1b2596b5SMatthias Ringwald /**
1450*1b2596b5SMatthias Ringwald  * \brief Immediately stop and disable USART receiver.
1451*1b2596b5SMatthias Ringwald  *
1452*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1453*1b2596b5SMatthias Ringwald  */
usart_reset_rx(Usart * p_usart)1454*1b2596b5SMatthias Ringwald void usart_reset_rx(Usart *p_usart)
1455*1b2596b5SMatthias Ringwald {
1456*1b2596b5SMatthias Ringwald 	/* Reset Receiver */
1457*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RSTRX | US_CR_RXDIS;
1458*1b2596b5SMatthias Ringwald }
1459*1b2596b5SMatthias Ringwald 
1460*1b2596b5SMatthias Ringwald /**
1461*1b2596b5SMatthias Ringwald  * \brief Configure the receive timeout register.
1462*1b2596b5SMatthias Ringwald  *
1463*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1464*1b2596b5SMatthias Ringwald  * \param timeout The value of receive timeout.
1465*1b2596b5SMatthias Ringwald  */
usart_set_rx_timeout(Usart * p_usart,uint32_t timeout)1466*1b2596b5SMatthias Ringwald void usart_set_rx_timeout(Usart *p_usart, uint32_t timeout)
1467*1b2596b5SMatthias Ringwald {
1468*1b2596b5SMatthias Ringwald 	p_usart->US_RTOR = timeout;
1469*1b2596b5SMatthias Ringwald }
1470*1b2596b5SMatthias Ringwald 
1471*1b2596b5SMatthias Ringwald /**
1472*1b2596b5SMatthias Ringwald  * \brief Enable USART interrupts.
1473*1b2596b5SMatthias Ringwald  *
1474*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART peripheral.
1475*1b2596b5SMatthias Ringwald  * \param ul_sources Interrupt sources bit map.
1476*1b2596b5SMatthias Ringwald  */
usart_enable_interrupt(Usart * p_usart,uint32_t ul_sources)1477*1b2596b5SMatthias Ringwald void usart_enable_interrupt(Usart *p_usart, uint32_t ul_sources)
1478*1b2596b5SMatthias Ringwald {
1479*1b2596b5SMatthias Ringwald 	p_usart->US_IER = ul_sources;
1480*1b2596b5SMatthias Ringwald }
1481*1b2596b5SMatthias Ringwald 
1482*1b2596b5SMatthias Ringwald /**
1483*1b2596b5SMatthias Ringwald  * \brief Disable USART interrupts.
1484*1b2596b5SMatthias Ringwald  *
1485*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART peripheral.
1486*1b2596b5SMatthias Ringwald  * \param ul_sources Interrupt sources bit map.
1487*1b2596b5SMatthias Ringwald  */
usart_disable_interrupt(Usart * p_usart,uint32_t ul_sources)1488*1b2596b5SMatthias Ringwald void usart_disable_interrupt(Usart *p_usart, uint32_t ul_sources)
1489*1b2596b5SMatthias Ringwald {
1490*1b2596b5SMatthias Ringwald 	p_usart->US_IDR = ul_sources;
1491*1b2596b5SMatthias Ringwald }
1492*1b2596b5SMatthias Ringwald 
1493*1b2596b5SMatthias Ringwald /**
1494*1b2596b5SMatthias Ringwald  * \brief Read USART interrupt mask.
1495*1b2596b5SMatthias Ringwald  *
1496*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART peripheral.
1497*1b2596b5SMatthias Ringwald  *
1498*1b2596b5SMatthias Ringwald  * \return The interrupt mask value.
1499*1b2596b5SMatthias Ringwald  */
usart_get_interrupt_mask(Usart * p_usart)1500*1b2596b5SMatthias Ringwald uint32_t usart_get_interrupt_mask(Usart *p_usart)
1501*1b2596b5SMatthias Ringwald {
1502*1b2596b5SMatthias Ringwald 	return p_usart->US_IMR;
1503*1b2596b5SMatthias Ringwald }
1504*1b2596b5SMatthias Ringwald 
1505*1b2596b5SMatthias Ringwald /**
1506*1b2596b5SMatthias Ringwald  * \brief Get current status.
1507*1b2596b5SMatthias Ringwald  *
1508*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1509*1b2596b5SMatthias Ringwald  *
1510*1b2596b5SMatthias Ringwald  * \return The current USART status.
1511*1b2596b5SMatthias Ringwald  */
usart_get_status(Usart * p_usart)1512*1b2596b5SMatthias Ringwald uint32_t usart_get_status(Usart *p_usart)
1513*1b2596b5SMatthias Ringwald {
1514*1b2596b5SMatthias Ringwald 	return p_usart->US_CSR;
1515*1b2596b5SMatthias Ringwald }
1516*1b2596b5SMatthias Ringwald 
1517*1b2596b5SMatthias Ringwald /**
1518*1b2596b5SMatthias Ringwald  * \brief Reset status bits (PARE, OVER, MANERR, UNRE and PXBRK in US_CSR).
1519*1b2596b5SMatthias Ringwald  *
1520*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1521*1b2596b5SMatthias Ringwald  */
usart_reset_status(Usart * p_usart)1522*1b2596b5SMatthias Ringwald void usart_reset_status(Usart *p_usart)
1523*1b2596b5SMatthias Ringwald {
1524*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RSTSTA;
1525*1b2596b5SMatthias Ringwald }
1526*1b2596b5SMatthias Ringwald 
1527*1b2596b5SMatthias Ringwald /**
1528*1b2596b5SMatthias Ringwald  * \brief Start transmission of a break.
1529*1b2596b5SMatthias Ringwald  *
1530*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1531*1b2596b5SMatthias Ringwald  */
usart_start_tx_break(Usart * p_usart)1532*1b2596b5SMatthias Ringwald void usart_start_tx_break(Usart *p_usart)
1533*1b2596b5SMatthias Ringwald {
1534*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_STTBRK;
1535*1b2596b5SMatthias Ringwald }
1536*1b2596b5SMatthias Ringwald 
1537*1b2596b5SMatthias Ringwald /**
1538*1b2596b5SMatthias Ringwald  * \brief Stop transmission of a break.
1539*1b2596b5SMatthias Ringwald  *
1540*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1541*1b2596b5SMatthias Ringwald  */
usart_stop_tx_break(Usart * p_usart)1542*1b2596b5SMatthias Ringwald void usart_stop_tx_break(Usart *p_usart)
1543*1b2596b5SMatthias Ringwald {
1544*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_STPBRK;
1545*1b2596b5SMatthias Ringwald }
1546*1b2596b5SMatthias Ringwald 
1547*1b2596b5SMatthias Ringwald /**
1548*1b2596b5SMatthias Ringwald  * \brief Start waiting for a character before clocking the timeout count.
1549*1b2596b5SMatthias Ringwald  * Reset the status bit TIMEOUT in US_CSR.
1550*1b2596b5SMatthias Ringwald  *
1551*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1552*1b2596b5SMatthias Ringwald  */
usart_start_rx_timeout(Usart * p_usart)1553*1b2596b5SMatthias Ringwald void usart_start_rx_timeout(Usart *p_usart)
1554*1b2596b5SMatthias Ringwald {
1555*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_STTTO;
1556*1b2596b5SMatthias Ringwald }
1557*1b2596b5SMatthias Ringwald 
1558*1b2596b5SMatthias Ringwald /**
1559*1b2596b5SMatthias Ringwald  * \brief In Multidrop mode only, the next character written to the US_THR
1560*1b2596b5SMatthias Ringwald  * is sent with the address bit set.
1561*1b2596b5SMatthias Ringwald  *
1562*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1563*1b2596b5SMatthias Ringwald  * \param ul_addr The address to be sent out.
1564*1b2596b5SMatthias Ringwald  *
1565*1b2596b5SMatthias Ringwald  * \retval 0 on success.
1566*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
1567*1b2596b5SMatthias Ringwald  */
usart_send_address(Usart * p_usart,uint32_t ul_addr)1568*1b2596b5SMatthias Ringwald uint32_t usart_send_address(Usart *p_usart, uint32_t ul_addr)
1569*1b2596b5SMatthias Ringwald {
1570*1b2596b5SMatthias Ringwald 	if ((p_usart->US_MR & US_MR_PAR_MULTIDROP) != US_MR_PAR_MULTIDROP) {
1571*1b2596b5SMatthias Ringwald 		return 1;
1572*1b2596b5SMatthias Ringwald 	}
1573*1b2596b5SMatthias Ringwald 
1574*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_SENDA;
1575*1b2596b5SMatthias Ringwald 
1576*1b2596b5SMatthias Ringwald 	if (usart_write(p_usart, ul_addr)) {
1577*1b2596b5SMatthias Ringwald 		return 1;
1578*1b2596b5SMatthias Ringwald 	} else {
1579*1b2596b5SMatthias Ringwald 		return 0;
1580*1b2596b5SMatthias Ringwald 	}
1581*1b2596b5SMatthias Ringwald }
1582*1b2596b5SMatthias Ringwald 
1583*1b2596b5SMatthias Ringwald /**
1584*1b2596b5SMatthias Ringwald  * \brief Restart the receive timeout.
1585*1b2596b5SMatthias Ringwald  *
1586*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1587*1b2596b5SMatthias Ringwald  */
usart_restart_rx_timeout(Usart * p_usart)1588*1b2596b5SMatthias Ringwald void usart_restart_rx_timeout(Usart *p_usart)
1589*1b2596b5SMatthias Ringwald {
1590*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RETTO;
1591*1b2596b5SMatthias Ringwald }
1592*1b2596b5SMatthias Ringwald 
1593*1b2596b5SMatthias Ringwald #if (SAM3S || SAM4S || SAM3U || SAM4L || SAM4E)
1594*1b2596b5SMatthias Ringwald 
1595*1b2596b5SMatthias Ringwald /**
1596*1b2596b5SMatthias Ringwald  * \brief Drive the pin DTR to 0.
1597*1b2596b5SMatthias Ringwald  *
1598*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1599*1b2596b5SMatthias Ringwald  */
usart_drive_DTR_pin_low(Usart * p_usart)1600*1b2596b5SMatthias Ringwald void usart_drive_DTR_pin_low(Usart *p_usart)
1601*1b2596b5SMatthias Ringwald {
1602*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_DTREN;
1603*1b2596b5SMatthias Ringwald }
1604*1b2596b5SMatthias Ringwald 
1605*1b2596b5SMatthias Ringwald /**
1606*1b2596b5SMatthias Ringwald  * \brief Drive the pin DTR to 1.
1607*1b2596b5SMatthias Ringwald  *
1608*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1609*1b2596b5SMatthias Ringwald  */
usart_drive_DTR_pin_high(Usart * p_usart)1610*1b2596b5SMatthias Ringwald void usart_drive_DTR_pin_high(Usart *p_usart)
1611*1b2596b5SMatthias Ringwald {
1612*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_DTRDIS;
1613*1b2596b5SMatthias Ringwald }
1614*1b2596b5SMatthias Ringwald 
1615*1b2596b5SMatthias Ringwald #endif
1616*1b2596b5SMatthias Ringwald 
1617*1b2596b5SMatthias Ringwald /**
1618*1b2596b5SMatthias Ringwald  * \brief Drive the pin RTS to 0.
1619*1b2596b5SMatthias Ringwald  *
1620*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1621*1b2596b5SMatthias Ringwald  */
usart_drive_RTS_pin_low(Usart * p_usart)1622*1b2596b5SMatthias Ringwald void usart_drive_RTS_pin_low(Usart *p_usart)
1623*1b2596b5SMatthias Ringwald {
1624*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RTSEN;
1625*1b2596b5SMatthias Ringwald }
1626*1b2596b5SMatthias Ringwald 
1627*1b2596b5SMatthias Ringwald /**
1628*1b2596b5SMatthias Ringwald  * \brief Drive the pin RTS to 1.
1629*1b2596b5SMatthias Ringwald  *
1630*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1631*1b2596b5SMatthias Ringwald  */
usart_drive_RTS_pin_high(Usart * p_usart)1632*1b2596b5SMatthias Ringwald void usart_drive_RTS_pin_high(Usart *p_usart)
1633*1b2596b5SMatthias Ringwald {
1634*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RTSDIS;
1635*1b2596b5SMatthias Ringwald }
1636*1b2596b5SMatthias Ringwald 
1637*1b2596b5SMatthias Ringwald /**
1638*1b2596b5SMatthias Ringwald  * \brief Drive the slave select line NSS (RTS pin) to 0 in SPI master mode.
1639*1b2596b5SMatthias Ringwald  *
1640*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1641*1b2596b5SMatthias Ringwald  */
usart_spi_force_chip_select(Usart * p_usart)1642*1b2596b5SMatthias Ringwald void usart_spi_force_chip_select(Usart *p_usart)
1643*1b2596b5SMatthias Ringwald {
1644*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_FCS;
1645*1b2596b5SMatthias Ringwald }
1646*1b2596b5SMatthias Ringwald 
1647*1b2596b5SMatthias Ringwald /**
1648*1b2596b5SMatthias Ringwald  * \brief Drive the slave select line NSS (RTS pin) to 1 in SPI master mode.
1649*1b2596b5SMatthias Ringwald  *
1650*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1651*1b2596b5SMatthias Ringwald  */
usart_spi_release_chip_select(Usart * p_usart)1652*1b2596b5SMatthias Ringwald void usart_spi_release_chip_select(Usart *p_usart)
1653*1b2596b5SMatthias Ringwald {
1654*1b2596b5SMatthias Ringwald 	p_usart->US_CR = US_CR_RCS;
1655*1b2596b5SMatthias Ringwald }
1656*1b2596b5SMatthias Ringwald 
1657*1b2596b5SMatthias Ringwald /**
1658*1b2596b5SMatthias Ringwald  * \brief Check if Transmit is Ready.
1659*1b2596b5SMatthias Ringwald  * Check if data have been loaded in USART_THR and are waiting to be loaded
1660*1b2596b5SMatthias Ringwald  * into the Transmit Shift Register (TSR).
1661*1b2596b5SMatthias Ringwald  *
1662*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1663*1b2596b5SMatthias Ringwald  *
1664*1b2596b5SMatthias Ringwald  * \retval 1 No data is in the Transmit Holding Register.
1665*1b2596b5SMatthias Ringwald  * \retval 0 There is data in the Transmit Holding Register.
1666*1b2596b5SMatthias Ringwald  */
usart_is_tx_ready(Usart * p_usart)1667*1b2596b5SMatthias Ringwald uint32_t usart_is_tx_ready(Usart *p_usart)
1668*1b2596b5SMatthias Ringwald {
1669*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_TXRDY) > 0;
1670*1b2596b5SMatthias Ringwald }
1671*1b2596b5SMatthias Ringwald 
1672*1b2596b5SMatthias Ringwald /**
1673*1b2596b5SMatthias Ringwald  * \brief Check if Transmit Holding Register is empty.
1674*1b2596b5SMatthias Ringwald  * Check if the last data written in USART_THR have been loaded in TSR and the
1675*1b2596b5SMatthias Ringwald  * last data loaded in TSR have been transmitted.
1676*1b2596b5SMatthias Ringwald  *
1677*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1678*1b2596b5SMatthias Ringwald  *
1679*1b2596b5SMatthias Ringwald  * \retval 1 Transmitter is empty.
1680*1b2596b5SMatthias Ringwald  * \retval 0 Transmitter is not empty.
1681*1b2596b5SMatthias Ringwald  */
usart_is_tx_empty(Usart * p_usart)1682*1b2596b5SMatthias Ringwald uint32_t usart_is_tx_empty(Usart *p_usart)
1683*1b2596b5SMatthias Ringwald {
1684*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_TXEMPTY) > 0;
1685*1b2596b5SMatthias Ringwald }
1686*1b2596b5SMatthias Ringwald 
1687*1b2596b5SMatthias Ringwald /**
1688*1b2596b5SMatthias Ringwald  * \brief Check if the received data are ready.
1689*1b2596b5SMatthias Ringwald  * Check if Data have been received and loaded into USART_RHR.
1690*1b2596b5SMatthias Ringwald  *
1691*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1692*1b2596b5SMatthias Ringwald  *
1693*1b2596b5SMatthias Ringwald  * \retval 1 Some data has been received.
1694*1b2596b5SMatthias Ringwald  * \retval 0 No data has been received.
1695*1b2596b5SMatthias Ringwald  */
usart_is_rx_ready(Usart * p_usart)1696*1b2596b5SMatthias Ringwald uint32_t usart_is_rx_ready(Usart *p_usart)
1697*1b2596b5SMatthias Ringwald {
1698*1b2596b5SMatthias Ringwald 	return (p_usart->US_CSR & US_CSR_RXRDY) > 0;
1699*1b2596b5SMatthias Ringwald }
1700*1b2596b5SMatthias Ringwald 
1701*1b2596b5SMatthias Ringwald /**
1702*1b2596b5SMatthias Ringwald  * \brief Write to USART Transmit Holding Register.
1703*1b2596b5SMatthias Ringwald  *
1704*1b2596b5SMatthias Ringwald  * \note Before writing user should check if tx is ready (or empty).
1705*1b2596b5SMatthias Ringwald  *
1706*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1707*1b2596b5SMatthias Ringwald  * \param c Data to be sent.
1708*1b2596b5SMatthias Ringwald  *
1709*1b2596b5SMatthias Ringwald  * \retval 0 on success.
1710*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
1711*1b2596b5SMatthias Ringwald  */
usart_write(Usart * p_usart,uint32_t c)1712*1b2596b5SMatthias Ringwald uint32_t usart_write(Usart *p_usart, uint32_t c)
1713*1b2596b5SMatthias Ringwald {
1714*1b2596b5SMatthias Ringwald 	if (!(p_usart->US_CSR & US_CSR_TXRDY)) {
1715*1b2596b5SMatthias Ringwald 		return 1;
1716*1b2596b5SMatthias Ringwald 	}
1717*1b2596b5SMatthias Ringwald 
1718*1b2596b5SMatthias Ringwald 	p_usart->US_THR = US_THR_TXCHR(c);
1719*1b2596b5SMatthias Ringwald 	return 0;
1720*1b2596b5SMatthias Ringwald }
1721*1b2596b5SMatthias Ringwald 
1722*1b2596b5SMatthias Ringwald /**
1723*1b2596b5SMatthias Ringwald  * \brief Write to USART Transmit Holding Register.
1724*1b2596b5SMatthias Ringwald  *
1725*1b2596b5SMatthias Ringwald  * \note Before writing user should check if tx is ready (or empty).
1726*1b2596b5SMatthias Ringwald  *
1727*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1728*1b2596b5SMatthias Ringwald  * \param c Data to be sent.
1729*1b2596b5SMatthias Ringwald  *
1730*1b2596b5SMatthias Ringwald  * \retval 0 on success.
1731*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
1732*1b2596b5SMatthias Ringwald  */
usart_putchar(Usart * p_usart,uint32_t c)1733*1b2596b5SMatthias Ringwald uint32_t usart_putchar(Usart *p_usart, uint32_t c)
1734*1b2596b5SMatthias Ringwald {
1735*1b2596b5SMatthias Ringwald 	while (!(p_usart->US_CSR & US_CSR_TXRDY)) {
1736*1b2596b5SMatthias Ringwald 	}
1737*1b2596b5SMatthias Ringwald 
1738*1b2596b5SMatthias Ringwald 	p_usart->US_THR = US_THR_TXCHR(c);
1739*1b2596b5SMatthias Ringwald 
1740*1b2596b5SMatthias Ringwald 	return 0;
1741*1b2596b5SMatthias Ringwald }
1742*1b2596b5SMatthias Ringwald 
1743*1b2596b5SMatthias Ringwald /**
1744*1b2596b5SMatthias Ringwald  * \brief Write one-line string through USART.
1745*1b2596b5SMatthias Ringwald  *
1746*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1747*1b2596b5SMatthias Ringwald  * \param string Pointer to one-line string to be sent.
1748*1b2596b5SMatthias Ringwald  */
usart_write_line(Usart * p_usart,const char * string)1749*1b2596b5SMatthias Ringwald void usart_write_line(Usart *p_usart, const char *string)
1750*1b2596b5SMatthias Ringwald {
1751*1b2596b5SMatthias Ringwald 	while (*string != '\0') {
1752*1b2596b5SMatthias Ringwald 		usart_putchar(p_usart, *string++);
1753*1b2596b5SMatthias Ringwald 	}
1754*1b2596b5SMatthias Ringwald }
1755*1b2596b5SMatthias Ringwald 
1756*1b2596b5SMatthias Ringwald /**
1757*1b2596b5SMatthias Ringwald  * \brief Read from USART Receive Holding Register.
1758*1b2596b5SMatthias Ringwald  *
1759*1b2596b5SMatthias Ringwald  * \note Before reading user should check if rx is ready.
1760*1b2596b5SMatthias Ringwald  *
1761*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1762*1b2596b5SMatthias Ringwald  * \param c Pointer where the one-byte received data will be stored.
1763*1b2596b5SMatthias Ringwald  *
1764*1b2596b5SMatthias Ringwald  * \retval 0 on success.
1765*1b2596b5SMatthias Ringwald  * \retval 1 if no data is available or errors.
1766*1b2596b5SMatthias Ringwald  */
usart_read(Usart * p_usart,uint32_t * c)1767*1b2596b5SMatthias Ringwald uint32_t usart_read(Usart *p_usart, uint32_t *c)
1768*1b2596b5SMatthias Ringwald {
1769*1b2596b5SMatthias Ringwald 	if (!(p_usart->US_CSR & US_CSR_RXRDY)) {
1770*1b2596b5SMatthias Ringwald 		return 1;
1771*1b2596b5SMatthias Ringwald 	}
1772*1b2596b5SMatthias Ringwald 
1773*1b2596b5SMatthias Ringwald 	/* Read character */
1774*1b2596b5SMatthias Ringwald 	*c = p_usart->US_RHR & US_RHR_RXCHR_Msk;
1775*1b2596b5SMatthias Ringwald 
1776*1b2596b5SMatthias Ringwald 	return 0;
1777*1b2596b5SMatthias Ringwald }
1778*1b2596b5SMatthias Ringwald 
1779*1b2596b5SMatthias Ringwald /**
1780*1b2596b5SMatthias Ringwald  * \brief Read from USART Receive Holding Register.
1781*1b2596b5SMatthias Ringwald  * Before reading user should check if rx is ready.
1782*1b2596b5SMatthias Ringwald  *
1783*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1784*1b2596b5SMatthias Ringwald  * \param c Pointer where the one-byte received data will be stored.
1785*1b2596b5SMatthias Ringwald  *
1786*1b2596b5SMatthias Ringwald  * \retval 0 Data has been received.
1787*1b2596b5SMatthias Ringwald  * \retval 1 on failure.
1788*1b2596b5SMatthias Ringwald  */
usart_getchar(Usart * p_usart,uint32_t * c)1789*1b2596b5SMatthias Ringwald uint32_t usart_getchar(Usart *p_usart, uint32_t *c)
1790*1b2596b5SMatthias Ringwald {
1791*1b2596b5SMatthias Ringwald 	/* Wait until it's not empty or timeout has reached. */
1792*1b2596b5SMatthias Ringwald 	while (!(p_usart->US_CSR & US_CSR_RXRDY)) {
1793*1b2596b5SMatthias Ringwald 	}
1794*1b2596b5SMatthias Ringwald 
1795*1b2596b5SMatthias Ringwald 	/* Read character */
1796*1b2596b5SMatthias Ringwald 	*c = p_usart->US_RHR & US_RHR_RXCHR_Msk;
1797*1b2596b5SMatthias Ringwald 
1798*1b2596b5SMatthias Ringwald 	return 0;
1799*1b2596b5SMatthias Ringwald }
1800*1b2596b5SMatthias Ringwald 
1801*1b2596b5SMatthias Ringwald #if (SAM3XA || SAM3U)
1802*1b2596b5SMatthias Ringwald /**
1803*1b2596b5SMatthias Ringwald  * \brief Get Transmit address for DMA operation.
1804*1b2596b5SMatthias Ringwald  *
1805*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1806*1b2596b5SMatthias Ringwald  *
1807*1b2596b5SMatthias Ringwald  * \return Transmit address for DMA access.
1808*1b2596b5SMatthias Ringwald  */
usart_get_tx_access(Usart * p_usart)1809*1b2596b5SMatthias Ringwald uint32_t *usart_get_tx_access(Usart *p_usart)
1810*1b2596b5SMatthias Ringwald {
1811*1b2596b5SMatthias Ringwald 	return (uint32_t *)&(p_usart->US_THR);
1812*1b2596b5SMatthias Ringwald }
1813*1b2596b5SMatthias Ringwald 
1814*1b2596b5SMatthias Ringwald /**
1815*1b2596b5SMatthias Ringwald  * \brief Get Receive address for DMA operation.
1816*1b2596b5SMatthias Ringwald  *
1817*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1818*1b2596b5SMatthias Ringwald  *
1819*1b2596b5SMatthias Ringwald  * \return Receive address for DMA access.
1820*1b2596b5SMatthias Ringwald  */
usart_get_rx_access(Usart * p_usart)1821*1b2596b5SMatthias Ringwald uint32_t *usart_get_rx_access(Usart *p_usart)
1822*1b2596b5SMatthias Ringwald {
1823*1b2596b5SMatthias Ringwald 	return (uint32_t *)&(p_usart->US_RHR);
1824*1b2596b5SMatthias Ringwald }
1825*1b2596b5SMatthias Ringwald #endif
1826*1b2596b5SMatthias Ringwald 
1827*1b2596b5SMatthias Ringwald #if (!SAM4L && !SAMV71 && !SAMV70 && !SAME70 && !SAMS70)
1828*1b2596b5SMatthias Ringwald /**
1829*1b2596b5SMatthias Ringwald  * \brief Get USART PDC base address.
1830*1b2596b5SMatthias Ringwald  *
1831*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a UART instance.
1832*1b2596b5SMatthias Ringwald  *
1833*1b2596b5SMatthias Ringwald  * \return USART PDC registers base for PDC driver to access.
1834*1b2596b5SMatthias Ringwald  */
usart_get_pdc_base(Usart * p_usart)1835*1b2596b5SMatthias Ringwald Pdc *usart_get_pdc_base(Usart *p_usart)
1836*1b2596b5SMatthias Ringwald {
1837*1b2596b5SMatthias Ringwald 	Pdc *p_pdc_base;
1838*1b2596b5SMatthias Ringwald 
1839*1b2596b5SMatthias Ringwald 	p_pdc_base = (Pdc *)NULL;
1840*1b2596b5SMatthias Ringwald 
1841*1b2596b5SMatthias Ringwald #ifdef PDC_USART
1842*1b2596b5SMatthias Ringwald 	if (p_usart == USART) {
1843*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART;
1844*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1845*1b2596b5SMatthias Ringwald 	}
1846*1b2596b5SMatthias Ringwald #endif
1847*1b2596b5SMatthias Ringwald #ifdef PDC_USART0
1848*1b2596b5SMatthias Ringwald 	if (p_usart == USART0) {
1849*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART0;
1850*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1851*1b2596b5SMatthias Ringwald 	}
1852*1b2596b5SMatthias Ringwald #endif
1853*1b2596b5SMatthias Ringwald #ifdef PDC_USART1
1854*1b2596b5SMatthias Ringwald 	else if (p_usart == USART1) {
1855*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART1;
1856*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1857*1b2596b5SMatthias Ringwald 	}
1858*1b2596b5SMatthias Ringwald #endif
1859*1b2596b5SMatthias Ringwald #ifdef PDC_USART2
1860*1b2596b5SMatthias Ringwald 	else if (p_usart == USART2) {
1861*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART2;
1862*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1863*1b2596b5SMatthias Ringwald 	}
1864*1b2596b5SMatthias Ringwald #endif
1865*1b2596b5SMatthias Ringwald #ifdef PDC_USART3
1866*1b2596b5SMatthias Ringwald 	else if (p_usart == USART3) {
1867*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART3;
1868*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1869*1b2596b5SMatthias Ringwald 	}
1870*1b2596b5SMatthias Ringwald #endif
1871*1b2596b5SMatthias Ringwald #ifdef PDC_USART4
1872*1b2596b5SMatthias Ringwald 	else if (p_usart == USART4) {
1873*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART4;
1874*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1875*1b2596b5SMatthias Ringwald 	}
1876*1b2596b5SMatthias Ringwald #endif
1877*1b2596b5SMatthias Ringwald #ifdef PDC_USART5
1878*1b2596b5SMatthias Ringwald 	else if (p_usart == USART5) {
1879*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART5;
1880*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1881*1b2596b5SMatthias Ringwald 	}
1882*1b2596b5SMatthias Ringwald #endif
1883*1b2596b5SMatthias Ringwald #ifdef PDC_USART6
1884*1b2596b5SMatthias Ringwald 	else if (p_usart == USART6) {
1885*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART6;
1886*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1887*1b2596b5SMatthias Ringwald 	}
1888*1b2596b5SMatthias Ringwald #endif
1889*1b2596b5SMatthias Ringwald #ifdef PDC_USART7
1890*1b2596b5SMatthias Ringwald 	else if (p_usart == USART7) {
1891*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_USART7;
1892*1b2596b5SMatthias Ringwald 		return p_pdc_base;
1893*1b2596b5SMatthias Ringwald 	}
1894*1b2596b5SMatthias Ringwald #endif
1895*1b2596b5SMatthias Ringwald 
1896*1b2596b5SMatthias Ringwald 	return p_pdc_base;
1897*1b2596b5SMatthias Ringwald }
1898*1b2596b5SMatthias Ringwald #endif
1899*1b2596b5SMatthias Ringwald 
1900*1b2596b5SMatthias Ringwald /**
1901*1b2596b5SMatthias Ringwald  * \brief Enable write protect of USART registers.
1902*1b2596b5SMatthias Ringwald  *
1903*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1904*1b2596b5SMatthias Ringwald  */
usart_enable_writeprotect(Usart * p_usart)1905*1b2596b5SMatthias Ringwald void usart_enable_writeprotect(Usart *p_usart)
1906*1b2596b5SMatthias Ringwald {
1907*1b2596b5SMatthias Ringwald 	p_usart->US_WPMR = US_WPMR_WPEN | US_WPMR_WPKEY_PASSWD;
1908*1b2596b5SMatthias Ringwald }
1909*1b2596b5SMatthias Ringwald 
1910*1b2596b5SMatthias Ringwald /**
1911*1b2596b5SMatthias Ringwald  * \brief Disable write protect of USART registers.
1912*1b2596b5SMatthias Ringwald  *
1913*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1914*1b2596b5SMatthias Ringwald  */
usart_disable_writeprotect(Usart * p_usart)1915*1b2596b5SMatthias Ringwald void usart_disable_writeprotect(Usart *p_usart)
1916*1b2596b5SMatthias Ringwald {
1917*1b2596b5SMatthias Ringwald 	p_usart->US_WPMR = US_WPMR_WPKEY_PASSWD;
1918*1b2596b5SMatthias Ringwald }
1919*1b2596b5SMatthias Ringwald 
1920*1b2596b5SMatthias Ringwald /**
1921*1b2596b5SMatthias Ringwald  * \brief Get write protect status.
1922*1b2596b5SMatthias Ringwald  *
1923*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1924*1b2596b5SMatthias Ringwald  *
1925*1b2596b5SMatthias Ringwald  * \return 0 if no write protect violation occurred, or 16-bit write protect
1926*1b2596b5SMatthias Ringwald  * violation source.
1927*1b2596b5SMatthias Ringwald  */
usart_get_writeprotect_status(Usart * p_usart)1928*1b2596b5SMatthias Ringwald uint32_t usart_get_writeprotect_status(Usart *p_usart)
1929*1b2596b5SMatthias Ringwald {
1930*1b2596b5SMatthias Ringwald 	uint32_t reg_value;
1931*1b2596b5SMatthias Ringwald 
1932*1b2596b5SMatthias Ringwald 	reg_value = p_usart->US_WPSR;
1933*1b2596b5SMatthias Ringwald 	if (reg_value & US_WPSR_WPVS) {
1934*1b2596b5SMatthias Ringwald 		return (reg_value & US_WPSR_WPVSRC_Msk) >> US_WPSR_WPVSRC_Pos;
1935*1b2596b5SMatthias Ringwald 	} else {
1936*1b2596b5SMatthias Ringwald 		return 0;
1937*1b2596b5SMatthias Ringwald 	}
1938*1b2596b5SMatthias Ringwald }
1939*1b2596b5SMatthias Ringwald 
1940*1b2596b5SMatthias Ringwald #if (SAM3S || SAM4S || SAM3U || SAM3XA || SAM4L || SAM4E || SAM4C || SAM4CP || SAM4CM)
1941*1b2596b5SMatthias Ringwald 
1942*1b2596b5SMatthias Ringwald /**
1943*1b2596b5SMatthias Ringwald  * \brief Configure the transmitter preamble length when the Manchester
1944*1b2596b5SMatthias Ringwald  * encode/decode is enabled.
1945*1b2596b5SMatthias Ringwald  *
1946*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1947*1b2596b5SMatthias Ringwald  * \param uc_len The transmitter preamble length, which should be 0 ~ 15.
1948*1b2596b5SMatthias Ringwald  */
usart_man_set_tx_pre_len(Usart * p_usart,uint8_t uc_len)1949*1b2596b5SMatthias Ringwald void usart_man_set_tx_pre_len(Usart *p_usart, uint8_t uc_len)
1950*1b2596b5SMatthias Ringwald {
1951*1b2596b5SMatthias Ringwald 	p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PL_Msk) |
1952*1b2596b5SMatthias Ringwald 			US_MAN_TX_PL(uc_len);
1953*1b2596b5SMatthias Ringwald }
1954*1b2596b5SMatthias Ringwald 
1955*1b2596b5SMatthias Ringwald /**
1956*1b2596b5SMatthias Ringwald  * \brief Configure the transmitter preamble pattern when the Manchester
1957*1b2596b5SMatthias Ringwald  * encode/decode is enabled, which should be 0 ~ 3.
1958*1b2596b5SMatthias Ringwald  *
1959*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1960*1b2596b5SMatthias Ringwald  * \param uc_pattern 0 if the preamble is composed of '1's;
1961*1b2596b5SMatthias Ringwald  * 1 if the preamble is composed of '0's;
1962*1b2596b5SMatthias Ringwald  * 2 if the preamble is composed of '01's;
1963*1b2596b5SMatthias Ringwald  * 3 if the preamble is composed of '10's.
1964*1b2596b5SMatthias Ringwald  */
usart_man_set_tx_pre_pattern(Usart * p_usart,uint8_t uc_pattern)1965*1b2596b5SMatthias Ringwald void usart_man_set_tx_pre_pattern(Usart *p_usart, uint8_t uc_pattern)
1966*1b2596b5SMatthias Ringwald {
1967*1b2596b5SMatthias Ringwald 	p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PP_Msk) |
1968*1b2596b5SMatthias Ringwald 			(uc_pattern << US_MAN_TX_PP_Pos);
1969*1b2596b5SMatthias Ringwald }
1970*1b2596b5SMatthias Ringwald 
1971*1b2596b5SMatthias Ringwald /**
1972*1b2596b5SMatthias Ringwald  * \brief Configure the transmitter Manchester polarity when the Manchester
1973*1b2596b5SMatthias Ringwald  * encode/decode is enabled.
1974*1b2596b5SMatthias Ringwald  *
1975*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1976*1b2596b5SMatthias Ringwald  * \param uc_polarity Indicate the transmitter Manchester polarity, which
1977*1b2596b5SMatthias Ringwald  * should be 0 or 1.
1978*1b2596b5SMatthias Ringwald  */
usart_man_set_tx_polarity(Usart * p_usart,uint8_t uc_polarity)1979*1b2596b5SMatthias Ringwald void usart_man_set_tx_polarity(Usart *p_usart, uint8_t uc_polarity)
1980*1b2596b5SMatthias Ringwald {
1981*1b2596b5SMatthias Ringwald 	p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_MPOL) |
1982*1b2596b5SMatthias Ringwald 			(uc_polarity << 12);
1983*1b2596b5SMatthias Ringwald }
1984*1b2596b5SMatthias Ringwald 
1985*1b2596b5SMatthias Ringwald /**
1986*1b2596b5SMatthias Ringwald  * \brief Configure the detected receiver preamble length when the Manchester
1987*1b2596b5SMatthias Ringwald  * encode/decode is enabled.
1988*1b2596b5SMatthias Ringwald  *
1989*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
1990*1b2596b5SMatthias Ringwald  * \param uc_len The detected receiver preamble length, which should be 0 ~ 15.
1991*1b2596b5SMatthias Ringwald  */
usart_man_set_rx_pre_len(Usart * p_usart,uint8_t uc_len)1992*1b2596b5SMatthias Ringwald void usart_man_set_rx_pre_len(Usart *p_usart, uint8_t uc_len)
1993*1b2596b5SMatthias Ringwald {
1994*1b2596b5SMatthias Ringwald 	p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PL_Msk) |
1995*1b2596b5SMatthias Ringwald 			US_MAN_RX_PL(uc_len);
1996*1b2596b5SMatthias Ringwald }
1997*1b2596b5SMatthias Ringwald 
1998*1b2596b5SMatthias Ringwald /**
1999*1b2596b5SMatthias Ringwald  * \brief Configure the detected receiver preamble pattern when the Manchester
2000*1b2596b5SMatthias Ringwald  *  encode/decode is enabled, which should be 0 ~ 3.
2001*1b2596b5SMatthias Ringwald  *
2002*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
2003*1b2596b5SMatthias Ringwald  * \param uc_pattern 0 if the preamble is composed of '1's;
2004*1b2596b5SMatthias Ringwald  * 1 if the preamble is composed of '0's;
2005*1b2596b5SMatthias Ringwald  * 2 if the preamble is composed of '01's;
2006*1b2596b5SMatthias Ringwald  * 3 if the preamble is composed of '10's.
2007*1b2596b5SMatthias Ringwald  */
usart_man_set_rx_pre_pattern(Usart * p_usart,uint8_t uc_pattern)2008*1b2596b5SMatthias Ringwald void usart_man_set_rx_pre_pattern(Usart *p_usart, uint8_t uc_pattern)
2009*1b2596b5SMatthias Ringwald {
2010*1b2596b5SMatthias Ringwald 	p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PP_Msk) |
2011*1b2596b5SMatthias Ringwald 			(uc_pattern << US_MAN_RX_PP_Pos);
2012*1b2596b5SMatthias Ringwald }
2013*1b2596b5SMatthias Ringwald 
2014*1b2596b5SMatthias Ringwald /**
2015*1b2596b5SMatthias Ringwald  * \brief Configure the receiver Manchester polarity when the Manchester
2016*1b2596b5SMatthias Ringwald  * encode/decode is enabled.
2017*1b2596b5SMatthias Ringwald  *
2018*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
2019*1b2596b5SMatthias Ringwald  * \param uc_polarity Indicate the receiver Manchester polarity, which should
2020*1b2596b5SMatthias Ringwald  * be 0 or 1.
2021*1b2596b5SMatthias Ringwald  */
usart_man_set_rx_polarity(Usart * p_usart,uint8_t uc_polarity)2022*1b2596b5SMatthias Ringwald void usart_man_set_rx_polarity(Usart *p_usart, uint8_t uc_polarity)
2023*1b2596b5SMatthias Ringwald {
2024*1b2596b5SMatthias Ringwald 	p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_MPOL) |
2025*1b2596b5SMatthias Ringwald 			(uc_polarity << 28);
2026*1b2596b5SMatthias Ringwald }
2027*1b2596b5SMatthias Ringwald 
2028*1b2596b5SMatthias Ringwald /**
2029*1b2596b5SMatthias Ringwald  * \brief Enable drift compensation.
2030*1b2596b5SMatthias Ringwald  *
2031*1b2596b5SMatthias Ringwald  * \note The 16X clock mode must be enabled.
2032*1b2596b5SMatthias Ringwald  *
2033*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
2034*1b2596b5SMatthias Ringwald  */
usart_man_enable_drift_compensation(Usart * p_usart)2035*1b2596b5SMatthias Ringwald void usart_man_enable_drift_compensation(Usart *p_usart)
2036*1b2596b5SMatthias Ringwald {
2037*1b2596b5SMatthias Ringwald 	p_usart->US_MAN |= US_MAN_DRIFT;
2038*1b2596b5SMatthias Ringwald }
2039*1b2596b5SMatthias Ringwald 
2040*1b2596b5SMatthias Ringwald /**
2041*1b2596b5SMatthias Ringwald  * \brief Disable drift compensation.
2042*1b2596b5SMatthias Ringwald  *
2043*1b2596b5SMatthias Ringwald  * \param p_usart Pointer to a USART instance.
2044*1b2596b5SMatthias Ringwald  */
usart_man_disable_drift_compensation(Usart * p_usart)2045*1b2596b5SMatthias Ringwald void usart_man_disable_drift_compensation(Usart *p_usart)
2046*1b2596b5SMatthias Ringwald {
2047*1b2596b5SMatthias Ringwald 	p_usart->US_MAN &= ~US_MAN_DRIFT;
2048*1b2596b5SMatthias Ringwald }
2049*1b2596b5SMatthias Ringwald 
2050*1b2596b5SMatthias Ringwald #endif
2051*1b2596b5SMatthias Ringwald 
2052*1b2596b5SMatthias Ringwald #if SAM4L
2053*1b2596b5SMatthias Ringwald 
usart_get_version(Usart * p_usart)2054*1b2596b5SMatthias Ringwald uint32_t usart_get_version(Usart *p_usart)
2055*1b2596b5SMatthias Ringwald {
2056*1b2596b5SMatthias Ringwald 	return p_usart->US_VERSION;
2057*1b2596b5SMatthias Ringwald }
2058*1b2596b5SMatthias Ringwald 
2059*1b2596b5SMatthias Ringwald #endif
2060*1b2596b5SMatthias Ringwald 
2061*1b2596b5SMatthias Ringwald #if SAMG55
2062*1b2596b5SMatthias Ringwald /**
2063*1b2596b5SMatthias Ringwald  * \brief Set sleepwalking match mode.
2064*1b2596b5SMatthias Ringwald  *
2065*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a USART instance.
2066*1b2596b5SMatthias Ringwald  * \param ul_low_value First comparison value for received character.
2067*1b2596b5SMatthias Ringwald  * \param ul_high_value Second comparison value for received character.
2068*1b2596b5SMatthias Ringwald  * \param cmpmode ture for start condition, false for flag only.
2069*1b2596b5SMatthias Ringwald  * \param cmppar ture for parity check, false for no.
2070*1b2596b5SMatthias Ringwald  */
usart_set_sleepwalking(Usart * p_uart,uint8_t ul_low_value,bool cmpmode,bool cmppar,uint8_t ul_high_value)2071*1b2596b5SMatthias Ringwald void usart_set_sleepwalking(Usart *p_uart, uint8_t ul_low_value,
2072*1b2596b5SMatthias Ringwald 		bool cmpmode, bool cmppar, uint8_t ul_high_value)
2073*1b2596b5SMatthias Ringwald {
2074*1b2596b5SMatthias Ringwald 	Assert(ul_low_value <= ul_high_value);
2075*1b2596b5SMatthias Ringwald 
2076*1b2596b5SMatthias Ringwald 	uint32_t temp = 0;
2077*1b2596b5SMatthias Ringwald 
2078*1b2596b5SMatthias Ringwald 	if (cmpmode) {
2079*1b2596b5SMatthias Ringwald 		temp |= US_CMPR_CMPMODE_START_CONDITION;
2080*1b2596b5SMatthias Ringwald 	}
2081*1b2596b5SMatthias Ringwald 
2082*1b2596b5SMatthias Ringwald 	if (cmppar) {
2083*1b2596b5SMatthias Ringwald 		temp |= US_CMPR_CMPPAR;
2084*1b2596b5SMatthias Ringwald 	}
2085*1b2596b5SMatthias Ringwald 
2086*1b2596b5SMatthias Ringwald 	temp |= US_CMPR_VAL1(ul_low_value);
2087*1b2596b5SMatthias Ringwald 
2088*1b2596b5SMatthias Ringwald 	temp |= US_CMPR_VAL2(ul_high_value);
2089*1b2596b5SMatthias Ringwald 
2090*1b2596b5SMatthias Ringwald 	p_uart->US_CMPR= temp;
2091*1b2596b5SMatthias Ringwald }
2092*1b2596b5SMatthias Ringwald #endif
2093*1b2596b5SMatthias Ringwald 
2094*1b2596b5SMatthias Ringwald //@}
2095*1b2596b5SMatthias Ringwald 
2096*1b2596b5SMatthias Ringwald /// @cond 0
2097*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
2098*1b2596b5SMatthias Ringwald #ifdef __cplusplus
2099*1b2596b5SMatthias Ringwald }
2100*1b2596b5SMatthias Ringwald #endif
2101*1b2596b5SMatthias Ringwald /**INDENT-ON**/
2102*1b2596b5SMatthias Ringwald /// @endcond
2103