xref: /btstack/port/samv71-xplained-atwilc3000/ASF/sam/drivers/uart/uart.c (revision 1b2596b5303dd8caeea8565532c93cca8dab8cc4)
1*1b2596b5SMatthias Ringwald /**
2*1b2596b5SMatthias Ringwald  * \file
3*1b2596b5SMatthias Ringwald  *
4*1b2596b5SMatthias Ringwald  * \brief Universal Asynchronous Receiver Transceiver (UART) driver for SAM.
5*1b2596b5SMatthias Ringwald  *
6*1b2596b5SMatthias Ringwald  * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
7*1b2596b5SMatthias Ringwald  *
8*1b2596b5SMatthias Ringwald  * \asf_license_start
9*1b2596b5SMatthias Ringwald  *
10*1b2596b5SMatthias Ringwald  * \page License
11*1b2596b5SMatthias Ringwald  *
12*1b2596b5SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
13*1b2596b5SMatthias Ringwald  * modification, are permitted provided that the following conditions are met:
14*1b2596b5SMatthias Ringwald  *
15*1b2596b5SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright notice,
16*1b2596b5SMatthias Ringwald  *    this list of conditions and the following disclaimer.
17*1b2596b5SMatthias Ringwald  *
18*1b2596b5SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright notice,
19*1b2596b5SMatthias Ringwald  *    this list of conditions and the following disclaimer in the documentation
20*1b2596b5SMatthias Ringwald  *    and/or other materials provided with the distribution.
21*1b2596b5SMatthias Ringwald  *
22*1b2596b5SMatthias Ringwald  * 3. The name of Atmel may not be used to endorse or promote products derived
23*1b2596b5SMatthias Ringwald  *    from this software without specific prior written permission.
24*1b2596b5SMatthias Ringwald  *
25*1b2596b5SMatthias Ringwald  * 4. This software may only be redistributed and used in connection with an
26*1b2596b5SMatthias Ringwald  *    Atmel microcontroller product.
27*1b2596b5SMatthias Ringwald  *
28*1b2596b5SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29*1b2596b5SMatthias Ringwald  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30*1b2596b5SMatthias Ringwald  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31*1b2596b5SMatthias Ringwald  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32*1b2596b5SMatthias Ringwald  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33*1b2596b5SMatthias Ringwald  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34*1b2596b5SMatthias Ringwald  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35*1b2596b5SMatthias Ringwald  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36*1b2596b5SMatthias Ringwald  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37*1b2596b5SMatthias Ringwald  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38*1b2596b5SMatthias Ringwald  * POSSIBILITY OF SUCH DAMAGE.
39*1b2596b5SMatthias Ringwald  *
40*1b2596b5SMatthias Ringwald  * \asf_license_stop
41*1b2596b5SMatthias Ringwald  *
42*1b2596b5SMatthias Ringwald  */
43*1b2596b5SMatthias Ringwald /*
44*1b2596b5SMatthias Ringwald  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45*1b2596b5SMatthias Ringwald  */
46*1b2596b5SMatthias Ringwald 
47*1b2596b5SMatthias Ringwald #include "uart.h"
48*1b2596b5SMatthias Ringwald 
49*1b2596b5SMatthias Ringwald /// @cond 0
50*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
51*1b2596b5SMatthias Ringwald #ifdef __cplusplus
52*1b2596b5SMatthias Ringwald extern "C" {
53*1b2596b5SMatthias Ringwald #endif
54*1b2596b5SMatthias Ringwald /**INDENT-ON**/
55*1b2596b5SMatthias Ringwald /// @endcond
56*1b2596b5SMatthias Ringwald 
57*1b2596b5SMatthias Ringwald /**
58*1b2596b5SMatthias Ringwald  * \defgroup sam_drivers_uart_group Universal Asynchronous Receiver Transceiver (UART)
59*1b2596b5SMatthias Ringwald  *
60*1b2596b5SMatthias Ringwald  * The Universal Asynchronous Receiver Transmitter features a two-pin UART that
61*1b2596b5SMatthias Ringwald  * can be used for communication and trace purposes and offers an ideal medium
62*1b2596b5SMatthias Ringwald  * for in-situ programming solutions. Moreover, the association with two
63*1b2596b5SMatthias Ringwald  * peripheral DMA controller (PDC) channels permits packet handling for these
64*1b2596b5SMatthias Ringwald  * tasks with processor time reduced to a minimum.
65*1b2596b5SMatthias Ringwald  *
66*1b2596b5SMatthias Ringwald  * \par Usage
67*1b2596b5SMatthias Ringwald  *
68*1b2596b5SMatthias Ringwald  * -# Enable the UART peripheral clock in the PMC.
69*1b2596b5SMatthias Ringwald  * -# Enable the required UART PIOs (see pio.h).
70*1b2596b5SMatthias Ringwald  * -# Configure the UART by calling uart_init.
71*1b2596b5SMatthias Ringwald  * -# Send data through the UART using the uart_write.
72*1b2596b5SMatthias Ringwald  * -# Receive data from the UART using the uart_read; the availability of data
73*1b2596b5SMatthias Ringwald  *    can be polled with uart_is_rx_ready.
74*1b2596b5SMatthias Ringwald  * -# Disable the transmitter and/or the receiver of the UART with
75*1b2596b5SMatthias Ringwald  *    uart_disable_tx and uart_disable_rx.
76*1b2596b5SMatthias Ringwald  *
77*1b2596b5SMatthias Ringwald  * @{
78*1b2596b5SMatthias Ringwald  */
79*1b2596b5SMatthias Ringwald 
80*1b2596b5SMatthias Ringwald /**
81*1b2596b5SMatthias Ringwald  * \brief Configure UART with the specified parameters.
82*1b2596b5SMatthias Ringwald  *
83*1b2596b5SMatthias Ringwald  * \note The PMC and PIOs must be configured first.
84*1b2596b5SMatthias Ringwald  *
85*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
86*1b2596b5SMatthias Ringwald  * \param p_uart_opt Pointer to sam_uart_opt_t instance.
87*1b2596b5SMatthias Ringwald  *
88*1b2596b5SMatthias Ringwald  * \retval 0 Success.
89*1b2596b5SMatthias Ringwald  * \retval 1 Bad baud rate generator value.
90*1b2596b5SMatthias Ringwald  */
uart_init(Uart * p_uart,const sam_uart_opt_t * p_uart_opt)91*1b2596b5SMatthias Ringwald uint32_t uart_init(Uart *p_uart, const sam_uart_opt_t *p_uart_opt)
92*1b2596b5SMatthias Ringwald {
93*1b2596b5SMatthias Ringwald 	uint32_t cd = 0;
94*1b2596b5SMatthias Ringwald 
95*1b2596b5SMatthias Ringwald 	/* Reset and disable receiver & transmitter */
96*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
97*1b2596b5SMatthias Ringwald 			| UART_CR_RXDIS | UART_CR_TXDIS;
98*1b2596b5SMatthias Ringwald 
99*1b2596b5SMatthias Ringwald 	/* Check and configure baudrate */
100*1b2596b5SMatthias Ringwald 	/* Asynchronous, no oversampling */
101*1b2596b5SMatthias Ringwald 	cd = (p_uart_opt->ul_mck / p_uart_opt->ul_baudrate) / UART_MCK_DIV;
102*1b2596b5SMatthias Ringwald 	if (cd < UART_MCK_DIV_MIN_FACTOR || cd > UART_MCK_DIV_MAX_FACTOR)
103*1b2596b5SMatthias Ringwald 		return 1;
104*1b2596b5SMatthias Ringwald 
105*1b2596b5SMatthias Ringwald 	p_uart->UART_BRGR = cd;
106*1b2596b5SMatthias Ringwald 	/* Configure mode */
107*1b2596b5SMatthias Ringwald 	p_uart->UART_MR = p_uart_opt->ul_mode;
108*1b2596b5SMatthias Ringwald 
109*1b2596b5SMatthias Ringwald #if (!SAMV71 && !SAMV70 && !SAME70 && !SAMS70)
110*1b2596b5SMatthias Ringwald 	/* Disable PDC channel */
111*1b2596b5SMatthias Ringwald 	p_uart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
112*1b2596b5SMatthias Ringwald #endif
113*1b2596b5SMatthias Ringwald 
114*1b2596b5SMatthias Ringwald 	/* Enable receiver and transmitter */
115*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
116*1b2596b5SMatthias Ringwald 
117*1b2596b5SMatthias Ringwald 	return 0;
118*1b2596b5SMatthias Ringwald }
119*1b2596b5SMatthias Ringwald 
120*1b2596b5SMatthias Ringwald /**
121*1b2596b5SMatthias Ringwald  * \brief Enable UART transmitter.
122*1b2596b5SMatthias Ringwald  *
123*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
124*1b2596b5SMatthias Ringwald  */
uart_enable_tx(Uart * p_uart)125*1b2596b5SMatthias Ringwald void uart_enable_tx(Uart *p_uart)
126*1b2596b5SMatthias Ringwald {
127*1b2596b5SMatthias Ringwald 	/* Enable transmitter */
128*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_TXEN;
129*1b2596b5SMatthias Ringwald }
130*1b2596b5SMatthias Ringwald 
131*1b2596b5SMatthias Ringwald /**
132*1b2596b5SMatthias Ringwald  * \brief Disable UART transmitter.
133*1b2596b5SMatthias Ringwald  *
134*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
135*1b2596b5SMatthias Ringwald  */
uart_disable_tx(Uart * p_uart)136*1b2596b5SMatthias Ringwald void uart_disable_tx(Uart *p_uart)
137*1b2596b5SMatthias Ringwald {
138*1b2596b5SMatthias Ringwald 	/* Disable transmitter */
139*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_TXDIS;
140*1b2596b5SMatthias Ringwald }
141*1b2596b5SMatthias Ringwald 
142*1b2596b5SMatthias Ringwald /**
143*1b2596b5SMatthias Ringwald  * \brief Reset UART transmitter.
144*1b2596b5SMatthias Ringwald  *
145*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
146*1b2596b5SMatthias Ringwald  */
uart_reset_tx(Uart * p_uart)147*1b2596b5SMatthias Ringwald void uart_reset_tx(Uart *p_uart)
148*1b2596b5SMatthias Ringwald {
149*1b2596b5SMatthias Ringwald 	/* Reset transmitter */
150*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RSTTX | UART_CR_TXDIS;
151*1b2596b5SMatthias Ringwald }
152*1b2596b5SMatthias Ringwald 
153*1b2596b5SMatthias Ringwald /**
154*1b2596b5SMatthias Ringwald  * \brief Enable UART receiver.
155*1b2596b5SMatthias Ringwald  *
156*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
157*1b2596b5SMatthias Ringwald  */
uart_enable_rx(Uart * p_uart)158*1b2596b5SMatthias Ringwald void uart_enable_rx(Uart *p_uart)
159*1b2596b5SMatthias Ringwald {
160*1b2596b5SMatthias Ringwald 	/* Enable receiver */
161*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RXEN;
162*1b2596b5SMatthias Ringwald }
163*1b2596b5SMatthias Ringwald 
164*1b2596b5SMatthias Ringwald /**
165*1b2596b5SMatthias Ringwald  * \brief Disable UART receiver.
166*1b2596b5SMatthias Ringwald  *
167*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
168*1b2596b5SMatthias Ringwald  */
uart_disable_rx(Uart * p_uart)169*1b2596b5SMatthias Ringwald void uart_disable_rx(Uart *p_uart)
170*1b2596b5SMatthias Ringwald {
171*1b2596b5SMatthias Ringwald 	/* Disable receiver */
172*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RXDIS;
173*1b2596b5SMatthias Ringwald }
174*1b2596b5SMatthias Ringwald 
175*1b2596b5SMatthias Ringwald /**
176*1b2596b5SMatthias Ringwald  * \brief Reset UART receiver.
177*1b2596b5SMatthias Ringwald  *
178*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
179*1b2596b5SMatthias Ringwald  */
uart_reset_rx(Uart * p_uart)180*1b2596b5SMatthias Ringwald void uart_reset_rx(Uart *p_uart)
181*1b2596b5SMatthias Ringwald {
182*1b2596b5SMatthias Ringwald 	/* Reset receiver */
183*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RSTRX | UART_CR_RXDIS;
184*1b2596b5SMatthias Ringwald }
185*1b2596b5SMatthias Ringwald 
186*1b2596b5SMatthias Ringwald /**
187*1b2596b5SMatthias Ringwald  * \brief Enable UART receiver and transmitter.
188*1b2596b5SMatthias Ringwald  *
189*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
190*1b2596b5SMatthias Ringwald  */
uart_enable(Uart * p_uart)191*1b2596b5SMatthias Ringwald void uart_enable(Uart *p_uart)
192*1b2596b5SMatthias Ringwald {
193*1b2596b5SMatthias Ringwald 	/* Enable receiver and transmitter */
194*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
195*1b2596b5SMatthias Ringwald }
196*1b2596b5SMatthias Ringwald 
197*1b2596b5SMatthias Ringwald /**
198*1b2596b5SMatthias Ringwald  * \brief Disable UART receiver and transmitter.
199*1b2596b5SMatthias Ringwald  *
200*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
201*1b2596b5SMatthias Ringwald  */
uart_disable(Uart * p_uart)202*1b2596b5SMatthias Ringwald void uart_disable(Uart *p_uart)
203*1b2596b5SMatthias Ringwald {
204*1b2596b5SMatthias Ringwald 	/* Disable receiver and transmitter */
205*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RXDIS | UART_CR_TXDIS;
206*1b2596b5SMatthias Ringwald }
207*1b2596b5SMatthias Ringwald 
208*1b2596b5SMatthias Ringwald /**
209*1b2596b5SMatthias Ringwald  * \brief Reset UART receiver and transmitter.
210*1b2596b5SMatthias Ringwald  *
211*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
212*1b2596b5SMatthias Ringwald  */
uart_reset(Uart * p_uart)213*1b2596b5SMatthias Ringwald void uart_reset(Uart *p_uart)
214*1b2596b5SMatthias Ringwald {
215*1b2596b5SMatthias Ringwald 	/* Reset and disable receiver & transmitter */
216*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
217*1b2596b5SMatthias Ringwald 			| UART_CR_RXDIS | UART_CR_TXDIS;
218*1b2596b5SMatthias Ringwald }
219*1b2596b5SMatthias Ringwald 
220*1b2596b5SMatthias Ringwald /** \brief Enable UART interrupts.
221*1b2596b5SMatthias Ringwald  *
222*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
223*1b2596b5SMatthias Ringwald  *  \param ul_sources Interrupts to be enabled.
224*1b2596b5SMatthias Ringwald  */
uart_enable_interrupt(Uart * p_uart,uint32_t ul_sources)225*1b2596b5SMatthias Ringwald void uart_enable_interrupt(Uart *p_uart, uint32_t ul_sources)
226*1b2596b5SMatthias Ringwald {
227*1b2596b5SMatthias Ringwald 	p_uart->UART_IER = ul_sources;
228*1b2596b5SMatthias Ringwald }
229*1b2596b5SMatthias Ringwald 
230*1b2596b5SMatthias Ringwald /** \brief Disable UART interrupts.
231*1b2596b5SMatthias Ringwald  *
232*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
233*1b2596b5SMatthias Ringwald  *  \param ul_sources Interrupts to be disabled.
234*1b2596b5SMatthias Ringwald  */
uart_disable_interrupt(Uart * p_uart,uint32_t ul_sources)235*1b2596b5SMatthias Ringwald void uart_disable_interrupt(Uart *p_uart, uint32_t ul_sources)
236*1b2596b5SMatthias Ringwald {
237*1b2596b5SMatthias Ringwald 	p_uart->UART_IDR = ul_sources;
238*1b2596b5SMatthias Ringwald }
239*1b2596b5SMatthias Ringwald 
240*1b2596b5SMatthias Ringwald /** \brief Read UART interrupt mask.
241*1b2596b5SMatthias Ringwald  *
242*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
243*1b2596b5SMatthias Ringwald  *
244*1b2596b5SMatthias Ringwald  *  \return The interrupt mask value.
245*1b2596b5SMatthias Ringwald  */
uart_get_interrupt_mask(Uart * p_uart)246*1b2596b5SMatthias Ringwald uint32_t uart_get_interrupt_mask(Uart *p_uart)
247*1b2596b5SMatthias Ringwald {
248*1b2596b5SMatthias Ringwald 	return p_uart->UART_IMR;
249*1b2596b5SMatthias Ringwald }
250*1b2596b5SMatthias Ringwald 
251*1b2596b5SMatthias Ringwald /**
252*1b2596b5SMatthias Ringwald  * \brief Get current status.
253*1b2596b5SMatthias Ringwald  *
254*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
255*1b2596b5SMatthias Ringwald  *
256*1b2596b5SMatthias Ringwald  * \return The current UART status.
257*1b2596b5SMatthias Ringwald  */
uart_get_status(Uart * p_uart)258*1b2596b5SMatthias Ringwald uint32_t uart_get_status(Uart *p_uart)
259*1b2596b5SMatthias Ringwald {
260*1b2596b5SMatthias Ringwald 	return p_uart->UART_SR;
261*1b2596b5SMatthias Ringwald }
262*1b2596b5SMatthias Ringwald 
263*1b2596b5SMatthias Ringwald /**
264*1b2596b5SMatthias Ringwald  * \brief Reset status bits.
265*1b2596b5SMatthias Ringwald  *
266*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
267*1b2596b5SMatthias Ringwald  */
uart_reset_status(Uart * p_uart)268*1b2596b5SMatthias Ringwald void uart_reset_status(Uart *p_uart)
269*1b2596b5SMatthias Ringwald {
270*1b2596b5SMatthias Ringwald 	p_uart->UART_CR = UART_CR_RSTSTA;
271*1b2596b5SMatthias Ringwald }
272*1b2596b5SMatthias Ringwald 
273*1b2596b5SMatthias Ringwald /**
274*1b2596b5SMatthias Ringwald  * \brief Check if Transmit is Ready.
275*1b2596b5SMatthias Ringwald  * Check if data has been loaded in UART_THR and is waiting to be loaded in the
276*1b2596b5SMatthias Ringwald  * Transmit Shift Register (TSR).
277*1b2596b5SMatthias Ringwald  *
278*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
279*1b2596b5SMatthias Ringwald  *
280*1b2596b5SMatthias Ringwald  * \retval 1 Data has been transmitted.
281*1b2596b5SMatthias Ringwald  * \retval 0 Transmit is not ready, data pending.
282*1b2596b5SMatthias Ringwald  */
uart_is_tx_ready(Uart * p_uart)283*1b2596b5SMatthias Ringwald uint32_t uart_is_tx_ready(Uart *p_uart)
284*1b2596b5SMatthias Ringwald {
285*1b2596b5SMatthias Ringwald 	return (p_uart->UART_SR & UART_SR_TXRDY) > 0;
286*1b2596b5SMatthias Ringwald }
287*1b2596b5SMatthias Ringwald 
288*1b2596b5SMatthias Ringwald /**
289*1b2596b5SMatthias Ringwald  * \brief Check if Transmit Hold Register is empty.
290*1b2596b5SMatthias Ringwald  * Check if the last data written in UART_THR has been loaded in TSR and the
291*1b2596b5SMatthias Ringwald  * last data loaded in TSR has been transmitted.
292*1b2596b5SMatthias Ringwald  *
293*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
294*1b2596b5SMatthias Ringwald  *
295*1b2596b5SMatthias Ringwald  * \retval 1 Transmitter is empty.
296*1b2596b5SMatthias Ringwald  * \retval 0 Transmitter is not empty.
297*1b2596b5SMatthias Ringwald  */
uart_is_tx_empty(Uart * p_uart)298*1b2596b5SMatthias Ringwald uint32_t uart_is_tx_empty(Uart *p_uart)
299*1b2596b5SMatthias Ringwald {
300*1b2596b5SMatthias Ringwald 	return (p_uart->UART_SR & UART_SR_TXEMPTY) > 0;
301*1b2596b5SMatthias Ringwald }
302*1b2596b5SMatthias Ringwald 
303*1b2596b5SMatthias Ringwald /**
304*1b2596b5SMatthias Ringwald  * \brief Check if Received data is ready.
305*1b2596b5SMatthias Ringwald  * Check if data has been received and loaded in UART_RHR.
306*1b2596b5SMatthias Ringwald  *
307*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
308*1b2596b5SMatthias Ringwald  *
309*1b2596b5SMatthias Ringwald  * \retval 1 One data has been received.
310*1b2596b5SMatthias Ringwald  * \retval 0 No data has been received.
311*1b2596b5SMatthias Ringwald  */
uart_is_rx_ready(Uart * p_uart)312*1b2596b5SMatthias Ringwald uint32_t uart_is_rx_ready(Uart *p_uart)
313*1b2596b5SMatthias Ringwald {
314*1b2596b5SMatthias Ringwald 	return (p_uart->UART_SR & UART_SR_RXRDY) > 0;
315*1b2596b5SMatthias Ringwald }
316*1b2596b5SMatthias Ringwald 
317*1b2596b5SMatthias Ringwald /**
318*1b2596b5SMatthias Ringwald  * \brief Check if both transmit buffers are sent out.
319*1b2596b5SMatthias Ringwald  *
320*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
321*1b2596b5SMatthias Ringwald  *
322*1b2596b5SMatthias Ringwald  * \retval 1 Transmit buffer is empty.
323*1b2596b5SMatthias Ringwald  * \retval 0 Transmit buffer is not empty.
324*1b2596b5SMatthias Ringwald  */
uart_is_tx_buf_empty(Uart * p_uart)325*1b2596b5SMatthias Ringwald uint32_t uart_is_tx_buf_empty(Uart *p_uart)
326*1b2596b5SMatthias Ringwald {
327*1b2596b5SMatthias Ringwald 	return (p_uart->UART_SR & UART_SR_TXEMPTY) > 0;
328*1b2596b5SMatthias Ringwald }
329*1b2596b5SMatthias Ringwald 
330*1b2596b5SMatthias Ringwald /**
331*1b2596b5SMatthias Ringwald  * \brief Set UART clock divisor value
332*1b2596b5SMatthias Ringwald  *
333*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
334*1b2596b5SMatthias Ringwald  * \param us_divisor Value to be set.
335*1b2596b5SMatthias Ringwald  *
336*1b2596b5SMatthias Ringwald  */
uart_set_clock_divisor(Uart * p_uart,uint16_t us_divisor)337*1b2596b5SMatthias Ringwald void uart_set_clock_divisor(Uart *p_uart, uint16_t us_divisor)
338*1b2596b5SMatthias Ringwald {
339*1b2596b5SMatthias Ringwald 	p_uart->UART_BRGR = us_divisor;
340*1b2596b5SMatthias Ringwald }
341*1b2596b5SMatthias Ringwald 
342*1b2596b5SMatthias Ringwald /**
343*1b2596b5SMatthias Ringwald  * \brief Write to UART Transmit Holding Register
344*1b2596b5SMatthias Ringwald  * Before writing user should check if tx is ready (or empty).
345*1b2596b5SMatthias Ringwald  *
346*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
347*1b2596b5SMatthias Ringwald  * \param data Data to be sent.
348*1b2596b5SMatthias Ringwald  *
349*1b2596b5SMatthias Ringwald  * \retval 0 Success.
350*1b2596b5SMatthias Ringwald  * \retval 1 I/O Failure, UART is not ready.
351*1b2596b5SMatthias Ringwald  */
uart_write(Uart * p_uart,const uint8_t uc_data)352*1b2596b5SMatthias Ringwald uint32_t uart_write(Uart *p_uart, const uint8_t uc_data)
353*1b2596b5SMatthias Ringwald {
354*1b2596b5SMatthias Ringwald 	/* Check if the transmitter is ready */
355*1b2596b5SMatthias Ringwald 	if (!(p_uart->UART_SR & UART_SR_TXRDY))
356*1b2596b5SMatthias Ringwald 		return 1;
357*1b2596b5SMatthias Ringwald 
358*1b2596b5SMatthias Ringwald 	/* Send character */
359*1b2596b5SMatthias Ringwald 	p_uart->UART_THR = uc_data;
360*1b2596b5SMatthias Ringwald 	return 0;
361*1b2596b5SMatthias Ringwald }
362*1b2596b5SMatthias Ringwald 
363*1b2596b5SMatthias Ringwald /**
364*1b2596b5SMatthias Ringwald  * \brief Read from UART Receive Holding Register.
365*1b2596b5SMatthias Ringwald  * Before reading user should check if rx is ready.
366*1b2596b5SMatthias Ringwald  *
367*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
368*1b2596b5SMatthias Ringwald  *
369*1b2596b5SMatthias Ringwald  * \retval 0 Success.
370*1b2596b5SMatthias Ringwald  * \retval 1 I/O Failure, UART is not ready.
371*1b2596b5SMatthias Ringwald  */
uart_read(Uart * p_uart,uint8_t * puc_data)372*1b2596b5SMatthias Ringwald uint32_t uart_read(Uart *p_uart, uint8_t *puc_data)
373*1b2596b5SMatthias Ringwald {
374*1b2596b5SMatthias Ringwald 	/* Check if the receiver is ready */
375*1b2596b5SMatthias Ringwald 	if ((p_uart->UART_SR & UART_SR_RXRDY) == 0)
376*1b2596b5SMatthias Ringwald 		return 1;
377*1b2596b5SMatthias Ringwald 
378*1b2596b5SMatthias Ringwald 	/* Read character */
379*1b2596b5SMatthias Ringwald 	*puc_data = (uint8_t) p_uart->UART_RHR;
380*1b2596b5SMatthias Ringwald 	return 0;
381*1b2596b5SMatthias Ringwald }
382*1b2596b5SMatthias Ringwald 
383*1b2596b5SMatthias Ringwald #if (!SAMV71 && !SAMV70 && !SAME70 && !SAMS70)
384*1b2596b5SMatthias Ringwald /**
385*1b2596b5SMatthias Ringwald  * \brief Check if one receive buffer is filled.
386*1b2596b5SMatthias Ringwald  *
387*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
388*1b2596b5SMatthias Ringwald  *
389*1b2596b5SMatthias Ringwald  * \retval 1 Receive is completed.
390*1b2596b5SMatthias Ringwald  * \retval 0 Receive is still pending.
391*1b2596b5SMatthias Ringwald  */
uart_is_rx_buf_end(Uart * p_uart)392*1b2596b5SMatthias Ringwald uint32_t uart_is_rx_buf_end(Uart *p_uart)
393*1b2596b5SMatthias Ringwald {
394*1b2596b5SMatthias Ringwald 	return (p_uart->UART_SR & UART_SR_ENDRX) > 0;
395*1b2596b5SMatthias Ringwald }
396*1b2596b5SMatthias Ringwald 
397*1b2596b5SMatthias Ringwald /**
398*1b2596b5SMatthias Ringwald  * \brief Check if one transmit buffer is sent out.
399*1b2596b5SMatthias Ringwald  *
400*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
401*1b2596b5SMatthias Ringwald  *
402*1b2596b5SMatthias Ringwald  * \retval 1 Transmit is completed.
403*1b2596b5SMatthias Ringwald  * \retval 0 Transmit is still pending.
404*1b2596b5SMatthias Ringwald  */
uart_is_tx_buf_end(Uart * p_uart)405*1b2596b5SMatthias Ringwald uint32_t uart_is_tx_buf_end(Uart *p_uart)
406*1b2596b5SMatthias Ringwald {
407*1b2596b5SMatthias Ringwald 	return (p_uart->UART_SR & UART_SR_ENDTX) > 0;
408*1b2596b5SMatthias Ringwald }
409*1b2596b5SMatthias Ringwald 
410*1b2596b5SMatthias Ringwald /**
411*1b2596b5SMatthias Ringwald  * \brief Check if both receive buffers are full.
412*1b2596b5SMatthias Ringwald  *
413*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
414*1b2596b5SMatthias Ringwald  *
415*1b2596b5SMatthias Ringwald  * \retval 1 Receive buffers are full.
416*1b2596b5SMatthias Ringwald  * \retval 0 Receive buffers are not full.
417*1b2596b5SMatthias Ringwald  */
uart_is_rx_buf_full(Uart * p_uart)418*1b2596b5SMatthias Ringwald uint32_t uart_is_rx_buf_full(Uart *p_uart)
419*1b2596b5SMatthias Ringwald {
420*1b2596b5SMatthias Ringwald 	return (p_uart->UART_SR & UART_SR_RXBUFF) > 0;
421*1b2596b5SMatthias Ringwald }
422*1b2596b5SMatthias Ringwald 
423*1b2596b5SMatthias Ringwald /**
424*1b2596b5SMatthias Ringwald  * \brief Get UART PDC base address.
425*1b2596b5SMatthias Ringwald  *
426*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
427*1b2596b5SMatthias Ringwald  *
428*1b2596b5SMatthias Ringwald  * \return UART PDC registers base for PDC driver to access.
429*1b2596b5SMatthias Ringwald  */
uart_get_pdc_base(Uart * p_uart)430*1b2596b5SMatthias Ringwald Pdc *uart_get_pdc_base(Uart *p_uart)
431*1b2596b5SMatthias Ringwald {
432*1b2596b5SMatthias Ringwald 	Pdc *p_pdc_base;
433*1b2596b5SMatthias Ringwald 
434*1b2596b5SMatthias Ringwald #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM)
435*1b2596b5SMatthias Ringwald 	if (p_uart == UART0)
436*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_UART0;
437*1b2596b5SMatthias Ringwald #elif (SAM3XA || SAM3U)
438*1b2596b5SMatthias Ringwald 	if (p_uart == UART)
439*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_UART;
440*1b2596b5SMatthias Ringwald #else
441*1b2596b5SMatthias Ringwald #error "Unsupported device"
442*1b2596b5SMatthias Ringwald #endif
443*1b2596b5SMatthias Ringwald 
444*1b2596b5SMatthias Ringwald #if (SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM)
445*1b2596b5SMatthias Ringwald 	if (p_uart == UART1)
446*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_UART1;
447*1b2596b5SMatthias Ringwald #endif
448*1b2596b5SMatthias Ringwald 
449*1b2596b5SMatthias Ringwald #if (SAM4N)
450*1b2596b5SMatthias Ringwald 	if (p_uart == UART2)
451*1b2596b5SMatthias Ringwald 		p_pdc_base = PDC_UART2;
452*1b2596b5SMatthias Ringwald #endif
453*1b2596b5SMatthias Ringwald 
454*1b2596b5SMatthias Ringwald 	return p_pdc_base;
455*1b2596b5SMatthias Ringwald }
456*1b2596b5SMatthias Ringwald #endif
457*1b2596b5SMatthias Ringwald 
458*1b2596b5SMatthias Ringwald #if (SAM4C || SAM4CP || SAM4CM)
459*1b2596b5SMatthias Ringwald /**
460*1b2596b5SMatthias Ringwald  * \brief Enable UART optical interface.
461*1b2596b5SMatthias Ringwald  *
462*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
463*1b2596b5SMatthias Ringwald  */
uart_enable_optical_interface(Uart * p_uart)464*1b2596b5SMatthias Ringwald void uart_enable_optical_interface(Uart *p_uart)
465*1b2596b5SMatthias Ringwald {
466*1b2596b5SMatthias Ringwald 	Assert(p_uart == UART1);
467*1b2596b5SMatthias Ringwald 	p_uart->UART_MR |= UART_MR_OPT_EN;
468*1b2596b5SMatthias Ringwald }
469*1b2596b5SMatthias Ringwald 
470*1b2596b5SMatthias Ringwald /**
471*1b2596b5SMatthias Ringwald  * \brief Disable UART optical interface.
472*1b2596b5SMatthias Ringwald  *
473*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
474*1b2596b5SMatthias Ringwald  */
uart_disable_optical_interface(Uart * p_uart)475*1b2596b5SMatthias Ringwald void uart_disable_optical_interface(Uart *p_uart)
476*1b2596b5SMatthias Ringwald {
477*1b2596b5SMatthias Ringwald 	Assert(p_uart == UART1);
478*1b2596b5SMatthias Ringwald 	p_uart->UART_MR &= ~UART_MR_OPT_EN;
479*1b2596b5SMatthias Ringwald }
480*1b2596b5SMatthias Ringwald 
481*1b2596b5SMatthias Ringwald /**
482*1b2596b5SMatthias Ringwald  * \brief Enable UART optical interface.
483*1b2596b5SMatthias Ringwald  *
484*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
485*1b2596b5SMatthias Ringwald  * \param cfg Pointer to a UART optical interface configuration.
486*1b2596b5SMatthias Ringwald  */
uart_config_optical_interface(Uart * p_uart,struct uart_config_optical * cfg)487*1b2596b5SMatthias Ringwald void uart_config_optical_interface(Uart *p_uart,
488*1b2596b5SMatthias Ringwald 		struct uart_config_optical *cfg)
489*1b2596b5SMatthias Ringwald {
490*1b2596b5SMatthias Ringwald 	Assert(p_uart == UART1);
491*1b2596b5SMatthias Ringwald 	uint32_t reg = p_uart->UART_MR;
492*1b2596b5SMatthias Ringwald 
493*1b2596b5SMatthias Ringwald 	reg &= ~(UART_MR_OPT_RXINV | UART_MR_OPT_MDINV | UART_MR_FILTER
494*1b2596b5SMatthias Ringwald 			| UART_MR_OPT_CLKDIV_Msk | UART_MR_OPT_DUTY_Msk
495*1b2596b5SMatthias Ringwald 			| UART_MR_OPT_CMPTH_Msk);
496*1b2596b5SMatthias Ringwald 	reg |= (cfg->rx_inverted ? UART_MR_OPT_RXINV : 0)
497*1b2596b5SMatthias Ringwald 			| (cfg->tx_inverted ? UART_MR_OPT_MDINV : 0)
498*1b2596b5SMatthias Ringwald 			| (cfg->rx_filter ? UART_MR_FILTER : 0)
499*1b2596b5SMatthias Ringwald 			| UART_MR_OPT_CLKDIV(cfg->clk_div)
500*1b2596b5SMatthias Ringwald 			| cfg->duty | cfg->threshold;
501*1b2596b5SMatthias Ringwald 
502*1b2596b5SMatthias Ringwald 	p_uart->UART_MR = reg;
503*1b2596b5SMatthias Ringwald }
504*1b2596b5SMatthias Ringwald #endif
505*1b2596b5SMatthias Ringwald 
506*1b2596b5SMatthias Ringwald #if (SAMG53 || SAMG54 || SAMV71 || SAMV70 || SAME70 || SAMS70)
507*1b2596b5SMatthias Ringwald /**
508*1b2596b5SMatthias Ringwald  * \brief Set sleepwalking match mode.
509*1b2596b5SMatthias Ringwald  *
510*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
511*1b2596b5SMatthias Ringwald  * \param ul_low_value First comparison value for received character.
512*1b2596b5SMatthias Ringwald  * \param ul_high_value Second comparison value for received character.
513*1b2596b5SMatthias Ringwald  * \param cmpmode ture for start condition, false for flag only.
514*1b2596b5SMatthias Ringwald  * \param cmppar ture for parity check, false for no.
515*1b2596b5SMatthias Ringwald  */
uart_set_sleepwalking(Uart * p_uart,uint8_t ul_low_value,bool cmpmode,bool cmppar,uint8_t ul_high_value)516*1b2596b5SMatthias Ringwald void uart_set_sleepwalking(Uart *p_uart, uint8_t ul_low_value,
517*1b2596b5SMatthias Ringwald 		bool cmpmode, bool cmppar, uint8_t ul_high_value)
518*1b2596b5SMatthias Ringwald {
519*1b2596b5SMatthias Ringwald 	Assert(ul_low_value <= ul_high_value);
520*1b2596b5SMatthias Ringwald 
521*1b2596b5SMatthias Ringwald 	uint32_t temp = 0;
522*1b2596b5SMatthias Ringwald 
523*1b2596b5SMatthias Ringwald 	if (cmpmode) {
524*1b2596b5SMatthias Ringwald 		temp |= UART_CMPR_CMPMODE_START_CONDITION;
525*1b2596b5SMatthias Ringwald 	}
526*1b2596b5SMatthias Ringwald 
527*1b2596b5SMatthias Ringwald 	if (cmppar) {
528*1b2596b5SMatthias Ringwald 		temp |= UART_CMPR_CMPPAR;
529*1b2596b5SMatthias Ringwald 	}
530*1b2596b5SMatthias Ringwald 
531*1b2596b5SMatthias Ringwald 	temp |= UART_CMPR_VAL1(ul_low_value);
532*1b2596b5SMatthias Ringwald 
533*1b2596b5SMatthias Ringwald 	temp |= UART_CMPR_VAL2(ul_high_value);
534*1b2596b5SMatthias Ringwald 
535*1b2596b5SMatthias Ringwald 	p_uart->UART_CMPR= temp;
536*1b2596b5SMatthias Ringwald }
537*1b2596b5SMatthias Ringwald 
538*1b2596b5SMatthias Ringwald /**
539*1b2596b5SMatthias Ringwald  * \brief Enables/Disables write protection mode.
540*1b2596b5SMatthias Ringwald  *
541*1b2596b5SMatthias Ringwald  * \param p_uart Pointer to a UART instance.
542*1b2596b5SMatthias Ringwald  * \param flag ture for enable, false for disable.
543*1b2596b5SMatthias Ringwald  */
uart_set_write_protection(Uart * p_uart,bool flag)544*1b2596b5SMatthias Ringwald void uart_set_write_protection(Uart *p_uart, bool flag)
545*1b2596b5SMatthias Ringwald {
546*1b2596b5SMatthias Ringwald 	if (flag) {
547*1b2596b5SMatthias Ringwald 		p_uart->UART_WPMR = UART_WPMR_WPKEY_PASSWD | UART_WPMR_WPEN;
548*1b2596b5SMatthias Ringwald 	} else {
549*1b2596b5SMatthias Ringwald 		p_uart->UART_WPMR = UART_WPMR_WPKEY_PASSWD;
550*1b2596b5SMatthias Ringwald 	}
551*1b2596b5SMatthias Ringwald }
552*1b2596b5SMatthias Ringwald #endif
553*1b2596b5SMatthias Ringwald 
554*1b2596b5SMatthias Ringwald //@}
555*1b2596b5SMatthias Ringwald 
556*1b2596b5SMatthias Ringwald /// @cond 0
557*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
558*1b2596b5SMatthias Ringwald #ifdef __cplusplus
559*1b2596b5SMatthias Ringwald }
560*1b2596b5SMatthias Ringwald #endif
561*1b2596b5SMatthias Ringwald /**INDENT-ON**/
562*1b2596b5SMatthias Ringwald /// @endcond
563