4 * \brief Universal Synchronous Asynchronous Receiver Transmitter (USART) driver for SAM.
\r
6 * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
\r
12 * Redistribution and use in source and binary forms, with or without
\r
13 * modification, are permitted provided that the following conditions are met:
\r
15 * 1. Redistributions of source code must retain the above copyright notice,
\r
16 * this list of conditions and the following disclaimer.
\r
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
19 * this list of conditions and the following disclaimer in the documentation
\r
20 * and/or other materials provided with the distribution.
\r
22 * 3. The name of Atmel may not be used to endorse or promote products derived
\r
23 * from this software without specific prior written permission.
\r
25 * 4. This software may only be redistributed and used in connection with an
\r
26 * Atmel microcontroller product.
\r
28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
\r
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
\r
32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\r
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\r
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
\r
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
\r
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
\r
38 * POSSIBILITY OF SUCH DAMAGE.
\r
55 * \defgroup sam_drivers_usart_group Universal Synchronous Asynchronous Receiver Transmitter (USART)
\r
57 * The Universal Synchronous Asynchronous Receiver Transceiver (USART) provides one full duplex
\r
58 * universal synchronous asynchronous serial link. Data frame format is widely programmable
\r
59 * (data length, parity, number of stop bits) to support a maximum of standards. The receiver
\r
60 * implements parity error, framing error and overrun error detection. The receiver time-out enables
\r
61 * handling variable-length frames and the transmitter timeguard facilitates communications with
\r
62 * slow remote devices. Multidrop communications are also supported through address bit handling
\r
63 * in reception and transmission.
\r
64 * The driver supports the following modes: RS232, RS485, SPI, IrDA, ISO7816, MODEM,
\r
65 * Hardware handshaking and LIN.
\r
70 /* The write protect key value. */
\r
71 #define US_WPKEY_VALUE 0x555341
\r
73 /* The CD value scope programmed in MR register. */
\r
74 #define MIN_CD_VALUE 0x01
\r
75 #define MIN_CD_VALUE_SPI 0x04
\r
76 #define MAX_CD_VALUE US_BRGR_CD_Msk
\r
78 /* Define the default time-out value for USART. */
\r
79 #define USART_DEFAULT_TIMEOUT 1000
\r
81 /* The receiver sampling divide of baudrate clock. */
\r
82 #define HIGH_FRQ_SAMPLE_DIV 16
\r
83 #define LOW_FRQ_SAMPLE_DIV 8
\r
85 /* Max transmitter timeguard. */
\r
86 #define MAX_TRAN_GUARD_TIME US_TTGR_TG_Msk
\r
88 /* The non-existent parity error number. */
\r
89 #define USART_PARITY_ERROR 5
\r
91 /* ISO7816 protocol type. */
\r
92 #define ISO7816_T_0 0
\r
93 #define ISO7816_T_1 1
\r
96 * \brief Calculate a clock divider(CD) and a fractional part (FP) for the
\r
97 * USART asynchronous modes to generate a baudrate as close as possible to
\r
98 * the baudrate set point.
\r
100 * \note Baud rate calculation: Baudrate = ul_mck/(Over * (CD + FP/8))
\r
101 * (Over being 16 or 8). The maximal oversampling is selected if it allows to
\r
102 * generate a baudrate close to the set point.
\r
104 * \param p_usart Pointer to a USART instance.
\r
105 * \param baudrate Baud rate set point.
\r
106 * \param ul_mck USART module input clock frequency.
\r
108 * \retval 0 Baud rate is successfully initialized.
\r
109 * \retval 1 Baud rate set point is out of range for the given input clock
\r
112 static uint32_t usart_set_async_baudrate(Usart *p_usart,
\r
113 uint32_t baudrate, uint32_t ul_mck)
\r
120 /* Calculate the receiver sampling divide of baudrate clock. */
\r
121 if (ul_mck >= HIGH_FRQ_SAMPLE_DIV * baudrate) {
\r
122 over = HIGH_FRQ_SAMPLE_DIV;
\r
124 over = LOW_FRQ_SAMPLE_DIV;
\r
127 /* Calculate the clock divider according to the fraction calculated formula. */
\r
128 cd_fp = (8 * ul_mck + (over * baudrate) / 2) / (over * baudrate);
\r
131 if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {
\r
135 /* Configure the OVER bit in MR register. */
\r
137 p_usart->US_MR |= US_MR_OVER;
\r
140 /* Configure the baudrate generate register. */
\r
141 p_usart->US_BRGR = (cd << US_BRGR_CD_Pos) | (fp << US_BRGR_FP_Pos);
\r
147 * \brief Calculate a clock divider for the USART synchronous master modes
\r
148 * to generate a baudrate as close as possible to the baudrate set point.
\r
150 * \note Synchronous baudrate calculation: baudrate = ul_mck / cd
\r
152 * \param p_usart Pointer to a USART instance.
\r
153 * \param baudrate Baud rate set point.
\r
154 * \param ul_mck USART module input clock frequency.
\r
156 * \retval 0 Baud rate is successfully initialized.
\r
157 * \retval 1 Baud rate set point is out of range for the given input clock
\r
160 static uint32_t usart_set_sync_master_baudrate(Usart *p_usart,
\r
161 uint32_t baudrate, uint32_t ul_mck)
\r
165 /* Calculate the clock divider according to the formula in synchronous mode. */
\r
166 cd = (ul_mck + baudrate / 2) / baudrate;
\r
168 if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {
\r
172 /* Configure the baudrate generate register. */
\r
173 p_usart->US_BRGR = cd << US_BRGR_CD_Pos;
\r
175 p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) |
\r
176 US_MR_USCLKS_MCK | US_MR_SYNC;
\r
181 * \brief Select the SCK pin as the source of baud rate for the USART
\r
182 * synchronous slave modes.
\r
184 * \param p_usart Pointer to a USART instance.
\r
186 static void usart_set_sync_slave_baudrate(Usart *p_usart)
\r
188 p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) |
\r
189 US_MR_USCLKS_SCK | US_MR_SYNC;
\r
194 * \brief Calculate a clock divider (\e CD) for the USART ISO7816 mode to
\r
195 * generate an ISO7816 clock as close as possible to the clock set point.
\r
197 * \note ISO7816 clock calculation: Clock = ul_mck / cd
\r
199 * \param p_usart Pointer to a USART instance.
\r
200 * \param clock ISO7816 clock set point.
\r
201 * \param ul_mck USART module input clock frequency.
\r
203 * \retval 0 ISO7816 clock is successfully initialized.
\r
204 * \retval 1 ISO7816 clock set point is out of range for the given input clock
\r
207 static uint32_t usart_set_iso7816_clock(Usart *p_usart,
\r
208 uint32_t clock, uint32_t ul_mck)
\r
212 /* Calculate the clock divider according to the formula in ISO7816 mode. */
\r
213 cd = (ul_mck + clock / 2) / clock;
\r
215 if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {
\r
219 p_usart->US_MR = (p_usart->US_MR & ~(US_MR_USCLKS_Msk | US_MR_SYNC |
\r
220 US_MR_OVER)) | US_MR_USCLKS_MCK | US_MR_CLKO;
\r
222 /* Configure the baudrate generate register. */
\r
223 p_usart->US_BRGR = cd << US_BRGR_CD_Pos;
\r
229 * \brief Calculate a clock divider (\e CD) for the USART SPI master mode to
\r
230 * generate a baud rate as close as possible to the baud rate set point.
\r
232 * \note Baud rate calculation:
\r
233 * \f$ Baudrate = \frac{SelectedClock}{CD} \f$.
\r
235 * \param p_usart Pointer to a USART instance.
\r
236 * \param baudrate Baud rate set point.
\r
237 * \param ul_mck USART module input clock frequency.
\r
239 * \retval 0 Baud rate is successfully initialized.
\r
240 * \retval 1 Baud rate set point is out of range for the given input clock
\r
243 static uint32_t usart_set_spi_master_baudrate(Usart *p_usart,
\r
244 uint32_t baudrate, uint32_t ul_mck)
\r
248 /* Calculate the clock divider according to the formula in SPI mode. */
\r
249 cd = (ul_mck + baudrate / 2) / baudrate;
\r
251 if (cd < MIN_CD_VALUE_SPI || cd > MAX_CD_VALUE) {
\r
255 p_usart->US_BRGR = cd << US_BRGR_CD_Pos;
\r
261 * \brief Select the SCK pin as the source of baudrate for the USART SPI slave
\r
264 * \param p_usart Pointer to a USART instance.
\r
266 static void usart_set_spi_slave_baudrate(Usart *p_usart)
\r
268 p_usart->US_MR &= ~US_MR_USCLKS_Msk;
\r
269 p_usart->US_MR |= US_MR_USCLKS_SCK;
\r
273 * \brief Reset the USART and disable TX and RX.
\r
275 * \param p_usart Pointer to a USART instance.
\r
277 void usart_reset(Usart *p_usart)
\r
279 /* Disable the Write Protect. Some register can't be written if the write protect is enabled. */
\r
280 usart_disable_writeprotect(p_usart);
\r
282 /* Reset mode and other registers that could cause unpredictable behavior after reset. */
\r
283 p_usart->US_MR = 0;
\r
284 p_usart->US_RTOR = 0;
\r
285 p_usart->US_TTGR = 0;
\r
287 /* Disable TX and RX, reset status bits and turn off RTS and DTR if exist. */
\r
288 usart_reset_tx(p_usart);
\r
289 usart_reset_rx(p_usart);
\r
290 usart_reset_status(p_usart);
\r
291 usart_drive_RTS_pin_high(p_usart);
\r
292 #if (SAM3S || SAM4S || SAM3U)
\r
293 usart_drive_DTR_pin_high(p_usart);
\r
298 * \brief Configure USART to work in RS232 mode.
\r
300 * \note By default, the transmitter and receiver aren't enabled.
\r
302 * \param p_usart Pointer to a USART instance.
\r
303 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
304 * \param ul_mck USART module input clock frequency.
\r
306 * \retval 0 on success.
\r
307 * \retval 1 on failure.
\r
309 uint32_t usart_init_rs232(Usart *p_usart,
\r
310 const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
\r
312 static uint32_t ul_reg_val;
\r
314 /* Reset the USART and shut down TX and RX. */
\r
315 usart_reset(p_usart);
\r
318 /* Check whether the input values are legal. */
\r
319 if (!p_usart_opt ||
\r
320 usart_set_async_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) {
\r
324 /* Configure the character length, parity type, channel mode and stop bit length. */
\r
325 ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type |
\r
326 p_usart_opt->channel_mode | p_usart_opt->stop_bits;
\r
328 /* Configure the USART mode as normal mode. */
\r
329 ul_reg_val |= US_MR_USART_MODE_NORMAL;
\r
331 p_usart->US_MR |= ul_reg_val;
\r
337 * \brief Configure USART to work in hardware handshaking mode.
\r
339 * \note By default, the transmitter and receiver aren't enabled.
\r
341 * \param p_usart Pointer to a USART instance.
\r
342 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
343 * \param ul_mck USART module input clock frequency.
\r
345 * \retval 0 on success.
\r
346 * \retval 1 on failure.
\r
348 uint32_t usart_init_hw_handshaking(Usart *p_usart,
\r
349 const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
\r
351 /* Initialize the USART as standard RS232. */
\r
352 if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {
\r
356 /* Set hardware handshaking mode. */
\r
357 p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
\r
358 US_MR_USART_MODE_HW_HANDSHAKING;
\r
363 #if (SAM3S || SAM4S || SAM3U)
\r
365 * \brief Configure USART to work in modem mode.
\r
367 * \note By default, the transmitter and receiver aren't enabled.
\r
369 * \param p_usart Pointer to a USART instance.
\r
370 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
371 * \param ul_mck USART module input clock frequency.
\r
373 * \retval 0 on success.
\r
374 * \retval 1 on failure.
\r
376 uint32_t usart_init_modem(Usart *p_usart,
\r
377 const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
\r
379 /* SAM3S || SAM4S series support MODEM mode only on USART1, and
\r
380 SAM3U series support MODEM mode only on USART0. */
\r
381 #if (SAM3S || SAM4S)
\r
382 if (p_usart != USART1) {
\r
386 if (p_usart != USART0) {
\r
391 /* Initialize the USART as standard RS232. */
\r
392 if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {
\r
396 /* Set MODEM mode. */
\r
397 p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
\r
398 US_MR_USART_MODE_MODEM;
\r
405 * \brief Configure USART to work in SYNC mode and act as a master.
\r
407 * \note By default, the transmitter and receiver aren't enabled.
\r
409 * \param p_usart Pointer to a USART instance.
\r
410 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
411 * \param ul_mck USART module input clock frequency.
\r
413 * \retval 0 on success.
\r
414 * \retval 1 on failure.
\r
416 uint32_t usart_init_sync_master(Usart *p_usart,
\r
417 const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
\r
419 static uint32_t ul_reg_val;
\r
421 /* Reset the USART and shut down TX and RX. */
\r
422 usart_reset(p_usart);
\r
425 /* Check whether the input values are legal. */
\r
426 if (!p_usart_opt ||
\r
427 usart_set_sync_master_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) {
\r
431 /* Configure the character length, parity type, channel mode and stop bit length. */
\r
432 ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type |
\r
433 p_usart_opt->channel_mode | p_usart_opt->stop_bits;
\r
435 /* Set normal mode and output clock on the SCK pin as synchronous master. */
\r
436 ul_reg_val |= US_MR_USART_MODE_NORMAL | US_MR_CLKO;
\r
437 p_usart->US_MR |= ul_reg_val;
\r
443 * \brief Configure USART to work in SYNC mode and act as a slave.
\r
445 * \note By default, the transmitter and receiver aren't enabled.
\r
447 * \param p_usart Pointer to a USART instance.
\r
448 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
450 * \retval 0 on success.
\r
451 * \retval 1 on failure.
\r
453 uint32_t usart_init_sync_slave(Usart *p_usart,
\r
454 const sam_usart_opt_t *p_usart_opt)
\r
456 static uint32_t ul_reg_val;
\r
458 /* Reset the USART and shut down TX and RX. */
\r
459 usart_reset(p_usart);
\r
462 usart_set_sync_slave_baudrate(p_usart);
\r
464 /* Check whether the input values are legal. */
\r
465 if (!p_usart_opt) {
\r
469 /* Configure the character length, parity type, channel mode and stop bit length. */
\r
470 ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type |
\r
471 p_usart_opt->channel_mode | p_usart_opt->stop_bits;
\r
473 /* Set normal mode. */
\r
474 ul_reg_val |= US_MR_USART_MODE_NORMAL;
\r
475 p_usart->US_MR |= ul_reg_val;
\r
481 * \brief Configure USART to work in RS485 mode.
\r
483 * \note By default, the transmitter and receiver aren't enabled.
\r
485 * \param p_usart Pointer to a USART instance.
\r
486 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
487 * \param ul_mck USART module input clock frequency.
\r
489 * \retval 0 on success.
\r
490 * \retval 1 on failure.
\r
492 uint32_t usart_init_rs485(Usart *p_usart,
\r
493 const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
\r
495 /* Initialize the USART as standard RS232. */
\r
496 if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {
\r
500 /* Set RS485 mode. */
\r
501 p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
\r
502 US_MR_USART_MODE_RS485;
\r
508 * \brief Configure USART to work in IrDA mode.
\r
510 * \note By default, the transmitter and receiver aren't enabled.
\r
512 * \param p_usart Pointer to a USART instance.
\r
513 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
514 * \param ul_mck USART module input clock frequency.
\r
516 * \retval 0 on success.
\r
517 * \retval 1 on failure.
\r
519 uint32_t usart_init_irda(Usart *p_usart,
\r
520 const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
\r
522 /* Initialize the USART as standard RS232. */
\r
523 if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {
\r
527 /* Set IrDA filter. */
\r
528 p_usart->US_IF = p_usart_opt->irda_filter;
\r
530 /* Set IrDA mode. */
\r
531 p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
\r
532 US_MR_USART_MODE_IRDA;
\r
538 * \brief Configure USART to work in ISO7816 mode.
\r
540 * \note By default, the transmitter and receiver aren't enabled.
\r
542 * \param p_usart Pointer to a USART instance.
\r
543 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
544 * \param ul_mck USART module input clock frequency.
\r
546 * \retval 0 on success.
\r
547 * \retval 1 on failure.
\r
549 uint32_t usart_init_iso7816(Usart *p_usart,
\r
550 const usart_iso7816_opt_t *p_usart_opt, uint32_t ul_mck)
\r
552 static uint32_t ul_reg_val;
\r
554 /* Reset the USART and shut down TX and RX. */
\r
555 usart_reset(p_usart);
\r
559 /* Check whether the input values are legal. */
\r
560 if (!p_usart_opt || ((p_usart_opt->parity_type != US_MR_PAR_EVEN) &&
\r
561 (p_usart_opt->parity_type != US_MR_PAR_ODD))) {
\r
565 if (p_usart_opt->protocol_type == ISO7816_T_0) {
\r
566 ul_reg_val |= US_MR_USART_MODE_IS07816_T_0 | US_MR_NBSTOP_2_BIT |
\r
567 (p_usart_opt->max_iterations << US_MR_MAX_ITERATION_Pos);
\r
569 if (p_usart_opt->bit_order) {
\r
570 ul_reg_val |= US_MR_MSBF;
\r
572 } else if (p_usart_opt->protocol_type == ISO7816_T_1) {
\r
573 /* Only LSBF is used in the T=1 protocol, and max_iterations field is only used in T=0 mode.*/
\r
574 if (p_usart_opt->bit_order || p_usart_opt->max_iterations) {
\r
578 /* Set USART mode to ISO7816, T=1, and always uses 1 stop bit. */
\r
579 ul_reg_val |= US_MR_USART_MODE_IS07816_T_1 | US_MR_NBSTOP_1_BIT;
\r
584 /* Set up the baudrate. */
\r
585 if (usart_set_iso7816_clock(p_usart, p_usart_opt->iso7816_hz, ul_mck)) {
\r
589 /* Set FIDI register: bit rate = iso7816_hz / fidi_ratio. */
\r
590 p_usart->US_FIDI = p_usart_opt->fidi_ratio;
\r
592 /* Set ISO7816 parity type in the MODE register. */
\r
593 ul_reg_val |= p_usart_opt->parity_type;
\r
595 if (p_usart_opt->inhibit_nack) {
\r
596 ul_reg_val |= US_MR_INACK;
\r
598 if (p_usart_opt->dis_suc_nack) {
\r
599 ul_reg_val |= US_MR_DSNACK;
\r
602 p_usart->US_MR |= ul_reg_val;
\r
608 * \brief Configure USART to work in SPI mode and act as a master.
\r
610 * \note By default, the transmitter and receiver aren't enabled.
\r
612 * \param p_usart Pointer to a USART instance.
\r
613 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
614 * \param ul_mck USART module input clock frequency.
\r
616 * \retval 0 on success.
\r
617 * \retval 1 on failure.
\r
619 uint32_t usart_init_spi_master(Usart *p_usart,
\r
620 const usart_spi_opt_t *p_usart_opt, uint32_t ul_mck)
\r
622 static uint32_t ul_reg_val;
\r
624 /* Reset the USART and shut down TX and RX. */
\r
625 usart_reset(p_usart);
\r
628 /* Check whether the input values are legal. */
\r
629 if (!p_usart_opt ||
\r
630 (p_usart_opt->spi_mode > SPI_MODE_3) ||
\r
631 usart_set_spi_master_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) {
\r
635 /* Configure the character length bit in MR register. */
\r
636 ul_reg_val |= p_usart_opt->char_length;
\r
638 /* Set SPI master mode and channel mode. */
\r
639 ul_reg_val |= US_MR_USART_MODE_SPI_MASTER | US_MR_CLKO |
\r
640 p_usart_opt->channel_mode;
\r
642 switch (p_usart_opt->spi_mode) {
\r
644 ul_reg_val |= US_MR_CPHA;
\r
645 ul_reg_val &= ~US_MR_CPOL;
\r
648 ul_reg_val &= ~US_MR_CPHA;
\r
649 ul_reg_val &= ~US_MR_CPOL;
\r
652 ul_reg_val |= US_MR_CPHA;
\r
653 ul_reg_val |= US_MR_CPOL;
\r
656 ul_reg_val |= US_MR_CPOL;
\r
657 ul_reg_val &= ~US_MR_CPHA;
\r
663 p_usart->US_MR |= ul_reg_val;
\r
669 * \brief Configure USART to work in SPI mode and act as a slave.
\r
671 * \note By default, the transmitter and receiver aren't enabled.
\r
673 * \param p_usart Pointer to a USART instance.
\r
674 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
676 * \retval 0 on success.
\r
677 * \retval 1 on failure.
\r
679 uint32_t usart_init_spi_slave(Usart *p_usart,
\r
680 const usart_spi_opt_t *p_usart_opt)
\r
682 static uint32_t ul_reg_val;
\r
684 /* Reset the USART and shut down TX and RX. */
\r
685 usart_reset(p_usart);
\r
688 usart_set_spi_slave_baudrate(p_usart);
\r
690 /* Check whether the input values are legal. */
\r
691 if (!p_usart_opt ||
\r
692 p_usart_opt->spi_mode > SPI_MODE_3) {
\r
696 /* Configure the character length bit in MR register. */
\r
697 ul_reg_val |= p_usart_opt->char_length;
\r
699 /* Set SPI slave mode and channel mode. */
\r
700 ul_reg_val |= US_MR_USART_MODE_SPI_SLAVE | p_usart_opt->channel_mode;
\r
702 switch (p_usart_opt->spi_mode) {
\r
704 ul_reg_val |= US_MR_CPHA;
\r
705 ul_reg_val &= ~US_MR_CPOL;
\r
708 ul_reg_val &= ~US_MR_CPHA;
\r
709 ul_reg_val &= ~US_MR_CPOL;
\r
712 ul_reg_val |= US_MR_CPHA;
\r
713 ul_reg_val |= US_MR_CPOL;
\r
716 ul_reg_val |= US_MR_CPOL;
\r
717 ul_reg_val &= ~US_MR_CPHA;
\r
723 p_usart->US_MR |= ul_reg_val;
\r
730 * \brief Configure USART to work in LIN mode and act as a LIN master.
\r
732 * \note By default, the transmitter and receiver aren't enabled.
\r
734 * \param p_usart Pointer to a USART instance.
\r
735 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
736 * \param ul_mck USART module input clock frequency.
\r
738 * \retval 0 on success.
\r
739 * \retval 1 on failure.
\r
741 uint32_t usart_init_lin_master(Usart *p_usart,
\r
742 const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
\r
744 /* Reset the USART and shut down TX and RX. */
\r
745 usart_reset(p_usart);
\r
747 /* Set up the baudrate. */
\r
748 if (usart_set_async_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) {
\r
752 /* Set LIN master mode. */
\r
753 p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
\r
754 US_MR_USART_MODE_LIN_MASTER;
\r
760 * \brief Configure USART to work in LIN mode and act as a LIN slave.
\r
762 * \note By default, the transmitter and receiver aren't enabled.
\r
764 * \param p_usart Pointer to a USART instance.
\r
765 * \param p_usart_opt Pointer to sam_usart_opt_t instance.
\r
766 * \param ul_mck USART module input clock frequency.
\r
768 * \retval 0 on success.
\r
769 * \retval 1 on failure.
\r
771 uint32_t usart_init_lin_slave(Usart *p_usart,
\r
772 const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck)
\r
774 /* Reset the USART and shut down TX and RX. */
\r
775 usart_reset(p_usart);
\r
777 /* Set up the baudrate. */
\r
778 if (usart_set_async_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) {
\r
782 /* Set LIN slave mode. */
\r
783 p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
\r
784 US_MR_USART_MODE_LIN_SLAVE;
\r
790 * \brief Abort the current LIN transmission.
\r
792 * \param p_usart Pointer to a USART instance.
\r
794 void usart_lin_abort_tx(Usart *p_usart)
\r
796 p_usart->US_CR = US_CR_LINABT;
\r
800 * \brief Send a wakeup signal on the LIN bus.
\r
802 * \param p_usart Pointer to a USART instance.
\r
804 void usart_lin_send_wakeup_signal(Usart *p_usart)
\r
806 p_usart->US_CR = US_CR_LINWKUP;
\r
810 * \brief Configure the LIN node action, which should be one of PUBLISH,
\r
811 * SUBSCRIBE or IGNORE.
\r
813 * \param p_usart Pointer to a USART instance.
\r
814 * \param uc_action 0 for PUBLISH, 1 for SUBSCRIBE, 2 for IGNORE.
\r
816 void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action)
\r
818 p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_NACT_Msk) |
\r
819 (uc_action << US_LINMR_NACT_Pos);
\r
823 * \brief Disable the parity check during the LIN communication.
\r
825 * \param p_usart Pointer to a USART instance.
\r
827 void usart_lin_disable_parity(Usart *p_usart)
\r
829 p_usart->US_LINMR |= US_LINMR_PARDIS;
\r
833 * \brief Enable the parity check during the LIN communication.
\r
835 * \param p_usart Pointer to a USART instance.
\r
837 void usart_lin_enable_parity(Usart *p_usart)
\r
839 p_usart->US_LINMR &= ~US_LINMR_PARDIS;
\r
843 * \brief Disable the checksum during the LIN communication.
\r
845 * \param p_usart Pointer to a USART instance.
\r
847 void usart_lin_disable_checksum(Usart *p_usart)
\r
849 p_usart->US_LINMR |= US_LINMR_CHKDIS;
\r
853 * \brief Enable the checksum during the LIN communication.
\r
855 * \param p_usart Pointer to a USART instance.
\r
857 void usart_lin_enable_checksum(Usart *p_usart)
\r
859 p_usart->US_LINMR &= ~US_LINMR_CHKDIS;
\r
863 * \brief Configure the checksum type during the LIN communication.
\r
865 * \param p_usart Pointer to a USART instance.
\r
866 * \param uc_type 0 for LIN 2.0 Enhanced checksum or 1 for LIN 1.3 Classic checksum.
\r
868 void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type)
\r
870 p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_CHKTYP) |
\r
875 * \brief Configure the data length mode during the LIN communication.
\r
877 * \param p_usart Pointer to a USART instance.
\r
878 * \param uc_mode Indicate the checksum type: 0 if the data length is defined by the
\r
879 * DLC of LIN mode register or 1 if the data length is defined by the bit 5 and 6 of
\r
882 void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode)
\r
884 p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLM) |
\r
889 * \brief Disable the frame slot mode during the LIN communication.
\r
891 * \param p_usart Pointer to a USART instance.
\r
893 void usart_lin_disable_frame_slot(Usart *p_usart)
\r
895 p_usart->US_LINMR |= US_LINMR_FSDIS;
\r
899 * \brief Enable the frame slot mode during the LIN communication.
\r
901 * \param p_usart Pointer to a USART instance.
\r
903 void usart_lin_enable_frame_slot(Usart *p_usart)
\r
905 p_usart->US_LINMR &= ~US_LINMR_FSDIS;
\r
909 * \brief Configure the wakeup signal type during the LIN communication.
\r
911 * \param p_usart Pointer to a USART instance.
\r
912 * \param uc_type Indicate the checksum type: 0 if the wakeup signal is a LIN 2.0
\r
913 * wakeup signal; 1 if the wakeup signal is a LIN 1.3 wakeup signal.
\r
915 void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type)
\r
917 p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_WKUPTYP) |
\r
922 * \brief Configure the response data length if the data length is defined by
\r
923 * the DLC field during the LIN communication.
\r
925 * \param p_usart Pointer to a USART instance.
\r
926 * \param uc_len Indicate the response data length.
\r
928 void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len)
\r
930 p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLC_Msk) |
\r
931 (uc_len << US_LINMR_DLC_Pos);
\r
935 * \brief The LIN mode register is not written by the PDC.
\r
937 * \param p_usart Pointer to a USART instance.
\r
939 void usart_lin_disable_pdc_mode(Usart *p_usart)
\r
941 p_usart->US_LINMR &= ~US_LINMR_PDCM;
\r
945 * \brief The LIN mode register (except this flag) is written by the PDC.
\r
947 * \param p_usart Pointer to a USART instance.
\r
949 void usart_lin_enable_pdc_mode(Usart *p_usart)
\r
951 p_usart->US_LINMR |= US_LINMR_PDCM;
\r
955 * \brief Configure the LIN identifier when USART works in LIN master mode.
\r
957 * \param p_usart Pointer to a USART instance.
\r
958 * \param uc_id The identifier to be transmitted.
\r
960 void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id)
\r
962 p_usart->US_LINIR = (p_usart->US_LINIR & ~US_LINIR_IDCHR_Msk) |
\r
963 US_LINIR_IDCHR(uc_id);
\r
967 * \brief Read the identifier when USART works in LIN mode.
\r
969 * \param p_usart Pointer to a USART instance.
\r
971 * \return The last identifier received in LIN slave mode or the last identifier
\r
972 * transmitted in LIN master mode.
\r
974 uint8_t usart_lin_read_identifier(Usart *p_usart)
\r
976 return (p_usart->US_LINMR & US_LINIR_IDCHR_Msk);
\r
981 * \brief Enable USART transmitter.
\r
983 * \param p_usart Pointer to a USART instance.
\r
985 void usart_enable_tx(Usart *p_usart)
\r
987 p_usart->US_CR = US_CR_TXEN;
\r
991 * \brief Disable USART transmitter.
\r
993 * \param p_usart Pointer to a USART instance.
\r
995 void usart_disable_tx(Usart *p_usart)
\r
997 p_usart->US_CR = US_CR_TXDIS;
\r
1001 * \brief Immediately stop and disable USART transmitter.
\r
1003 * \param p_usart Pointer to a USART instance.
\r
1005 void usart_reset_tx(Usart *p_usart)
\r
1007 /* Reset transmitter */
\r
1008 p_usart->US_CR = US_CR_RSTTX | US_CR_TXDIS;
\r
1012 * \brief Configure the transmit timeguard register.
\r
1014 * \param p_usart Pointer to a USART instance.
\r
1015 * \param timeguard The value of transmit timeguard.
\r
1017 void usart_set_tx_timeguard(Usart *p_usart, uint32_t timeguard)
\r
1019 p_usart->US_TTGR = timeguard;
\r
1023 * \brief Enable USART receiver.
\r
1025 * \param p_usart Pointer to a USART instance.
\r
1027 void usart_enable_rx(Usart *p_usart)
\r
1029 p_usart->US_CR = US_CR_RXEN;
\r
1033 * \brief Disable USART receiver.
\r
1035 * \param p_usart Pointer to a USART instance.
\r
1037 void usart_disable_rx(Usart *p_usart)
\r
1039 p_usart->US_CR = US_CR_RXDIS;
\r
1043 * \brief Immediately stop and disable USART receiver.
\r
1045 * \param p_usart Pointer to a USART instance.
\r
1047 void usart_reset_rx(Usart *p_usart)
\r
1049 /* Reset Receiver */
\r
1050 p_usart->US_CR = US_CR_RSTRX | US_CR_RXDIS;
\r
1054 * \brief Configure the receive timeout register.
\r
1056 * \param p_usart Pointer to a USART instance.
\r
1057 * \param timeout The value of receive timeout.
\r
1059 void usart_set_rx_timeout(Usart *p_usart, uint32_t timeout)
\r
1061 p_usart->US_RTOR = timeout;
\r
1065 * \brief Enable USART interrupts.
\r
1067 * \param p_usart Pointer to a USART peripheral.
\r
1068 * \param ul_sources Interrupt sources bit map.
\r
1070 void usart_enable_interrupt(Usart *p_usart, uint32_t ul_sources)
\r
1072 p_usart->US_IER = ul_sources;
\r
1076 * \brief Disable USART interrupts.
\r
1078 * \param p_usart Pointer to a USART peripheral.
\r
1079 * \param ul_sources Interrupt sources bit map.
\r
1081 void usart_disable_interrupt(Usart *p_usart, uint32_t ul_sources)
\r
1083 p_usart->US_IDR = ul_sources;
\r
1087 * \brief Read USART interrupt mask.
\r
1089 * \param p_usart Pointer to a USART peripheral.
\r
1091 * \return The interrupt mask value.
\r
1093 uint32_t usart_get_interrupt_mask(Usart *p_usart)
\r
1095 return p_usart->US_IMR;
\r
1099 * \brief Get current status.
\r
1101 * \param p_usart Pointer to a USART instance.
\r
1103 * \return The current USART status.
\r
1105 uint32_t usart_get_status(Usart *p_usart)
\r
1107 return p_usart->US_CSR;
\r
1111 * \brief Reset status bits (PARE, OVER, MANERR, UNRE and PXBRK in US_CSR).
\r
1113 * \param p_usart Pointer to a USART instance.
\r
1115 void usart_reset_status(Usart *p_usart)
\r
1117 p_usart->US_CR = US_CR_RSTSTA;
\r
1121 * \brief Start transmission of a break.
\r
1123 * \param p_usart Pointer to a USART instance.
\r
1125 void usart_start_tx_break(Usart *p_usart)
\r
1127 p_usart->US_CR = US_CR_STTBRK;
\r
1131 * \brief Stop transmission of a break.
\r
1133 * \param p_usart Pointer to a USART instance.
\r
1135 void usart_stop_tx_break(Usart *p_usart)
\r
1137 p_usart->US_CR = US_CR_STPBRK;
\r
1141 * \brief Start waiting for a character before clocking the timeout count.
\r
1142 * Reset the status bit TIMEOUT in US_CSR.
\r
1144 * \param p_usart Pointer to a USART instance.
\r
1146 void usart_start_rx_timeout(Usart *p_usart)
\r
1148 p_usart->US_CR = US_CR_STTTO;
\r
1152 * \brief In Multidrop mode only, the next character written to the US_THR
\r
1153 * is sent with the address bit set.
\r
1155 * \param p_usart Pointer to a USART instance.
\r
1156 * \param ul_addr The address to be sent out.
\r
1158 * \retval 0 on success.
\r
1159 * \retval 1 on failure.
\r
1161 uint32_t usart_send_address(Usart *p_usart, uint32_t ul_addr)
\r
1163 if ((p_usart->US_MR & US_MR_PAR_MULTIDROP) != US_MR_PAR_MULTIDROP) {
\r
1167 p_usart->US_CR = US_CR_SENDA;
\r
1169 if (usart_write(p_usart, ul_addr)) {
\r
1177 * \brief Reset the ITERATION in US_CSR when the ISO7816 mode is enabled.
\r
1179 * \param p_usart Pointer to a USART instance.
\r
1181 void usart_reset_iterations(Usart *p_usart)
\r
1183 p_usart->US_CR = US_CR_RSTIT;
\r
1187 * \brief Reset NACK in US_CSR.
\r
1189 * \param p_usart Pointer to a USART instance.
\r
1191 void usart_reset_nack(Usart *p_usart)
\r
1193 p_usart->US_CR = US_CR_RSTNACK;
\r
1197 * \brief Restart the receive timeout.
\r
1199 * \param p_usart Pointer to a USART instance.
\r
1201 void usart_restart_rx_timeout(Usart *p_usart)
\r
1203 p_usart->US_CR = US_CR_RETTO;
\r
1206 #if (SAM3S || SAM4S || SAM3U)
\r
1208 * \brief Drive the pin DTR to 0.
\r
1210 * \param p_usart Pointer to a USART instance.
\r
1212 void usart_drive_DTR_pin_low(Usart *p_usart)
\r
1214 p_usart->US_CR = US_CR_DTREN;
\r
1218 * \brief Drive the pin DTR to 1.
\r
1220 * \param p_usart Pointer to a USART instance.
\r
1222 void usart_drive_DTR_pin_high(Usart *p_usart)
\r
1224 p_usart->US_CR = US_CR_DTRDIS;
\r
1229 * \brief Drive the pin RTS to 0.
\r
1231 * \param p_usart Pointer to a USART instance.
\r
1233 void usart_drive_RTS_pin_low(Usart *p_usart)
\r
1235 p_usart->US_CR = US_CR_RTSEN;
\r
1239 * \brief Drive the pin RTS to 1.
\r
1241 * \param p_usart Pointer to a USART instance.
\r
1243 void usart_drive_RTS_pin_high(Usart *p_usart)
\r
1245 p_usart->US_CR = US_CR_RTSDIS;
\r
1249 * \brief Drive the slave select line NSS (RTS pin) to 0 in SPI master mode.
\r
1251 * \param p_usart Pointer to a USART instance.
\r
1253 void usart_spi_force_chip_select(Usart *p_usart)
\r
1255 p_usart->US_CR = US_CR_FCS;
\r
1259 * \brief Drive the slave select line NSS (RTS pin) to 1 in SPI master mode.
\r
1261 * \param p_usart Pointer to a USART instance.
\r
1263 void usart_spi_release_chip_select(Usart *p_usart)
\r
1265 p_usart->US_CR = US_CR_RCS;
\r
1269 * \brief Check if Transmit is Ready.
\r
1270 * Check if data have been loaded in USART_THR and are waiting to be loaded
\r
1271 * into the Transmit Shift Register (TSR).
\r
1273 * \param p_usart Pointer to a USART instance.
\r
1275 * \retval 1 No data is in the Transmit Holding Register.
\r
1276 * \retval 0 There is data in the Transmit Holding Register.
\r
1278 uint32_t usart_is_tx_ready(Usart *p_usart)
\r
1280 return (p_usart->US_CSR & US_CSR_TXRDY) > 0;
\r
1284 * \brief Check if Transmit Holding Register is empty.
\r
1285 * Check if the last data written in USART_THR have been loaded in TSR and the last
\r
1286 * data loaded in TSR have been transmitted.
\r
1288 * \param p_usart Pointer to a USART instance.
\r
1290 * \retval 1 Transmitter is empty.
\r
1291 * \retval 0 Transmitter is not empty.
\r
1293 uint32_t usart_is_tx_empty(Usart *p_usart)
\r
1295 return (p_usart->US_CSR & US_CSR_TXEMPTY) > 0;
\r
1299 * \brief Check if the received data are ready.
\r
1300 * Check if Data have been received and loaded into USART_RHR.
\r
1302 * \param p_usart Pointer to a USART instance.
\r
1304 * \retval 1 Some data has been received.
\r
1305 * \retval 0 No data has been received.
\r
1307 uint32_t usart_is_rx_ready(Usart *p_usart)
\r
1309 return (p_usart->US_CSR & US_CSR_RXRDY) > 0;
\r
1313 * \brief Check if one receive buffer is filled.
\r
1315 * \param p_usart Pointer to a USART instance.
\r
1317 * \retval 1 Receive is complete.
\r
1318 * \retval 0 Receive is still pending.
\r
1320 uint32_t usart_is_rx_buf_end(Usart *p_usart)
\r
1322 return (p_usart->US_CSR & US_CSR_ENDRX) > 0;
\r
1326 * \brief Check if one transmit buffer is empty.
\r
1328 * \param p_usart Pointer to a USART instance.
\r
1330 * \retval 1 Transmit is complete.
\r
1331 * \retval 0 Transmit is still pending.
\r
1333 uint32_t usart_is_tx_buf_end(Usart *p_usart)
\r
1335 return (p_usart->US_CSR & US_CSR_ENDTX) > 0;
\r
1339 * \brief Check if both receive buffers are full.
\r
1341 * \param p_usart Pointer to a USART instance.
\r
1343 * \retval 1 Receive buffers are full.
\r
1344 * \retval 0 Receive buffers are not full.
\r
1346 uint32_t usart_is_rx_buf_full(Usart *p_usart)
\r
1348 return (p_usart->US_CSR & US_CSR_RXBUFF) > 0;
\r
1352 * \brief Check if both transmit buffers are empty.
\r
1354 * \param p_usart Pointer to a USART instance.
\r
1356 * \retval 1 Transmit buffers are empty.
\r
1357 * \retval 0 Transmit buffers are not empty.
\r
1359 uint32_t usart_is_tx_buf_empty(Usart *p_usart)
\r
1361 return (p_usart->US_CSR & US_CSR_TXBUFE) > 0;
\r
1365 * \brief Write to USART Transmit Holding Register.
\r
1367 * \note Before writing user should check if tx is ready (or empty).
\r
1369 * \param p_usart Pointer to a USART instance.
\r
1370 * \param c Data to be sent.
\r
1372 * \retval 0 on success.
\r
1373 * \retval 1 on failure.
\r
1375 uint32_t usart_write(Usart *p_usart, uint32_t c)
\r
1377 if (!(p_usart->US_CSR & US_CSR_TXRDY)) {
\r
1381 p_usart->US_THR = US_THR_TXCHR(c);
\r
1386 * \brief Write to USART Transmit Holding Register.
\r
1388 * \note Before writing user should check if tx is ready (or empty).
\r
1390 * \param p_usart Pointer to a USART instance.
\r
1391 * \param c Data to be sent.
\r
1393 * \retval 0 on success.
\r
1394 * \retval 1 on failure.
\r
1396 uint32_t usart_putchar(Usart *p_usart, uint32_t c)
\r
1398 uint32_t timeout = USART_DEFAULT_TIMEOUT;
\r
1400 while (!(p_usart->US_CSR & US_CSR_TXRDY)) {
\r
1406 p_usart->US_THR = US_THR_TXCHR(c);
\r
1412 * \brief Write one-line string through USART.
\r
1414 * \param p_usart Pointer to a USART instance.
\r
1415 * \param string Pointer to one-line string to be sent.
\r
1417 void usart_write_line(Usart *p_usart, const char *string)
\r
1419 while (*string != '\0') {
\r
1420 usart_putchar(p_usart, *string++);
\r
1425 * \brief Read from USART Receive Holding Register.
\r
1427 * \note Before reading user should check if rx is ready.
\r
1429 * \param p_usart Pointer to a USART instance.
\r
1430 * \param c Pointer where the one-byte received data will be stored.
\r
1432 * \retval 0 on success.
\r
1433 * \retval 1 if no data is available or errors.
\r
1435 uint32_t usart_read(Usart *p_usart, uint32_t *c)
\r
1437 if (!(p_usart->US_CSR & US_CSR_RXRDY)) {
\r
1441 /* Read character */
\r
1442 *c = p_usart->US_RHR & US_RHR_RXCHR_Msk;
\r
1448 * \brief Read from USART Receive Holding Register.
\r
1449 * Before reading user should check if rx is ready.
\r
1451 * \param p_usart Pointer to a USART instance.
\r
1452 * \param c Pointer where the one-byte received data will be stored.
\r
1454 * \retval 0 Data has been received.
\r
1455 * \retval 1 on failure.
\r
1457 uint32_t usart_getchar(Usart *p_usart, uint32_t *c)
\r
1459 uint32_t timeout = USART_DEFAULT_TIMEOUT;
\r
1461 /* If the receiver is empty, wait until it's not empty or timeout has reached. */
\r
1462 while (!(p_usart->US_CSR & US_CSR_RXRDY)) {
\r
1468 /* Read character */
\r
1469 *c = p_usart->US_RHR & US_RHR_RXCHR_Msk;
\r
1474 #if (SAM3XA || SAM3U)
\r
1476 * \brief Get Transmit address for DMA operation.
\r
1478 * \param p_usart Pointer to a USART instance.
\r
1480 * \return Transmit address for DMA access.
\r
1482 uint32_t *usart_get_tx_access(Usart *p_usart)
\r
1484 return (uint32_t *)&(p_usart->US_THR);
\r
1488 * \brief Get Receive address for DMA operation.
\r
1490 * \param p_usart Pointer to a USART instance.
\r
1492 * \return Receive address for DMA access.
\r
1494 uint32_t *usart_get_rx_access(Usart *p_usart)
\r
1496 return (uint32_t *)&(p_usart->US_RHR);
\r
1501 * \brief Get USART PDC base address.
\r
1503 * \param p_usart Pointer to a UART instance.
\r
1505 * \return USART PDC registers base for PDC driver to access.
\r
1507 Pdc *usart_get_pdc_base(Usart *p_usart)
\r
1511 p_pdc_base = (Pdc *) NULL;
\r
1513 if (p_usart == USART0) {
\r
1514 p_pdc_base = PDC_USART0;
\r
1515 return p_pdc_base;
\r
1517 #if (SAM3S || SAM4S || SAM3XA || SAM3U)
\r
1518 else if (p_usart == USART1) {
\r
1519 p_pdc_base = PDC_USART1;
\r
1520 return p_pdc_base;
\r
1523 #if (SAM3SD8 || SAM3XA || SAM3U)
\r
1524 else if (p_usart == USART2) {
\r
1525 p_pdc_base = PDC_USART2;
\r
1526 return p_pdc_base;
\r
1529 #if (SAM3XA || SAM3U)
\r
1530 else if (p_usart == USART3) {
\r
1531 p_pdc_base = PDC_USART3;
\r
1532 return p_pdc_base;
\r
1536 return p_pdc_base;
\r
1540 * \brief Enable write protect of USART registers.
\r
1542 * \param p_usart Pointer to a USART instance.
\r
1544 void usart_enable_writeprotect(Usart *p_usart)
\r
1546 p_usart->US_WPMR = US_WPMR_WPEN | US_WPMR_WPKEY(US_WPKEY_VALUE);
\r
1550 * \brief Disable write protect of USART registers.
\r
1552 * \param p_usart Pointer to a USART instance.
\r
1554 void usart_disable_writeprotect(Usart *p_usart)
\r
1556 p_usart->US_WPMR = US_WPMR_WPKEY(US_WPKEY_VALUE);
\r
1560 * \brief Get write protect status.
\r
1562 * \param p_usart Pointer to a USART instance.
\r
1564 * \return 0 if the peripheral is not protected.
\r
1565 * \return 16-bit Write Protect Violation Status otherwise.
\r
1567 uint32_t usart_get_writeprotect_status(Usart *p_usart)
\r
1569 uint32_t reg_value;
\r
1571 reg_value = p_usart->US_WPSR;
\r
1572 if (reg_value & US_WPSR_WPVS) {
\r
1573 return (reg_value & US_WPSR_WPVSRC_Msk) >> US_WPSR_WPVSRC_Pos;
\r
1580 * \brief Get the total number of errors that occur during an ISO7816 transfer.
\r
1582 * \param p_usart Pointer to a USART instance.
\r
1584 * \return The number of errors that occurred.
\r
1586 uint8_t usart_get_error_number(Usart *p_usart)
\r
1588 return (p_usart->US_NER & US_NER_NB_ERRORS_Msk);
\r
1591 #if (SAM3S || SAM4S || SAM3U || SAM3XA)
\r
1593 * \brief Configure the transmitter preamble length when the Manchester
\r
1594 * encode/decode is enabled.
\r
1596 * \param p_usart Pointer to a USART instance.
\r
1597 * \param uc_len The transmitter preamble length, which should be 0 ~ 15.
\r
1599 void usart_man_set_tx_pre_len(Usart *p_usart, uint8_t uc_len)
\r
1601 p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PL_Msk) |
\r
1602 US_MAN_TX_PL(uc_len);
\r
1606 * \brief Configure the transmitter preamble pattern when the Manchester
\r
1607 * encode/decode is enabled, which should be 0 ~ 3.
\r
1609 * \param p_usart Pointer to a USART instance.
\r
1610 * \param uc_pattern 0 if the preamble is composed of '1's;
\r
1611 * 1 if the preamble is composed of '0's;
\r
1612 * 2 if the preamble is composed of '01's;
\r
1613 * 3 if the preamble is composed of '10's.
\r
1615 void usart_man_set_tx_pre_pattern(Usart *p_usart, uint8_t uc_pattern)
\r
1617 p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PP_Msk) |
\r
1618 (uc_pattern << US_MAN_TX_PP_Pos);
\r
1622 * \brief Configure the transmitter Manchester polarity when the Manchester
\r
1623 * encode/decode is enabled.
\r
1625 * \param p_usart Pointer to a USART instance.
\r
1626 * \param uc_polarity Indicate the transmitter Manchester polarity, which
\r
1627 * should be 0 or 1.
\r
1629 void usart_man_set_tx_polarity(Usart *p_usart, uint8_t uc_polarity)
\r
1631 p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_MPOL) |
\r
1632 (uc_polarity << 12);
\r
1636 * \brief Configure the detected receiver preamble length when the Manchester
\r
1637 * encode/decode is enabled.
\r
1639 * \param p_usart Pointer to a USART instance.
\r
1640 * \param uc_len The detected receiver preamble length, which should be 0 ~ 15.
\r
1642 void usart_man_set_rx_pre_len(Usart *p_usart, uint8_t uc_len)
\r
1644 p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PL_Msk) |
\r
1645 US_MAN_RX_PL(uc_len);
\r
1649 * \brief Configure the detected receiver preamble pattern when the Manchester
\r
1650 * encode/decode is enabled, which should be 0 ~ 3.
\r
1652 * \param p_usart Pointer to a USART instance.
\r
1653 * \param uc_pattern 0 if the preamble is composed of '1's;
\r
1654 * 1 if the preamble is composed of '0's;
\r
1655 * 2 if the preamble is composed of '01's;
\r
1656 * 3 if the preamble is composed of '10's.
\r
1658 void usart_man_set_rx_pre_pattern(Usart *p_usart, uint8_t uc_pattern)
\r
1660 p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PP_Msk) |
\r
1661 (uc_pattern << US_MAN_RX_PP_Pos);
\r
1665 * \brief Configure the receiver Manchester polarity when the Manchester
\r
1666 * encode/decode is enabled.
\r
1668 * \param p_usart Pointer to a USART instance.
\r
1669 * \param uc_polarity Indicate the receiver Manchester polarity, which should
\r
1672 void usart_man_set_rx_polarity(Usart *p_usart, uint8_t uc_polarity)
\r
1674 p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_MPOL) |
\r
1675 (uc_polarity << 28);
\r
1679 * \brief Enable drift compensation.
\r
1681 * \note The 16X clock mode must be enabled.
\r
1683 * \param p_usart Pointer to a USART instance.
\r
1685 void usart_man_enable_drift_compensation(Usart *p_usart)
\r
1687 p_usart->US_MAN |= US_MAN_DRIFT;
\r
1691 * \brief Disable drift compensation.
\r
1693 * \param p_usart Pointer to a USART instance.
\r
1695 void usart_man_disable_drift_compensation(Usart *p_usart)
\r
1697 p_usart->US_MAN &= ~US_MAN_DRIFT;
\r
1705 #ifdef __cplusplus
\r