1 /**
2  *
3  * \file
4  *
5  * \brief SAM SERCOM USART Driver
6  *
7  * Copyright (C) 2012-2016 Atmel Corporation. All rights reserved.
8  *
9  * \asf_license_start
10  *
11  * \page License
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  *    this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright notice,
20  *    this list of conditions and the following disclaimer in the documentation
21  *    and/or other materials provided with the distribution.
22  *
23  * 3. The name of Atmel may not be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * 4. This software may only be redistributed and used in connection with an
27  *    Atmel microcontroller product.
28  *
29  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
30  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
32  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
33  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39  * POSSIBILITY OF SUCH DAMAGE.
40  *
41  * \asf_license_stop
42  *
43  */
44 /*
45  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
46  */
47 #ifndef USART_H_INCLUDED
48 #define USART_H_INCLUDED
49 
50 /**
51  * \defgroup asfdoc_sam0_sercom_usart_group SAM Serial USART (SERCOM USART) Driver
52  *
53  * This driver for Atmel&reg; | SMART ARM&reg;-based microcontrollers provides
54  * an interface for the configuration and management of the SERCOM module in
55  * its USART mode to transfer or receive USART data frames. The following driver
56  * API modes are covered by this manual:
57  *
58  *  - Polled APIs
59  * \if USART_CALLBACK_MODE
60  *  - Callback APIs
61  * \endif
62  *
63  * The following peripheral is used by this module:
64  * - SERCOM (Serial Communication Interface)
65  *
66  * The following devices can use this module:
67  *  - Atmel | SMART SAM D20/D21
68  *  - Atmel | SMART SAM R21
69  *  - Atmel | SMART SAM D09/D10/D11
70  *  - Atmel | SMART SAM D10/D11
71  *  - Atmel | SMART SAM L21/L22
72  *  - Atmel | SMART SAM DA1
73  *  - Atmel | SMART SAM C20/C21
74  *  - Atmel | SMART SAM HA1
75  *
76  * The outline of this documentation is as follows:
77  * - \ref asfdoc_sam0_sercom_usart_prerequisites
78  * - \ref asfdoc_sam0_sercom_usart_overview
79  * - \ref asfdoc_sam0_sercom_usart_special_considerations
80  * - \ref asfdoc_sam0_sercom_usart_extra_info
81  * - \ref asfdoc_sam0_sercom_usart_examples
82  * - \ref asfdoc_sam0_sercom_usart_api_overview
83  *
84  * \section asfdoc_sam0_sercom_usart_prerequisites Prerequisites
85  *
86  * To use the USART you need to have a GCLK generator enabled and running
87  * that can be used as the SERCOM clock source. This can either be configured
88  * in conf_clocks.h or by using the system clock driver.
89  *
90  * \section asfdoc_sam0_sercom_usart_overview Module Overview
91  *
92  * This driver will use one (or more) SERCOM interface(s) in the system
93  * and configure it to run as a USART interface in either synchronous
94  * or asynchronous mode.
95  *
96  * \subsection asfdoc_sam0_sercom_usart_features Driver Feature Macro Definition
97  * <table>
98  *  <tr>
99  *    <th>Driver Feature Macro</th>
100  *    <th>Supported devices</th>
101  *  </tr>
102  *  <tr>
103  *    <td>FEATURE_USART_SYNC_SCHEME_V2</td>
104  *    <td>SAM D21/R21/D09/D10/D11/L21/L22/DA1/C20/C21</td>
105  *  </tr>
106  *  <tr>
107  *    <td>FEATURE_USART_OVER_SAMPLE</td>
108  *    <td>SAM D21/R21/D09/D10/D11/L21/L22/DA1/C20/C21</td>
109  *  </tr>
110  *  <tr>
111  *    <td>FEATURE_USART_HARDWARE_FLOW_CONTROL</td>
112  *    <td>SAM D21/R21/D09/D10/D11/L21/L22/DA1/C20/C21</td>
113  *  </tr>
114  *  <tr>
115  *    <td>FEATURE_USART_IRDA</td>
116  *    <td>SAM D21/R21/D09/D10/D11/L21/L22/DA1/C20/C21</td>
117  *  </tr>
118  *  <tr>
119  *    <td>FEATURE_USART_LIN_SLAVE</td>
120  *    <td>SAM D21/R21/D09/D10/D11/L21/L22/DA1/C20/C21</td>
121  *  </tr>
122  *  <tr>
123  *    <td>FEATURE_USART_COLLISION_DECTION</td>
124  *    <td>SAM D21/R21/D09/D10/D11/L21/L22/DA1/C20/C21</td>
125  *  </tr>
126  *  <tr>
127  *    <td>FEATURE_USART_START_FRAME_DECTION</td>
128  *    <td>SAM D21/R21/D09/D10/D11/L21/L22/DA1/C20/C21</td>
129  *  </tr>
130  *  <tr>
131  *    <td>FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION</td>
132  *    <td>SAM D21/R21/D09/D10/D11/L21/L22/DA1/C20/C21</td>
133  *  </tr>
134  *  <tr>
135  *    <td>FEATURE_USART_RS485</td>
136  *    <td>SAM C20/C21</td>
137  *  </tr>
138  * <tr>
139  *    <td>FEATURE_USART_LIN_MASTER</td>
140  *    <td>SAM L22/C20/C21</td>
141  *  </tr>
142  * </table>
143  * \note The specific features are only available in the driver when the
144  * selected device supports those features.
145  *
146  * \subsection asfdoc_sam0_sercom_usart_overview_frame_format Frame Format
147  *
148  * Communication is based on frames, where the frame format can be customized
149  * to accommodate a wide range of standards. A frame consists of a start bit,
150  * a number of data bits, an optional parity bit for error detection as well
151  * as a configurable length stop bit(s) - see
152  * \ref asfdoc_sam0_sercom_usart_frame_diagram "the figure below".
153  * \ref asfdoc_sam0_sercom_usart_frame_params "The table below" shows the
154  * available parameters you can change in a frame.
155  *
156  * \anchor asfdoc_sam0_sercom_usart_frame_params
157  * <table>
158  *  <caption>USART Frame Parameters</caption>
159  *  <tr>
160  *      <th>Parameter</th>
161  *      <th>Options</th>
162  *  </tr>
163  *  <tr>
164  *      <td>Start bit</td>
165  *      <td>1</td>
166  *  </tr>
167  *  <tr>
168  *      <td>Data bits</td>
169  *      <td>5, 6, 7, 8, 9</td>
170  *  </tr>
171  *  <tr>
172  *      <td>Parity bit</td>
173  *      <td>None, Even, Odd</td>
174  *  </tr>
175  *  <tr>
176  *      <td>Stop bits</td>
177  *      <td>1, 2</td>
178  *  </tr>
179  * </table>
180  *
181  * \anchor asfdoc_sam0_sercom_usart_frame_diagram
182  * \image html usart_frame.svg "USART Frame Overview" width=100%
183  *
184  * \subsection asfdoc_sam0_sercom_usart_overview_sync Synchronous Mode
185  *
186  * In synchronous mode a dedicated clock line is provided; either by the USART
187  * itself if in master mode, or by an external master if in slave mode.
188  * Maximum transmission speed is the same as the GCLK clocking the USART
189  * peripheral when in slave mode, and the GCLK divided by two if in
190  * master mode. In synchronous mode the interface needs three lines to
191  * communicate:
192  * - TX (Transmit pin)
193  * - RX (Receive pin)
194  * - XCK (Clock pin)
195  *
196  * \subsubsection asfdoc_sam0_sercom_usart_overview_sync_sampling Data Sampling
197  * In synchronous mode the data is sampled on either the rising or falling edge
198  * of the clock signal. This is configured by setting the clock polarity in the
199  * configuration struct.
200  *
201  * \subsection asfdoc_sam0_sercom_usart_overview_async Asynchronous Mode
202  *
203  * In asynchronous mode no dedicated clock line is used, and the communication
204  * is based on matching the clock speed on the transmitter and receiver. The
205  * clock is generated from the internal SERCOM baudrate generator, and the
206  * frames are synchronized by using the frame start bits. Maximum transmission
207  * speed is limited to the SERCOM GCLK divided by 16.
208  * In asynchronous mode the interface only needs two lines to communicate:
209  * - TX (Transmit pin)
210  * - RX (Receive pin)
211  *
212  * \subsubsection asfdoc_sam0_sercom_usart_overview_async_clock_matching Transmitter/receiver Clock Matching
213  *
214  * For successful transmit and receive using the asynchronous mode the receiver
215  * and transmitter clocks needs to be closely matched. When receiving a frame
216  * that does not match the selected baudrate closely enough the receiver will
217  * be unable to synchronize the frame(s), and garbage transmissions will
218  * result.
219  *
220  * \subsection asfdoc_sam0_sercom_usart_parity Parity
221  * Parity can be enabled to detect if a transmission was in error. This is done
222  * by counting the number of "1" bits in the frame. When using even parity the
223  * parity bit will be set if the total number of "1"s in the frame are an even
224  * number. If using odd parity the parity bit will be set if the total number
225  * of "1"s are odd.
226  *
227  * When receiving a character the receiver will count the number of "1"s in the
228  * frame and give an error if the received frame and parity bit disagree.
229  *
230  * \subsection asfdoc_sam0_sercom_usart_overview_pin_configuration GPIO Configuration
231  *
232  * The SERCOM module has four internal pads; the RX pin can be placed freely on
233  * any one of the four pads, and the TX and XCK pins have two predefined
234  * positions that can be selected as a pair. The pads can then be routed to an
235  * external GPIO pin using the normal pin multiplexing scheme on the SAM.
236  *
237  * \section asfdoc_sam0_sercom_usart_special_considerations Special Considerations
238  *
239  * \if USART_CALLBACK_MODE
240  * Never execute large portions of code in the callbacks. These
241  * are run from the interrupt routine, and thus having long callbacks will
242  * keep the processor in the interrupt handler for an equally long time.
243  * A common way to handle this is to use global flags signaling the
244  * main application that an interrupt event has happened, and only do the
245  * minimal needed processing in the callback.
246  * \else
247  * No special considerations.
248  * \endif
249  *
250  * \section asfdoc_sam0_sercom_usart_extra_info Extra Information
251  *
252  * For extra information, see \ref asfdoc_sam0_sercom_usart_extra. This includes:
253  * - \ref asfdoc_sam0_sercom_usart_extra_acronyms
254  * - \ref asfdoc_sam0_sercom_usart_extra_dependencies
255  * - \ref asfdoc_sam0_sercom_usart_extra_errata
256  * - \ref asfdoc_sam0_sercom_usart_extra_history
257  *
258  * \section asfdoc_sam0_sercom_usart_examples Examples
259  *
260  * For a list of examples related to this driver, see
261  * \ref asfdoc_sam0_sercom_usart_exqsg.
262  *
263  * \section asfdoc_sam0_sercom_usart_api_overview API Overview
264  * @{
265  */
266 
267 #include <compiler.h>
268 #include <sercom.h>
269 #include <pinmux.h>
270 
271 #if USART_CALLBACK_MODE == true
272 #  include <sercom_interrupt.h>
273 #endif
274 
275 #ifdef __cplusplus
276 extern "C" {
277 #endif
278 
279 /**
280  * \name Driver Feature Definition
281  * Define SERCOM USART features set according to different device family.
282  * @{
283  */
284 
285 #if (SAMD21) || (SAMR21) || (SAMD09) || (SAMD10) || (SAMD11) || \
286 	(SAML21) || (SAML22) || (SAMDA1) || (SAMC20) || (SAMC21) || \
287 	(SAMR30) || (SAMHA1) || defined(__DOXYGEN__)
288 /** USART sync scheme version 2. */
289 #  define FEATURE_USART_SYNC_SCHEME_V2
290 /** USART oversampling. */
291 #  define FEATURE_USART_OVER_SAMPLE
292 /** USART hardware control flow. */
293 #  define FEATURE_USART_HARDWARE_FLOW_CONTROL
294 /** IrDA mode. */
295 #  define FEATURE_USART_IRDA
296 /** LIN slave mode. */
297 #  define FEATURE_USART_LIN_SLAVE
298 /** USART collision detection. */
299 #  define FEATURE_USART_COLLISION_DECTION
300 /** USART start frame detection. */
301 #  define FEATURE_USART_START_FRAME_DECTION
302 /** USART start buffer overflow notification. */
303 #  define FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION
304 #endif
305 
306 #if (SAML22) || defined(__DOXYGEN__)
307 /** ISO7816 for smart card interfacing. */
308 #define FEATURE_USART_ISO7816
309 #endif
310 #if (SAMC20) || (SAMC21) || defined(__DOXYGEN__)
311 /** LIN master mode. */
312 #define FEATURE_USART_LIN_MASTER
313 #endif
314 #if (SAML22) || (SAMC20) || (SAMC21) || defined(__DOXYGEN__)
315 /** RS485 mode. */
316 #  define FEATURE_USART_RS485
317 #endif
318 /*@}*/
319 
320 #ifdef FEATURE_USART_LIN_MASTER
321 /**
322  * \brief LIN node type
323  *
324  * LIN node type.
325  */
326 enum lin_node_type {
327 	/** LIN master mode */
328 	LIN_MASTER_NODE = SERCOM_USART_CTRLA_FORM(0x02),
329 	/** LIN slave mode */
330 	LIN_SLAVE_NODE = SERCOM_USART_CTRLA_FORM(0x04),
331 	/** Neither LIN master nor LIN slave mode */
332 	LIN_INVALID_MODE = SERCOM_USART_CTRLA_FORM(0x00),
333 };
334 
335 /**
336  * \brief LIN master command enum
337  *
338  * LIN master command enum.
339  */
340 enum lin_master_cmd {
341 	/** LIN master software control transmission command */
342 	LIN_MASTER_SOFTWARE_CONTROL_TRANSMIT_CMD = SERCOM_USART_CTRLB_LINCMD(0x01),
343 	/** LIN master automatically transmission command */
344 	LIN_MASTER_AUTO_TRANSMIT_CMD = SERCOM_USART_CTRLB_LINCMD(0x02),
345 };
346 
347 /**
348  * \brief LIN master header delay
349  *
350  * LIN master header delay between break and sync transmission,
351  * and between the sync and identifier (ID) fields.
352  * This field is only valid when using automatically transmission command
353  */
354 enum lin_master_header_delay {
355 	/** Delay between break and sync transmission is 1 bit time.
356 		Delay between sync and ID transmission is 1 bit time. */
357 	LIN_MASTER_HEADER_DELAY_0 = SERCOM_USART_CTRLC_HDRDLY(0x0),
358 	/** Delay between break and sync transmission is 4 bit time.
359 		Delay between sync and ID transmission is 4 bit time. */
360 	LIN_MASTER_HEADER_DELAY_1 = SERCOM_USART_CTRLC_HDRDLY(0x01),
361 	/** Delay between break and sync transmission is 8 bit time.
362 		Delay between sync and ID transmission is 4 bit time. */
363 	LIN_MASTER_HEADER_DELAY_2 = SERCOM_USART_CTRLC_HDRDLY(0x02),
364 	/** Delay between break and sync transmission is 14 bit time.
365 		Delay between sync and ID transmission is 4 bit time. */
366 	LIN_MASTER_HEADER_DELAY_3 = SERCOM_USART_CTRLC_HDRDLY(0x03),
367 };
368 
369 /**
370  * \brief LIN master break length
371  *
372  * Length of the break field transmitted when in LIN master mode
373  */
374 enum lin_master_break_length {
375 	/** Break field transmission is 13 bit times */
376 	LIN_MASTER_BREAK_LENGTH_13_BIT = SERCOM_USART_CTRLC_BRKLEN(0x0),
377 	/** Break field transmission is 17 bit times */
378 	LIN_MASTER_BREAK_LENGTH_17_BIT = SERCOM_USART_CTRLC_BRKLEN(0x1),
379 	/** Break field transmission is 21 bit times */
380 	LIN_MASTER_BREAK_LENGTH_21_BIT = SERCOM_USART_CTRLC_BRKLEN(0x2),
381 	/** Break field transmission is 26 bit times */
382 	LIN_MASTER_BREAK_LENGTH_26_BIT = SERCOM_USART_CTRLC_BRKLEN(0x3),
383 };
384 #endif
385 #ifdef FEATURE_USART_ISO7816
386 /**
387  * \brief ISO7816 protocol type
388  *
389  * ISO7816 protocol type.
390  */
391 enum iso7816_protocol_type {
392 	/** ISO7816 protocol type 0 */
393 	ISO7816_PROTOCOL_T_0 = SERCOM_USART_CTRLA_CMODE,
394 	/** ISO7816 protocol type 1 */
395 	ISO7816_PROTOCOL_T_1 = (0x0ul << SERCOM_USART_CTRLA_CMODE_Pos),
396 };
397 
398 /**
399  * \brief ISO7816 guard time
400  *
401  * The value of ISO7816 guard time.
402  */
403 enum iso7816_guard_time {
404 	/** The guard time is 2-bit times */
405 	ISO7816_GUARD_TIME_2_BIT = 2,
406 	/** The guard time is 3-bit times */
407 	ISO7816_GUARD_TIME_3_BIT,
408 	/** The guard time is 4-bit times */
409 	ISO7816_GUARD_TIME_4_BIT,
410 	/** The guard time is 5-bit times */
411 	ISO7816_GUARD_TIME_5_BIT,
412 	/** The guard time is 6-bit times */
413 	ISO7816_GUARD_TIME_6_BIT,
414 	/** The guard time is 7-bit times */
415 	ISO7816_GUARD_TIME_7_BIT,
416 };
417 
418 /**
419  * \brief ISO7816 receive NACK inhibit
420  *
421  * The value of ISO7816 receive NACK inhibit.
422  */
423 enum iso7816_inhibit_nack {
424 	/** The NACK is generated */
425 	ISO7816_INHIBIT_NACK_DISABLE = (0x0ul << SERCOM_USART_CTRLC_INACK_Pos),
426 	/** The NACK is not generated */
427 	ISO7816_INHIBIT_NACK_ENABLE = SERCOM_USART_CTRLC_INACK,
428 };
429 
430 /**
431  * \brief ISO7816 disable successive receive NACK
432  *
433  * The value of ISO7816 disable successive receive NACK.
434  */
435 enum iso7816_successive_recv_nack {
436 	/** The successive receive NACK is enable. */
437 	ISO7816_SUCCESSIVE_RECV_NACK_DISABLE = (0x0ul << SERCOM_USART_CTRLC_INACK_Pos),
438 	/** The successive receive NACK is disable. */
439 	ISO7816_SUCCESSIVE_RECV_NACK_ENABLE = SERCOM_USART_CTRLC_DSNACK,
440 };
441 
442 /**
443  * \brief ISO7816 configuration struct
444  *
445  * ISO7816 configuration structure.
446  */
447 struct iso7816_config_t {
448 	/* ISO7816 mode enable */
449 	bool enabled;
450 	/** ISO7816 protocol type */
451 	enum iso7816_protocol_type protocol_t;
452 	/** Enable inverse transmission and reception */
453 	bool enable_inverse;
454 	/** Guard time, which lasts two bit times */
455 	enum iso7816_guard_time guard_time;
456 	/**
457 	 * Inhibit Non Acknowledge:
458 	 *   - 0: the NACK is generated;
459 	 *   - 1: the NACK is not generated.
460 	 */
461 	enum iso7816_inhibit_nack inhibit_nack;
462 	/**
463 	 * Disable successive NACKs.
464 	 *  - 0: NACK is sent on the ISO line as soon as a parity error occurs
465 	 * in the received character. Successive parity errors are counted up to
466 	 * the value in the max_iterations field. These parity errors generate
467 	 * a NACK on the ISO line. As soon as this value is reached, no additional
468 	 * NACK is sent on the ISO line. The ITERATION flag is asserted.
469 	 */
470 	enum iso7816_successive_recv_nack successive_recv_nack;
471 	/* Max number of repetitions */
472 	uint32_t max_iterations;
473 };
474 #endif
475 
476 #ifndef PINMUX_DEFAULT
477 /** Default pinmux */
478 #  define PINMUX_DEFAULT 0
479 #endif
480 
481 #ifndef PINMUX_UNUSED
482 /** Unused pinmux */
483 #  define PINMUX_UNUSED 0xFFFFFFFF
484 #endif
485 
486 #ifndef USART_TIMEOUT
487 /** USART timeout value */
488 #  define USART_TIMEOUT 0xFFFF
489 #endif
490 
491 #if USART_CALLBACK_MODE == true
492 /**
493  * \brief USART callback enum
494  *
495  * Callbacks for the Asynchronous USART driver.
496  */
497 enum usart_callback {
498 	/** Callback for buffer transmitted */
499 	USART_CALLBACK_BUFFER_TRANSMITTED,
500 	/** Callback for buffer received */
501 	USART_CALLBACK_BUFFER_RECEIVED,
502 	/** Callback for error */
503 	USART_CALLBACK_ERROR,
504 #ifdef FEATURE_USART_LIN_SLAVE
505 	/** Callback for break character is received */
506 	USART_CALLBACK_BREAK_RECEIVED,
507 #endif
508 #ifdef FEATURE_USART_HARDWARE_FLOW_CONTROL
509 	/** Callback for a change is detected on the CTS pin */
510 	USART_CALLBACK_CTS_INPUT_CHANGE,
511 #endif
512 #ifdef FEATURE_USART_START_FRAME_DECTION
513 	/** Callback for a start condition is detected on the RxD line */
514 	USART_CALLBACK_START_RECEIVED,
515 #endif
516 #  if !defined(__DOXYGEN__)
517 	/** Number of available callbacks */
518 	USART_CALLBACK_N,
519 #  endif
520 };
521 #endif
522 
523 /**
524  * \brief USART Data Order enum
525  *
526  * The data order decides which MSB or LSB is shifted out first when data is
527  * transferred.
528  */
529 enum usart_dataorder {
530 	/** The MSB will be shifted out first during transmission,
531 	 *  and shifted in first during reception */
532 	USART_DATAORDER_MSB = 0,
533 	/** The LSB will be shifted out first during transmission,
534 	 *  and shifted in first during reception */
535 	USART_DATAORDER_LSB = SERCOM_USART_CTRLA_DORD,
536 };
537 
538 /**
539  * \brief USART Transfer mode enum
540  *
541  * Select USART transfer mode.
542  */
543 enum usart_transfer_mode {
544 	/** Transfer of data is done synchronously */
545 	USART_TRANSFER_SYNCHRONOUSLY = (SERCOM_USART_CTRLA_CMODE),
546 	/** Transfer of data is done asynchronously */
547 	USART_TRANSFER_ASYNCHRONOUSLY = (0x0ul << SERCOM_USART_CTRLA_CMODE_Pos),
548 };
549 
550 /**
551  * \brief USART Parity enum
552  *
553  * Select parity USART parity mode.
554  */
555 enum usart_parity {
556 	/** For odd parity checking, the parity bit will be set if number of
557 	 *  ones being transferred is even */
558 	USART_PARITY_ODD  = SERCOM_USART_CTRLB_PMODE,
559 
560 	/** For even parity checking, the parity bit will be set if number of
561 	 *  ones being received is odd */
562 	USART_PARITY_EVEN = 0,
563 
564 	/** No parity checking will be executed, and there will be no parity bit
565 	 *  in the received frame */
566 	USART_PARITY_NONE = 0xFF,
567 };
568 
569 /**
570  * \brief USART signal MUX settings
571  *
572  * Set the functionality of the SERCOM pins.
573  *
574  * See \ref asfdoc_sam0_sercom_usart_mux_settings for a description of the
575  * various MUX setting options.
576  */
577 enum usart_signal_mux_settings {
578 #ifdef FEATURE_USART_HARDWARE_FLOW_CONTROL
579 	/** MUX setting RX_0_TX_0_XCK_1 */
580 	USART_RX_0_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(0)),
581 	/** MUX setting RX_0_TX_2_XCK_3 */
582 	USART_RX_0_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(1)),
583 	/** MUX setting USART_RX_0_TX_0_RTS_2_CTS_3 */
584 	USART_RX_0_TX_0_RTS_2_CTS_3 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(2)),
585 	/** MUX setting RX_1_TX_0_XCK_1 */
586 	USART_RX_1_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(0)),
587 	/** MUX setting RX_1_TX_2_XCK_3 */
588 	USART_RX_1_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(1)),
589 	/** MUX setting USART_RX_1_TX_0_RTS_2_CTS_3 */
590 	USART_RX_1_TX_0_RTS_2_CTS_3 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(2)),
591 	/** MUX setting RX_2_TX_0_XCK_1 */
592 	USART_RX_2_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO(0)),
593 	/** MUX setting RX_2_TX_2_XCK_3 */
594 	USART_RX_2_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO(1)),
595 	/** MUX setting USART_RX_2_TX_0_RTS_2_CTS_3 */
596 	USART_RX_2_TX_0_RTS_2_CTS_3 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO(2)),
597 	/** MUX setting RX_3_TX_0_XCK_1 */
598 	USART_RX_3_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(0)),
599 	/** MUX setting RX_3_TX_2_XCK_3 */
600 	USART_RX_3_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1)),
601 	/** MUX setting USART_RX_3_TX_0_RTS_2_CTS_3 */
602 	USART_RX_3_TX_0_RTS_2_CTS_3 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(2)),
603 #ifdef FEATURE_USART_RS485
604 	/** MUX setting USART_RX_0_TX_0_XCK_1_TE_2 */
605 	USART_RX_0_TX_0_XCK_1_TE_2 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(3)),
606 	/** MUX setting USART_RX_1_TX_0_XCK_1_TE_2 */
607 	USART_RX_1_TX_0_XCK_1_TE_2 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(3)),
608 	/** MUX setting USART_RX_2_TX_0_XCK_1_TE_2 */
609 	USART_RX_2_TX_0_XCK_1_TE_2 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO(3)),
610 	/** MUX setting USART_RX_3_TX_0_XCK_1_TE_2 */
611 	USART_RX_3_TX_0_XCK_1_TE_2 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(3)),
612 #endif
613 #else
614 	/** MUX setting RX_0_TX_0_XCK_1 */
615 	USART_RX_0_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(0)),
616 	/** MUX setting RX_0_TX_2_XCK_3 */
617 	USART_RX_0_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO),
618 	/** MUX setting RX_1_TX_0_XCK_1 */
619 	USART_RX_1_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(1)),
620 	/** MUX setting RX_1_TX_2_XCK_3 */
621 	USART_RX_1_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO),
622 	/** MUX setting RX_2_TX_0_XCK_1 */
623 	USART_RX_2_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(2)),
624 	/** MUX setting RX_2_TX_2_XCK_3 */
625 	USART_RX_2_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO),
626 	/** MUX setting RX_3_TX_0_XCK_1 */
627 	USART_RX_3_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(3)),
628 	/** MUX setting RX_3_TX_2_XCK_3 */
629 	USART_RX_3_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO),
630 #endif
631 };
632 
633 /**
634  * \brief USART Stop Bits enum
635  *
636  * Number of stop bits for a frame.
637  */
638 enum usart_stopbits {
639 	/** Each transferred frame contains one stop bit */
640 	USART_STOPBITS_1 = 0,
641 	/** Each transferred frame contains two stop bits */
642 	USART_STOPBITS_2 = SERCOM_USART_CTRLB_SBMODE,
643 };
644 
645 /**
646  * \brief USART Character Size
647  *
648  * Number of bits for the character sent in a frame.
649  */
650 enum usart_character_size {
651 	/** The char being sent in a frame is five bits long */
652 	USART_CHARACTER_SIZE_5BIT = SERCOM_USART_CTRLB_CHSIZE(5),
653 	/** The char being sent in a frame is six bits long */
654 	USART_CHARACTER_SIZE_6BIT = SERCOM_USART_CTRLB_CHSIZE(6),
655 	/** The char being sent in a frame is seven bits long */
656 	USART_CHARACTER_SIZE_7BIT = SERCOM_USART_CTRLB_CHSIZE(7),
657 	/** The char being sent in a frame is eight bits long */
658 	USART_CHARACTER_SIZE_8BIT = SERCOM_USART_CTRLB_CHSIZE(0),
659 	/** The char being sent in a frame is nine bits long */
660 	USART_CHARACTER_SIZE_9BIT = SERCOM_USART_CTRLB_CHSIZE(1),
661 };
662 
663 #ifdef FEATURE_USART_OVER_SAMPLE
664 /**
665  * \brief USART Sample Rate
666  *
667  * The value of sample rate and baudrate generation mode.
668  */
669 enum usart_sample_rate {
670 	/** 16x over-sampling using arithmetic baudrate generation */
671 	USART_SAMPLE_RATE_16X_ARITHMETIC = SERCOM_USART_CTRLA_SAMPR(0),
672 	/** 16x over-sampling using fractional baudrate generation */
673 	USART_SAMPLE_RATE_16X_FRACTIONAL = SERCOM_USART_CTRLA_SAMPR(1),
674 	/** 8x over-sampling using arithmetic baudrate generation */
675 	USART_SAMPLE_RATE_8X_ARITHMETIC = SERCOM_USART_CTRLA_SAMPR(2),
676 	/** 8x over-sampling using fractional baudrate generation */
677 	USART_SAMPLE_RATE_8X_FRACTIONAL = SERCOM_USART_CTRLA_SAMPR(3),
678 	/** 3x over-sampling using arithmetic baudrate generation */
679 	USART_SAMPLE_RATE_3X_ARITHMETIC = SERCOM_USART_CTRLA_SAMPR(4),
680 };
681 
682 /**
683  * \brief USART Sample Adjustment
684  *
685  * The value of sample number used for majority voting.
686  */
687 enum usart_sample_adjustment {
688 	/** The first, middle and last sample number used for majority voting is 7-8-9 */
689 	USART_SAMPLE_ADJUSTMENT_7_8_9 = SERCOM_USART_CTRLA_SAMPA(0),
690 	/** The first, middle and last sample number used for majority voting is 9-10-11 */
691 	USART_SAMPLE_ADJUSTMENT_9_10_11 = SERCOM_USART_CTRLA_SAMPA(1),
692 	/** The first, middle and last sample number used for majority voting is 11-12-13 */
693 	USART_SAMPLE_ADJUSTMENT_11_12_13 = SERCOM_USART_CTRLA_SAMPA(2),
694 	/** The first, middle and last sample number used for majority voting is 13-14-15 */
695 	USART_SAMPLE_ADJUSTMENT_13_14_15 = SERCOM_USART_CTRLA_SAMPA(3),
696 };
697 #endif
698 
699 #ifdef FEATURE_USART_RS485
700 /**
701  * \brief RS485 Guard Time
702  *
703  * The value of RS485 guard time.
704  */
705 enum rs485_guard_time {
706 	/** The guard time is 0-bit time */
707 	RS485_GUARD_TIME_0_BIT = 0,
708 	/** The guard time is 1-bit time */
709 	RS485_GUARD_TIME_1_BIT,
710 	/** The guard time is 2-bit times */
711 	RS485_GUARD_TIME_2_BIT,
712 	/** The guard time is 3-bit times */
713 	RS485_GUARD_TIME_3_BIT,
714 	/** The guard time is 4-bit times */
715 	RS485_GUARD_TIME_4_BIT,
716 	/** The guard time is 5-bit times */
717 	RS485_GUARD_TIME_5_BIT,
718 	/** The guard time is 6-bit times */
719 	RS485_GUARD_TIME_6_BIT,
720 	/** The guard time is 7-bit times */
721 	RS485_GUARD_TIME_7_BIT,
722 };
723 #endif
724 
725 /**
726  * \brief USART Transceiver
727  *
728  * Select Receiver or Transmitter.
729  */
730 enum usart_transceiver_type {
731 	/** The parameter is for the Receiver */
732 	USART_TRANSCEIVER_RX,
733 	/** The parameter is for the Transmitter */
734 	USART_TRANSCEIVER_TX,
735 };
736 
737 /**
738  * \brief USART configuration struct
739  *
740  * Configuration options for USART.
741  */
742 struct usart_config {
743 	/** USART bit order (MSB or LSB first) */
744 	enum usart_dataorder data_order;
745 	/** USART in asynchronous or synchronous mode */
746 	enum usart_transfer_mode transfer_mode;
747 	/** USART parity */
748 	enum usart_parity parity;
749 	/** Number of stop bits */
750 	enum usart_stopbits stopbits;
751 	/** USART character size */
752 	enum usart_character_size character_size;
753 	/** USART pin out */
754 	enum usart_signal_mux_settings mux_setting;
755 #ifdef FEATURE_USART_OVER_SAMPLE
756 	/** USART sample rate */
757 	enum usart_sample_rate sample_rate;
758 	/** USART sample adjustment */
759 	enum usart_sample_adjustment sample_adjustment;
760 #endif
761 #ifdef FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION
762 	/** Controls when the buffer overflow status bit is asserted when a buffer overflow occurs */
763 	bool immediate_buffer_overflow_notification;
764 #endif
765 #ifdef FEATURE_USART_IRDA
766 	/** Enable IrDA encoding format */
767 	bool encoding_format_enable;
768 	/** The minimum pulse length required for a pulse to be accepted by the IrDA receiver */
769 	uint8_t receive_pulse_length;
770 #endif
771 #ifdef FEATURE_USART_LIN_SLAVE
772 	/** Enable LIN Slave Support */
773 	bool lin_slave_enable;
774 #endif
775 
776 #ifdef FEATURE_USART_LIN_MASTER
777 	/** LIN node type */
778 	enum lin_node_type lin_node;
779 	/** LIN master header delay */
780 	enum lin_master_header_delay lin_header_delay;
781 	/** LIN Master Break Length */
782 	enum lin_master_break_length lin_break_length;
783 #endif
784 
785 #ifdef FEATURE_USART_START_FRAME_DECTION
786 	/** Enable start of frame dection */
787 	bool start_frame_detection_enable;
788 #endif
789 #ifdef FEATURE_USART_ISO7816
790 	/** Enable ISO7816 for smart card interfacing */
791 	struct iso7816_config_t iso7816_config;
792 #endif
793 #ifdef FEATURE_USART_RS485
794 	/** RS485 guard time */
795 	enum rs485_guard_time rs485_guard_time;
796 #endif
797 #ifdef FEATURE_USART_COLLISION_DECTION
798 	/** Enable collision dection */
799 	bool collision_detection_enable;
800 #endif
801 	/** USART baudrate */
802 	uint32_t baudrate;
803 	/** Enable receiver */
804 	bool receiver_enable;
805 	/** Enable transmitter */
806 	bool transmitter_enable;
807 
808 	/** USART Clock Polarity.
809 	 * If true, data changes on falling XCK edge and
810 	 * is sampled at rising edge.
811 	 * If false, data changes on rising XCK edge and
812 	 * is sampled at falling edge.
813 	 * */
814 	bool clock_polarity_inverted;
815 
816 	/** States whether to use the external clock applied to the XCK pin.
817 	 * In synchronous mode the shift register will act directly on the XCK clock.
818 	 * In asynchronous mode the XCK will be the input to the USART hardware module.
819 	 */
820 	bool use_external_clock;
821 	/** External clock frequency in synchronous mode.
822 	 * This must be set if \c use_external_clock is true. */
823 	uint32_t ext_clock_freq;
824 	/** If true the USART will be kept running in Standby sleep mode */
825 	bool run_in_standby;
826 	/** GCLK generator source */
827 	enum gclk_generator generator_source;
828 	/** PAD0 pinmux.
829 	 *
830 	 * If current USARTx has several alternative multiplexing I/O pins for PAD0, then
831 	 * only one peripheral multiplexing I/O can be enabled for current USARTx PAD0
832 	 * function. Make sure that no other alternative multiplexing I/O is associated
833 	 * with the same USARTx PAD0.
834 	 */
835 	uint32_t pinmux_pad0;
836 	/** PAD1 pinmux.
837 	 *
838 	 * If current USARTx has several alternative multiplexing I/O pins for PAD1, then
839 	 * only one peripheral multiplexing I/O can be enabled for current USARTx PAD1
840 	 * function. Make sure that no other alternative multiplexing I/O is associated
841 	 * with the same USARTx PAD1.
842 	 */
843 	uint32_t pinmux_pad1;
844 	/** PAD2 pinmux.
845 	 *
846 	 * If current USARTx has several alternative multiplexing I/O pins for PAD2, then
847 	 * only one peripheral multiplexing I/O can be enabled for current USARTx PAD2
848 	 * function. Make sure that no other alternative multiplexing I/O is associated
849 	 * with the same USARTx PAD2.
850 	 */
851 	uint32_t pinmux_pad2;
852 	/** PAD3 pinmux.
853 	 *
854 	 * If current USARTx has several alternative multiplexing I/O pins for PAD3, then
855 	 * only one peripheral multiplexing I/O can be enabled for current USARTx PAD3
856 	 * function. Make sure that no other alternative multiplexing I/O is associated
857 	 * with the same USARTx PAD3.
858 	 */
859 	uint32_t pinmux_pad3;
860 };
861 
862 #if USART_CALLBACK_MODE == true
863 /**
864  * \brief USART module instance
865  *
866  * Forward Declaration for the device instance.
867  */
868 struct usart_module;
869 
870 /**
871  * \brief USART callback type
872  *
873  * Type of the callback functions.
874  */
875 typedef void (*usart_callback_t)(struct usart_module *const module);
876 #endif
877 
878 /**
879  * \brief SERCOM USART driver software device instance structure.
880  *
881  * SERCOM USART driver software instance structure, used to retain software
882  * state information of an associated hardware module instance.
883  *
884  * \note The fields of this structure should not be altered by the user
885  *       application; they are reserved for module-internal use only.
886  */
887 struct usart_module {
888 #if !defined(__DOXYGEN__)
889 	/** Pointer to the hardware instance */
890 	Sercom *hw;
891 	/** Module lock */
892 	volatile bool locked;
893 	/** Character size of the data being transferred */
894 	enum usart_character_size character_size;
895 	/** Receiver enabled */
896 	bool receiver_enabled;
897 	/** Transmitter enabled */
898 	bool transmitter_enabled;
899 #ifdef FEATURE_USART_LIN_SLAVE
900 	/** LIN Slave Support enabled */
901 	bool lin_slave_enabled;
902 #endif
903 #ifdef FEATURE_USART_START_FRAME_DECTION
904 	/** Start of frame dection enabled */
905 	bool start_frame_detection_enabled;
906 #endif
907 #ifdef FEATURE_USART_ISO7816
908 	/** ISO7816 mode enable */
909 	bool iso7816_mode_enabled;
910 #endif
911 #  if USART_CALLBACK_MODE == true
912 	/** Array to store callback function pointers in */
913 	usart_callback_t callback[USART_CALLBACK_N];
914 	/** Buffer pointer to where the next received character will be put */
915 	volatile uint8_t *rx_buffer_ptr;
916 
917 	/** Buffer pointer to where the next character will be transmitted from
918 	**/
919 	volatile uint8_t *tx_buffer_ptr;
920 	/** Remaining characters to receive */
921 	volatile uint16_t remaining_rx_buffer_length;
922 	/** Remaining characters to transmit */
923 	volatile uint16_t remaining_tx_buffer_length;
924 	/** Bit mask for callbacks registered */
925 	uint8_t callback_reg_mask;
926 	/** Bit mask for callbacks enabled */
927 	uint8_t callback_enable_mask;
928 	/** Holds the status of the ongoing or last read operation */
929 	volatile enum status_code rx_status;
930 	/** Holds the status of the ongoing or last write operation */
931 	volatile enum status_code tx_status;
932 #  endif
933 #endif
934 };
935 
936  /**
937  * \name Lock/Unlock
938  * @{
939  */
940 
941 /**
942  * \brief Attempt to get lock on driver instance
943  *
944  * This function checks the instance's lock, which indicates whether or not it
945  * is currently in use, and sets the lock if it was not already set.
946  *
947  * The purpose of this is to enable exclusive access to driver instances, so
948  * that, e.g., transactions by different services will not interfere with each
949  * other.
950  *
951  * \param[in,out] module Pointer to the driver instance to lock
952  *
953  * \retval STATUS_OK If the module was locked
954  * \retval STATUS_BUSY If the module was already locked
955  */
usart_lock(struct usart_module * const module)956 static inline enum status_code usart_lock(
957 		struct usart_module *const module)
958 {
959 	enum status_code status;
960 
961 	system_interrupt_enter_critical_section();
962 
963 	if (module->locked) {
964 		status = STATUS_BUSY;
965 	} else {
966 		module->locked = true;
967 		status = STATUS_OK;
968 	}
969 
970 	system_interrupt_leave_critical_section();
971 
972 	return status;
973 }
974 
975 /**
976  * \brief Unlock driver instance
977  *
978  * This function clears the instance lock, indicating that it is available for
979  * use.
980  *
981  * \param[in,out] module Pointer to the driver instance to lock
982  *
983  */
usart_unlock(struct usart_module * const module)984 static inline void usart_unlock(struct usart_module *const module)
985 {
986 	module->locked = false;
987 }
988 
989 /** @} */
990 
991 /**
992  * \brief Check if peripheral is busy syncing registers across clock domains
993  *
994  * Return peripheral synchronization status. If doing a non-blocking
995  * implementation this function can be used to check the sync state and hold of
996  * any new actions until sync is complete. If this function is not run; the
997  * functions will block until the sync has completed.
998  *
999  * \param[in]  module  Pointer to peripheral module
1000  *
1001  * \return Peripheral sync status.
1002  *
1003  * \retval true   Peripheral is busy syncing
1004  * \retval false  Peripheral is not busy syncing and can be read/written without
1005  *                stalling the bus
1006  */
usart_is_syncing(const struct usart_module * const module)1007 static inline bool usart_is_syncing(
1008 		const struct usart_module *const module)
1009 {
1010 	/* Sanity check arguments */
1011 	Assert(module);
1012 	Assert(module->hw);
1013 
1014 	SercomUsart *const usart_hw = &(module->hw->USART);
1015 
1016 #ifdef FEATURE_USART_SYNC_SCHEME_V2
1017 	return (usart_hw->SYNCBUSY.reg);
1018 #else
1019 	return (usart_hw->STATUS.reg & SERCOM_USART_STATUS_SYNCBUSY);
1020 #endif
1021 }
1022 
1023 #if !defined (__DOXYGEN__)
1024 /**
1025  * \internal
1026  * Waits until synchronization is complete
1027  */
_usart_wait_for_sync(const struct usart_module * const module)1028 static inline void _usart_wait_for_sync(
1029 		const struct usart_module *const module)
1030 {
1031 	/* Sanity check */
1032 	Assert(module);
1033 
1034 	while (usart_is_syncing(module)) {
1035 		/* Wait until the synchronization is complete */
1036 	}
1037 }
1038 #endif
1039 
1040 /**
1041  * \brief Initializes the device to predefined defaults
1042  *
1043  * Initialize the USART device to predefined defaults:
1044  * - 8-bit asynchronous USART
1045  * - No parity
1046  * - One stop bit
1047  * - 9600 baud
1048  * - Transmitter enabled
1049  * - Receiver enabled
1050  * - GCLK generator 0 as clock source
1051  * - Default pin configuration
1052  *
1053  * The configuration struct will be updated with the default
1054  * configuration.
1055  *
1056  * \param[in,out] config  Pointer to configuration struct
1057  */
usart_get_config_defaults(struct usart_config * const config)1058 static inline void usart_get_config_defaults(
1059 		struct usart_config *const config)
1060 {
1061 	/* Sanity check arguments */
1062 	Assert(config);
1063 
1064 	/* Set default config in the config struct */
1065 	config->data_order       = USART_DATAORDER_LSB;
1066 	config->transfer_mode    = USART_TRANSFER_ASYNCHRONOUSLY;
1067 	config->parity           = USART_PARITY_NONE;
1068 	config->stopbits         = USART_STOPBITS_1;
1069 	config->character_size   = USART_CHARACTER_SIZE_8BIT;
1070 	config->baudrate         = 9600;
1071 	config->receiver_enable  = true;
1072 	config->transmitter_enable = true;
1073 	config->clock_polarity_inverted = false;
1074 	config->use_external_clock = false;
1075 	config->ext_clock_freq   = 0;
1076 	config->mux_setting      = USART_RX_1_TX_2_XCK_3;
1077 	config->run_in_standby   = false;
1078 	config->generator_source = GCLK_GENERATOR_0;
1079 	config->pinmux_pad0      = PINMUX_DEFAULT;
1080 	config->pinmux_pad1      = PINMUX_DEFAULT;
1081 	config->pinmux_pad2      = PINMUX_DEFAULT;
1082 	config->pinmux_pad3      = PINMUX_DEFAULT;
1083 #ifdef FEATURE_USART_OVER_SAMPLE
1084 	config->sample_adjustment     = USART_SAMPLE_ADJUSTMENT_7_8_9;
1085 	config->sample_rate           = USART_SAMPLE_RATE_16X_ARITHMETIC;
1086 #endif
1087 #ifdef FEATURE_USART_LIN_SLAVE
1088 	config->lin_slave_enable      = false;
1089 #endif
1090 
1091 #ifdef FEATURE_USART_LIN_MASTER
1092 	config->lin_node = LIN_INVALID_MODE;
1093 	config->lin_header_delay = LIN_MASTER_HEADER_DELAY_0;
1094 	config->lin_break_length = LIN_MASTER_BREAK_LENGTH_13_BIT;
1095 #endif
1096 
1097 #ifdef FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION
1098 	config->immediate_buffer_overflow_notification  = false;
1099 #endif
1100 #ifdef FEATURE_USART_START_FRAME_DECTION
1101 	config->start_frame_detection_enable            = false;
1102 #endif
1103 #ifdef FEATURE_USART_IRDA
1104 	config->encoding_format_enable                  = false;
1105 	config->receive_pulse_length                    = 19;
1106 #endif
1107 #ifdef FEATURE_USART_ISO7816
1108 	config->iso7816_config.enabled                  = false;
1109 	config->iso7816_config.guard_time               = ISO7816_GUARD_TIME_2_BIT;
1110 	config->iso7816_config.protocol_t               = ISO7816_PROTOCOL_T_0;
1111 	config->iso7816_config.enable_inverse           = false;
1112 	config->iso7816_config.inhibit_nack             = ISO7816_INHIBIT_NACK_DISABLE;
1113 	config->iso7816_config.successive_recv_nack     = ISO7816_SUCCESSIVE_RECV_NACK_DISABLE;
1114 	config->iso7816_config.max_iterations           = 7;
1115 #endif
1116 #ifdef FEATURE_USART_COLLISION_DECTION
1117 	config->collision_detection_enable              = false;
1118 #endif
1119 #ifdef FEATURE_USART_RS485
1120 	config->rs485_guard_time = RS485_GUARD_TIME_0_BIT;
1121 #endif
1122 }
1123 
1124 enum status_code usart_init(
1125 		struct usart_module *const module,
1126 		Sercom *const hw,
1127 		const struct usart_config *const config);
1128 
1129 /**
1130  * \brief Enable the module
1131  *
1132  * Enables the USART module.
1133  *
1134  * \param[in]  module  Pointer to USART software instance struct
1135  */
usart_enable(const struct usart_module * const module)1136 static inline void usart_enable(
1137 		const struct usart_module *const module)
1138 {
1139 	/* Sanity check arguments */
1140 	Assert(module);
1141 	Assert(module->hw);
1142 
1143 	/* Get a pointer to the hardware module instance */
1144 	SercomUsart *const usart_hw = &(module->hw->USART);
1145 
1146 #if USART_CALLBACK_MODE == true
1147 	/* Enable Global interrupt for module */
1148 	system_interrupt_enable(_sercom_get_interrupt_vector(module->hw));
1149 #endif
1150 
1151 	/* Wait until synchronization is complete */
1152 	_usart_wait_for_sync(module);
1153 
1154 	/* Enable USART module */
1155 	usart_hw->CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
1156 }
1157 
1158 /**
1159  * \brief Disable module
1160  *
1161  * Disables the USART module.
1162  *
1163  * \param[in]  module  Pointer to USART software instance struct
1164  */
usart_disable(const struct usart_module * const module)1165 static inline void usart_disable(
1166 		const struct usart_module *const module)
1167 {
1168 	/* Sanity check arguments */
1169 	Assert(module);
1170 	Assert(module->hw);
1171 
1172 	/* Get a pointer to the hardware module instance */
1173 	SercomUsart *const usart_hw = &(module->hw->USART);
1174 
1175 #if USART_CALLBACK_MODE == true
1176 	/* Disable Global interrupt for module */
1177 	system_interrupt_disable(_sercom_get_interrupt_vector(module->hw));
1178 #endif
1179 
1180 	/* Wait until synchronization is complete */
1181 	_usart_wait_for_sync(module);
1182 
1183 	/* Disable USART module */
1184 	usart_hw->CTRLA.reg &= ~SERCOM_USART_CTRLA_ENABLE;
1185 }
1186 
1187 /**
1188  * \brief Resets the USART module
1189  *
1190  * Disables and resets the USART module.
1191  *
1192  * \param[in]  module  Pointer to the USART software instance struct
1193  */
usart_reset(const struct usart_module * const module)1194 static inline void usart_reset(
1195 		const struct usart_module *const module)
1196 {
1197 	/* Sanity check arguments */
1198 	Assert(module);
1199 	Assert(module->hw);
1200 
1201 	/* Get a pointer to the hardware module instance */
1202 	SercomUsart *const usart_hw = &(module->hw->USART);
1203 
1204 	usart_disable(module);
1205 
1206 	/* Wait until synchronization is complete */
1207 	_usart_wait_for_sync(module);
1208 
1209 	/* Reset module */
1210 	usart_hw->CTRLA.reg = SERCOM_USART_CTRLA_SWRST;
1211 }
1212 
1213 /**
1214  * \name Writing and Reading
1215  * @{
1216  */
1217 enum status_code usart_write_wait(
1218 		struct usart_module *const module,
1219 		const uint16_t tx_data);
1220 
1221 enum status_code usart_read_wait(
1222 		struct usart_module *const module,
1223 		uint16_t *const rx_data);
1224 
1225 enum status_code usart_write_buffer_wait(
1226 		struct usart_module *const module,
1227 		const uint8_t *tx_data,
1228 		uint16_t length);
1229 
1230 enum status_code usart_read_buffer_wait(
1231 		struct usart_module *const module,
1232 		uint8_t *rx_data,
1233 		uint16_t length);
1234 /** @} */
1235 
1236 /**
1237  * \name Enabling/Disabling Receiver and Transmitter
1238  * @{
1239  */
1240 
1241 /**
1242  * \brief Enable Transceiver
1243  *
1244  * Enable the given transceiver. Either RX or TX.
1245  *
1246  * \param[in]  module            Pointer to USART software instance struct
1247  * \param[in]  transceiver_type  Transceiver type
1248  */
usart_enable_transceiver(struct usart_module * const module,enum usart_transceiver_type transceiver_type)1249 static inline void usart_enable_transceiver(
1250 		struct usart_module *const module,
1251 		enum usart_transceiver_type transceiver_type)
1252 {
1253 	/* Sanity check arguments */
1254 	Assert(module);
1255 	Assert(module->hw);
1256 
1257 	/* Get a pointer to the hardware module instance */
1258 	SercomUsart *const usart_hw = &(module->hw->USART);
1259 
1260 	/* Wait until synchronization is complete */
1261 	_usart_wait_for_sync(module);
1262 
1263 	switch (transceiver_type) {
1264 		case USART_TRANSCEIVER_RX:
1265 			/* Enable RX */
1266 			usart_hw->CTRLB.reg |= SERCOM_USART_CTRLB_RXEN;
1267 			module->receiver_enabled = true;
1268 			break;
1269 
1270 		case USART_TRANSCEIVER_TX:
1271 			/* Enable TX */
1272 			usart_hw->CTRLB.reg |= SERCOM_USART_CTRLB_TXEN;
1273 			module->transmitter_enabled = true;
1274 			break;
1275 	}
1276 	_usart_wait_for_sync(module);
1277 }
1278 
1279 /**
1280  * \brief Disable Transceiver
1281  *
1282  * Disable the given transceiver (RX or TX).
1283  *
1284  * \param[in]  module            Pointer to USART software instance struct
1285  * \param[in]  transceiver_type  Transceiver type
1286  */
usart_disable_transceiver(struct usart_module * const module,enum usart_transceiver_type transceiver_type)1287 static inline void usart_disable_transceiver(
1288 		struct usart_module *const module,
1289 		enum usart_transceiver_type transceiver_type)
1290 {
1291 	/* Sanity check arguments */
1292 	Assert(module);
1293 	Assert(module->hw);
1294 
1295 	/* Get a pointer to the hardware module instance */
1296 	SercomUsart *const usart_hw = &(module->hw->USART);
1297 
1298 	/* Wait until synchronization is complete */
1299 	_usart_wait_for_sync(module);
1300 
1301 	switch (transceiver_type) {
1302 		case USART_TRANSCEIVER_RX:
1303 			/* Disable RX */
1304 			usart_hw->CTRLB.reg &= ~SERCOM_USART_CTRLB_RXEN;
1305 			module->receiver_enabled = false;
1306 			break;
1307 
1308 		case USART_TRANSCEIVER_TX:
1309 			/* Disable TX */
1310 			usart_hw->CTRLB.reg &= ~SERCOM_USART_CTRLB_TXEN;
1311 			module->transmitter_enabled = false;
1312 			break;
1313 	}
1314 }
1315 
1316 /** @} */
1317 
1318 #ifdef FEATURE_USART_LIN_MASTER
1319 /**
1320  * \name LIN Master Command and Status
1321  * @{
1322  */
1323 
1324 /**
1325  * \brief Sending LIN command.
1326  *
1327  * Sending LIN command.
1328  *
1329  * \param[in]  module Pointer to USART software instance struct
1330  * \param[in]  cmd  Cammand type
1331  */
lin_master_send_cmd(struct usart_module * const module,enum lin_master_cmd cmd)1332 static inline void lin_master_send_cmd(
1333 		struct usart_module *const module,
1334 		enum lin_master_cmd cmd)
1335 {
1336 	SercomUsart *const usart_hw = &(module->hw->USART);
1337 	_usart_wait_for_sync(module);
1338 	usart_hw->CTRLB.reg |= cmd;
1339 }
1340 
1341 /**
1342  * \brief Get LIN transmission status
1343  *
1344  * Get LIN transmission status.
1345  *
1346  * \param[in]  module Pointer to USART software instance struct
1347  *
1348  * \return Status of LIN master transmission.
1349  * \retval true   Data transmission completed
1350  * \retval false  Transmission is ongoing
1351  */
lin_master_transmission_status(struct usart_module * const module)1352 static inline bool lin_master_transmission_status(struct usart_module *const module)
1353 {
1354 	SercomUsart *const usart_hw = &(module->hw->USART);
1355 	return ((usart_hw->STATUS.reg & SERCOM_USART_STATUS_TXE)? true:false);
1356 }
1357 
1358 /** @} */
1359 #endif
1360 
1361 #ifdef __cplusplus
1362 }
1363 #endif
1364 
1365 /** @} */
1366 
1367 /**
1368 * \page asfdoc_sam0_sercom_usart_extra Extra Information for SERCOM USART Driver
1369 *
1370 * \section asfdoc_sam0_sercom_usart_extra_acronyms Acronyms
1371 *
1372 * Below is a table listing the acronyms used in this module, along with their
1373 * intended meanings.
1374 *
1375 * <table>
1376 * <tr>
1377 * <th>Acronym</th>
1378 * <th>Description</th>
1379 * </tr>
1380 * <tr>
1381 * <td>SERCOM</td>
1382 * <td>Serial Communication Interface</td>
1383 * </tr>
1384 * <tr>
1385 * <td>USART</td>
1386 * <td>Universal Synchronous and Asynchronous Serial Receiver and Transmitter</td>
1387 * </tr>
1388 * <tr>
1389 * <td>LSB</td>
1390 * <td>Least Significant Bit</td>
1391 * </tr>
1392 * <tr>
1393 * <td>MSB</td>
1394 * <td>Most Significant Bit</td>
1395 * </tr>
1396 * <tr>
1397 * <td>DMA</td>
1398 * <td>Direct Memory Access</td>
1399 * </tr>
1400 * </table>
1401 *
1402 *
1403 * \section asfdoc_sam0_sercom_usart_extra_dependencies Dependencies
1404 * This driver has the following dependencies:
1405 *
1406 * - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver"
1407 * - \ref asfdoc_sam0_system_clock_group "System clock configuration"
1408 *
1409 *
1410 * \section asfdoc_sam0_sercom_usart_extra_errata Errata
1411 * There are no errata related to this driver.
1412 *
1413 *
1414 * \section asfdoc_sam0_sercom_usart_extra_history Module History
1415 * An overview of the module history is presented in the table below, with
1416 * details on the enhancements and fixes made to the module since its first
1417 * release. The current version of this corresponds to the newest version in
1418 * the table.
1419 *
1420  * <table>
1421  *	<tr>
1422  *		<th>Changelog</th>
1423  *	</tr>
1424  *	<tr>
1425  *		<td>Added new feature as below:
1426  *          \li ISO7816
1427  *	</tr>
1428  *	<tr>
1429  *		<td>Added new features as below:
1430  *          \li LIN master
1431  *          \li RS485
1432  *	</tr>
1433  *	<tr>
1434  *		<td>Added new features as below:
1435  *          \li Oversample
1436  *          \li Buffer overflow notification
1437  *          \li Irda
1438  *          \li Lin slave
1439  *          \li Start frame detection
1440  *          \li Hardware flow control
1441  *          \li Collision detection
1442  *          \li DMA support </td>
1443  *	</tr>
1444  *	<tr>
1445  *		<td>\li Added new \c transmitter_enable and \c receiver_enable Boolean
1446  *              values to \c struct usart_config
1447  *          \li Altered \c usart_write_* and usart_read_* functions to abort with
1448  *              an error code if the relevant transceiver is not enabled
1449  *          \li Fixed \c usart_write_buffer_wait() and \c usart_read_buffer_wait()
1450  *              not aborting correctly when a timeout condition occurs</td>
1451  *	</tr>
1452  *	<tr>
1453  *		<td>Initial Release</td>
1454  *	</tr>
1455  * </table>
1456 */
1457 
1458 /**
1459  * \page asfdoc_sam0_sercom_usart_exqsg Examples for SERCOM USART Driver
1460  *
1461  * This is a list of the available Quick Start guides (QSGs) and example
1462  * applications for \ref asfdoc_sam0_sercom_usart_group. QSGs are simple examples with
1463  * step-by-step instructions to configure and use this driver in a selection of
1464  * use cases. Note that a QSG can be compiled as a standalone application or be
1465  * added to the user application.
1466  *
1467  * - \subpage asfdoc_sam0_sercom_usart_basic_use_case
1468  * \if USART_CALLBACK_MODE
1469  * - \subpage asfdoc_sam0_sercom_usart_callback_use_case
1470  * \endif
1471  * - \subpage asfdoc_sam0_sercom_usart_dma_use_case
1472  * - \subpage asfdoc_sam0_sercom_usart_lin_use_case
1473  */
1474 
1475 /**
1476  * \page asfdoc_sam0_sercom_usart_mux_settings SERCOM USART MUX Settings
1477  *
1478  * The following lists the possible internal SERCOM module pad function
1479  * assignments, for the four SERCOM pads when in USART mode. Note that this is
1480  * in addition to the physical GPIO pin MUX of the device, and can be used in
1481  * conjunction to optimize the serial data pin-out.
1482  *
1483  * When TX and RX are connected to the same pin, the USART will operate in
1484  * half-duplex mode if both one transmitter and several receivers are enabled.
1485  *
1486  * \note When RX and XCK are connected to the same pin, the receiver must not
1487  *       be enabled if the USART is configured to use an external clock.
1488  *
1489  *
1490  * <table>
1491  *		<tr>
1492  *			<th>MUX/Pad</th>
1493  *			<th>PAD 0</th>
1494  *			<th>PAD 1</th>
1495  *			<th>PAD 2</th>
1496  *			<th>PAD 3</th>
1497  *		</tr>
1498  *		<tr>
1499  *			<td>RX_0_TX_0_XCK_1</td>
1500  *			<td>TX / RX</td>
1501  *			<td>XCK</td>
1502  *			<td>-</td>
1503  *			<td>-</td>
1504  *		</tr>
1505  *		<tr>
1506  *			<td>RX_0_TX_2_XCK_3</td>
1507  *			<td>RX</td>
1508  *			<td>-</td>
1509  *			<td>TX</td>
1510  *			<td>XCK</td>
1511  *		</tr>
1512  *		<tr>
1513  *			<td>RX_1_TX_0_XCK_1</td>
1514  *			<td>TX</td>
1515  *			<td>RX / XCK</td>
1516  *			<td>-</td>
1517  *			<td>-</td>
1518  *		</tr>
1519  *		<tr>
1520  *			<td>RX_1_TX_2_XCK_3</td>
1521  *			<td>-</td>
1522  *			<td>RX</td>
1523  *			<td>TX</td>
1524  *			<td>XCK</td>
1525  *		</tr>
1526  *		<tr>
1527  *			<td>RX_2_TX_0_XCK_1</td>
1528  *			<td>TX</td>
1529  *			<td>XCK</td>
1530  *			<td>RX</td>
1531  *			<td>-</td>
1532  *		</tr>
1533  *		<tr>
1534  *			<td>RX_2_TX_2_XCK_3</td>
1535  *			<td>-</td>
1536  *			<td>-</td>
1537  *			<td>TX / RX</td>
1538  *			<td>XCK</td>
1539  *		</tr>
1540  *		<tr>
1541  *			<td>RX_3_TX_0_XCK_1</td>
1542  *			<td>TX</td>
1543  *			<td>XCK</td>
1544  *			<td>-</td>
1545  *			<td>RX</td>
1546  *		</tr>
1547  *		<tr>
1548  *			<td>RX_3_TX_2_XCK_3</td>
1549  *			<td>-</td>
1550  *			<td>-</td>
1551  *			<td>TX</td>
1552  *			<td>RX / XCK</td>
1553  *		</tr>
1554  * </table>
1555  *
1556  * \page asfdoc_sam0_sercom_usart_document_revision_history Document Revision History
1557  *
1558  * <table>
1559  *	<tr>
1560  *		<th>Doc. Rev.</td>
1561  *		<th>Date</td>
1562  *		<th>Comments</td>
1563  *	</tr>
1564  *	<tr>
1565  *		<td>42118F</td>
1566  *		<td>12/2015</td>
1567  *		<td>Added support for SAM L21/L22, SAM DA1, SAM D09, SAMR30 and SAM C20/C21</td>
1568  *	</tr>
1569  *	<tr>
1570  *		<td>42118E</td>
1571  *		<td>12/2014</td>
1572  *		<td>Added support for SAM R21 and SAM D10/D11</td>
1573  *	</tr>
1574  *	<tr>
1575  *		<td>42118D</td>
1576  *		<td>01/2014</td>
1577  *		<td>Added support for SAM D21</td>
1578  *	</tr>
1579  *	<tr>
1580  *		<td>42118C</td>
1581  *		<td>10/2013</td>
1582  *		<td>Replaced the pad multiplexing documentation with a condensed table</td>
1583  *	</tr>
1584  *	<tr>
1585  *		<td>42118B</td>
1586  *		<td>06/2013</td>
1587  *		<td>Corrected documentation typos</td>
1588  *	</tr>
1589  *	<tr>
1590  *		<td>42118A</td>
1591  *		<td>06/2013</td>
1592  *		<td>Initial release</td>
1593  *	</tr>
1594  * </table>
1595  */
1596 #endif /* USART_H_INCLUDED */
1597