blob: 8de0797f367e03bffa7b9860e5b52a88ea42eb76 [file] [log] [blame]
/***************************************************************************//**
* @file em_usart.h
* @brief Universal synchronous/asynchronous receiver/transmitter (USART/UART)
* peripheral API
* @version 5.1.2
*******************************************************************************
* @section License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef EM_USART_H
#define EM_USART_H
#include "em_device.h"
#if defined(USART_COUNT) && (USART_COUNT > 0)
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup USART
* @brief Universal Synchronous/Asynchronous Receiver/Transmitter
* Peripheral API
* @details
* The Universal Synchronous/Asynchronous Receiver/Transmitter (USART)
* is a very flexible serial I/O module. It supports full duplex asynchronous UART
* communication as well as RS-485, SPI, MicroWire and 3-wire. It can also interface
* with ISO7816 Smart-Cards, and IrDA devices.
*
* The USART has a wide selection of operating modes, frame formats and baud rates.
* All features are supported through the API of this module.
*
* Triple buffering and DMA support makes high data-rates possible with minimal
* CPU intervention and it is possible to transmit and receive large frames while
* the MCU remains in EM1 Sleep.
*
* This module does not support DMA configuration. The @ref UARTDRV and @ref SPIDRV drivers
* provide full support for DMA and more.
*
* The following steps are necessary for basic operation:
*
* Clock enable:
* @include em_usart_clock_enable.c
*
* To initialize the USART for asynchronous operation (eg. UART):
* @include em_usart_init_async.c
*
* To initialize the USART for synchronous operation (eg. SPI):
* @include em_usart_init_sync.c
*
* After pins are assigned for the application/board, enable pins at the
* desired location. Available locations can be obtained from the Pin Definitions
* section in the datasheet.
* @if DOXYDOC_P1_DEVICE
* @include em_usart_route_p1.c
* @note UART hardware flow control is not directly supported in hardware on
* @ref _SILICON_LABS_32B_SERIES_0 parts.
* @endif
* @if DOXYDOC_P2_DEVICE
* @include em_usart_route_p2.c
* @endif
* @note @ref UARTDRV supports all types of UART flow control. Software assisted
* hardware flow control is available for parts without true UART hardware
* flow control.
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Databit selection. */
typedef enum
{
usartDatabits4 = USART_FRAME_DATABITS_FOUR, /**< 4 databits (not available for UART). */
usartDatabits5 = USART_FRAME_DATABITS_FIVE, /**< 5 databits (not available for UART). */
usartDatabits6 = USART_FRAME_DATABITS_SIX, /**< 6 databits (not available for UART). */
usartDatabits7 = USART_FRAME_DATABITS_SEVEN, /**< 7 databits (not available for UART). */
usartDatabits8 = USART_FRAME_DATABITS_EIGHT, /**< 8 databits. */
usartDatabits9 = USART_FRAME_DATABITS_NINE, /**< 9 databits. */
usartDatabits10 = USART_FRAME_DATABITS_TEN, /**< 10 databits (not available for UART). */
usartDatabits11 = USART_FRAME_DATABITS_ELEVEN, /**< 11 databits (not available for UART). */
usartDatabits12 = USART_FRAME_DATABITS_TWELVE, /**< 12 databits (not available for UART). */
usartDatabits13 = USART_FRAME_DATABITS_THIRTEEN, /**< 13 databits (not available for UART). */
usartDatabits14 = USART_FRAME_DATABITS_FOURTEEN, /**< 14 databits (not available for UART). */
usartDatabits15 = USART_FRAME_DATABITS_FIFTEEN, /**< 15 databits (not available for UART). */
usartDatabits16 = USART_FRAME_DATABITS_SIXTEEN /**< 16 databits (not available for UART). */
} USART_Databits_TypeDef;
/** Enable selection. */
typedef enum
{
/** Disable both receiver and transmitter. */
usartDisable = 0x0,
/** Enable receiver only, transmitter disabled. */
usartEnableRx = USART_CMD_RXEN,
/** Enable transmitter only, receiver disabled. */
usartEnableTx = USART_CMD_TXEN,
/** Enable both receiver and transmitter. */
usartEnable = (USART_CMD_RXEN | USART_CMD_TXEN)
} USART_Enable_TypeDef;
/** Oversampling selection, used for asynchronous operation. */
typedef enum
{
usartOVS16 = USART_CTRL_OVS_X16, /**< 16x oversampling (normal). */
usartOVS8 = USART_CTRL_OVS_X8, /**< 8x oversampling. */
usartOVS6 = USART_CTRL_OVS_X6, /**< 6x oversampling. */
usartOVS4 = USART_CTRL_OVS_X4 /**< 4x oversampling. */
} USART_OVS_TypeDef;
/** Parity selection, mainly used for asynchronous operation. */
typedef enum
{
usartNoParity = USART_FRAME_PARITY_NONE, /**< No parity. */
usartEvenParity = USART_FRAME_PARITY_EVEN, /**< Even parity. */
usartOddParity = USART_FRAME_PARITY_ODD /**< Odd parity. */
} USART_Parity_TypeDef;
/** Stopbits selection, used for asynchronous operation. */
typedef enum
{
usartStopbits0p5 = USART_FRAME_STOPBITS_HALF, /**< 0.5 stopbits. */
usartStopbits1 = USART_FRAME_STOPBITS_ONE, /**< 1 stopbits. */
usartStopbits1p5 = USART_FRAME_STOPBITS_ONEANDAHALF, /**< 1.5 stopbits. */
usartStopbits2 = USART_FRAME_STOPBITS_TWO /**< 2 stopbits. */
} USART_Stopbits_TypeDef;
/** Clock polarity/phase mode. */
typedef enum
{
/** Clock idle low, sample on rising edge. */
usartClockMode0 = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLELEADING,
/** Clock idle low, sample on falling edge. */
usartClockMode1 = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLETRAILING,
/** Clock idle high, sample on falling edge. */
usartClockMode2 = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLELEADING,
/** Clock idle high, sample on rising edge. */
usartClockMode3 = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLETRAILING
} USART_ClockMode_TypeDef;
/** Pulse width selection for IrDA mode. */
typedef enum
{
/** IrDA pulse width is 1/16 for OVS=0 and 1/8 for OVS=1 */
usartIrDAPwONE = USART_IRCTRL_IRPW_ONE,
/** IrDA pulse width is 2/16 for OVS=0 and 2/8 for OVS=1 */
usartIrDAPwTWO = USART_IRCTRL_IRPW_TWO,
/** IrDA pulse width is 3/16 for OVS=0 and 3/8 for OVS=1 */
usartIrDAPwTHREE = USART_IRCTRL_IRPW_THREE,
/** IrDA pulse width is 4/16 for OVS=0 and 4/8 for OVS=1 */
usartIrDAPwFOUR = USART_IRCTRL_IRPW_FOUR
} USART_IrDAPw_Typedef;
/** PRS channel selection for IrDA mode. */
typedef enum
{
usartIrDAPrsCh0 = USART_IRCTRL_IRPRSSEL_PRSCH0, /**< PRS channel 0 */
usartIrDAPrsCh1 = USART_IRCTRL_IRPRSSEL_PRSCH1, /**< PRS channel 1 */
usartIrDAPrsCh2 = USART_IRCTRL_IRPRSSEL_PRSCH2, /**< PRS channel 2 */
usartIrDAPrsCh3 = USART_IRCTRL_IRPRSSEL_PRSCH3, /**< PRS channel 3 */
#if defined(USART_IRCTRL_IRPRSSEL_PRSCH4)
usartIrDAPrsCh4 = USART_IRCTRL_IRPRSSEL_PRSCH4, /**< PRS channel 4 */
#endif
#if defined(USART_IRCTRL_IRPRSSEL_PRSCH5)
usartIrDAPrsCh5 = USART_IRCTRL_IRPRSSEL_PRSCH5, /**< PRS channel 5 */
#endif
#if defined(USART_IRCTRL_IRPRSSEL_PRSCH6)
usartIrDAPrsCh6 = USART_IRCTRL_IRPRSSEL_PRSCH6, /**< PRS channel 6 */
#endif
#if defined(USART_IRCTRL_IRPRSSEL_PRSCH7)
usartIrDAPrsCh7 = USART_IRCTRL_IRPRSSEL_PRSCH7, /**< PRS channel 7 */
#endif
} USART_IrDAPrsSel_Typedef;
#if defined(_USART_I2SCTRL_MASK)
/** I2S format selection. */
typedef enum
{
usartI2sFormatW32D32 = USART_I2SCTRL_FORMAT_W32D32, /**< 32-bit word, 32-bit data */
usartI2sFormatW32D24M = USART_I2SCTRL_FORMAT_W32D24M, /**< 32-bit word, 32-bit data with 8 lsb masked */
usartI2sFormatW32D24 = USART_I2SCTRL_FORMAT_W32D24, /**< 32-bit word, 24-bit data */
usartI2sFormatW32D16 = USART_I2SCTRL_FORMAT_W32D16, /**< 32-bit word, 16-bit data */
usartI2sFormatW32D8 = USART_I2SCTRL_FORMAT_W32D8, /**< 32-bit word, 8-bit data */
usartI2sFormatW16D16 = USART_I2SCTRL_FORMAT_W16D16, /**< 16-bit word, 16-bit data */
usartI2sFormatW16D8 = USART_I2SCTRL_FORMAT_W16D8, /**< 16-bit word, 8-bit data */
usartI2sFormatW8D8 = USART_I2SCTRL_FORMAT_W8D8 /**< 8-bit word, 8-bit data */
} USART_I2sFormat_TypeDef;
/** I2S frame data justify. */
typedef enum
{
usartI2sJustifyLeft = USART_I2SCTRL_JUSTIFY_LEFT, /**< Data is left-justified within the frame */
usartI2sJustifyRight = USART_I2SCTRL_JUSTIFY_RIGHT /**< Data is right-justified within the frame */
} USART_I2sJustify_TypeDef;
#endif
#if defined(_USART_INPUT_MASK)
/** USART Rx input PRS selection. */
typedef enum
{
usartPrsRxCh0 = USART_INPUT_RXPRSSEL_PRSCH0, /**< PRSCH0 selected as USART_INPUT */
usartPrsRxCh1 = USART_INPUT_RXPRSSEL_PRSCH1, /**< PRSCH1 selected as USART_INPUT */
usartPrsRxCh2 = USART_INPUT_RXPRSSEL_PRSCH2, /**< PRSCH2 selected as USART_INPUT */
usartPrsRxCh3 = USART_INPUT_RXPRSSEL_PRSCH3, /**< PRSCH3 selected as USART_INPUT */
#if defined(USART_INPUT_RXPRSSEL_PRSCH7)
usartPrsRxCh4 = USART_INPUT_RXPRSSEL_PRSCH4, /**< PRSCH4 selected as USART_INPUT */
usartPrsRxCh5 = USART_INPUT_RXPRSSEL_PRSCH5, /**< PRSCH5 selected as USART_INPUT */
usartPrsRxCh6 = USART_INPUT_RXPRSSEL_PRSCH6, /**< PRSCH6 selected as USART_INPUT */
usartPrsRxCh7 = USART_INPUT_RXPRSSEL_PRSCH7, /**< PRSCH7 selected as USART_INPUT */
#endif
#if defined(USART_INPUT_RXPRSSEL_PRSCH11)
usartPrsRxCh8 = USART_INPUT_RXPRSSEL_PRSCH8, /**< PRSCH8 selected as USART_INPUT */
usartPrsRxCh9 = USART_INPUT_RXPRSSEL_PRSCH9, /**< PRSCH9 selected as USART_INPUT */
usartPrsRxCh10 = USART_INPUT_RXPRSSEL_PRSCH10, /**< PRSCH10 selected as USART_INPUT */
usartPrsRxCh11 = USART_INPUT_RXPRSSEL_PRSCH11 /**< PRSCH11 selected as USART_INPUT */
#endif
} USART_PrsRxCh_TypeDef;
#endif
/** USART PRS Transmit Trigger Channels */
typedef enum
{
usartPrsTriggerCh0 = USART_TRIGCTRL_TSEL_PRSCH0, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh1 = USART_TRIGCTRL_TSEL_PRSCH1, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh2 = USART_TRIGCTRL_TSEL_PRSCH2, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh3 = USART_TRIGCTRL_TSEL_PRSCH3, /**< PRSCH0 selected as USART Trigger */
#if defined(USART_TRIGCTRL_TSEL_PRSCH7)
usartPrsTriggerCh4 = USART_TRIGCTRL_TSEL_PRSCH4, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh5 = USART_TRIGCTRL_TSEL_PRSCH5, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh6 = USART_TRIGCTRL_TSEL_PRSCH6, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh7 = USART_TRIGCTRL_TSEL_PRSCH7, /**< PRSCH0 selected as USART Trigger */
#endif
} USART_PrsTriggerCh_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Asynchronous mode init structure. */
typedef struct
{
/** Specifies whether TX and/or RX shall be enabled when init completed. */
USART_Enable_TypeDef enable;
/**
* USART/UART reference clock assumed when configuring baudrate setup. Set
* it to 0 if currently configurated reference clock shall be used.
*/
uint32_t refFreq;
/** Desired baudrate. */
uint32_t baudrate;
/** Oversampling used. */
USART_OVS_TypeDef oversampling;
/** Number of databits in frame. Notice that UART modules only support 8 or
* 9 databits. */
USART_Databits_TypeDef databits;
/** Parity mode to use. */
USART_Parity_TypeDef parity;
/** Number of stopbits to use. */
USART_Stopbits_TypeDef stopbits;
#if defined(USART_INPUT_RXPRS) && defined(USART_CTRL_MVDIS)
/** Majority Vote Disable for 16x, 8x and 6x oversampling modes. */
bool mvdis;
/** Enable USART Rx via PRS. */
bool prsRxEnable;
/** Select PRS channel for USART Rx. (Only valid if prsRxEnable is true). */
USART_PrsRxCh_TypeDef prsRxCh;
#endif
#if defined(_USART_TIMING_CSHOLD_MASK)
/** Auto CS enabling */
bool autoCsEnable;
/** Auto CS hold time in baud cycles */
uint8_t autoCsHold;
/** Auto CS setup time in baud cycles */
uint8_t autoCsSetup;
#endif
} USART_InitAsync_TypeDef;
/** USART PRS trigger enable */
typedef struct
{
#if defined(USART_TRIGCTRL_AUTOTXTEN)
/** Enable AUTOTX */
bool autoTxTriggerEnable;
#endif
/** Trigger receive via PRS channel */
bool rxTriggerEnable;
/** Trigger transmit via PRS channel */
bool txTriggerEnable;
/** PRS channel to be used to trigger auto transmission */
USART_PrsTriggerCh_TypeDef prsTriggerChannel;
} USART_PrsTriggerInit_TypeDef;
/** Default config for USART async init structure. */
#if defined(_USART_TIMING_CSHOLD_MASK) && defined(USART_CTRL_MVDIS)
#define USART_INITASYNC_DEFAULT \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartNoParity, /* No parity. */ \
usartStopbits1, /* 1 stopbit. */ \
false, /* Do not disable majority vote. */ \
false, /* Not USART PRS input mode. */ \
usartPrsRxCh0, /* PRS channel 0. */ \
false, /* Auto CS functionality enable/disable switch */ \
0, /* Auto CS Hold cycles */ \
0 /* Auto CS Setup cycles */ \
}
#elif defined(USART_INPUT_RXPRS) && defined(USART_CTRL_MVDIS)
#define USART_INITASYNC_DEFAULT \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartNoParity, /* No parity. */ \
usartStopbits1, /* 1 stopbit. */ \
false, /* Do not disable majority vote. */ \
false, /* Not USART PRS input mode. */ \
usartPrsRxCh0 /* PRS channel 0. */ \
}
#else
#define USART_INITASYNC_DEFAULT \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartNoParity, /* No parity. */ \
usartStopbits1 /* 1 stopbit. */ \
}
#endif
/** Default config for USART PRS triggering structure. */
#if defined(USART_TRIGCTRL_AUTOTXTEN)
#define USART_INITPRSTRIGGER_DEFAULT \
{ \
false, /* Do not enable autoTX triggering. */ \
false, /* Do not enable receive triggering. */ \
false, /* Do not enable transmit triggering. */ \
usartPrsTriggerCh0 /* Set default channel to zero. */ \
}
#else
#define USART_INITPRSTRIGGER_DEFAULT \
{ \
false, /* Do not enable receive triggering. */ \
false, /* Do not enable transmit triggering. */ \
usartPrsTriggerCh0 /* Set default channel to zero. */ \
}
#endif
/** Synchronous mode init structure. */
typedef struct
{
/** Specifies whether TX and/or RX shall be enabled when init completed. */
USART_Enable_TypeDef enable;
/**
* USART/UART reference clock assumed when configuring baudrate setup. Set
* it to 0 if currently configurated reference clock shall be used.
*/
uint32_t refFreq;
/** Desired baudrate. */
uint32_t baudrate;
/** Number of databits in frame. */
USART_Databits_TypeDef databits;
/** Select if to operate in master or slave mode. */
bool master;
/** Select if to send most or least significant bit first. */
bool msbf;
/** Clock polarity/phase mode. */
USART_ClockMode_TypeDef clockMode;
#if defined(USART_INPUT_RXPRS) && defined(USART_TRIGCTRL_AUTOTXTEN)
/** Enable USART Rx via PRS. */
bool prsRxEnable;
/** Select PRS channel for USART Rx. (Only valid if prsRxEnable is true). */
USART_PrsRxCh_TypeDef prsRxCh;
/** Enable AUTOTX mode. Transmits as long as RX is not full.
* If TX is empty, underflows are generated. */
bool autoTx;
#endif
#if defined(_USART_TIMING_CSHOLD_MASK)
/** Auto CS enabling */
bool autoCsEnable;
/** Auto CS hold time in baud cycles */
uint8_t autoCsHold;
/** Auto CS setup time in baud cycles */
uint8_t autoCsSetup;
#endif
} USART_InitSync_TypeDef;
/** Default config for USART sync init structure. */
#if defined(_USART_TIMING_CSHOLD_MASK)
#define USART_INITSYNC_DEFAULT \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
1000000, /* 1 Mbits/s. */ \
usartDatabits8, /* 8 databits. */ \
true, /* Master mode. */ \
false, /* Send least significant bit first. */ \
usartClockMode0, /* Clock idle low, sample on rising edge. */ \
false, /* Not USART PRS input mode. */ \
usartPrsRxCh0, /* PRS channel 0. */ \
false, /* No AUTOTX mode. */ \
false, /* No AUTOCS mode */ \
0, /* Auto CS Hold cycles */ \
0 /* Auto CS Setup cycles */ \
}
#elif defined(USART_INPUT_RXPRS) && defined(USART_TRIGCTRL_AUTOTXTEN)
#define USART_INITSYNC_DEFAULT \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
1000000, /* 1 Mbits/s. */ \
usartDatabits8, /* 8 databits. */ \
true, /* Master mode. */ \
false, /* Send least significant bit first. */ \
usartClockMode0, /* Clock idle low, sample on rising edge. */ \
false, /* Not USART PRS input mode. */ \
usartPrsRxCh0, /* PRS channel 0. */ \
false /* No AUTOTX mode. */ \
}
#else
#define USART_INITSYNC_DEFAULT \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
1000000, /* 1 Mbits/s. */ \
usartDatabits8, /* 8 databits. */ \
true, /* Master mode. */ \
false, /* Send least significant bit first. */ \
usartClockMode0 /* Clock idle low, sample on rising edge. */ \
}
#endif
/** IrDA mode init structure. Inherited from asynchronous mode init structure */
typedef struct
{
/** General Async initialization structure. */
USART_InitAsync_TypeDef async;
/** Set to invert Rx signal before IrDA demodulator. */
bool irRxInv;
/** Set to enable filter on IrDA demodulator. */
bool irFilt;
/** Configure the pulse width generated by the IrDA modulator as a fraction
* of the configured USART bit period. */
USART_IrDAPw_Typedef irPw;
/** Enable the PRS channel selected by irPrsSel as input to IrDA module
* instead of TX. */
bool irPrsEn;
/** A PRS can be used as input to the pulse modulator instead of TX.
* This value selects the channel to use. */
USART_IrDAPrsSel_Typedef irPrsSel;
} USART_InitIrDA_TypeDef;
/** Default config for IrDA mode init structure. */
#if defined(_USART_TIMING_CSHOLD_MASK) && defined(USART_CTRL_MVDIS)
#define USART_INITIRDA_DEFAULT \
{ \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartEvenParity, /* Even parity. */ \
usartStopbits1, /* 1 stopbit. */ \
false, /* Do not disable majority vote. */ \
false, /* Not USART PRS input mode. */ \
usartPrsRxCh0, /* PRS channel 0. */ \
false, /* Auto CS functionality enable/disable switch */ \
0, /* Auto CS Hold cycles */ \
0 /* Auto CS Setup cycles */ \
}, \
false, /* Rx invert disabled. */ \
false, /* Filtering disabled. */ \
usartIrDAPwTHREE, /* Pulse width is set to ONE. */ \
false, /* Routing to PRS is disabled. */ \
usartIrDAPrsCh0 /* PRS channel 0. */ \
}
#elif defined(USART_INPUT_RXPRS) && defined(USART_CTRL_MVDIS)
#define USART_INITIRDA_DEFAULT \
{ \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartEvenParity, /* Even parity. */ \
usartStopbits1, /* 1 stopbit. */ \
false, /* Do not disable majority vote. */ \
false, /* Not USART PRS input mode. */ \
usartPrsRxCh0 /* PRS channel 0. */ \
}, \
false, /* Rx invert disabled. */ \
false, /* Filtering disabled. */ \
usartIrDAPwTHREE, /* Pulse width is set to ONE. */ \
false, /* Routing to PRS is disabled. */ \
usartIrDAPrsCh0 /* PRS channel 0. */ \
}
#else
#define USART_INITIRDA_DEFAULT \
{ \
{ \
usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartEvenParity, /* Even parity. */ \
usartStopbits1 /* 1 stopbit. */ \
}, \
false, /* Rx invert disabled. */ \
false, /* Filtering disabled. */ \
usartIrDAPwTHREE, /* Pulse width is set to ONE. */ \
false, /* Routing to PRS is disabled. */ \
usartIrDAPrsCh0 /* PRS channel 0. */ \
}
#endif
#if defined(_USART_I2SCTRL_MASK)
/** I2S mode init structure. Inherited from synchronous mode init structure */
typedef struct
{
/** General Sync initialization structure. */
USART_InitSync_TypeDef sync;
/** I2S mode. */
USART_I2sFormat_TypeDef format;
/** Delay on I2S data. Set to add a one-cycle delay between a transition
* on the word-clock and the start of the I2S word.
* Should be set for standard I2S format. */
bool delay;
/** Separate DMA Request For Left/Right Data. */
bool dmaSplit;
/** Justification of I2S data within the frame */
USART_I2sJustify_TypeDef justify;
/** Stero or Mono, set to true for mono. */
bool mono;
} USART_InitI2s_TypeDef;
/** Default config for I2S mode init structure. */
#if defined(_USART_TIMING_CSHOLD_MASK)
#define USART_INITI2S_DEFAULT \
{ \
{ \
usartEnableTx, /* Enable TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
1000000, /* Baudrate 1M bits/s. */ \
usartDatabits16, /* 16 databits. */ \
true, /* Operate as I2S master. */ \
true, /* Most significant bit first. */ \
usartClockMode0, /* Clock idle low, sample on rising edge. */ \
false, /* Don't enable USARTRx via PRS. */ \
usartPrsRxCh0, /* PRS channel selection (dummy). */ \
false, /* Disable AUTOTX mode. */ \
false, /* No AUTOCS mode */ \
0, /* Auto CS Hold cycles */ \
0 /* Auto CS Setup cycles */ \
}, \
usartI2sFormatW16D16, /* 16-bit word, 16-bit data */ \
true, /* Delay on I2S data. */ \
false, /* No DMA split. */ \
usartI2sJustifyLeft, /* Data is left-justified within the frame */ \
false /* Stereo mode. */ \
}
#else
#define USART_INITI2S_DEFAULT \
{ \
{ \
usartEnableTx, /* Enable TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
1000000, /* Baudrate 1M bits/s. */ \
usartDatabits16, /* 16 databits. */ \
true, /* Operate as I2S master. */ \
true, /* Most significant bit first. */ \
usartClockMode0, /* Clock idle low, sample on rising edge. */ \
false, /* Don't enable USARTRx via PRS. */ \
usartPrsRxCh0, /* PRS channel selection (dummy). */ \
false /* Disable AUTOTX mode. */ \
}, \
usartI2sFormatW16D16, /* 16-bit word, 16-bit data */ \
true, /* Delay on I2S data. */ \
false, /* No DMA split. */ \
usartI2sJustifyLeft, /* Data is left-justified within the frame */ \
false /* Stereo mode. */ \
}
#endif
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void USART_BaudrateAsyncSet(USART_TypeDef *usart,
uint32_t refFreq,
uint32_t baudrate,
USART_OVS_TypeDef ovs);
uint32_t USART_BaudrateCalc(uint32_t refFreq,
uint32_t clkdiv,
bool syncmode,
USART_OVS_TypeDef ovs);
uint32_t USART_BaudrateGet(USART_TypeDef *usart);
void USART_BaudrateSyncSet(USART_TypeDef *usart,
uint32_t refFreq,
uint32_t baudrate);
void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable);
void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init);
void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init);
void USARTn_InitIrDA(USART_TypeDef *usart, const USART_InitIrDA_TypeDef *init);
#if defined(_USART_I2SCTRL_MASK)
void USART_InitI2s(USART_TypeDef *usart, USART_InitI2s_TypeDef *init);
#endif
void USART_InitPrsTrigger(USART_TypeDef *usart, const USART_PrsTriggerInit_TypeDef *init);
#if defined(DEFAULT_IRDA_USART) || defined(USART0) || ((USART_COUNT == 1) && defined(USART1))
/***************************************************************************//**
* @brief
* Init DEFAULT_IRDA_USART for asynchronous IrDA mode.
*
* @details
* This function will configure basic settings in order to operate in
* asynchronous IrDA mode.
*
* Special control setup not covered by this function must be done after
* using this function by direct modification of the CTRL and IRCTRL
* registers.
*
* Notice that pins used by the USART/UART module must be properly configured
* by the user explicitly, in order for the USART/UART to work as intended.
* (When configuring pins, one should remember to consider the sequence of
* configuration, in order to avoid unintended pulses/glitches on output
* pins.)
*
* @param[in] init
* Pointer to initialization structure used to configure async IrDA setup.
*
* @deprecated
* Deprecated function. New code should use USARTn_InitIrDA().
* This function uses DEFAULT_IRDA_USART, which unless otherwise specified, is
* USART0 on most devices, and USART1 on devices that don't have a USART0.
*
******************************************************************************/
__STATIC_INLINE void USART_InitIrDA(const USART_InitIrDA_TypeDef *init)
{
#if defined(DEFAULT_IRDA_USART)
USART_TypeDef *usart = DEFAULT_IRDA_USART;
#elif (USART_COUNT == 1) && defined(USART1)
USART_TypeDef *usart = USART1;
#else
USART_TypeDef *usart = USART0;
#endif
USARTn_InitIrDA(usart, init);
}
#endif
/***************************************************************************//**
* @brief
* Clear one or more pending USART interrupts.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @param[in] flags
* Pending USART/UART interrupt source(s) to clear. Use one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
__STATIC_INLINE void USART_IntClear(USART_TypeDef *usart, uint32_t flags)
{
usart->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more USART interrupts.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @param[in] flags
* USART/UART interrupt source(s) to disable. Use one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
__STATIC_INLINE void USART_IntDisable(USART_TypeDef *usart, uint32_t flags)
{
usart->IEN &= ~flags;
}
/***************************************************************************//**
* @brief
* Enable one or more USART interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using USART_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @param[in] flags
* USART/UART interrupt source(s) to enable. Use one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
__STATIC_INLINE void USART_IntEnable(USART_TypeDef *usart, uint32_t flags)
{
usart->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending USART interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @return
* USART/UART interrupt source(s) pending. Returns one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
__STATIC_INLINE uint32_t USART_IntGet(USART_TypeDef *usart)
{
return usart->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending USART interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @note
* Interrupt flags are not cleared by the use of this function.
*
* @return
* Pending and enabled USART interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in USARTx_IEN_nnn
* register (USARTx_IEN_nnn) and
* - the OR combination of valid interrupt flags of the USART module
* (USARTx_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t USART_IntGetEnabled(USART_TypeDef *usart)
{
uint32_t ien;
/* Store USARTx->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
ien = usart->IEN;
/* Bitwise AND of pending and enabled interrupts */
return usart->IF & ien;
}
/***************************************************************************//**
* @brief
* Set one or more pending USART interrupts from SW.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @param[in] flags
* USART/UART interrupt source(s) to set to pending. Use one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
__STATIC_INLINE void USART_IntSet(USART_TypeDef *usart, uint32_t flags)
{
usart->IFS = flags;
}
/***************************************************************************//**
* @brief
* Get USART STATUS register.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @return
* STATUS register value.
*
******************************************************************************/
__STATIC_INLINE uint32_t USART_StatusGet(USART_TypeDef *usart)
{
return usart->STATUS;
}
void USART_Reset(USART_TypeDef *usart);
uint8_t USART_Rx(USART_TypeDef *usart);
uint16_t USART_RxDouble(USART_TypeDef *usart);
uint32_t USART_RxDoubleExt(USART_TypeDef *usart);
uint16_t USART_RxExt(USART_TypeDef *usart);
/***************************************************************************//**
* @brief
* Receive one 4-8 bit frame, (or part of 10-16 bit frame).
*
* @details
* This function is used to quickly receive one 4-8 bits frame by reading the
* RXDATA register directly, without checking the STATUS register for the
* RXDATAV flag. This can be useful from the RXDATAV interrupt handler,
* i.e. waiting is superfluous, in order to quickly read the received data.
* Please refer to @ref USART_RxDataXGet() for reception of 9 bit frames.
*
* @note
* Since this function does not check whether the RXDATA register actually
* holds valid data, it should only be used in situations when it is certain
* that there is valid data, ensured by some external program routine, e.g.
* like when handling an RXDATAV interrupt. The @ref USART_Rx() is normally a
* better choice if the validity of the RXDATA register is not certain.
*
* @note
* Notice that possible parity/stop bits in asynchronous mode are not
* considered part of specified frame bit length.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @return
* Data received.
******************************************************************************/
__STATIC_INLINE uint8_t USART_RxDataGet(USART_TypeDef *usart)
{
return (uint8_t)usart->RXDATA;
}
/***************************************************************************//**
* @brief
* Receive two 4-8 bit frames, or one 10-16 bit frame.
*
* @details
* This function is used to quickly receive one 10-16 bits frame or two 4-8
* bit frames by reading the RXDOUBLE register directly, without checking
* the STATUS register for the RXDATAV flag. This can be useful from the
* RXDATAV interrupt handler, i.e. waiting is superfluous, in order to
* quickly read the received data.
* This function is normally used to receive one frame when operating with
* frame length 10-16 bits. Please refer to @ref USART_RxDoubleXGet()
* for reception of two 9 bit frames.
*
* @note
* Since this function does not check whether the RXDOUBLE register actually
* holds valid data, it should only be used in situations when it is certain
* that there is valid data, ensured by some external program routine, e.g.
* like when handling an RXDATAV interrupt. The @ref USART_RxDouble() is
* normally a better choice if the validity of the RXDOUBLE register is not
* certain.
*
* @note
* Notice that possible parity/stop bits in asynchronous mode are not
* considered part of specified frame bit length.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @return
* Data received.
******************************************************************************/
__STATIC_INLINE uint16_t USART_RxDoubleGet(USART_TypeDef *usart)
{
return (uint16_t)usart->RXDOUBLE;
}
/***************************************************************************//**
* @brief
* Receive two 4-9 bit frames, or one 10-16 bit frame with extended
* information.
*
* @details
* This function is used to quickly receive one 10-16 bits frame or two 4-9
* bit frames by reading the RXDOUBLEX register directly, without checking
* the STATUS register for the RXDATAV flag. This can be useful from the
* RXDATAV interrupt handler, i.e. waiting is superfluous, in order to
* quickly read the received data.
*
* @note
* Since this function does not check whether the RXDOUBLEX register actually
* holds valid data, it should only be used in situations when it is certain
* that there is valid data, ensured by some external program routine, e.g.
* like when handling an RXDATAV interrupt. The @ref USART_RxDoubleExt() is
* normally a better choice if the validity of the RXDOUBLEX register is not
* certain.
*
* @note
* Notice that possible parity/stop bits in asynchronous mode are not
* considered part of specified frame bit length.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @return
* Data received.
******************************************************************************/
__STATIC_INLINE uint32_t USART_RxDoubleXGet(USART_TypeDef *usart)
{
return usart->RXDOUBLEX;
}
/***************************************************************************//**
* @brief
* Receive one 4-9 bit frame, (or part of 10-16 bit frame) with extended
* information.
*
* @details
* This function is used to quickly receive one 4-9 bit frame, (or part of
* 10-16 bit frame) with extended information by reading the RXDATAX register
* directly, without checking the STATUS register for the RXDATAV flag. This
* can be useful from the RXDATAV interrupt handler, i.e. waiting is
* superfluous, in order to quickly read the received data.
*
* @note
* Since this function does not check whether the RXDATAX register actually
* holds valid data, it should only be used in situations when it is certain
* that there is valid data, ensured by some external program routine, e.g.
* like when handling an RXDATAV interrupt. The @ref USART_RxExt() is normally
* a better choice if the validity of the RXDATAX register is not certain.
*
* @note
* Notice that possible parity/stop bits in asynchronous mode are not
* considered part of specified frame bit length.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @return
* Data received.
******************************************************************************/
__STATIC_INLINE uint16_t USART_RxDataXGet(USART_TypeDef *usart)
{
return (uint16_t)usart->RXDATAX;
}
uint8_t USART_SpiTransfer(USART_TypeDef *usart, uint8_t data);
void USART_Tx(USART_TypeDef *usart, uint8_t data);
void USART_TxDouble(USART_TypeDef *usart, uint16_t data);
void USART_TxDoubleExt(USART_TypeDef *usart, uint32_t data);
void USART_TxExt(USART_TypeDef *usart, uint16_t data);
/** @} (end addtogroup USART) */
/** @} (end addtogroup emlib) */
#ifdef __cplusplus
}
#endif
#endif /* defined(USART_COUNT) && (USART_COUNT > 0) */
#endif /* EM_USART_H */