]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_ATSAM3S-EK2_Atmel_Studio/src/asf/sam/drivers/usart/usart.c
Add demo for SAM3S-EK2.
[freertos] / FreeRTOS / Demo / CORTEX_ATSAM3S-EK2_Atmel_Studio / src / asf / sam / drivers / usart / usart.c
1 /**\r
2  * \file\r
3  *\r
4  * \brief Universal Synchronous Asynchronous Receiver Transmitter (USART) driver for SAM.\r
5  *\r
6  * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.\r
7  *\r
8  * \asf_license_start\r
9  *\r
10  * \page License\r
11  *\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
14  *\r
15  * 1. Redistributions of source code must retain the above copyright notice,\r
16  *    this list of conditions and the following disclaimer.\r
17  *\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
21  *\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
24  *\r
25  * 4. This software may only be redistributed and used in connection with an\r
26  *    Atmel microcontroller product.\r
27  *\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
39  *\r
40  * \asf_license_stop\r
41  *\r
42  */\r
43  \r
44 #include "usart.h"\r
45 \r
46 /// @cond 0\r
47 /**INDENT-OFF**/\r
48 #ifdef __cplusplus\r
49 extern "C" {\r
50 #endif\r
51 /**INDENT-ON**/\r
52 /// @endcond\r
53 \r
54 /**\r
55  * \defgroup sam_drivers_usart_group Universal Synchronous Asynchronous Receiver Transmitter (USART)\r
56  *\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
66  *\r
67  * @{\r
68  */\r
69 \r
70 /* The write protect key value. */\r
71 #define US_WPKEY_VALUE                0x555341\r
72 \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
77 \r
78 /* Define the default time-out value for USART. */\r
79 #define USART_DEFAULT_TIMEOUT         1000\r
80 \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
84 \r
85 /* Max transmitter timeguard. */\r
86 #define MAX_TRAN_GUARD_TIME           US_TTGR_TG_Msk\r
87 \r
88 /* The non-existent parity error number. */\r
89 #define USART_PARITY_ERROR            5\r
90 \r
91 /* ISO7816 protocol type. */\r
92 #define ISO7816_T_0                   0\r
93 #define ISO7816_T_1                   1\r
94 \r
95 /**\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
99  *\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
103  *\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
107  *\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
110  * frequency.\r
111  */\r
112 static uint32_t usart_set_async_baudrate(Usart *p_usart,\r
113                 uint32_t baudrate, uint32_t ul_mck)\r
114 {\r
115         uint32_t over;\r
116         uint32_t cd_fp;\r
117         uint32_t cd;\r
118         uint32_t fp;\r
119 \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
123         } else {\r
124                 over = LOW_FRQ_SAMPLE_DIV;\r
125         }\r
126 \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
129         cd = cd_fp >> 3;\r
130         fp = cd_fp & 0x07;\r
131         if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {\r
132                 return 1;\r
133         }\r
134 \r
135         /* Configure the OVER bit in MR register. */\r
136         if (over == 8) {\r
137                 p_usart->US_MR |= US_MR_OVER;\r
138         }\r
139 \r
140         /* Configure the baudrate generate register. */\r
141         p_usart->US_BRGR = (cd << US_BRGR_CD_Pos) | (fp << US_BRGR_FP_Pos);\r
142 \r
143         return 0;\r
144 }\r
145 \r
146 /**\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
149  *\r
150  * \note Synchronous baudrate calculation: baudrate = ul_mck / cd\r
151  *\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
155  *\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
158  * frequency.\r
159  */\r
160 static uint32_t usart_set_sync_master_baudrate(Usart *p_usart,\r
161                 uint32_t baudrate, uint32_t ul_mck)\r
162 {\r
163         uint32_t cd;\r
164 \r
165         /* Calculate the clock divider according to the formula in synchronous mode. */\r
166         cd = (ul_mck + baudrate / 2) / baudrate;\r
167 \r
168         if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {\r
169                 return 1;\r
170         }\r
171 \r
172         /* Configure the baudrate generate register. */\r
173         p_usart->US_BRGR = cd << US_BRGR_CD_Pos;\r
174 \r
175         p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) |\r
176                         US_MR_USCLKS_MCK | US_MR_SYNC;\r
177         return 0;\r
178 }\r
179 \r
180 /**\r
181  * \brief Select the SCK pin as the source of baud rate for the USART\r
182  * synchronous slave modes.\r
183  *\r
184  * \param p_usart Pointer to a USART instance.\r
185  */\r
186 static void usart_set_sync_slave_baudrate(Usart *p_usart)\r
187 {\r
188         p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) |\r
189                         US_MR_USCLKS_SCK | US_MR_SYNC;\r
190 }\r
191 \r
192 \r
193 /**\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
196  *\r
197  * \note ISO7816 clock calculation: Clock = ul_mck / cd\r
198  *\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
202  *\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
205  * frequency.\r
206  */\r
207 static uint32_t usart_set_iso7816_clock(Usart *p_usart,\r
208                 uint32_t clock, uint32_t ul_mck)\r
209 {\r
210         uint32_t cd;\r
211 \r
212         /* Calculate the clock divider according to the formula in ISO7816 mode. */\r
213         cd = (ul_mck + clock / 2) / clock;\r
214 \r
215         if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) {\r
216                 return 1;\r
217         }\r
218 \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
221 \r
222         /* Configure the baudrate generate register. */\r
223         p_usart->US_BRGR = cd << US_BRGR_CD_Pos;\r
224 \r
225         return 0;\r
226 }\r
227 \r
228 /**\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
231  *\r
232  * \note Baud rate calculation:\r
233  * \f$ Baudrate = \frac{SelectedClock}{CD} \f$.\r
234  *\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
238  *\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
241  * frequency.\r
242  */\r
243 static uint32_t usart_set_spi_master_baudrate(Usart *p_usart,\r
244                 uint32_t baudrate, uint32_t ul_mck)\r
245 {\r
246         uint32_t cd;\r
247 \r
248         /* Calculate the clock divider according to the formula in SPI mode. */\r
249         cd = (ul_mck + baudrate / 2) / baudrate;\r
250 \r
251         if (cd < MIN_CD_VALUE_SPI || cd > MAX_CD_VALUE) {\r
252                 return 1;\r
253         }\r
254 \r
255         p_usart->US_BRGR = cd << US_BRGR_CD_Pos;\r
256 \r
257         return 0;\r
258 }\r
259 \r
260 /**\r
261  * \brief Select the SCK pin as the source of baudrate for the USART SPI slave \r
262  * mode.\r
263  *\r
264  * \param p_usart Pointer to a USART instance.\r
265  */\r
266 static void usart_set_spi_slave_baudrate(Usart *p_usart)\r
267 {\r
268         p_usart->US_MR &= ~US_MR_USCLKS_Msk;\r
269         p_usart->US_MR |= US_MR_USCLKS_SCK;\r
270 }\r
271 \r
272 /**\r
273  * \brief Reset the USART and disable TX and RX.\r
274  *\r
275  * \param p_usart Pointer to a USART instance.\r
276  */\r
277 void usart_reset(Usart *p_usart)\r
278 {\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
281 \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
286 \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
294 #endif\r
295 }\r
296 \r
297 /**\r
298  * \brief Configure USART to work in RS232 mode.\r
299  *\r
300  * \note By default, the transmitter and receiver aren't enabled.\r
301  *\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
305  *\r
306  * \retval 0 on success.\r
307  * \retval 1 on failure.\r
308  */\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
311 {\r
312         static uint32_t ul_reg_val;\r
313 \r
314         /* Reset the USART and shut down TX and RX. */\r
315         usart_reset(p_usart);\r
316 \r
317         ul_reg_val = 0;\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
321                 return 1;\r
322         }\r
323 \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
327         \r
328         /* Configure the USART mode as normal mode. */\r
329         ul_reg_val |= US_MR_USART_MODE_NORMAL;\r
330         \r
331         p_usart->US_MR |= ul_reg_val;\r
332         \r
333         return 0;\r
334 }\r
335 \r
336 /**\r
337  * \brief Configure USART to work in hardware handshaking mode.\r
338  *\r
339  * \note By default, the transmitter and receiver aren't enabled.\r
340  *\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
344  *\r
345  * \retval 0 on success.\r
346  * \retval 1 on failure.\r
347  */\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
350 {\r
351         /* Initialize the USART as standard RS232. */\r
352         if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {\r
353                 return 1;\r
354         }\r
355 \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
359 \r
360         return 0;\r
361 }\r
362 \r
363 #if (SAM3S || SAM4S || SAM3U)\r
364 /**\r
365  * \brief Configure USART to work in modem mode.\r
366  *\r
367  * \note By default, the transmitter and receiver aren't enabled.\r
368  *\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
372  *\r
373  * \retval 0 on success.\r
374  * \retval 1 on failure.\r
375  */\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
378 {\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
383                 return 1;\r
384         }\r
385 #elif (SAM3U)\r
386         if (p_usart != USART0) {\r
387                 return 1;\r
388         }\r
389 #endif\r
390 \r
391         /* Initialize the USART as standard RS232. */\r
392         if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {\r
393                 return 1;\r
394         }\r
395         \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
399 \r
400         return 0;\r
401 }\r
402 #endif\r
403 \r
404 /**\r
405  * \brief Configure USART to work in SYNC mode and act as a master.\r
406  *\r
407  * \note By default, the transmitter and receiver aren't enabled.\r
408  *\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
412  *\r
413  * \retval 0 on success.\r
414  * \retval 1 on failure.\r
415  */\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
418 {\r
419         static uint32_t ul_reg_val;\r
420 \r
421         /* Reset the USART and shut down TX and RX. */\r
422         usart_reset(p_usart);\r
423 \r
424         ul_reg_val = 0;\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
428                 return 1;\r
429         }\r
430 \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
434         \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
438 \r
439         return 0;\r
440 }\r
441 \r
442 /**\r
443  * \brief Configure USART to work in SYNC mode and act as a slave.\r
444  *\r
445  * \note By default, the transmitter and receiver aren't enabled.\r
446  *\r
447  * \param p_usart Pointer to a USART instance.\r
448  * \param p_usart_opt Pointer to sam_usart_opt_t instance.\r
449  *\r
450  * \retval 0 on success.\r
451  * \retval 1 on failure.\r
452  */\r
453 uint32_t usart_init_sync_slave(Usart *p_usart,\r
454                 const sam_usart_opt_t *p_usart_opt)\r
455 {\r
456         static uint32_t ul_reg_val;\r
457         \r
458         /* Reset the USART and shut down TX and RX. */\r
459         usart_reset(p_usart);\r
460         \r
461         ul_reg_val = 0;\r
462         usart_set_sync_slave_baudrate(p_usart);\r
463         \r
464         /* Check whether the input values are legal. */\r
465         if (!p_usart_opt) {\r
466                 return 1;\r
467         }\r
468 \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
472 \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
476 \r
477         return 0;\r
478 }\r
479 \r
480 /**\r
481  * \brief Configure USART to work in RS485 mode.\r
482  *\r
483  * \note By default, the transmitter and receiver aren't enabled.\r
484  *\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
488  *\r
489  * \retval 0 on success.\r
490  * \retval 1 on failure.\r
491  */\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
494 {\r
495         /* Initialize the USART as standard RS232. */\r
496         if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {\r
497                 return 1;\r
498         }\r
499 \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
503 \r
504         return 0;\r
505 }\r
506 \r
507 /**\r
508  * \brief Configure USART to work in IrDA mode.\r
509  *\r
510  * \note By default, the transmitter and receiver aren't enabled.\r
511  *\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
515  *\r
516  * \retval 0 on success.\r
517  * \retval 1 on failure.\r
518  */\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
521 {\r
522         /* Initialize the USART as standard RS232. */\r
523         if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) {\r
524                 return 1;\r
525         }\r
526 \r
527         /* Set IrDA filter. */\r
528         p_usart->US_IF = p_usart_opt->irda_filter;\r
529 \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
533 \r
534         return 0;\r
535 }\r
536 \r
537 /**\r
538  * \brief Configure USART to work in ISO7816 mode.\r
539  *\r
540  * \note By default, the transmitter and receiver aren't enabled.\r
541  *\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
545  *\r
546  * \retval 0 on success.\r
547  * \retval 1 on failure.\r
548  */\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
551 {\r
552         static uint32_t ul_reg_val;\r
553         \r
554         /* Reset the USART and shut down TX and RX. */\r
555         usart_reset(p_usart);\r
556         \r
557         ul_reg_val = 0;\r
558         \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
562                 return 1;\r
563         }\r
564         \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
568 \r
569                 if (p_usart_opt->bit_order) {\r
570                         ul_reg_val |= US_MR_MSBF;\r
571                 }\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
575                         return 1;\r
576                 }\r
577                 \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
580         } else {\r
581                 return 1;\r
582         }\r
583 \r
584         /* Set up the baudrate. */\r
585         if (usart_set_iso7816_clock(p_usart, p_usart_opt->iso7816_hz, ul_mck)) {\r
586                 return 1;\r
587         }\r
588 \r
589         /* Set FIDI register: bit rate = iso7816_hz / fidi_ratio. */\r
590         p_usart->US_FIDI = p_usart_opt->fidi_ratio;\r
591 \r
592         /* Set ISO7816 parity type in the MODE register. */\r
593         ul_reg_val |= p_usart_opt->parity_type;\r
594         \r
595         if (p_usart_opt->inhibit_nack) {\r
596                 ul_reg_val |= US_MR_INACK;\r
597         }\r
598         if (p_usart_opt->dis_suc_nack) {\r
599                 ul_reg_val |= US_MR_DSNACK;\r
600         }\r
601         \r
602         p_usart->US_MR |= ul_reg_val;\r
603 \r
604         return 0;\r
605 }\r
606 \r
607 /**\r
608  * \brief Configure USART to work in SPI mode and act as a master.\r
609  *\r
610  * \note By default, the transmitter and receiver aren't enabled.\r
611  *\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
615  *\r
616  * \retval 0 on success.\r
617  * \retval 1 on failure.\r
618  */\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
621 {\r
622         static uint32_t ul_reg_val;\r
623         \r
624         /* Reset the USART and shut down TX and RX. */\r
625         usart_reset(p_usart);\r
626         \r
627         ul_reg_val = 0;\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
632                 return 1;\r
633         }\r
634 \r
635         /* Configure the character length bit in MR register. */\r
636         ul_reg_val |= p_usart_opt->char_length;\r
637         \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
641                                         \r
642         switch (p_usart_opt->spi_mode) {\r
643         case SPI_MODE_0:\r
644                 ul_reg_val |= US_MR_CPHA;\r
645                 ul_reg_val &= ~US_MR_CPOL;\r
646                 break;\r
647         case SPI_MODE_1:\r
648                 ul_reg_val &= ~US_MR_CPHA;\r
649                 ul_reg_val &= ~US_MR_CPOL;\r
650                 break;\r
651         case SPI_MODE_2:\r
652                 ul_reg_val |= US_MR_CPHA;\r
653                 ul_reg_val |= US_MR_CPOL;\r
654                 break;\r
655         case SPI_MODE_3:\r
656                 ul_reg_val |= US_MR_CPOL;\r
657                 ul_reg_val &= ~US_MR_CPHA;\r
658                 break;\r
659         default:\r
660                 break;\r
661         }\r
662         \r
663         p_usart->US_MR |= ul_reg_val;\r
664 \r
665         return 0;\r
666 }\r
667 \r
668 /**\r
669  * \brief Configure USART to work in SPI mode and act as a slave.\r
670  *\r
671  * \note By default, the transmitter and receiver aren't enabled.\r
672  *\r
673  * \param p_usart Pointer to a USART instance.\r
674  * \param p_usart_opt Pointer to sam_usart_opt_t instance.\r
675  *\r
676  * \retval 0 on success.\r
677  * \retval 1 on failure.\r
678  */\r
679 uint32_t usart_init_spi_slave(Usart *p_usart,\r
680                 const usart_spi_opt_t *p_usart_opt)\r
681 {\r
682         static uint32_t ul_reg_val;\r
683 \r
684         /* Reset the USART and shut down TX and RX. */\r
685         usart_reset(p_usart);\r
686         \r
687         ul_reg_val = 0;\r
688         usart_set_spi_slave_baudrate(p_usart);\r
689         \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
693                 return 1;\r
694         }\r
695 \r
696         /* Configure the character length bit in MR register. */\r
697         ul_reg_val |= p_usart_opt->char_length;\r
698         \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
701                                         \r
702         switch (p_usart_opt->spi_mode) {\r
703         case SPI_MODE_0:\r
704                 ul_reg_val |= US_MR_CPHA;\r
705                 ul_reg_val &= ~US_MR_CPOL;\r
706                 break;\r
707         case SPI_MODE_1:\r
708                 ul_reg_val &= ~US_MR_CPHA;\r
709                 ul_reg_val &= ~US_MR_CPOL;\r
710                 break;\r
711         case SPI_MODE_2:\r
712                 ul_reg_val |= US_MR_CPHA;\r
713                 ul_reg_val |= US_MR_CPOL;\r
714                 break;\r
715         case SPI_MODE_3:\r
716                 ul_reg_val |= US_MR_CPOL;\r
717                 ul_reg_val &= ~US_MR_CPHA;\r
718                 break;\r
719         default:\r
720                 break;\r
721         }\r
722 \r
723         p_usart->US_MR |= ul_reg_val;\r
724 \r
725         return 0;\r
726 }\r
727 \r
728 #if SAM3XA\r
729 /**\r
730  * \brief Configure USART to work in LIN mode and act as a LIN master.\r
731  *\r
732  * \note By default, the transmitter and receiver aren't enabled.\r
733  *\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
737  *\r
738  * \retval 0 on success.\r
739  * \retval 1 on failure.\r
740  */\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
743 {\r
744         /* Reset the USART and shut down TX and RX. */\r
745         usart_reset(p_usart);\r
746 \r
747         /* Set up the baudrate. */\r
748         if (usart_set_async_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) {\r
749                 return 1;\r
750         }\r
751         \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
755 \r
756         return 0;\r
757 }\r
758 \r
759 /**\r
760  * \brief Configure USART to work in LIN mode and act as a LIN slave.\r
761  *\r
762  * \note By default, the transmitter and receiver aren't enabled.\r
763  *\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
767  *\r
768  * \retval 0 on success.\r
769  * \retval 1 on failure.\r
770  */\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
773 {\r
774         /* Reset the USART and shut down TX and RX. */\r
775         usart_reset(p_usart);\r
776 \r
777         /* Set up the baudrate. */\r
778         if (usart_set_async_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) {\r
779                 return 1;\r
780         }\r
781         \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
785 \r
786         return 0;\r
787 }\r
788 \r
789 /**\r
790  * \brief Abort the current LIN transmission.\r
791  *\r
792  * \param p_usart Pointer to a USART instance.\r
793  */\r
794 void usart_lin_abort_tx(Usart *p_usart)\r
795 {\r
796         p_usart->US_CR = US_CR_LINABT;\r
797 }\r
798 \r
799 /**\r
800  * \brief Send a wakeup signal on the LIN bus.\r
801  *\r
802  * \param p_usart Pointer to a USART instance.\r
803  */\r
804 void usart_lin_send_wakeup_signal(Usart *p_usart)\r
805 {\r
806         p_usart->US_CR = US_CR_LINWKUP;\r
807 }\r
808 \r
809 /**\r
810  * \brief Configure the LIN node action, which should be one of PUBLISH,\r
811  * SUBSCRIBE or IGNORE.\r
812  *\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
815  */\r
816 void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action)\r
817 {\r
818         p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_NACT_Msk) |\r
819                                         (uc_action << US_LINMR_NACT_Pos);\r
820 }\r
821 \r
822 /**\r
823  * \brief Disable the parity check during the LIN communication.\r
824  *\r
825  * \param p_usart Pointer to a USART instance.\r
826  */\r
827 void usart_lin_disable_parity(Usart *p_usart)\r
828 {\r
829         p_usart->US_LINMR |= US_LINMR_PARDIS;\r
830 }\r
831 \r
832 /**\r
833  * \brief Enable the parity check during the LIN communication.\r
834  *\r
835  * \param p_usart Pointer to a USART instance.\r
836  */\r
837 void usart_lin_enable_parity(Usart *p_usart)\r
838 {\r
839         p_usart->US_LINMR &= ~US_LINMR_PARDIS;\r
840 }\r
841 \r
842 /**\r
843  * \brief Disable the checksum during the LIN communication.\r
844  *\r
845  * \param p_usart Pointer to a USART instance.\r
846  */\r
847 void usart_lin_disable_checksum(Usart *p_usart)\r
848 {\r
849         p_usart->US_LINMR |= US_LINMR_CHKDIS;\r
850 }\r
851 \r
852 /**\r
853  * \brief Enable the checksum during the LIN communication.\r
854  *\r
855  * \param p_usart Pointer to a USART instance.\r
856  */\r
857 void usart_lin_enable_checksum(Usart *p_usart)\r
858 {\r
859         p_usart->US_LINMR &= ~US_LINMR_CHKDIS;\r
860 }\r
861 \r
862 /**\r
863  * \brief Configure the checksum type during the LIN communication.\r
864  *\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
867  */\r
868 void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type)\r
869 {\r
870         p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_CHKTYP) |\r
871                         (uc_type << 4);\r
872 }\r
873 \r
874 /**\r
875  * \brief Configure the data length mode during the LIN communication.\r
876  *\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
880  * the identifier.\r
881  */\r
882 void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode)\r
883 {\r
884         p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLM) |\r
885                         (uc_mode << 5);\r
886 }\r
887 \r
888 /**\r
889  * \brief Disable the frame slot mode during the LIN communication.\r
890  *\r
891  * \param p_usart Pointer to a USART instance.\r
892  */\r
893 void usart_lin_disable_frame_slot(Usart *p_usart)\r
894 {\r
895         p_usart->US_LINMR |= US_LINMR_FSDIS;\r
896 }\r
897 \r
898 /**\r
899  * \brief Enable the frame slot mode during the LIN communication.\r
900  *\r
901  * \param p_usart Pointer to a USART instance.\r
902  */\r
903 void usart_lin_enable_frame_slot(Usart *p_usart)\r
904 {\r
905         p_usart->US_LINMR &= ~US_LINMR_FSDIS;\r
906 }\r
907 \r
908 /**\r
909  * \brief Configure the wakeup signal type during the LIN communication.\r
910  *\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
914  */\r
915 void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type)\r
916 {\r
917         p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_WKUPTYP) |\r
918                                         (uc_type << 7);\r
919 }\r
920 \r
921 /**\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
924  *\r
925  * \param p_usart Pointer to a USART instance.\r
926  * \param uc_len Indicate the response data length.\r
927  */\r
928 void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len)\r
929 {\r
930         p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLC_Msk) |\r
931                         (uc_len << US_LINMR_DLC_Pos);\r
932 }\r
933 \r
934 /**\r
935  * \brief The LIN mode register is not written by the PDC.\r
936  *\r
937  * \param p_usart Pointer to a USART instance.\r
938  */\r
939 void usart_lin_disable_pdc_mode(Usart *p_usart)\r
940 {\r
941         p_usart->US_LINMR &= ~US_LINMR_PDCM;\r
942 }\r
943 \r
944 /**\r
945  * \brief The LIN mode register (except this flag) is written by the PDC.\r
946  *\r
947  * \param p_usart Pointer to a USART instance.\r
948  */\r
949 void usart_lin_enable_pdc_mode(Usart *p_usart)\r
950 {\r
951         p_usart->US_LINMR |= US_LINMR_PDCM;\r
952 }\r
953 \r
954 /**\r
955  * \brief Configure the LIN identifier when USART works in LIN master mode.\r
956  *\r
957  * \param p_usart Pointer to a USART instance.\r
958  * \param uc_id The identifier to be transmitted.\r
959  */\r
960 void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id)\r
961 {\r
962         p_usart->US_LINIR = (p_usart->US_LINIR & ~US_LINIR_IDCHR_Msk) |\r
963                         US_LINIR_IDCHR(uc_id);\r
964 }\r
965 \r
966 /**\r
967  * \brief Read the identifier when USART works in LIN mode.\r
968  *\r
969  * \param p_usart Pointer to a USART instance.\r
970  *\r
971  * \return The last identifier received in LIN slave mode or the last identifier \r
972  * transmitted in LIN master mode. \r
973  */\r
974 uint8_t usart_lin_read_identifier(Usart *p_usart)\r
975 {\r
976         return (p_usart->US_LINMR & US_LINIR_IDCHR_Msk);\r
977 }\r
978 #endif\r
979 \r
980 /**\r
981  * \brief Enable USART transmitter.\r
982  *\r
983  * \param p_usart Pointer to a USART instance.\r
984  */\r
985 void usart_enable_tx(Usart *p_usart)\r
986 {\r
987         p_usart->US_CR = US_CR_TXEN;\r
988 }\r
989 \r
990 /**\r
991  * \brief Disable USART transmitter.\r
992  *\r
993  * \param p_usart Pointer to a USART instance.\r
994  */\r
995 void usart_disable_tx(Usart *p_usart)\r
996 {\r
997         p_usart->US_CR = US_CR_TXDIS;\r
998 }\r
999 \r
1000 /**\r
1001  * \brief Immediately stop and disable USART transmitter.\r
1002  *\r
1003  * \param p_usart Pointer to a USART instance.\r
1004  */\r
1005 void usart_reset_tx(Usart *p_usart)\r
1006 {\r
1007         /* Reset transmitter */\r
1008         p_usart->US_CR = US_CR_RSTTX | US_CR_TXDIS;\r
1009 }\r
1010 \r
1011 /**\r
1012  * \brief Configure the transmit timeguard register.\r
1013  *\r
1014  * \param p_usart Pointer to a USART instance.\r
1015  * \param timeguard The value of transmit timeguard.\r
1016  */\r
1017 void usart_set_tx_timeguard(Usart *p_usart, uint32_t timeguard)\r
1018 {\r
1019         p_usart->US_TTGR = timeguard;\r
1020 }\r
1021 \r
1022 /**\r
1023  * \brief Enable USART receiver.\r
1024  *\r
1025  * \param p_usart Pointer to a USART instance.\r
1026  */\r
1027 void usart_enable_rx(Usart *p_usart)\r
1028 {\r
1029         p_usart->US_CR = US_CR_RXEN;\r
1030 }\r
1031 \r
1032 /**\r
1033  * \brief Disable USART receiver.\r
1034  *\r
1035  * \param p_usart Pointer to a USART instance.\r
1036  */\r
1037 void usart_disable_rx(Usart *p_usart)\r
1038 {\r
1039         p_usart->US_CR = US_CR_RXDIS;\r
1040 }\r
1041 \r
1042 /**\r
1043  * \brief Immediately stop and disable USART receiver.\r
1044  *\r
1045  * \param p_usart Pointer to a USART instance.\r
1046  */\r
1047 void usart_reset_rx(Usart *p_usart)\r
1048 {\r
1049         /* Reset Receiver */\r
1050         p_usart->US_CR = US_CR_RSTRX | US_CR_RXDIS;\r
1051 }\r
1052 \r
1053 /**\r
1054  * \brief Configure the receive timeout register.\r
1055  *\r
1056  * \param p_usart Pointer to a USART instance.\r
1057  * \param timeout The value of receive timeout.\r
1058  */\r
1059 void usart_set_rx_timeout(Usart *p_usart, uint32_t timeout)\r
1060 {\r
1061         p_usart->US_RTOR = timeout;\r
1062 }\r
1063 \r
1064 /**\r
1065  * \brief Enable USART interrupts.\r
1066  *\r
1067  * \param p_usart Pointer to a USART peripheral.\r
1068  * \param ul_sources Interrupt sources bit map.\r
1069  */\r
1070 void usart_enable_interrupt(Usart *p_usart, uint32_t ul_sources)\r
1071 {\r
1072         p_usart->US_IER = ul_sources;\r
1073 }\r
1074 \r
1075 /**\r
1076  * \brief Disable USART interrupts.\r
1077  *\r
1078  * \param p_usart Pointer to a USART peripheral.\r
1079  * \param ul_sources Interrupt sources bit map.\r
1080  */\r
1081 void usart_disable_interrupt(Usart *p_usart, uint32_t ul_sources)\r
1082 {\r
1083         p_usart->US_IDR = ul_sources;\r
1084 }\r
1085 \r
1086 /**\r
1087  * \brief Read USART interrupt mask.\r
1088  *\r
1089  * \param p_usart Pointer to a USART peripheral.\r
1090  *\r
1091  * \return The interrupt mask value.\r
1092  */\r
1093 uint32_t usart_get_interrupt_mask(Usart *p_usart)\r
1094 {\r
1095         return p_usart->US_IMR;\r
1096 }\r
1097 \r
1098 /**\r
1099  * \brief Get current status.\r
1100  *\r
1101  * \param p_usart Pointer to a USART instance.\r
1102  *\r
1103  * \return The current USART status.\r
1104  */\r
1105 uint32_t usart_get_status(Usart *p_usart)\r
1106 {\r
1107         return p_usart->US_CSR;\r
1108 }\r
1109 \r
1110 /**\r
1111  * \brief Reset status bits (PARE, OVER, MANERR, UNRE and PXBRK in US_CSR).\r
1112  *\r
1113  * \param p_usart Pointer to a USART instance.\r
1114  */\r
1115 void usart_reset_status(Usart *p_usart)\r
1116 {\r
1117         p_usart->US_CR = US_CR_RSTSTA;\r
1118 }\r
1119 \r
1120 /**\r
1121  * \brief Start transmission of a break.\r
1122  *\r
1123  * \param p_usart Pointer to a USART instance.\r
1124  */\r
1125 void usart_start_tx_break(Usart *p_usart)\r
1126 {\r
1127         p_usart->US_CR = US_CR_STTBRK;\r
1128 }\r
1129 \r
1130 /**\r
1131  * \brief Stop transmission of a break.\r
1132  *\r
1133  * \param p_usart Pointer to a USART instance.\r
1134  */\r
1135 void usart_stop_tx_break(Usart *p_usart)\r
1136 {\r
1137         p_usart->US_CR = US_CR_STPBRK;\r
1138 }\r
1139 \r
1140 /**\r
1141  * \brief Start waiting for a character before clocking the timeout count.\r
1142  * Reset the status bit TIMEOUT in US_CSR. \r
1143  *\r
1144  * \param p_usart Pointer to a USART instance.\r
1145  */\r
1146 void usart_start_rx_timeout(Usart *p_usart)\r
1147 {\r
1148         p_usart->US_CR = US_CR_STTTO;\r
1149 }\r
1150 \r
1151 /**\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
1154  *\r
1155  * \param p_usart Pointer to a USART instance.\r
1156  * \param ul_addr The address to be sent out.\r
1157  *\r
1158  * \retval 0 on success.\r
1159  * \retval 1 on failure.\r
1160  */\r
1161 uint32_t usart_send_address(Usart *p_usart, uint32_t ul_addr)\r
1162 {\r
1163         if ((p_usart->US_MR & US_MR_PAR_MULTIDROP) != US_MR_PAR_MULTIDROP) {\r
1164                 return 1;\r
1165         }\r
1166         \r
1167         p_usart->US_CR = US_CR_SENDA;\r
1168         \r
1169         if (usart_write(p_usart, ul_addr)) {\r
1170                 return 1;\r
1171         } else {\r
1172                 return 0;\r
1173         }\r
1174 }\r
1175 \r
1176 /**\r
1177  * \brief Reset the ITERATION in US_CSR when the ISO7816 mode is enabled.\r
1178  *\r
1179  * \param p_usart Pointer to a USART instance.\r
1180  */\r
1181 void usart_reset_iterations(Usart *p_usart)\r
1182 {\r
1183         p_usart->US_CR = US_CR_RSTIT;\r
1184 }\r
1185 \r
1186 /**\r
1187  * \brief Reset NACK in US_CSR.\r
1188  *\r
1189  * \param p_usart Pointer to a USART instance.\r
1190  */\r
1191 void usart_reset_nack(Usart *p_usart)\r
1192 {\r
1193         p_usart->US_CR = US_CR_RSTNACK;\r
1194 }\r
1195 \r
1196 /**\r
1197  * \brief Restart the receive timeout.\r
1198  *\r
1199  * \param p_usart Pointer to a USART instance.\r
1200  */\r
1201 void usart_restart_rx_timeout(Usart *p_usart)\r
1202 {\r
1203         p_usart->US_CR = US_CR_RETTO;\r
1204 }\r
1205 \r
1206 #if (SAM3S || SAM4S || SAM3U)\r
1207 /**\r
1208  * \brief Drive the pin DTR to 0.\r
1209  *\r
1210  * \param p_usart Pointer to a USART instance.\r
1211  */\r
1212 void usart_drive_DTR_pin_low(Usart *p_usart)\r
1213 {\r
1214         p_usart->US_CR = US_CR_DTREN;\r
1215 }\r
1216 \r
1217 /**\r
1218  * \brief Drive the pin DTR to 1.\r
1219  *\r
1220  * \param p_usart Pointer to a USART instance.\r
1221  */\r
1222 void usart_drive_DTR_pin_high(Usart *p_usart)\r
1223 {\r
1224         p_usart->US_CR = US_CR_DTRDIS;\r
1225 }\r
1226 #endif\r
1227 \r
1228 /**\r
1229  * \brief Drive the pin RTS to 0.\r
1230  *\r
1231  * \param p_usart Pointer to a USART instance.\r
1232  */\r
1233 void usart_drive_RTS_pin_low(Usart *p_usart)\r
1234 {\r
1235         p_usart->US_CR = US_CR_RTSEN;\r
1236 }\r
1237 \r
1238 /**\r
1239  * \brief Drive the pin RTS to 1.\r
1240  *\r
1241  * \param p_usart Pointer to a USART instance.\r
1242  */\r
1243 void usart_drive_RTS_pin_high(Usart *p_usart)\r
1244 {\r
1245         p_usart->US_CR = US_CR_RTSDIS;\r
1246 }\r
1247 \r
1248 /**\r
1249  * \brief Drive the slave select line NSS (RTS pin) to 0 in SPI master mode.\r
1250  *\r
1251  * \param p_usart Pointer to a USART instance.\r
1252  */\r
1253 void usart_spi_force_chip_select(Usart *p_usart)\r
1254 {\r
1255         p_usart->US_CR = US_CR_FCS;\r
1256 }\r
1257 \r
1258 /**\r
1259  * \brief Drive the slave select line NSS (RTS pin) to 1 in SPI master mode.\r
1260  *\r
1261  * \param p_usart Pointer to a USART instance.\r
1262  */\r
1263 void usart_spi_release_chip_select(Usart *p_usart)\r
1264 {\r
1265         p_usart->US_CR = US_CR_RCS;\r
1266 }\r
1267 \r
1268 /**\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
1272  *\r
1273  * \param p_usart Pointer to a USART instance.\r
1274  *\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
1277  */\r
1278 uint32_t usart_is_tx_ready(Usart *p_usart)\r
1279 {\r
1280         return (p_usart->US_CSR & US_CSR_TXRDY) > 0;\r
1281 }\r
1282 \r
1283 /**\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
1287  *\r
1288  * \param p_usart Pointer to a USART instance.\r
1289  *\r
1290  * \retval 1 Transmitter is empty.\r
1291  * \retval 0 Transmitter is not empty.\r
1292  */\r
1293 uint32_t usart_is_tx_empty(Usart *p_usart)\r
1294 {\r
1295         return (p_usart->US_CSR & US_CSR_TXEMPTY) > 0;\r
1296 }\r
1297 \r
1298 /**\r
1299  * \brief Check if the received data are ready.\r
1300  * Check if Data have been received and loaded into USART_RHR.\r
1301  *\r
1302  * \param p_usart Pointer to a USART instance.\r
1303  *\r
1304  * \retval 1 Some data has been received.\r
1305  * \retval 0 No data has been received.\r
1306  */\r
1307 uint32_t usart_is_rx_ready(Usart *p_usart)\r
1308 {\r
1309         return (p_usart->US_CSR & US_CSR_RXRDY) > 0;\r
1310 }\r
1311 \r
1312 /**\r
1313  * \brief Check if one receive buffer is filled.\r
1314  *\r
1315  * \param p_usart Pointer to a USART instance.\r
1316  *\r
1317  * \retval 1 Receive is complete.\r
1318  * \retval 0 Receive is still pending.\r
1319  */\r
1320 uint32_t usart_is_rx_buf_end(Usart *p_usart)\r
1321 {\r
1322         return (p_usart->US_CSR & US_CSR_ENDRX) > 0;\r
1323 }\r
1324 \r
1325 /**\r
1326  * \brief Check if one transmit buffer is empty.\r
1327  *\r
1328  * \param p_usart Pointer to a USART instance.\r
1329  *\r
1330  * \retval 1 Transmit is complete.\r
1331  * \retval 0 Transmit is still pending.\r
1332  */\r
1333 uint32_t usart_is_tx_buf_end(Usart *p_usart)\r
1334 {\r
1335         return (p_usart->US_CSR & US_CSR_ENDTX) > 0;\r
1336 }\r
1337 \r
1338 /**\r
1339  * \brief Check if both receive buffers are full.\r
1340  *\r
1341  * \param p_usart Pointer to a USART instance.\r
1342  *\r
1343  * \retval 1 Receive buffers are full.\r
1344  * \retval 0 Receive buffers are not full.\r
1345  */\r
1346 uint32_t usart_is_rx_buf_full(Usart *p_usart)\r
1347 {\r
1348         return (p_usart->US_CSR & US_CSR_RXBUFF) > 0;\r
1349 }\r
1350 \r
1351 /**\r
1352  * \brief Check if both transmit buffers are empty.\r
1353  *\r
1354  * \param p_usart Pointer to a USART instance.\r
1355  *\r
1356  * \retval 1 Transmit buffers are empty.\r
1357  * \retval 0 Transmit buffers are not empty.\r
1358  */\r
1359 uint32_t usart_is_tx_buf_empty(Usart *p_usart)\r
1360 {\r
1361         return (p_usart->US_CSR & US_CSR_TXBUFE) > 0;\r
1362 }\r
1363 \r
1364 /**\r
1365  * \brief Write to USART Transmit Holding Register.\r
1366  *\r
1367  * \note Before writing user should check if tx is ready (or empty).\r
1368  *\r
1369  * \param p_usart Pointer to a USART instance.\r
1370  * \param c Data to be sent.\r
1371  *\r
1372  * \retval 0 on success.\r
1373  * \retval 1 on failure.\r
1374  */\r
1375 uint32_t usart_write(Usart *p_usart, uint32_t c)\r
1376 {\r
1377         if (!(p_usart->US_CSR & US_CSR_TXRDY)) {\r
1378                 return 1;\r
1379         }\r
1380 \r
1381         p_usart->US_THR = US_THR_TXCHR(c);\r
1382         return 0;\r
1383 }\r
1384 \r
1385 /**\r
1386  * \brief Write to USART Transmit Holding Register.\r
1387  *\r
1388  * \note Before writing user should check if tx is ready (or empty).\r
1389  *\r
1390  * \param p_usart Pointer to a USART instance.\r
1391  * \param c Data to be sent.\r
1392  *\r
1393  * \retval 0 on success.\r
1394  * \retval 1 on failure.\r
1395  */\r
1396 uint32_t usart_putchar(Usart *p_usart, uint32_t c)\r
1397 {\r
1398         uint32_t timeout = USART_DEFAULT_TIMEOUT;\r
1399 \r
1400         while (!(p_usart->US_CSR & US_CSR_TXRDY)) {\r
1401                 if (!timeout--) {\r
1402                         return 1;\r
1403                 }\r
1404         }\r
1405 \r
1406         p_usart->US_THR = US_THR_TXCHR(c);\r
1407 \r
1408         return 0;\r
1409 }\r
1410 \r
1411 /**\r
1412  * \brief Write one-line string through USART.\r
1413  *\r
1414  * \param p_usart Pointer to a USART instance.\r
1415  * \param string Pointer to one-line string to be sent.\r
1416  */\r
1417 void usart_write_line(Usart *p_usart, const char *string)\r
1418 {\r
1419         while (*string != '\0') {\r
1420                 usart_putchar(p_usart, *string++);\r
1421         }\r
1422 }\r
1423 \r
1424 /**\r
1425  * \brief Read from USART Receive Holding Register.\r
1426  *\r
1427  * \note Before reading user should check if rx is ready.\r
1428  *\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
1431  *\r
1432  * \retval 0 on success.\r
1433  * \retval 1 if no data is available or errors.\r
1434  */\r
1435 uint32_t usart_read(Usart *p_usart, uint32_t *c)\r
1436 {\r
1437         if (!(p_usart->US_CSR & US_CSR_RXRDY)) {\r
1438                 return 1;\r
1439         }\r
1440         \r
1441         /* Read character */\r
1442         *c = p_usart->US_RHR & US_RHR_RXCHR_Msk;\r
1443         \r
1444         return 0;\r
1445 }\r
1446 \r
1447 /**\r
1448  * \brief Read from USART Receive Holding Register.\r
1449  * Before reading user should check if rx is ready.\r
1450  *\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
1453  *\r
1454  * \retval 0 Data has been received.\r
1455  * \retval 1 on failure.\r
1456  */\r
1457 uint32_t usart_getchar(Usart *p_usart, uint32_t *c)\r
1458 {\r
1459         uint32_t timeout = USART_DEFAULT_TIMEOUT;\r
1460 \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
1463                 if (!timeout--) {\r
1464                         return 1;\r
1465                 }\r
1466         }\r
1467 \r
1468         /* Read character */\r
1469         *c = p_usart->US_RHR & US_RHR_RXCHR_Msk;\r
1470 \r
1471         return 0;\r
1472 }\r
1473 \r
1474 #if (SAM3XA || SAM3U)\r
1475 /**\r
1476  * \brief Get Transmit address for DMA operation.\r
1477  *\r
1478  * \param p_usart Pointer to a USART instance.\r
1479  *\r
1480  * \return Transmit address for DMA access.\r
1481  */\r
1482 uint32_t *usart_get_tx_access(Usart *p_usart)\r
1483 {\r
1484         return (uint32_t *)&(p_usart->US_THR);\r
1485 }\r
1486 \r
1487 /**\r
1488  * \brief Get Receive address for DMA operation.\r
1489  *\r
1490  * \param p_usart Pointer to a USART instance.\r
1491  *\r
1492  * \return Receive address for DMA access.\r
1493  */\r
1494 uint32_t *usart_get_rx_access(Usart *p_usart)\r
1495 {\r
1496         return (uint32_t *)&(p_usart->US_RHR);\r
1497 }\r
1498 #endif\r
1499 \r
1500 /**\r
1501  * \brief Get USART PDC base address.\r
1502  *\r
1503  * \param p_usart Pointer to a UART instance.\r
1504  *\r
1505  * \return USART PDC registers base for PDC driver to access.\r
1506  */\r
1507 Pdc *usart_get_pdc_base(Usart *p_usart)\r
1508 {\r
1509         Pdc *p_pdc_base;\r
1510 \r
1511         p_pdc_base = (Pdc *) NULL;\r
1512 \r
1513         if (p_usart == USART0) {\r
1514                 p_pdc_base = PDC_USART0;\r
1515                 return p_pdc_base;\r
1516         }\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
1521         }\r
1522 #endif\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
1527         }\r
1528 #endif\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
1533         }\r
1534 #endif\r
1535 \r
1536         return p_pdc_base;\r
1537 }\r
1538 \r
1539 /**\r
1540  * \brief Enable write protect of USART registers.\r
1541  *\r
1542  * \param p_usart Pointer to a USART instance.\r
1543  */\r
1544 void usart_enable_writeprotect(Usart *p_usart)\r
1545 {\r
1546         p_usart->US_WPMR = US_WPMR_WPEN | US_WPMR_WPKEY(US_WPKEY_VALUE);\r
1547 }\r
1548 \r
1549 /**\r
1550  * \brief Disable write protect of USART registers.\r
1551  *\r
1552  * \param p_usart Pointer to a USART instance.\r
1553  */\r
1554 void usart_disable_writeprotect(Usart *p_usart)\r
1555 {\r
1556         p_usart->US_WPMR = US_WPMR_WPKEY(US_WPKEY_VALUE);\r
1557 }\r
1558 \r
1559 /**\r
1560  * \brief Get write protect status.\r
1561  *\r
1562  * \param p_usart Pointer to a USART instance.\r
1563  *\r
1564  * \return 0 if the peripheral is not protected. \r
1565  * \return 16-bit Write Protect Violation Status otherwise.\r
1566  */\r
1567 uint32_t usart_get_writeprotect_status(Usart *p_usart)\r
1568 {\r
1569         uint32_t reg_value;\r
1570 \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
1574         } else {\r
1575                 return 0;\r
1576         }\r
1577 }\r
1578 \r
1579 /**\r
1580  * \brief Get the total number of errors that occur during an ISO7816 transfer.\r
1581  *\r
1582  * \param p_usart Pointer to a USART instance.\r
1583  *\r
1584  * \return The number of errors that occurred.\r
1585  */\r
1586 uint8_t usart_get_error_number(Usart *p_usart)\r
1587 {\r
1588         return (p_usart->US_NER & US_NER_NB_ERRORS_Msk);\r
1589 }\r
1590 \r
1591 #if (SAM3S || SAM4S || SAM3U || SAM3XA)\r
1592 /**\r
1593  * \brief Configure the transmitter preamble length when the Manchester \r
1594  * encode/decode is enabled.\r
1595  *\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
1598  */\r
1599 void usart_man_set_tx_pre_len(Usart *p_usart, uint8_t uc_len)\r
1600 {\r
1601         p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PL_Msk) |\r
1602                         US_MAN_TX_PL(uc_len);\r
1603 }\r
1604 \r
1605 /**\r
1606  * \brief Configure the transmitter preamble pattern when the Manchester \r
1607  * encode/decode is enabled, which should be 0 ~ 3.\r
1608  *\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
1614  */\r
1615 void usart_man_set_tx_pre_pattern(Usart *p_usart, uint8_t uc_pattern)\r
1616 {\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
1619 }\r
1620 \r
1621 /**\r
1622  * \brief Configure the transmitter Manchester polarity when the Manchester \r
1623  * encode/decode is enabled.\r
1624  *\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
1628  */\r
1629 void usart_man_set_tx_polarity(Usart *p_usart, uint8_t uc_polarity)\r
1630 {\r
1631         p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_MPOL) |\r
1632                                 (uc_polarity << 12);\r
1633 }\r
1634 \r
1635 /**\r
1636  * \brief Configure the detected receiver preamble length when the Manchester \r
1637  * encode/decode is enabled.\r
1638  *\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
1641  */\r
1642 void usart_man_set_rx_pre_len(Usart *p_usart, uint8_t uc_len)\r
1643 {\r
1644         p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PL_Msk) |\r
1645                                 US_MAN_RX_PL(uc_len);\r
1646 }\r
1647 \r
1648 /**\r
1649  * \brief Configure the detected receiver preamble pattern when the Manchester \r
1650  *  encode/decode is enabled, which should be 0 ~ 3.\r
1651  *\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
1657  */\r
1658 void usart_man_set_rx_pre_pattern(Usart *p_usart, uint8_t uc_pattern)\r
1659 {\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
1662 }\r
1663 \r
1664 /**\r
1665  * \brief Configure the receiver Manchester polarity when the Manchester \r
1666  * encode/decode is enabled.\r
1667  *\r
1668  * \param p_usart Pointer to a USART instance.\r
1669  * \param uc_polarity Indicate the receiver Manchester polarity, which should \r
1670  * be 0 or 1.\r
1671  */\r
1672 void usart_man_set_rx_polarity(Usart *p_usart, uint8_t uc_polarity)\r
1673 {\r
1674         p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_MPOL) |\r
1675                                 (uc_polarity << 28);\r
1676 }\r
1677 \r
1678 /**\r
1679  * \brief Enable drift compensation.\r
1680  *\r
1681  * \note The 16X clock mode must be enabled.\r
1682  *\r
1683  * \param p_usart Pointer to a USART instance.\r
1684  */\r
1685 void usart_man_enable_drift_compensation(Usart *p_usart)\r
1686 {\r
1687         p_usart->US_MAN |= US_MAN_DRIFT;\r
1688 }\r
1689 \r
1690 /**\r
1691  * \brief Disable drift compensation.\r
1692  *\r
1693  * \param p_usart Pointer to a USART instance.\r
1694  */\r
1695 void usart_man_disable_drift_compensation(Usart *p_usart)\r
1696 {\r
1697         p_usart->US_MAN &= ~US_MAN_DRIFT;\r
1698 }\r
1699 #endif\r
1700 \r
1701 //@}\r
1702 \r
1703 /// @cond 0\r
1704 /**INDENT-OFF**/\r
1705 #ifdef __cplusplus\r
1706 }\r
1707 #endif\r
1708 /**INDENT-ON**/\r
1709 /// @endcond\r