Files
BoilerControlUnit_Firmware/Libs/platform/emdrv/uartdrv/inc/uartdrv.h
GClarkson 9d06f983af Imported more library files
Not compiling currently
2025-04-12 23:37:19 +01:00

471 lines
23 KiB
C

/***************************************************************************//**
* @file
* @brief UARTDRV API definition.
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* SPDX-License-Identifier: Zlib
*
* The licensor of this software is Silicon Laboratories Inc.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* 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. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 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.
*
******************************************************************************/
#ifndef UARTDRV_H
#define UARTDRV_H
#if defined(SL_COMPONENT_CATALOG_PRESENT)
#include "sl_component_catalog.h"
#endif
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
#endif
#include "em_device.h"
#include "sl_device_peripheral.h"
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
#include "em_usart.h"
#endif
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0)
#include "em_leuart.h"
#elif (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
#if (_SILICON_LABS_32B_SERIES > 2)
#define UARTDRV_USE_PERIPHERAL
#include "sl_hal_eusart.h"
#else
#include "em_eusart.h"
#endif
#endif
#include "sl_gpio.h"
#include "sl_clock_manager.h"
#include "ecode.h"
#include "uartdrv_config.h"
#include "dmadrv.h"
#include "sl_enum.h"
#include "sl_sleeptimer.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup uartdrv
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup uartdrv_error_codes Error Codes
* @{
******************************************************************************/
#define ECODE_EMDRV_UARTDRV_OK (ECODE_OK) ///< A successful return value.
#define ECODE_EMDRV_UARTDRV_WAITING (ECODE_EMDRV_UARTDRV_BASE | 0x00000001) ///< An operation is waiting in queue.
#define ECODE_EMDRV_UARTDRV_ILLEGAL_HANDLE (ECODE_EMDRV_UARTDRV_BASE | 0x00000002) ///< An illegal UART handle.
#define ECODE_EMDRV_UARTDRV_PARAM_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x00000003) ///< An illegal input parameter.
#define ECODE_EMDRV_UARTDRV_BUSY (ECODE_EMDRV_UARTDRV_BASE | 0x00000004) ///< The UART port is busy.
#define ECODE_EMDRV_UARTDRV_ILLEGAL_OPERATION (ECODE_EMDRV_UARTDRV_BASE | 0x00000005) ///< An illegal operation on the UART port.
#define ECODE_EMDRV_UARTDRV_IDLE (ECODE_EMDRV_UARTDRV_BASE | 0x00000008) ///< No UART transfer is in progress.
#define ECODE_EMDRV_UARTDRV_ABORTED (ECODE_EMDRV_UARTDRV_BASE | 0x00000009) ///< A UART transfer has been aborted.
#define ECODE_EMDRV_UARTDRV_QUEUE_FULL (ECODE_EMDRV_UARTDRV_BASE | 0x0000000A) ///< A UART operation queue is full.
#define ECODE_EMDRV_UARTDRV_QUEUE_EMPTY (ECODE_EMDRV_UARTDRV_BASE | 0x0000000B) ///< A UART operation queue is empty.
#define ECODE_EMDRV_UARTDRV_PARITY_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x0000000C) ///< A UART parity error frame. Data is ignored.
#define ECODE_EMDRV_UARTDRV_FRAME_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x0000000D) ///< A UART frame error. Data is ignored.
#define ECODE_EMDRV_UARTDRV_DMA_ALLOC_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x0000000E) ///< Unable to allocate DMA channels.
#define ECODE_EMDRV_UARTDRV_CLOCK_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x0000000F) ///< Unable to set a desired baudrate.
/** @} (end addtogroup error codes) */
/***************************************************************************//**
* @addtogroup uartdrv_status_codes Status Codes
* @{
******************************************************************************/
#define UARTDRV_STATUS_RXEN (1 << 0) ///< The receiver is enabled.
#define UARTDRV_STATUS_TXEN (1 << 1) ///< The transmitter is enabled.
#define UARTDRV_STATUS_RXBLOCK (1 << 3) ///< The receiver is blocked; incoming frames will be discarded.
#define UARTDRV_STATUS_TXTRI (1 << 4) ///< The transmitter is tristated.
#define UARTDRV_STATUS_TXC (1 << 5) ///< A transmit operation is complete. No more data is available in the transmit buffer and shift register.
#define UARTDRV_STATUS_TXBL (1 << 6) ///< The transmit buffer is empty.
#define UARTDRV_STATUS_RXDATAV (1 << 7) ///< Data is available in the receive buffer.
#define UARTDRV_STATUS_RXFULL (1 << 8) ///< The receive buffer is full.
#if defined(EUSART_STATUS_TXCANDTXIDLE)
#define UARTDRV_STATUS_TXCANDTXIDLE (1 << 9) ///< Set when both TXC and TXIDLE are set.
#endif
#define UARTDRV_STATUS_TXIDLE (1 << 13) ///< The transmitter is idle.
#if (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
#define UARTDRV_STATUS_RXIDLE (1 << 12) ///< The Receiver is idle.
#endif
/** @} (end addtogroup status codes) */
typedef uint32_t UARTDRV_Count_t; ///< A UART transfer count
typedef uint32_t UARTDRV_Status_t; ///< A UART status return type. Bitfield of UARTDRV_STATUS_* values.
/**
* @enum UARTDRV_FlowControlType_t
* @brief UARTDRV Flow Control method.
*/
SL_ENUM(UARTDRV_FlowControlType_t) {
uartdrvFlowControlNone = 0, ///< None
uartdrvFlowControlSw = 1, ///< Software XON/XOFF
uartdrvFlowControlHw = 2, ///< nRTS/nCTS hardware handshake
uartdrvFlowControlHwUart = 3 ///< UART peripheral controls nRTS/nCTS
};
/// Flow Control state
SL_ENUM(UARTDRV_FlowControlState_t) {
uartdrvFlowControlOn = 0, ///< XON or nRTS/nCTS low
uartdrvFlowControlOff = 1, ///< XOFF or nRTS/nCTS high
uartdrvFlowControlAuto = 2 ///< This driver controls the state.
};
/// Transfer abort type
SL_ENUM(UARTDRV_AbortType_t) {
uartdrvAbortTransmit = 1, ///< Abort current and queued transmit operations
uartdrvAbortReceive = 2, ///< Abort current and queued receive operations
uartdrvAbortAll = 3 ///< Abort all current and queued operations
};
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/// Type of a UART peripheral
SL_ENUM(UARTDRV_UartType_t) {
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
uartdrvUartTypeUart = 0, ///< USART/UART peripheral
#endif
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0)
uartdrvUartTypeLeuart = 1 ///< LEUART peripheral
#elif (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
uartdrvUartTypeEuart = 2 ///< EUART peripheral
#endif
};
/// @endcond
struct UARTDRV_HandleData;
/***************************************************************************//**
* @brief
* UARTDRV transfer completion callback function.
*
* @details
* Called when a transfer is complete. An
* application should check the transferStatus and itemsTransferred values.
*
* @param[in] handle
* The UARTDRV device handle used to start the transfer.
*
* @param[in] transferStatus
* Completion status of the transfer operation.
*
* @param[in] data
* A pointer to the transfer data buffer.
*
* @param[in] transferCount
* A number of bytes transferred.
******************************************************************************/
typedef void (*UARTDRV_Callback_t)(struct UARTDRV_HandleData *handle,
Ecode_t transferStatus,
uint8_t *data,
UARTDRV_Count_t transferCount);
/// UART transfer buffer
typedef struct {
uint8_t *data; ///< Transfer data buffer
UARTDRV_Count_t transferCount; ///< Transfer item count
volatile UARTDRV_Count_t itemsRemaining; ///< Transfer items remaining
UARTDRV_Callback_t callback; ///< Completion callback
Ecode_t transferStatus; ///< Completion status of the transfer operation
} UARTDRV_Buffer_t;
/// Transfer operation FIFO queue typedef
typedef struct {
volatile uint16_t head; ///< An index of the next byte to send.
volatile uint16_t tail; ///< An index of the location to enqueue the next message.
volatile uint16_t used; ///< A number of bytes queued.
const uint16_t size; ///< FIFO size.
UARTDRV_Buffer_t fifo[1]; ///< FIFO of queued data. Actual size varies.
} UARTDRV_Buffer_FifoQueue_t;
/// Macros to define FIFO and buffer queues. typedef can't be used because the size
/// of the FIFO array in the queues can change.
#define DEFINE_BUF_QUEUE(qSize, qName) \
typedef struct { \
uint16_t head; \
uint16_t tail; \
volatile uint16_t used; \
const uint16_t size; \
UARTDRV_Buffer_t fifo[qSize]; \
} _##qName; \
static volatile _##qName qName = \
{ \
.head = 0, \
.tail = 0, \
.used = 0, \
.size = qSize, \
}
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
/**
* @struct UARTDRV_InitUart_t
* @brief A UART driver instance initialization structure.
* LEUART driver instance initialization structure.
* Contains a number of UARTDRV configuration options.
* It is required for driver instance initialization.
* This structure is passed to @ref UARTDRV_Init() when initializing a UARTDRV
* instance.
*/
typedef struct {
USART_TypeDef *port; ///< The peripheral used for UART
uint32_t baudRate; ///< UART baud rate
#if defined(_USART_ROUTELOC0_MASK)
uint8_t portLocationTx; ///< A location number for UART Tx pin.
uint8_t portLocationRx; ///< A location number for UART Rx pin.
#elif defined(_USART_ROUTE_MASK)
uint8_t portLocation; ///< A location number for UART pins.
#elif defined(_GPIO_USART_ROUTEEN_MASK)
sl_gpio_port_t txPort; ///< Port for UART Tx pin.
sl_gpio_port_t rxPort; ///< Port for UART Rx pin.
uint8_t txPin; ///< Pin number for UART Tx.
uint8_t rxPin; ///< Pin number for UART Rx.
uint8_t uartNum; ///< UART instance number.
#endif
USART_Stopbits_TypeDef stopBits; ///< A number of stop bits.
USART_Parity_TypeDef parity; ///< Parity configuration.
USART_OVS_TypeDef oversampling; ///< Oversampling mode.
#if defined(USART_CTRL_MVDIS)
bool mvdis; ///< Majority Vote Disable for 16x, 8x and 6x oversampling modes.
#endif
UARTDRV_FlowControlType_t fcType; ///< Flow control mode.
sl_gpio_port_t ctsPort; ///< A CTS pin port number.
uint8_t ctsPin; ///< A CTS pin number.
sl_gpio_port_t rtsPort; ///< An RTS pin port number.
uint8_t rtsPin; ///< An RTS pin number.
UARTDRV_Buffer_FifoQueue_t *rxQueue; ///< A receive operation queue.
UARTDRV_Buffer_FifoQueue_t *txQueue; ///< T transmit operation queue.
#if defined(_USART_ROUTELOC1_MASK)
uint8_t portLocationCts; ///< A location number for the UART CTS pin.
uint8_t portLocationRts; ///< A location number for the UART RTS pin.
#endif
} UARTDRV_InitUart_t;
#endif
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0) && !defined(_SILICON_LABS_32B_SERIES_2)
/**
* @struct UARTDRV_InitLeuart_t
* @brief LEUART driver instance initialization structure.
* LEUART driver instance initialization structure.
* Contains a number of UARTDRV configuration options.
* It is required to initialize a driver instance.
* This structure is passed to @ref UARTDRV_InitLeuart() when initializing a UARTDRV
* instance.
*/
typedef struct {
LEUART_TypeDef *port; ///< The peripheral used for LEUART
uint32_t baudRate; ///< UART baud rate
#if defined(_LEUART_ROUTELOC0_MASK)
uint8_t portLocationTx; ///< Location number for LEUART Tx pin.
uint8_t portLocationRx; ///< Location number for LEUART Rx pin.
#else
uint8_t portLocation; ///< Location number for LEUART pins
#endif
LEUART_Stopbits_TypeDef stopBits; ///< Number of stop bits
LEUART_Parity_TypeDef parity; ///< Parity configuration
UARTDRV_FlowControlType_t fcType; ///< Flow control mode
sl_gpio_port_t ctsPort; ///< CTS pin port number
uint8_t ctsPin; ///< CTS pin number
sl_gpio_port_t rtsPort; ///< RTS pin port number
uint8_t rtsPin; ///< RTS pin number
UARTDRV_Buffer_FifoQueue_t *rxQueue; ///< Receive operation queue
UARTDRV_Buffer_FifoQueue_t *txQueue; ///< Transmit operation queue
} UARTDRV_InitLeuart_t;
#endif
#if (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
/// UART driver instance initialization structure.
/// Contains a number of UARTDRV configuration options.
/// It is required to initialize a driver instance.
/// This structure is passed to @ref UARTDRV_InitEuart() when initializing a UARTDRV
typedef struct {
EUSART_TypeDef *port; ///< The peripheral used for EUART
bool useLowFrequencyMode; ///< Clock configuration of the EUART
uint32_t baudRate; ///< EUART baud rate
sl_gpio_port_t txPort; ///< Port for UART Tx pin.
sl_gpio_port_t rxPort; ///< Port for UART Rx pin.
uint8_t txPin; ///< Pin number for UART Tx.
uint8_t rxPin; ///< Pin number for UART Rx.
uint8_t uartNum; ///< EUART instance number.
#if defined(UARTDRV_USE_PERIPHERAL)
sl_hal_eusart_stop_bits_t stopBits; ///< Number of stop bits
sl_hal_eusart_parity_t parity; ///< Parity configuration
sl_hal_eusart_ovs_t oversampling; ///< Oversampling mode.
sl_hal_eusart_majority_vote_t mvdis; ///< Majority Vote Disable for 16x, 8x and 6x oversampling modes.
#else
EUSART_Stopbits_TypeDef stopBits; ///< Number of stop bits
EUSART_Parity_TypeDef parity; ///< Parity configuration
EUSART_OVS_TypeDef oversampling; ///< Oversampling mode.
EUSART_MajorityVote_TypeDef mvdis; ///< Majority Vote Disable for 16x, 8x and 6x oversampling modes.
#endif
UARTDRV_FlowControlType_t fcType; ///< Flow control mode
sl_gpio_port_t ctsPort; ///< CTS pin port number
uint8_t ctsPin; ///< CTS pin number
sl_gpio_port_t rtsPort; ///< RTS pin port number
uint8_t rtsPin; ///< RTS pin number
UARTDRV_Buffer_FifoQueue_t *rxQueue; ///< Receive operation queue
UARTDRV_Buffer_FifoQueue_t *txQueue; ///< Transmit operation queue
} UARTDRV_InitEuart_t;
#endif
/// A UART driver instance handle data structure.
/// Allocated by the application using UARTDRV.
/// Several concurrent driver instances may exist in an application. The application must
/// not modify the contents of this handle and should not depend on its values.
typedef struct UARTDRV_HandleData{
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
union {
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
USART_TypeDef * uart;
#endif
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0) && !defined(_SILICON_LABS_32B_SERIES_2)
LEUART_TypeDef * leuart;
#endif
#if (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
EUSART_TypeDef * euart;
#endif
void * __reserved_space;
} peripheral;
uint8_t uartNum; // UART instance number
unsigned int txDmaCh; // A DMA ch assigned to Tx
unsigned int rxDmaCh; // A DMA ch assigned to Rx
DMADRV_PeripheralSignal_t txDmaSignal; // A DMA Tx trigger source signal
DMADRV_PeripheralSignal_t rxDmaSignal; // A DMA Rx trigger source signal
UARTDRV_FlowControlState_t fcSelfState; // A current self flow control state
UARTDRV_FlowControlState_t fcSelfCfg; // A self flow control override configuration
UARTDRV_FlowControlState_t fcPeerState; // A current peer flow control state
sl_gpio_port_t txPort; // A Tx pin port number
sl_gpio_port_t rxPort; // An Rx pin port number
sl_gpio_port_t ctsPort; // A CTS pin port number
sl_gpio_port_t rtsPort; // An RTS pin port number
uint8_t txPin; // A Tx pin number
uint8_t rxPin; // An Tx pin number
uint8_t ctsPin; // A CTS pin number
uint8_t rtsPin; // An RTS pin number
sl_peripheral_t usartPeripheral; // Usart peripheral select
UARTDRV_Buffer_FifoQueue_t *rxQueue; // A receive operation queue
UARTDRV_Buffer_FifoQueue_t *txQueue; // A transmit operation queue
volatile bool rxDmaActive; // A receive DMA is currently active
volatile bool txDmaActive; // A transmit DMA is currently active
volatile uint8_t txDmaPaused; // A transmit DMA pause counter
bool IgnoreRestrain; // A transmit does not respect uartdrvFlowControlOff
bool hasTransmitted; // Indicates whether the handle has transmitted data
UARTDRV_FlowControlType_t fcType; // A flow control mode
UARTDRV_UartType_t type; // A type of UART
volatile int em1RequestCount; // A EM1 request count for the handle
sl_sleeptimer_timer_handle_t delayedTxTimer; // A timer to wait for the last byte out
size_t sleep; // Sleep state on isr return
/// @endcond
} UARTDRV_HandleData_t;
/// Handle pointer
typedef UARTDRV_HandleData_t * UARTDRV_Handle_t;
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
Ecode_t UARTDRV_InitUart(UARTDRV_Handle_t handle,
const UARTDRV_InitUart_t * initData);
#endif
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0) && !defined(_SILICON_LABS_32B_SERIES_2)
Ecode_t UARTDRV_InitLeuart(UARTDRV_Handle_t handle,
const UARTDRV_InitLeuart_t * initData);
#endif
#if (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
Ecode_t UARTDRV_InitEuart(UARTDRV_Handle_t handle,
const UARTDRV_InitEuart_t * initData);
#endif
Ecode_t UARTDRV_DeInit(UARTDRV_Handle_t handle);
UARTDRV_Status_t UARTDRV_GetPeripheralStatus(UARTDRV_Handle_t handle);
UARTDRV_Status_t UARTDRV_GetReceiveStatus(UARTDRV_Handle_t handle,
uint8_t **buffer,
UARTDRV_Count_t *bytesReceived,
UARTDRV_Count_t *bytesRemaining);
UARTDRV_Status_t UARTDRV_GetTransmitStatus(UARTDRV_Handle_t handle,
uint8_t **buffer,
UARTDRV_Count_t *bytesSent,
UARTDRV_Count_t *bytesRemaining);
uint8_t UARTDRV_GetReceiveDepth(UARTDRV_Handle_t handle);
uint8_t UARTDRV_GetTransmitDepth(UARTDRV_Handle_t handle);
Ecode_t UARTDRV_Transmit(UARTDRV_Handle_t handle,
uint8_t *data,
UARTDRV_Count_t count,
UARTDRV_Callback_t callback);
Ecode_t UARTDRV_Receive(UARTDRV_Handle_t handle,
uint8_t *data,
UARTDRV_Count_t count,
UARTDRV_Callback_t callback);
Ecode_t UARTDRV_TransmitB(UARTDRV_Handle_t handle,
uint8_t *data,
UARTDRV_Count_t count);
Ecode_t UARTDRV_ReceiveB(UARTDRV_Handle_t handle,
uint8_t *data,
UARTDRV_Count_t count);
Ecode_t UARTDRV_ForceTransmit(UARTDRV_Handle_t handle,
uint8_t *data,
UARTDRV_Count_t count);
UARTDRV_Count_t UARTDRV_ForceReceive(UARTDRV_Handle_t handle,
uint8_t *data,
UARTDRV_Count_t maxLength);
Ecode_t UARTDRV_Abort(UARTDRV_Handle_t handle, UARTDRV_AbortType_t type);
Ecode_t UARTDRV_PauseTransmit(UARTDRV_Handle_t handle);
Ecode_t UARTDRV_ResumeTransmit(UARTDRV_Handle_t handle);
UARTDRV_FlowControlState_t UARTDRV_FlowControlGetSelfStatus(UARTDRV_Handle_t handle);
UARTDRV_FlowControlState_t UARTDRV_FlowControlGetPeerStatus(UARTDRV_Handle_t handle);
Ecode_t UARTDRV_FlowControlSet(UARTDRV_Handle_t handle, UARTDRV_FlowControlState_t state);
Ecode_t UARTDRV_FlowControlSetPeerStatus(UARTDRV_Handle_t handle, UARTDRV_FlowControlState_t state);
Ecode_t UARTDRV_FlowControlIgnoreRestrain(UARTDRV_Handle_t handle);
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) && !defined(SL_CATALOG_KERNEL_PRESENT)
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_UARTDRV, SL_CODE_CLASS_TIME_CRITICAL)
sl_power_manager_on_isr_exit_t sl_uartdrv_sleep_on_isr_exit(void);
#endif
/** @} (end addtogroup uartdrv) */
#ifdef __cplusplus
}
#endif
#endif // UARTDRV_H