1 /***************************************************************************//**
2  * @file
3  * @brief Universal synchronous/asynchronous receiver/transmitter (USART/UART)
4  *   peripheral API
5  *******************************************************************************
6  * # License
7  * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
8  *******************************************************************************
9  *
10  * SPDX-License-Identifier: Zlib
11  *
12  * The licensor of this software is Silicon Laboratories Inc.
13  *
14  * This software is provided 'as-is', without any express or implied
15  * warranty. In no event will the authors be held liable for any damages
16  * arising from the use of this software.
17  *
18  * Permission is granted to anyone to use this software for any purpose,
19  * including commercial applications, and to alter it and redistribute it
20  * freely, subject to the following restrictions:
21  *
22  * 1. The origin of this software must not be misrepresented; you must not
23  *    claim that you wrote the original software. If you use this software
24  *    in a product, an acknowledgment in the product documentation would be
25  *    appreciated but is not required.
26  * 2. Altered source versions must be plainly marked as such, and must not be
27  *    misrepresented as being the original software.
28  * 3. This notice may not be removed or altered from any source distribution.
29  *
30  ******************************************************************************/
31 
32 #ifndef EM_USART_H
33 #define EM_USART_H
34 
35 #include "em_device.h"
36 #if defined(USART_COUNT) && (USART_COUNT > 0)
37 
38 #include <stdbool.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /***************************************************************************//**
45  * @addtogroup usart USART - Synchronous/Asynchronous Serial
46  * @brief Universal Synchronous/Asynchronous Receiver/Transmitter
47  *   Peripheral API
48  * @details
49  * The Universal Synchronous/Asynchronous Receiver/Transmitter (USART)
50  * is a very flexible serial I/O module. It supports full duplex asynchronous UART
51  * communication as well as RS-485, SPI, MicroWire, and 3-wire. It can also interface
52  * with ISO7816 Smart-Cards, and IrDA devices.
53  *
54  * The USART has a wide selection of operating modes, frame formats, and baud rates.
55  * All features are supported through the API of this module.
56  *
57  * Triple buffering and DMA support makes high data-rates possible with minimal
58  * CPU intervention. It is possible to transmit and receive large frames while
59  * the MCU remains in EM1 Sleep.
60  *
61  * This module does not support DMA configuration. The UARTDRV and SPIDRV drivers
62  * provide full support for DMA and more.
63  *
64  *  The following steps are necessary for basic operation:
65  *
66  *  Clock enable:
67  *  @include em_usart_clock_enable.c
68  *
69  *  To initialize the USART for asynchronous operation (e.g., UART):
70  *  @include em_usart_init_async.c
71  *
72  *  To initialize the USART for synchronous operation (e.g., SPI):
73  *  @include em_usart_init_sync.c
74  *
75  *  After pins are assigned for the application/board, enable pins at the
76  *  desired location. Available locations can be obtained from the Pin Definitions
77  *  section in the data sheet.
78  *  @if DOXYDOC_P1_DEVICE
79  *  @include em_usart_route_p1.c
80  *  @note UART hardware flow control is not directly supported in hardware on
81  *        _SILICON_LABS_32B_SERIES_0 parts.
82  *  @endif
83  *  @if DOXYDOC_P2_DEVICE
84  *  @include em_usart_route_p2.c
85  *  @endif
86  *  @note UARTDRV supports all types of UART flow control. Software assisted
87  *        hardware flow control is available for parts without true UART hardware
88  *        flow control.
89  * @{
90  ******************************************************************************/
91 
92 /*******************************************************************************
93  ********************************   ENUMS   ************************************
94  ******************************************************************************/
95 
96 /** Databit selection. */
97 typedef enum {
98   usartDatabits4  = USART_FRAME_DATABITS_FOUR,     /**< 4 data bits (not available for UART). */
99   usartDatabits5  = USART_FRAME_DATABITS_FIVE,     /**< 5 data bits (not available for UART). */
100   usartDatabits6  = USART_FRAME_DATABITS_SIX,      /**< 6 data bits (not available for UART). */
101   usartDatabits7  = USART_FRAME_DATABITS_SEVEN,    /**< 7 data bits (not available for UART). */
102   usartDatabits8  = USART_FRAME_DATABITS_EIGHT,    /**< 8 data bits. */
103   usartDatabits9  = USART_FRAME_DATABITS_NINE,     /**< 9 data bits. */
104   usartDatabits10 = USART_FRAME_DATABITS_TEN,      /**< 10 data bits (not available for UART). */
105   usartDatabits11 = USART_FRAME_DATABITS_ELEVEN,   /**< 11 data bits (not available for UART). */
106   usartDatabits12 = USART_FRAME_DATABITS_TWELVE,   /**< 12 data bits (not available for UART). */
107   usartDatabits13 = USART_FRAME_DATABITS_THIRTEEN, /**< 13 data bits (not available for UART). */
108   usartDatabits14 = USART_FRAME_DATABITS_FOURTEEN, /**< 14 data bits (not available for UART). */
109   usartDatabits15 = USART_FRAME_DATABITS_FIFTEEN,  /**< 15 data bits (not available for UART). */
110   usartDatabits16 = USART_FRAME_DATABITS_SIXTEEN   /**< 16 data bits (not available for UART). */
111 } USART_Databits_TypeDef;
112 
113 /** Enable selection. */
114 typedef enum {
115   /** Disable both receiver and transmitter. */
116   usartDisable  = 0x0,
117 
118   /** Enable receiver only, transmitter disabled. */
119   usartEnableRx = USART_CMD_RXEN,
120 
121   /** Enable transmitter only, receiver disabled. */
122   usartEnableTx = USART_CMD_TXEN,
123 
124   /** Enable both receiver and transmitter. */
125   usartEnable   = (USART_CMD_RXEN | USART_CMD_TXEN)
126 } USART_Enable_TypeDef;
127 
128 /** Oversampling selection, used for asynchronous operation. */
129 typedef enum {
130   usartOVS16 = USART_CTRL_OVS_X16,     /**< 16x oversampling (normal). */
131   usartOVS8  = USART_CTRL_OVS_X8,      /**< 8x oversampling. */
132   usartOVS6  = USART_CTRL_OVS_X6,      /**< 6x oversampling. */
133   usartOVS4  = USART_CTRL_OVS_X4       /**< 4x oversampling. */
134 } USART_OVS_TypeDef;
135 
136 /** Parity selection, mainly used for asynchronous operation. */
137 typedef enum {
138   usartNoParity   = USART_FRAME_PARITY_NONE,    /**< No parity. */
139   usartEvenParity = USART_FRAME_PARITY_EVEN,    /**< Even parity. */
140   usartOddParity  = USART_FRAME_PARITY_ODD      /**< Odd parity. */
141 } USART_Parity_TypeDef;
142 
143 /** Stop bits selection, used for asynchronous operation. */
144 typedef enum {
145   usartStopbits0p5 = USART_FRAME_STOPBITS_HALF,        /**< 0.5 stop bits. */
146   usartStopbits1   = USART_FRAME_STOPBITS_ONE,         /**< 1 stop bits. */
147   usartStopbits1p5 = USART_FRAME_STOPBITS_ONEANDAHALF, /**< 1.5 stop bits. */
148   usartStopbits2   = USART_FRAME_STOPBITS_TWO          /**< 2 stop bits. */
149 } USART_Stopbits_TypeDef;
150 
151 #if defined(_USART_ROUTEPEN_RTSPEN_MASK) && defined(_USART_ROUTEPEN_CTSPEN_MASK)
152 /** Hardware Flow Control Selection. */
153 typedef enum {
154   /** No hardware flow control. */
155   usartHwFlowControlNone = 0,
156   /** CTS signal is enabled for TX flow control. */
157   usartHwFlowControlCts = USART_ROUTEPEN_CTSPEN,
158   /** RTS signal is enabled for RX flow control. */
159   usartHwFlowControlRts = USART_ROUTEPEN_RTSPEN,
160   /** CTS and RTS signals are enabled for TX and RX flow control. */
161   usartHwFlowControlCtsAndRts = USART_ROUTEPEN_CTSPEN | USART_ROUTEPEN_RTSPEN,
162 } USART_HwFlowControl_TypeDef;
163 
164 #elif defined(USART_CTRLX_CTSEN)
165 /** Hardware Flow Control Selection. */
166 typedef enum {
167   /** No hardware flow control. */
168   usartHwFlowControlNone = 0,
169   /** CTS signal is enabled for TX flow control. */
170   usartHwFlowControlCts,
171   /** RTS signal is enabled for RX flow control. */
172   usartHwFlowControlRts,
173   /** CTS and RTS signals are enabled for TX and RX flow control. */
174   usartHwFlowControlCtsAndRts
175 } USART_HwFlowControl_TypeDef;
176 #endif
177 
178 /** Clock polarity/phase mode. */
179 typedef enum {
180   /** Clock idle low, sample on rising edge. */
181   usartClockMode0 = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLELEADING,
182 
183   /** Clock idle low, sample on falling edge. */
184   usartClockMode1 = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLETRAILING,
185 
186   /** Clock idle high, sample on falling edge. */
187   usartClockMode2 = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLELEADING,
188 
189   /** Clock idle high, sample on rising edge. */
190   usartClockMode3 = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLETRAILING
191 } USART_ClockMode_TypeDef;
192 
193 /** Pulse width selection for IrDA mode. */
194 typedef enum {
195   /** IrDA pulse width is 1/16 for OVS=0 and 1/8 for OVS=1 */
196   usartIrDAPwONE   = USART_IRCTRL_IRPW_ONE,
197 
198   /** IrDA pulse width is 2/16 for OVS=0 and 2/8 for OVS=1 */
199   usartIrDAPwTWO   = USART_IRCTRL_IRPW_TWO,
200 
201   /** IrDA pulse width is 3/16 for OVS=0 and 3/8 for OVS=1 */
202   usartIrDAPwTHREE = USART_IRCTRL_IRPW_THREE,
203 
204   /** IrDA pulse width is 4/16 for OVS=0 and 4/8 for OVS=1 */
205   usartIrDAPwFOUR  = USART_IRCTRL_IRPW_FOUR
206 } USART_IrDAPw_Typedef;
207 
208 /** PRS Channel type */
209 typedef uint8_t USART_PRS_Channel_t;
210 
211 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
212 /** Deprecated PRS channel selector value.
213  *  New code should use an integer instead. */
214 #define usartIrDAPrsCh0       0U
215 #define usartIrDAPrsCh1       1U
216 #define usartIrDAPrsCh2       2U
217 #define usartIrDAPrsCh3       3U
218 #define usartIrDAPrsCh4       4U
219 #define usartIrDAPrsCh5       5U
220 #define usartIrDAPrsCh6       6U
221 #define usartIrDAPrsCh7       7U
222 #define usartPrsRxCh0         0U
223 #define usartPrsRxCh1         1U
224 #define usartPrsRxCh2         2U
225 #define usartPrsRxCh3         3U
226 #define usartPrsRxCh4         4U
227 #define usartPrsRxCh5         5U
228 #define usartPrsRxCh6         6U
229 #define usartPrsRxCh7         7U
230 #define usartPrsRxCh8         8U
231 #define usartPrsRxCh9         9U
232 #define usartPrsRxCh10       10U
233 #define usartPrsRxCh11       11U
234 #define usartPrsTriggerCh0    0U
235 #define usartPrsTriggerCh1    1U
236 #define usartPrsTriggerCh2    2U
237 #define usartPrsTriggerCh3    3U
238 #define usartPrsTriggerCh4    4U
239 #define usartPrsTriggerCh5    5U
240 #define usartPrsTriggerCh6    6U
241 #define usartPrsTriggerCh7    7U
242 /** @endcond */
243 
244 #if defined(_USART_I2SCTRL_MASK) && defined(USART_I2SCTRL_I2SEN)
245 /** I2S format selection. */
246 typedef enum {
247   usartI2sFormatW32D32  = USART_I2SCTRL_I2SFORMAT_W32D32,   /**< 32-bit word, 32-bit data */
248   usartI2sFormatW32D24M = USART_I2SCTRL_I2SFORMAT_W32D24M,  /**< 32-bit word, 32-bit data with 8 lsb masked */
249   usartI2sFormatW32D24  = USART_I2SCTRL_I2SFORMAT_W32D24,   /**< 32-bit word, 24-bit data */
250   usartI2sFormatW32D16  = USART_I2SCTRL_I2SFORMAT_W32D16,   /**< 32-bit word, 16-bit data */
251   usartI2sFormatW32D8   = USART_I2SCTRL_I2SFORMAT_W32D8,    /**< 32-bit word, 8-bit data  */
252   usartI2sFormatW16D16  = USART_I2SCTRL_I2SFORMAT_W16D16,   /**< 16-bit word, 16-bit data */
253   usartI2sFormatW16D8   = USART_I2SCTRL_I2SFORMAT_W16D8,    /**< 16-bit word, 8-bit data  */
254   usartI2sFormatW8D8    = USART_I2SCTRL_I2SFORMAT_W8D8      /**<  8-bit word, 8-bit data  */
255 } USART_I2sFormat_TypeDef;
256 
257 /** I2S frame data justify. */
258 typedef enum {
259   usartI2sJustifyLeft  = USART_I2SCTRL_I2SJUSTIFY_LEFT,  /**< Data is left-justified within the frame  */
260   usartI2sJustifyRight = USART_I2SCTRL_I2SJUSTIFY_RIGHT  /**< Data is right-justified within the frame */
261 } USART_I2sJustify_TypeDef;
262 
263 #elif defined(_USART_I2SCTRL_MASK)
264 /** I2S format selection. */
265 typedef enum {
266   usartI2sFormatW32D32  = USART_I2SCTRL_FORMAT_W32D32,   /**< 32-bit word, 32-bit data. */
267   usartI2sFormatW32D24M = USART_I2SCTRL_FORMAT_W32D24M,  /**< 32-bit word, 32-bit data with 8 lsb masked. */
268   usartI2sFormatW32D24  = USART_I2SCTRL_FORMAT_W32D24,   /**< 32-bit word, 24-bit data. */
269   usartI2sFormatW32D16  = USART_I2SCTRL_FORMAT_W32D16,   /**< 32-bit word, 16-bit data. */
270   usartI2sFormatW32D8   = USART_I2SCTRL_FORMAT_W32D8,    /**< 32-bit word, 8-bit data.  */
271   usartI2sFormatW16D16  = USART_I2SCTRL_FORMAT_W16D16,   /**< 16-bit word, 16-bit data. */
272   usartI2sFormatW16D8   = USART_I2SCTRL_FORMAT_W16D8,    /**< 16-bit word, 8-bit data.  */
273   usartI2sFormatW8D8    = USART_I2SCTRL_FORMAT_W8D8      /**<  8-bit word, 8-bit data.  */
274 } USART_I2sFormat_TypeDef;
275 
276 /** I2S frame data justify. */
277 typedef enum {
278   usartI2sJustifyLeft  = USART_I2SCTRL_JUSTIFY_LEFT,  /**< Data is left-justified within the frame.  */
279   usartI2sJustifyRight = USART_I2SCTRL_JUSTIFY_RIGHT  /**< Data is right-justified within the frame. */
280 } USART_I2sJustify_TypeDef;
281 #endif
282 
283 /*******************************************************************************
284  *******************************   STRUCTS   ***********************************
285  ******************************************************************************/
286 
287 /** Asynchronous mode initialization structure. */
288 typedef struct {
289   /** Specifies whether TX and/or RX is enabled when initialization is completed. */
290   USART_Enable_TypeDef   enable;
291 
292   /**
293    * USART/UART reference clock assumed when configuring baud rate setup.
294    * Set to 0 to use the currently configured reference clock.
295    */
296   uint32_t               refFreq;
297 
298   /** Desired baud rate. */
299   uint32_t               baudrate;
300 
301   /** Oversampling used. */
302   USART_OVS_TypeDef      oversampling;
303 
304   /** Number of data bits in frame. Notice that UART modules only support 8 or
305    * 9 data bits. */
306   USART_Databits_TypeDef databits;
307 
308   /** Parity mode to use. */
309   USART_Parity_TypeDef   parity;
310 
311   /** Number of stop bits to use. */
312   USART_Stopbits_TypeDef stopbits;
313 
314 #if !defined(_EFM32_GECKO_FAMILY)
315   /** Majority Vote Disable for 16x, 8x and 6x oversampling modes. */
316   bool                   mvdis;
317 
318   /** Enable USART Rx via PRS. */
319   bool                   prsRxEnable;
320 
321   /** Select PRS channel for USART Rx. (Only valid if prsRxEnable is true). */
322   USART_PRS_Channel_t    prsRxCh;
323 #endif
324 
325   /** Auto CS enabling. */
326   bool                  autoCsEnable;
327 
328   /** Enable CS invert. By default, chip select is active low.
329    * Set to true to make chip select active high. */
330   bool                  csInv;
331 
332 #if (_SILICON_LABS_32B_SERIES > 0)
333   /** Auto CS hold time in baud cycles. */
334   uint8_t               autoCsHold;
335 
336   /** Auto CS setup time in baud cycles. */
337   uint8_t               autoCsSetup;
338 
339   /** Hardware flow control mode. */
340   USART_HwFlowControl_TypeDef hwFlowControl;
341 #endif
342 } USART_InitAsync_TypeDef;
343 
344 /** USART PRS trigger enable. */
345 typedef struct {
346 #if defined(USART_TRIGCTRL_AUTOTXTEN)
347   /** Enable AUTOTX. */
348   bool autoTxTriggerEnable;
349 #endif
350   /** Trigger receive via PRS channel. */
351   bool rxTriggerEnable;
352   /** Trigger transmit via PRS channel. */
353   bool txTriggerEnable;
354   /** PRS channel to be used to trigger auto transmission. */
355   USART_PRS_Channel_t prsTriggerChannel;
356 } USART_PrsTriggerInit_TypeDef;
357 
358 /** Default configuration for USART asynchronous initialization structure. */
359 #if defined(_EFM32_GECKO_FAMILY)
360 /* Default USART Async struct for the EFM32G device */
361 #define USART_INITASYNC_DEFAULT                                                                    \
362   {                                                                                                \
363     usartEnable,           /* Enable RX/TX when initialization is complete. */                     \
364     0,                     /* Use current configured reference clock for configuring baud rate. */ \
365     115200,                /* 115200 bits/s. */                                                    \
366     usartOVS16,            /* 16x oversampling. */                                                 \
367     usartDatabits8,        /* 8 data bits. */                                                      \
368     usartNoParity,         /* No parity. */                                                        \
369     usartStopbits1,        /* 1 stop bit. */                                                       \
370     false,                 /* Auto CS functionality enable/disable switch. */                      \
371     false,                 /* No CS invert. */                                                     \
372   }
373 #elif defined(_SILICON_LABS_32B_SERIES_0)
374 /* Default USART Async struct for Series 0 devices */
375 #define USART_INITASYNC_DEFAULT                                                                    \
376   {                                                                                                \
377     usartEnable,           /* Enable RX/TX when initialization is complete. */                     \
378     0,                     /* Use current configured reference clock for configuring baud rate. */ \
379     115200,                /* 115200 bits/s. */                                                    \
380     usartOVS16,            /* 16x oversampling. */                                                 \
381     usartDatabits8,        /* 8 data bits. */                                                      \
382     usartNoParity,         /* No parity. */                                                        \
383     usartStopbits1,        /* 1 stop bit. */                                                       \
384     false,                 /* Do not disable majority vote. */                                     \
385     false,                 /* Not USART PRS input mode. */                                         \
386     0,                     /* PRS channel 0. */                                                    \
387     false,                 /* Auto CS functionality enable/disable switch. */                      \
388     false,                 /* No CS invert. */                                                     \
389   }
390 #elif (_SILICON_LABS_32B_SERIES > 0)
391 /* Default USART Async struct for Series 1 and Series 2 devices */
392 #define USART_INITASYNC_DEFAULT                                                                    \
393   {                                                                                                \
394     usartEnable,           /* Enable RX/TX when initialization is complete. */                     \
395     0,                     /* Use current configured reference clock for configuring baud rate. */ \
396     115200,                /* 115200 bits/s. */                                                    \
397     usartOVS16,            /* 16x oversampling. */                                                 \
398     usartDatabits8,        /* 8 data bits. */                                                      \
399     usartNoParity,         /* No parity. */                                                        \
400     usartStopbits1,        /* 1 stop bit. */                                                       \
401     false,                 /* Do not disable majority vote. */                                     \
402     false,                 /* Not USART PRS input mode. */                                         \
403     0,                     /* PRS channel 0. */                                                    \
404     false,                 /* Auto CS functionality enable/disable switch */                       \
405     false,                 /* No CS invert. */                                                     \
406     0,                     /* Auto CS Hold cycles. */                                              \
407     0,                     /* Auto CS Setup cycles. */                                             \
408     usartHwFlowControlNone /* No HW flow control. */                                               \
409   }
410 #endif
411 
412 /** Default configuration for USART PRS triggering structure. */
413 #if defined(USART_TRIGCTRL_AUTOTXTEN)
414 #define USART_INITPRSTRIGGER_DEFAULT                            \
415   {                                                             \
416     false,             /* Do not enable autoTX triggering. */   \
417     false,             /* Do not enable receive triggering. */  \
418     false,             /* Do not enable transmit triggering. */ \
419     0                  /* Set default channel to zero. */       \
420   }
421 #else
422 #define USART_INITPRSTRIGGER_DEFAULT                            \
423   {                                                             \
424     false,             /* Do not enable receive triggering. */  \
425     false,             /* Do not enable transmit triggering. */ \
426     0                  /* Set default channel to zero. */       \
427   }
428 #endif
429 
430 /** Synchronous mode initialization structure. */
431 typedef struct {
432   /** Specifies whether TX and/or RX shall be enabled when initialization is completed. */
433   USART_Enable_TypeDef    enable;
434 
435   /**
436    * USART/UART reference clock assumed when configuring baud rate setup.
437    * Set to 0 to use the currently configured reference clock.
438    */
439   uint32_t                refFreq;
440 
441   /** Desired baud rate. */
442   uint32_t                baudrate;
443 
444   /** Number of data bits in frame. */
445   USART_Databits_TypeDef  databits;
446 
447   /** Select if to operate in master or slave mode. */
448   bool                    master;
449 
450   /** Select if to send most or least significant bit first. */
451   bool                    msbf;
452 
453   /** Clock polarity/phase mode. */
454   USART_ClockMode_TypeDef clockMode;
455 
456 #if !defined(_EFM32_GECKO_FAMILY)
457   /** Enable USART Rx via PRS. */
458   bool                    prsRxEnable;
459 
460   /** Select PRS channel for USART Rx. (Only valid if prsRxEnable is true). */
461   USART_PRS_Channel_t     prsRxCh;
462 #endif
463 
464 #if defined(USART_TRIGCTRL_AUTOTXTEN)
465   /** Enable AUTOTX mode. Transmits as long as RX is not full.
466    *  Generates underflows if TX is empty. */
467   bool                    autoTx;
468 #endif
469 
470   /** Auto CS enabling */
471   bool                    autoCsEnable;
472 
473   /** Enable CS invert. By default, chip select is active low.
474    * Set to true to make chip select active high. */
475   bool                    csInv;
476 
477 #if defined(_USART_TIMING_CSHOLD_MASK)
478   /** Auto CS hold time in baud cycles */
479   uint8_t                 autoCsHold;
480 
481   /** Auto CS setup time in baud cycles */
482   uint8_t                 autoCsSetup;
483 #endif
484 } USART_InitSync_TypeDef;
485 
486 /** Default configuration for USART sync initialization structure. */
487 #if defined(_EFM32_GECKO_FAMILY)
488 /* Default USART Sync configuration for EFM32G devices. */
489 #define USART_INITSYNC_DEFAULT                                                               \
490   {                                                                                          \
491     usartEnable,     /* Enable RX/TX when initialization is complete. */                     \
492     0,               /* Use current configured reference clock for configuring baud rate. */ \
493     1000000,         /* 1 Mbits/s. */                                                        \
494     usartDatabits8,  /* 8 data bits. */                                                      \
495     true,            /* Master mode. */                                                      \
496     false,           /* Send least significant bit first. */                                 \
497     usartClockMode0, /* Clock idle low, sample on rising edge. */                            \
498     false,           /* No AUTOCS mode. */                                                   \
499     false,           /* No CS invert. */                                                     \
500   }
501 #elif defined(_SILICON_LABS_32B_SERIES_0)
502 /* Default USART Sync configuration for series 0 devices. */
503 #define USART_INITSYNC_DEFAULT                                                               \
504   {                                                                                          \
505     usartEnable,     /* Enable RX/TX when initialization is complete. */                     \
506     0,               /* Use current configured reference clock for configuring baud rate. */ \
507     1000000,         /* 1 Mbits/s. */                                                        \
508     usartDatabits8,  /* 8 data bits. */                                                      \
509     true,            /* Master mode. */                                                      \
510     false,           /* Send least significant bit first. */                                 \
511     usartClockMode0, /* Clock idle low, sample on rising edge. */                            \
512     false,           /* Not USART PRS input mode. */                                         \
513     0,               /* PRS channel 0. */                                                    \
514     false,           /* No AUTOTX mode. */                                                   \
515     false,           /* No AUTOCS mode. */                                                   \
516     false,           /* No CS invert. */                                                     \
517   }
518 #elif (_SILICON_LABS_32B_SERIES > 0)
519 /* Default USART Sync configuration for series 2 devices */
520 #define USART_INITSYNC_DEFAULT                                                               \
521   {                                                                                          \
522     usartEnable,     /* Enable RX/TX when initialization is complete. */                     \
523     0,               /* Use current configured reference clock for configuring baud rate. */ \
524     1000000,         /* 1 Mbits/s. */                                                        \
525     usartDatabits8,  /* 8 databits. */                                                       \
526     true,            /* Master mode. */                                                      \
527     false,           /* Send least significant bit first. */                                 \
528     usartClockMode0, /* Clock idle low, sample on rising edge. */                            \
529     false,           /* Not USART PRS input mode. */                                         \
530     0,               /* PRS channel 0. */                                                    \
531     false,           /* No AUTOTX mode. */                                                   \
532     false,           /* No AUTOCS mode. */                                                   \
533     false,           /* No CS invert. */                                                     \
534     0,               /* Auto CS Hold cycles. */                                              \
535     0                /* Auto CS Setup cycles. */                                             \
536   }
537 #endif
538 
539 /** IrDA mode initialization structure. Inherited from asynchronous mode initialization structure. */
540 typedef struct {
541   /** General Asynchronous initialization structure. */
542   USART_InitAsync_TypeDef  async;
543 
544   /** Set to invert Rx signal before IrDA demodulator. */
545   bool                     irRxInv;
546 
547   /** Set to enable filter on IrDA demodulator. */
548   bool                     irFilt;
549 
550   /** Configure the pulse width generated by the IrDA modulator as a fraction
551    *  of the configured USART bit period. */
552   USART_IrDAPw_Typedef     irPw;
553 
554 #if defined(USART_IRCTRL_IRPRSEN)
555   /** Enable the PRS channel selected by irPrsSel as input to IrDA module
556    *  instead of TX. */
557   bool                     irPrsEn;
558 
559   /** PRS can be used as input to the pulse modulator instead of TX.
560    *  This value selects the channel to use. */
561   USART_PRS_Channel_t      irPrsSel;
562 #endif
563 } USART_InitIrDA_TypeDef;
564 
565 /** Default configuration for IrDA mode initialization structure. */
566 #if defined(_EFM32_GECKO_FAMILY)
567 /* Default USART IrDA struct for the EFM32G device */
568 #define USART_INITIRDA_DEFAULT                                                                       \
569   {                                                                                                  \
570     {                                                                                                \
571       usartEnable,           /* Enable RX/TX when initialization is complete. */                     \
572       0,                     /* Use current configured reference clock for configuring baud rate. */ \
573       115200,                /* 115200 bits/s. */                                                    \
574       usartOVS16,            /* 16x oversampling. */                                                 \
575       usartDatabits8,        /* 8 data bits. */                                                      \
576       usartEvenParity,       /* Even parity. */                                                      \
577       usartStopbits1,        /* 1 stop bit. */                                                       \
578       false,                 /* Auto CS functionality enable/disable switch */                       \
579       false,                 /* No CS invert. */                                                     \
580     },                                                                                               \
581     false,            /* Rx invert disabled. */                                                      \
582     false,            /* Filtering disabled. */                                                      \
583     usartIrDAPwTHREE, /* Pulse width is set to ONE. */                                               \
584     false,            /* Routing to PRS is disabled. */                                              \
585     0                 /* PRS channel 0. */                                                           \
586   }
587 #elif defined(_SILICON_LABS_32B_SERIES_0)
588 /* Default USART IrDA struct for Series 0 devices */
589 #define USART_INITIRDA_DEFAULT                                                                       \
590   {                                                                                                  \
591     {                                                                                                \
592       usartEnable,           /* Enable RX/TX when initialization is complete. */                     \
593       0,                     /* Use current configured reference clock for configuring baud rate. */ \
594       115200,                /* 115200 bits/s. */                                                    \
595       usartOVS16,            /* 16x oversampling. */                                                 \
596       usartDatabits8,        /* 8 data bits. */                                                      \
597       usartEvenParity,       /* Even parity. */                                                      \
598       usartStopbits1,        /* 1 stop bit. */                                                       \
599       false,                 /* Do not disable majority vote. */                                     \
600       false,                 /* Not USART PRS input mode. */                                         \
601       0,                     /* PRS channel 0. */                                                    \
602       false,                 /* Auto CS functionality enable/disable switch */                       \
603       false,                 /* No CS invert. */                                                     \
604     },                                                                                               \
605     false,            /* Rx invert disabled. */                                                      \
606     false,            /* Filtering disabled. */                                                      \
607     usartIrDAPwTHREE, /* Pulse width is set to ONE. */                                               \
608     false,            /* Routing to PRS is disabled. */                                              \
609     0                 /* PRS channel 0. */                                                           \
610   }
611 #elif (_SILICON_LABS_32B_SERIES > 0)
612 /* Default USART IrDA struct for Series 1 and Series 2 devices */
613 #if defined(USART_IRCTRL_IRPRSEN)
614 #define USART_INITIRDA_DEFAULT                                                                       \
615   {                                                                                                  \
616     {                                                                                                \
617       usartEnable,           /* Enable RX/TX when initialization is complete. */                     \
618       0,                     /* Use current configured reference clock for configuring baud rate. */ \
619       115200,                /* 115200 bits/s. */                                                    \
620       usartOVS16,            /* 16x oversampling. */                                                 \
621       usartDatabits8,        /* 8 data bits. */                                                      \
622       usartEvenParity,       /* Even parity. */                                                      \
623       usartStopbits1,        /* 1 stop bit. */                                                       \
624       false,                 /* Do not disable majority vote. */                                     \
625       false,                 /* Not USART PRS input mode. */                                         \
626       0,                     /* PRS channel 0. */                                                    \
627       false,                 /* Auto CS functionality enable/disable switch */                       \
628       false,                 /* No CS invert. */                                                     \
629       0,                     /* Auto CS Hold cycles */                                               \
630       0,                     /* Auto CS Setup cycles */                                              \
631       usartHwFlowControlNone /* No HW flow control */                                                \
632     },                                                                                               \
633     false,            /* Rx invert disabled. */                                                      \
634     false,            /* Filtering disabled. */                                                      \
635     usartIrDAPwTHREE, /* Pulse width is set to ONE. */                                               \
636     false,            /* Routing to PRS is disabled. */                                              \
637     0                 /* PRS channel 0. */                                                           \
638   }
639 #else
640 #define USART_INITIRDA_DEFAULT                                                                       \
641   {                                                                                                  \
642     {                                                                                                \
643       usartEnable,           /* Enable RX/TX when initialization is complete. */                     \
644       0,                     /* Use current configured reference clock for configuring baud rate. */ \
645       115200,                /* 115200 bits/s. */                                                    \
646       usartOVS16,            /* 16x oversampling. */                                                 \
647       usartDatabits8,        /* 8 data bits. */                                                      \
648       usartEvenParity,       /* Even parity. */                                                      \
649       usartStopbits1,        /* 1 stop bit. */                                                       \
650       false,                 /* Do not disable majority vote. */                                     \
651       false,                 /* Not USART PRS input mode. */                                         \
652       0,                     /* PRS channel 0. */                                                    \
653       false,                 /* Auto CS functionality enable/disable switch */                       \
654       false,                 /* No CS invert. */                                                     \
655       0,                     /* Auto CS Hold cycles */                                               \
656       0,                     /* Auto CS Setup cycles */                                              \
657       usartHwFlowControlNone /* No HW flow control */                                                \
658     },                                                                                               \
659     false,            /* Rx invert disabled. */                                                      \
660     false,            /* Filtering disabled. */                                                      \
661     usartIrDAPwTHREE  /* Pulse width is set to ONE. */                                               \
662   }
663 #endif
664 #endif
665 
666 #if defined(_USART_I2SCTRL_MASK)
667 /** I2S mode initialization structure. Inherited from synchronous mode initialization structure. */
668 typedef struct {
669   /** General Synchronous initialization structure. */
670   USART_InitSync_TypeDef   sync;
671 
672   /** I2S mode. */
673   USART_I2sFormat_TypeDef  format;
674 
675   /** Delay on I2S data. Set to add a one-cycle delay between a transition
676    *  on the word-clock and the start of the I2S word.
677    *  Should be set for standard I2S format. */
678   bool                     delay;
679 
680   /** Separate DMA Request For Left/Right Data. */
681   bool                     dmaSplit;
682 
683   /** Justification of I2S data within the frame. */
684   USART_I2sJustify_TypeDef justify;
685 
686   /** Stereo or Mono, set to true for mono. */
687   bool                     mono;
688 } USART_InitI2s_TypeDef;
689 
690 /** Default configuration for I2S mode initialization structure. */
691 #if defined(_EFM32_GECKO_FAMILY)
692 /* Default USART Sync configuration for EFM32G devices. */
693 #define USART_INITI2S_DEFAULT                                                                  \
694   {                                                                                            \
695     {                                                                                          \
696       usartEnable,     /* Enable RX/TX when initialization is complete. */                     \
697       0,               /* Use current configured reference clock for configuring baud rate. */ \
698       1000000,         /* 1 Mbits/s. */                                                        \
699       usartDatabits16, /* 16 databits. */                                                      \
700       true,            /* Master mode. */                                                      \
701       true,            /* Most significant bit first. */                                       \
702       usartClockMode0, /* Clock idle low, sample on rising edge. */                            \
703       false,           /* No AUTOCS mode */                                                    \
704       false,           /* No CS invert. */                                                     \
705     },                                                                                         \
706     usartI2sFormatW16D16, /* 16-bit word, 16-bit data */                                       \
707     true,               /* Delay on I2S data. */                                               \
708     false,              /* No DMA split. */                                                    \
709     usartI2sJustifyLeft,/* Data is left-justified within the frame */                          \
710     false               /* Stereo mode. */                                                     \
711   }
712 #elif defined(_SILICON_LABS_32B_SERIES_0)
713 /* Default USART Sync configuration for series 0 devices. */
714 #define USART_INITI2S_DEFAULT                                                                  \
715   {                                                                                            \
716     {                                                                                          \
717       usartEnable,     /* Enable RX/TX when initialization is complete. */                     \
718       0,               /* Use current configured reference clock for configuring baud rate. */ \
719       1000000,         /* 1 Mbits/s. */                                                        \
720       usartDatabits16, /* 16 databits. */                                                      \
721       true,            /* Master mode. */                                                      \
722       true,            /* Most significant bit first. */                                       \
723       usartClockMode0, /* Clock idle low, sample on rising edge. */                            \
724       false,           /* Not USART PRS input mode. */                                         \
725       0,               /* PRS channel 0. */                                                    \
726       false,           /* No AUTOTX mode. */                                                   \
727       false,           /* No AUTOCS mode */                                                    \
728       false,           /* No CS invert. */                                                     \
729     },                                                                                         \
730     usartI2sFormatW16D16, /* 16-bit word, 16-bit data */                                       \
731     true,               /* Delay on I2S data. */                                               \
732     false,              /* No DMA split. */                                                    \
733     usartI2sJustifyLeft,/* Data is left-justified within the frame */                          \
734     false               /* Stereo mode. */                                                     \
735   }
736 #elif (_SILICON_LABS_32B_SERIES > 0)
737 /* Default USART Sync configuration for series 2 devices */
738 #define USART_INITI2S_DEFAULT                                                                  \
739   {                                                                                            \
740     {                                                                                          \
741       usartEnableTx,    /* Enable TX when init completed. */                                   \
742       0,                /* Use current configured reference clock for configuring baudrate. */ \
743       1000000,          /* Baudrate 1M bits/s. */                                              \
744       usartDatabits16,  /* 16 databits. */                                                     \
745       true,             /* Operate as I2S master. */                                           \
746       true,             /* Most significant bit first. */                                      \
747       usartClockMode0,  /* Clock idle low, sample on rising edge. */                           \
748       false,            /* Don't enable USARTRx via PRS. */                                    \
749       usartPrsRxCh0,    /* PRS channel selection (dummy). */                                   \
750       false,            /* Disable AUTOTX mode. */                                             \
751       false,            /* No AUTOCS mode */                                                   \
752       false,            /* No CS invert. */                                                    \
753       0,                /* Auto CS Hold cycles */                                              \
754       0                 /* Auto CS Setup cycles */                                             \
755     },                                                                                         \
756     usartI2sFormatW16D16, /* 16-bit word, 16-bit data */                                       \
757     true,               /* Delay on I2S data. */                                               \
758     false,              /* No DMA split. */                                                    \
759     usartI2sJustifyLeft,/* Data is left-justified within the frame */                          \
760     false               /* Stereo mode. */                                                     \
761   }
762 #endif
763 #endif
764 
765 /*******************************************************************************
766  *****************************   PROTOTYPES   **********************************
767  ******************************************************************************/
768 
769 void USART_BaudrateAsyncSet(USART_TypeDef *usart,
770                             uint32_t refFreq,
771                             uint32_t baudrate,
772                             USART_OVS_TypeDef ovs);
773 uint32_t USART_BaudrateCalc(uint32_t refFreq,
774                             uint32_t clkdiv,
775                             bool syncmode,
776                             USART_OVS_TypeDef ovs);
777 uint32_t USART_BaudrateGet(USART_TypeDef *usart);
778 void USART_BaudrateSyncSet(USART_TypeDef *usart,
779                            uint32_t refFreq,
780                            uint32_t baudrate);
781 void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable);
782 
783 void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init);
784 void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init);
785 void USARTn_InitIrDA(USART_TypeDef *usart, const USART_InitIrDA_TypeDef *init);
786 
787 #if defined(_USART_I2SCTRL_MASK)
788 void USART_InitI2s(USART_TypeDef *usart, USART_InitI2s_TypeDef *init);
789 #endif
790 void USART_InitPrsTrigger(USART_TypeDef *usart, const USART_PrsTriggerInit_TypeDef *init);
791 
792 /***************************************************************************//**
793  * @brief
794  *   Clear one or more pending USART interrupts.
795  *
796  * @param[in] usart
797  *   Pointer to the USART/UART peripheral register block.
798  *
799  * @param[in] flags
800  *   Pending USART/UART interrupt source(s) to clear. Use one or more valid
801  *   interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
802  ******************************************************************************/
USART_IntClear(USART_TypeDef * usart,uint32_t flags)803 __STATIC_INLINE void USART_IntClear(USART_TypeDef *usart, uint32_t flags)
804 {
805 #if defined (USART_HAS_SET_CLEAR)
806   usart->IF_CLR = flags;
807 #else
808   usart->IFC = flags;
809 #endif
810 }
811 
812 /***************************************************************************//**
813  * @brief
814  *   Disable one or more USART interrupts.
815  *
816  * @param[in] usart
817  *   Pointer to the USART/UART peripheral register block.
818  *
819  * @param[in] flags
820  *   USART/UART interrupt source(s) to disable. Use one or more valid
821  *   interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
822  ******************************************************************************/
USART_IntDisable(USART_TypeDef * usart,uint32_t flags)823 __STATIC_INLINE void USART_IntDisable(USART_TypeDef *usart, uint32_t flags)
824 {
825   usart->IEN &= ~flags;
826 }
827 
828 /***************************************************************************//**
829  * @brief
830  *   Enable one or more USART interrupts.
831  *
832  * @note
833  *   Depending on the use, a pending interrupt may already be set prior to
834  *   enabling the interrupt. To ignore a pending interrupt, consider using
835  *   USART_IntClear() prior to enabling the interrupt.
836  *
837  * @param[in] usart
838  *   Pointer to the USART/UART peripheral register block.
839  *
840  * @param[in] flags
841  *   USART/UART interrupt source(s) to enable. Use one or more valid
842  *   interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
843  ******************************************************************************/
USART_IntEnable(USART_TypeDef * usart,uint32_t flags)844 __STATIC_INLINE void USART_IntEnable(USART_TypeDef *usart, uint32_t flags)
845 {
846   usart->IEN |= flags;
847 }
848 
849 /***************************************************************************//**
850  * @brief
851  *   Get pending USART interrupt flags.
852  *
853  * @note
854  *   The event bits are not cleared by the use of this function.
855  *
856  * @param[in] usart
857  *   Pointer to the USART/UART peripheral register block.
858  *
859  * @return
860  *   USART/UART interrupt source(s) pending. Returns one or more valid
861  *   interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
862  ******************************************************************************/
USART_IntGet(USART_TypeDef * usart)863 __STATIC_INLINE uint32_t USART_IntGet(USART_TypeDef *usart)
864 {
865   return usart->IF;
866 }
867 
868 /***************************************************************************//**
869  * @brief
870  *   Get enabled and pending USART interrupt flags.
871  *   Useful for handling more interrupt sources in the same interrupt handler.
872  *
873  * @param[in] usart
874  *   Pointer to the USART/UART peripheral register block.
875  *
876  * @note
877  *   Interrupt flags are not cleared by the use of this function.
878  *
879  * @return
880  *   Pending and enabled USART interrupt sources.
881  *   The return value is the bitwise AND combination of
882  *   - the OR combination of enabled interrupt sources in USARTx_IEN_nnn
883  *     register (USARTx_IEN_nnn) and
884  *   - the OR combination of valid interrupt flags of the USART module
885  *     (USARTx_IF_nnn).
886  ******************************************************************************/
USART_IntGetEnabled(USART_TypeDef * usart)887 __STATIC_INLINE uint32_t USART_IntGetEnabled(USART_TypeDef *usart)
888 {
889   uint32_t ien;
890 
891   /* Store USARTx->IEN in temporary variable in order to define explicit order
892    * of volatile accesses. */
893   ien = usart->IEN;
894 
895   /* Bitwise AND of pending and enabled interrupts. */
896   return usart->IF & ien;
897 }
898 
899 /***************************************************************************//**
900  * @brief
901  *   Set one or more pending USART interrupts from SW.
902  *
903  * @param[in] usart
904  *   Pointer to the USART/UART peripheral register block.
905  *
906  * @param[in] flags
907  *   USART/UART interrupt source(s) to set to pending. Use one or more valid
908  *   interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
909  ******************************************************************************/
USART_IntSet(USART_TypeDef * usart,uint32_t flags)910 __STATIC_INLINE void USART_IntSet(USART_TypeDef *usart, uint32_t flags)
911 {
912 #if defined (USART_HAS_SET_CLEAR)
913   usart->IF_SET = flags;
914 #else
915   usart->IFS = flags;
916 #endif
917 }
918 
919 /***************************************************************************//**
920  * @brief
921  *   Get USART STATUS register.
922  *
923  * @param[in] usart
924  *   Pointer to the USART/UART peripheral register block.
925  *
926  * @return
927  *  STATUS register value.
928  *
929  ******************************************************************************/
USART_StatusGet(USART_TypeDef * usart)930 __STATIC_INLINE uint32_t USART_StatusGet(USART_TypeDef *usart)
931 {
932   return usart->STATUS;
933 }
934 
935 void USART_Reset(USART_TypeDef *usart);
936 uint8_t USART_Rx(USART_TypeDef *usart);
937 uint16_t USART_RxDouble(USART_TypeDef *usart);
938 uint32_t USART_RxDoubleExt(USART_TypeDef *usart);
939 uint16_t USART_RxExt(USART_TypeDef *usart);
940 
941 /***************************************************************************//**
942  * @brief
943  *   Receive one 4-8 bit frame, (or part of 10-16 bit frame).
944  *
945  * @details
946  *   This function is used to quickly receive one 4-8 bits frame by reading the
947  *   RXDATA register directly, without checking the STATUS register for the
948  *   RXDATAV flag. This can be useful from the RXDATAV interrupt handler,
949  *   i.e., waiting is superfluous, in order to quickly read the received data.
950  *   Please refer to @ref USART_RxDataXGet() for reception of 9 bit frames.
951  *
952  * @note
953  *   Because this function does not check whether the RXDATA register actually
954  *   holds valid data, it should only be used in situations when it is certain
955  *   that there is valid data, ensured by some external program routine, e.g.,
956  *   when handling an RXDATAV interrupt. The @ref USART_Rx() is normally a
957  *   better choice if the validity of the RXDATA register is not certain.
958  *
959  * @note
960  *   Notice that possible parity/stop bits in asynchronous mode are not
961  *   considered part of specified frame bit length.
962  *
963  * @param[in] usart
964  *   Pointer to USART/UART peripheral register block.
965  *
966  * @return
967  *   Data received.
968  ******************************************************************************/
USART_RxDataGet(USART_TypeDef * usart)969 __STATIC_INLINE uint8_t USART_RxDataGet(USART_TypeDef *usart)
970 {
971   return (uint8_t)usart->RXDATA;
972 }
973 
974 /***************************************************************************//**
975  * @brief
976  *   Receive two 4-8 bit frames, or one 10-16 bit frame.
977  *
978  * @details
979  *   This function is used to quickly receive one 10-16 bits frame or two 4-8
980  *   bit frames by reading the RXDOUBLE register directly, without checking
981  *   the STATUS register for the RXDATAV flag. This can be useful from the
982  *   RXDATAV interrupt handler, i.e., waiting is superfluous, in order to
983  *   quickly read the received data.
984  *   This function is normally used to receive one frame when operating with
985  *   frame length 10-16 bits. Please refer to @ref USART_RxDoubleXGet()
986  *   for reception of two 9 bit frames.
987  *
988  * @note
989  *   Because this function does not check whether the RXDOUBLE register actually
990  *   holds valid data, it should only be used in situations when it is certain
991  *   that there is valid data, ensured by some external program routine, e.g.,
992  *   when handling an RXDATAV interrupt. The @ref USART_RxDouble() is
993  *   normally a better choice if the validity of the RXDOUBLE register is not
994  *   certain.
995  *
996  * @note
997  *   Notice that possible parity/stop bits in asynchronous mode are not
998  *   considered part of specified frame bit length.
999  *
1000  * @param[in] usart
1001  *   Pointer to USART/UART peripheral register block.
1002  *
1003  * @return
1004  *   Data received.
1005  ******************************************************************************/
USART_RxDoubleGet(USART_TypeDef * usart)1006 __STATIC_INLINE uint16_t USART_RxDoubleGet(USART_TypeDef *usart)
1007 {
1008   return (uint16_t)usart->RXDOUBLE;
1009 }
1010 
1011 /***************************************************************************//**
1012  * @brief
1013  *   Receive two 4-9 bit frames, or one 10-16 bit frame with extended
1014  *   information.
1015  *
1016  * @details
1017  *   This function is used to quickly receive one 10-16 bits frame or two 4-9
1018  *   bit frames by reading the RXDOUBLEX register directly, without checking
1019  *   the STATUS register for the RXDATAV flag. This can be useful from the
1020  *   RXDATAV interrupt handler, i.e., waiting is superfluous, in order to
1021  *   quickly read the received data.
1022  *
1023  * @note
1024  *   Because this function does not check whether the RXDOUBLEX register actually
1025  *   holds valid data, it should only be used in situations when it is certain
1026  *   that there is valid data, ensured by some external program routine, e.g.,
1027  *   when handling an RXDATAV interrupt. The @ref USART_RxDoubleExt() is
1028  *   normally a better choice if the validity of the RXDOUBLEX register is not
1029  *   certain.
1030  *
1031  * @note
1032  *   Notice that possible parity/stop bits in asynchronous mode are not
1033  *   considered part of specified frame bit length.
1034  *
1035  * @param[in] usart
1036  *   Pointer to USART/UART peripheral register block.
1037  *
1038  * @return
1039  *   Data received.
1040  ******************************************************************************/
USART_RxDoubleXGet(USART_TypeDef * usart)1041 __STATIC_INLINE uint32_t USART_RxDoubleXGet(USART_TypeDef *usart)
1042 {
1043   return usart->RXDOUBLEX;
1044 }
1045 
1046 /***************************************************************************//**
1047  * @brief
1048  *   Receive one 4-9 bit frame, (or part of 10-16 bit frame) with extended
1049  *   information.
1050  *
1051  * @details
1052  *   This function is used to quickly receive one 4-9 bit frame, (or part of
1053  *   10-16 bit frame) with extended information by reading the RXDATAX register
1054  *   directly, without checking the STATUS register for the RXDATAV flag. This
1055  *   can be useful from the RXDATAV interrupt handler, i.e., waiting is
1056  *   superfluous, in order to quickly read the received data.
1057  *
1058  * @note
1059  *   Because this function does not check whether the RXDATAX register actually
1060  *   holds valid data, it should only be used in situations when it is certain
1061  *   that there is valid data, ensured by some external program routine, e.g.,
1062  *   when handling an RXDATAV interrupt. The @ref USART_RxExt() is normally
1063  *   a better choice if the validity of the RXDATAX register is not certain.
1064  *
1065  * @note
1066  *   Notice that possible parity/stop bits in asynchronous mode are not
1067  *   considered part of specified frame bit length.
1068  *
1069  * @param[in] usart
1070  *   Pointer to USART/UART peripheral register block.
1071  *
1072  * @return
1073  *   Data received.
1074  ******************************************************************************/
USART_RxDataXGet(USART_TypeDef * usart)1075 __STATIC_INLINE uint16_t USART_RxDataXGet(USART_TypeDef *usart)
1076 {
1077   return (uint16_t)usart->RXDATAX;
1078 }
1079 
1080 uint8_t USART_SpiTransfer(USART_TypeDef *usart, uint8_t data);
1081 void USART_Tx(USART_TypeDef *usart, uint8_t data);
1082 void USART_TxDouble(USART_TypeDef *usart, uint16_t data);
1083 void USART_TxDoubleExt(USART_TypeDef *usart, uint32_t data);
1084 void USART_TxExt(USART_TypeDef *usart, uint16_t data);
1085 
1086 /** @} (end addtogroup usart) */
1087 
1088 #ifdef __cplusplus
1089 }
1090 #endif
1091 
1092 #endif /* defined(USART_COUNT) && (USART_COUNT > 0) */
1093 #endif /* EM_USART_H */
1094