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