PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_fcuart.c

1769 lines
66 KiB
C

/**
* @file fc7xxx_driver_fcuart.c
* @author Flagchip
* @brief FC7xxx FCUart driver type definition and API
* @version 0.1.0
* @date 2024-01-14
*
* @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd.
*
*/
/********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2024-01-14 Flagchip0122 N/A FC7xxx internal release version
********************************************************************************/
#include "fc7xxx_driver_fcuart.h"
/********* Macro ************/
/********* Local typedef ************/
typedef enum {
UART_PRINT_RADIX_BIN = 2U,
UART_PRINT_RADIX_OCT = 8U,
UART_PRINT_RADIX_DEC = 10U,
UART_PRINT_RADIX_HEX = 16U
} UART_PrintIntType;
/**
* @brief FCUART Operation Sequence
*
*/
typedef enum {
FCUART_SEQUENCE_VAR_NOINIT, /**< FCUART_SEQUENCE_DEINIT means fcuart variables data is not initialed */
FCUART_SEQUENCE_DEINIT, /**< FCUART_SEQUENCE_DEINIT means fcuart driver is not initialed */
FCUART_SEQUENCE_NOTSTART_RECEIVE, /**< FCUART_SEQUENCE_NOTSTART_RECEIVE means fcuart driver initialed and write/erase is allowed */
FCUART_SEQUENCE_START_RECEIVE /**< FCUART_SEQUENCE_START_RECEIVE means fcuart driver started received */
} FCUART_SequenceType;
/********* Local Variables ************/
/* UART instance array */
static FCUART_Type *const s_aFCUART_InstanceTable[FCUART_INSTANCE_COUNT] = FCUART_BASE_PTRS;
/* sequence table */
static FCUART_SequenceType s_aCurrentSequence[FCUART_INSTANCE_COUNT] = {FCUART_SEQUENCE_VAR_NOINIT};
/* error notify callback function point */
static FCUART_ErrorInterrupt_CallBackType s_aFCUART_ErrorNotifyTable[FCUART_INSTANCE_COUNT];
/* receive notify callback function point */
static FCUART_TxRxInterrupt_CallBackType s_aFCUART_RxNotifyTable[FCUART_INSTANCE_COUNT];
/* Transfer empty notify callback function point */
static FCUART_TxRxInterrupt_CallBackType s_aFCUART_TxEmptyNotifyTable[FCUART_INSTANCE_COUNT];
/* Transfer complete notify callback function point */
static FCUART_TxRxInterrupt_CallBackType s_aFCUART_TxCompleteNotifyTable[FCUART_INSTANCE_COUNT];
/* Idle notify callback function point */
static FCUART_IdleInterrupt_CallBackType s_aFCUART_IdleNotifyTable[FCUART_INSTANCE_COUNT];
/* check every pUart instance whether is used */
static uint8_t s_aFCUART_UartUsed[FCUART_INSTANCE_COUNT];
/* check every pUart instance transmit timeout */
static uint32_t s_aFCUART_TransmitTimeout[FCUART_INSTANCE_COUNT];
/* pUart instance receive buffer */
static FCUART_DataType *s_aFCUART_RxMsg[FCUART_INSTANCE_COUNT];
/* pUart instance transfer buffer */
static FCUART_DataType *s_aFCUART_TxMsg[FCUART_INSTANCE_COUNT];
/********* Local Prototype Functions ************/
static FCUART_ErrorType FCUART_LL_CheckInstance(uint8_t u8UartIndex);
static uint32_t FCUART_LL_Error(uint8_t u8UartIndex);
static FCUART_ErrorType FCUART_LL_ProcessBaud(uint32_t u32Smb, uint32_t *u32OverSamp, uint32_t *u32Sbr);
static FCUART_ErrorType FCUART_LL_Transmit_Char(FCUART_Type *pUart, uint8_t u8Data, uint32_t u32TimeoutTick);
static FCUART_ErrorType FCUART_LL_Receive(uint8_t u8UartIndex, FCUART_DataType *pUartData);
static FCUART_ErrorType FCUART_LL_Transmit_Empty(uint8_t u8UartIndex, FCUART_DataType *pUartData);
static FCUART_ErrorType FCUART_LL_Transmit_Complete(uint8_t u8UartIndex);
static FCUART_ErrorType FCUART_LL_Idle(uint8_t u8UartIndex);
static uint8_t FCUART_Float2Char(double Value, char *pOutStr, uint32_t u32Eps);
static uint8_t FCUART_Int2Char(int i32Value, char *pOutStr, UART_PrintIntType eRadix, bool bHexUpper);
/********* Global Prototype Functions ************/
/********* Local Functions ************/
/**
* @brief Check UART instance
*
* @param u8UartIndex UART instance number
* @return
*/
static FCUART_ErrorType FCUART_LL_CheckInstance(uint8_t u8UartIndex) {
FCUART_ErrorType tRetVal;
if (u8UartIndex < FCUART_INSTANCE_COUNT) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
return tRetVal;
}
/**
* @brief Process get OverSamp and SBR
*
* @param u32Smb the value OverSame*SBR
* @param u32OverSamp out OverSampe
* @param u32Sbr out
* @return FCUART_ERROR_OK is ok, others are not ok
*/
static FCUART_ErrorType FCUART_LL_ProcessBaud(uint32_t u32Smb, uint32_t *u32OverSamp, uint32_t *u32Sbr) {
FCUART_ErrorType tRetVal;
uint32_t u32SbrTemp;
uint32_t u32OverSampTemp;
uint32_t u32TempSmbDiff;
uint32_t u32SmbDiff;
uint32_t u32CalcSmb;
uint32_t u32OverSamp1;
uint32_t u32Sbr1;
uint32_t u32OriginDiff;
u32OverSamp1 = 4U; /* 4..32 */
/* sbr = smb / oversamp */
u32Sbr1 = (uint16_t) (u32Smb / (u32OverSamp1));
u32CalcSmb = (u32OverSamp1) * (u32Sbr1);
if (u32CalcSmb > u32Smb) {
u32SmbDiff = u32CalcSmb - u32Smb;
} else {
u32SmbDiff = u32Smb - u32CalcSmb;
}
u32OriginDiff = u32SmbDiff;
if (u32SmbDiff != 0U) {
/* loop to find the best u32OverSamp1 value possible, one that generates minimum u32SmbDiff
* iterate through the rest of the supported values of u32OverSamp */
for (u32OverSampTemp = 5U; u32OverSampTemp <= 32U; u32OverSampTemp++) {
/* calculate the temporary u32Sbr value */
u32SbrTemp = (uint32_t) (u32Smb / u32OverSampTemp);
/* calculate the baud rate based on the temporary u32OverSamp and u32Sbr values */
u32CalcSmb = (uint32_t) (u32OverSampTemp * u32SbrTemp);
if (u32CalcSmb > u32Smb) {
u32TempSmbDiff = u32CalcSmb - u32Smb;
} else {
u32TempSmbDiff = u32Smb - u32CalcSmb;
}
if (u32TempSmbDiff < u32SmbDiff) {
u32SmbDiff = u32TempSmbDiff;
u32OverSamp1 = u32OverSampTemp; /* update and store the best u32OverSamp value calculated */
u32Sbr1 = u32SbrTemp; /* update store the best u32Sbr value calculated */
}
/* when differ is 0U, break */
if (u32SmbDiff == 0U) {
break;
}
}
}
/* check differ */
if (u32SmbDiff <= u32OriginDiff) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
/* out the calculated value */
*u32Sbr = u32Sbr1;
*u32OverSamp = u32OverSamp1;
} else {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_FAILED;
}
return tRetVal;
}
/**
* @brief Function to Transmit single Char
*
* @param pUart UART Instance point
* @param u8Data UART data
* @return FCUART_ERROR_OK is ok, others are not ok
*/
static FCUART_ErrorType FCUART_LL_Transmit_Char(FCUART_Type *pUart, uint8_t u8Data, uint32_t u32TimeoutTick) {
uint32_t u32Result;
uint32_t u32TryCount;
/* check transmit ready flag */
u32Result = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TDREF);
if (u32Result != 0U) {
FCUART_HWA_SetData(pUart, (uint32_t) u8Data); /* Send data */
FCUART_HWA_SetTxTransfer(pUart, true); /* start transmit */
u32Result = 0U;
u32TryCount = 0U;
while ((u32Result == 0U) && (u32TryCount < u32TimeoutTick)) {
/* check transmit flag */
u32Result = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TCF);
u32TryCount++;
}
/* after transmit completed, close TE */
FCUART_HWA_SetTxTransfer(pUart, false);
}
return (u32Result == 0U) ? (FCUART_ErrorType) FCUART_ERROR_FAILED : (FCUART_ErrorType) FCUART_ERROR_OK;
}
/**
* @brief Function to Transmit single Char by interrupt
*
* @param u8UartIndex UART Instance
* @param pUartData UART receive buffer
* @return FCUART_ERROR_OK is ok, others are not ok
*/
static FCUART_ErrorType FCUART_LL_Transmit_Empty(uint8_t u8UartIndex, FCUART_DataType *pUartData) {
FCUART_ErrorType tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
FCUART_Type *pUart;
uint32_t u32TempStats;
uint32_t u32Index;
uint8_t u8Index;
uint8_t u8TxWaterMark;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
if ((pUartData != NULL) && (pUartData->pDatas != NULL)) {
/* get and clear receive flag */
u32TempStats = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TDREF);
if (u32TempStats > 0U) {
/* TDRFF Flag has been got */
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
if (pUartData->u32DataLen > 0U) {
if (true == FCUART_HWA_GetEnStatusTxFifo(pUart)) {
/* Tx fifo enable */
u8TxWaterMark = FCUART_HWA_GetTxWaterMark(pUart);
if (((pUartData->u32DataLen) >= (uint32_t) (FCUART_FIFO_DEPTH - u8TxWaterMark))) {
for (u8Index = 0U; u8Index < (FCUART_FIFO_DEPTH - u8TxWaterMark); u8Index++) {
FCUART_HWA_SetData(pUart, (uint8_t) (pUartData->pDatas[0U])); /* Send data */
/* Update pointer position */
(pUartData->pDatas)++;
(pUartData->u32DataLen)--;
}
} else {
for (u32Index = 0U; u32Index < (pUartData->u32DataLen); u32Index++) {
FCUART_HWA_SetData(pUart, (uint8_t) (pUartData->pDatas[0U])); /* Send data */
/* Update pointer position */
(pUartData->pDatas)++;
(pUartData->u32DataLen)--;
}
}
} else {
/* Tx fifo disable */
FCUART_HWA_SetData(pUart, (uint8_t) (pUartData->pDatas[0U])); /* Send data */
/* Update pointer position */
(pUartData->pDatas)++;
(pUartData->u32DataLen)--;
}
if (0U == pUartData->u32DataLen) {
/* There's no new data, disable transmit empty interrupt and enable transmit complete interrupt */
FCUART_HWA_DisableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TIE);
FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TCIE);
}
}
}
}
return tRetVal;
}
/**
* @brief Function to deal transmit complete
*
* @param u8UartIndex UART Instance
* @return FCUART_ERROR_OK is ok, others are not ok
*/
static FCUART_ErrorType FCUART_LL_Transmit_Complete(uint8_t u8UartIndex) {
FCUART_ErrorType tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
FCUART_Type *pUart;
uint32_t u32TempStats;
/* No need to check instance */
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* get and clear receive flag */
u32TempStats = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TCF);
if (u32TempStats > 0U) {
/* TCF Flag has been got */
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
FCUART_HWA_DisableInterrupt(pUart, (uint32_t) (FCUART_INT_CTRL_TE | FCUART_INT_CTRL_TCIE));
}
return tRetVal;
}
/**
* @brief Function to deal idle line
*
* @param u8UartIndex UART Instance
* @return FCUART_ERROR_OK is ok, others are not ok
*/
static FCUART_ErrorType FCUART_LL_Idle(uint8_t u8UartIndex) {
FCUART_ErrorType tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
FCUART_Type *pUart;
uint32_t u32TempStats;
/* get and clear receive flag */
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* No need to check instance */
u32TempStats = FCUART_HWA_GetStatus(pUart, FCUART_STAT_IDLEF);
if (u32TempStats > 0U) {
/* IDLF Flag has been got */
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
FCUART_HWA_ClearStatus(pUart, (uint32_t) FCUART_STAT_IDLEF);
}
return tRetVal;
}
/**
* @brief Receive UART data
*
* @param u8UartIndex UART Instance
* @param pUartData UART receive buffer
* @return FCUART_ERROR_OK is ok, others are not ok
*/
static FCUART_ErrorType FCUART_LL_Receive(uint8_t u8UartIndex, FCUART_DataType *pUartData) {
FCUART_ErrorType tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
FCUART_Type *pUart;
uint8_t u8ReadData;
uint32_t u32TempStats;
uint8_t u8RxCount;
uint8_t u8Index;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
if ((pUartData != NULL) && (pUartData->pDatas != NULL)) {
/* get and clear receive flag */
u32TempStats = FCUART_HWA_GetStatus(pUart, FCUART_STAT_RDRFF);
if (u32TempStats > 0U) {
/* RDRFF Flag has been got */
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
pUartData->u32DataLen = 0U;
if (true == FCUART_HWA_GetEnStatusRxFifo(pUart)) {
/* Rx fifo enable */
u8RxCount = FCUART_HWA_GetFifoRxCount(pUart);
for (u8Index = 0U; u8Index < u8RxCount; u8Index++) {
u8ReadData = FCUART_HWA_GetData(pUart);
pUartData->pDatas[u8Index] = u8ReadData;
pUartData->u32DataLen++;
}
} else {
/* Rx fifo disable */
u8ReadData = FCUART_HWA_GetData(pUart);
pUartData->pDatas[0U] = u8ReadData;
pUartData->u32DataLen++;
}
}
}
return tRetVal;
}
/**
* @brief Get Error Status
*
* @param u8UartIndex
* @return All Error Combine, 0U is no error
*/
static uint32_t FCUART_LL_Error(uint8_t u8UartIndex) {
uint32_t u32RetVal;
uint32_t u32ErrorValue;
FCUART_Type *pUart;
u32ErrorValue = 0U;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* receive overrun */
u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_RORF);
/* FCUART_HWA_ClearStatus(pUart, FCUART_STAT_RORF); */
if (u32RetVal != 0U) {
u32ErrorValue = (uint32_t) FCUART_ERROR_RORF;
}
/* noise flag */
u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_NF);
/*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_NF);*/
if (u32RetVal != 0U) {
u32ErrorValue |= (uint32_t) FCUART_ERROR_NF;
}
/* Frame Error flag */
u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_FEF);
/*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_FEF);*/
if (u32RetVal != 0U) {
u32ErrorValue |= (uint32_t) FCUART_ERROR_FEF;
}
/* Parity Error Flag */
u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_PEF);
/*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_PEF);*/
if (u32RetVal != 0U) {
u32ErrorValue |= (uint32_t) FCUART_ERROR_PEF;
}
/* Receive Data Parity Error Flag */
u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_RPEF);
/*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_RPEF);*/
if (u32RetVal != 0U) {
u32ErrorValue |= (uint32_t) FCUART_ERROR_RPEF;
}
/* Transmit Data Parity Error Flag */
u32RetVal = FCUART_HWA_GetStatus(pUart, FCUART_STAT_TPEF);
/*FCUART_HWA_ClearStatus(pUart, FCUART_STAT_TPEF);*/
if (u32RetVal != 0U) {
u32ErrorValue |= (uint32_t) FCUART_ERROR_TPEF;
}
/* clear error flags */
FCUART_HWA_ClearStatus(pUart, u32ErrorValue);
return u32ErrorValue;
}
/********************* Global Functions *********************/
/**
* @brief Initial UART variables Memory
*
*/
void FCUART_InitMemory(uint8_t u8UartIndex) {
s_aFCUART_ErrorNotifyTable[u8UartIndex] = NULL;
s_aFCUART_RxNotifyTable[u8UartIndex] = NULL;
s_aFCUART_TxEmptyNotifyTable[u8UartIndex] = NULL;
s_aFCUART_TxCompleteNotifyTable[u8UartIndex] = NULL;
s_aFCUART_IdleNotifyTable[u8UartIndex] = NULL;
s_aFCUART_UartUsed[u8UartIndex] = 0U;
/* set first state */
s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_DEINIT;
}
/**
* @brief This Function is used to initial UART instance
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pInitCfg contains clock, baud-rate, Bit Mode, parity and so on.
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_Init(uint8_t u8UartIndex, FCUART_InitType *pInitCfg) {
FCUART_ErrorType tRetVal;
uint32_t u32TempBaudReg;
uint32_t u32TempCtrlReg;
uint32_t u32TempFifoReg;
uint32_t u32TempWatermarkReg;
uint32_t u32TempStat;
uint32_t u32TempModir;
FCUART_Type *pUart;
uint32_t u32Sbr = 0U;
uint32_t u32OverSamp = 0U;
uint32_t u32Smb = 0U;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
(s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_DEINIT)) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (pInitCfg != NULL) {
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
/* set not start state */
s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_NOTSTART_RECEIVE;
if (0U != pInitCfg->u32Baudrate) {
u32Smb = pInitCfg->u32ClkSrcHz / pInitCfg->u32Baudrate;
} else {
u32Smb = 0;
tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* process for baud-rate */
if ((FCUART_ErrorType) FCUART_ERROR_OK == FCUART_LL_ProcessBaud(u32Smb, &u32OverSamp, &u32Sbr)) {
/* temporary BAUD register */
u32TempBaudReg = (uint32_t) 0U |
/* initial value */
FCUART_BAUD_MAEN0(0U) |
/* Match mode enable 0 */
FCUART_BAUD_MAEN1(0U) |
/* Match mode enable 1 */
FCUART_BAUD_10BIT_MODE(0U) |
/* 10bit mode select */
FCUART_BAUD_OVR_SAMP(u32OverSamp - 1U) |
/* Over sampling Ratio, n+1 */
FCUART_BAUD_TDMAEN(pInitCfg->bEnTxEmptyDma) |
/* Transmitter DMA Enable */
FCUART_BAUD_RDMAEN(pInitCfg->bEnRxFullDma) |
/* Receiver Full DMA Enable */
FCUART_BAUD_RIDMAEN(0U) |
/* Receiver Idle DMA Enable */
FCUART_BAUD_MATCH_CFG(0U) |
/* Match Configuration */
FCUART_BAUD_BEDGE_SAMP(1U) |
/* Both Edge Sampling */
FCUART_BAUD_RESYNC_DIS(0U) |
/* Re-synchronization Disable */
FCUART_BAUD_LBKDIE(0U) |
/* LIN Break Detect Interrupt Enable */
FCUART_BAUD_RIAEIE(0U) |
/* RX Input Active Edge Interrupt Enable */
FCUART_BAUD_SBNS(pInitCfg->eStopBit) |
/* Stop Bit Number Select */
FCUART_BAUD_SBR(
u32Sbr); /* Baud Rate Modulo Divisor. baud-rate = baud clock / ((OVR_SAMP+1) * SBR) */
/* temporary CTRL register */
u32TempCtrlReg = (uint32_t) 0U |/* initial value */
FCUART_CTRL_R8T9(0U) |
/* Receive Bit 8 / Transmit Bit 9 */
FCUART_CTRL_R9T8(0U) |
/* Receive Bit 9 / Transmit Bit 8 */
FCUART_CTRL_TXDIR(0U) |
/* TXD Pin Direction in Single-Wire Mode */
FCUART_CTRL_TXINV(0U) |
/* Transmit Data Inversion */
FCUART_CTRL_ORIE(0U) |
/* Overrun Interrupt Enable */
FCUART_CTRL_NEIE(0U) |
/* Noise Error Interrupt Enable */
FCUART_CTRL_FEIE(0U) |
/* Frame Error Interrupt Enable */
FCUART_CTRL_PEIE(0U) |
/* Parity Error Interrupt Enable */
FCUART_CTRL_TIE(0U) |
/* Transmit Interrupt Enable */
FCUART_CTRL_TCIE(0U) |
/* Transmission Complete Interrupt Enable */
FCUART_CTRL_RIE(0U) |
/* Receiver Interrupt Enable */
FCUART_CTRL_IIE(0U) |
/* Idle Line Interrupt Enable */
FCUART_CTRL_TE(0U) |
/* Transmitter Enable */
FCUART_CTRL_RE(0U) |
/* Receiver Enable */
FCUART_CTRL_RWC(0U) |
/* Receiver WakeUp Control */
FCUART_CTRL_SBK(0U) |
/* Send Break */
FCUART_CTRL_M0IE(0U) |
/* Match address 0 Interrupt Enable */
FCUART_CTRL_M1IE(0U) |
/* Match address 1 Interrupt Enable */
FCUART_CTRL_7BMS(0U) |
/* 7-Bit Mode Select */
FCUART_CTRL_IDLECFG(pInitCfg->eIdleCharNum) |
/* Idle Configuration 2^n bytes time no data entry IDLE */
FCUART_CTRL_LOOPMS(0U) |
/* Loop Mode Select */
FCUART_CTRL_WAITEN(0U) |
/* WAIT Enable */
FCUART_CTRL_RXSRC(0U) |
/* Receiver Source Select */
FCUART_CTRL_BMSEL(pInitCfg->eBitMode) |
/* 9-Bit or 8-Bit Mode Select */
FCUART_CTRL_RSWMS(0U) |
/* Receiver WakeUp Method Select */
FCUART_CTRL_ITS(pInitCfg->eIdleStart) |
/* Idle Line Type Select */
FCUART_CTRL_PE(pInitCfg->bParityEnable) |
/* Parity Enable */
FCUART_CTRL_PT(
pInitCfg->eParityType); /* Parity Type */
/* temporary FIFO register */
u32TempFifoReg =
(uint32_t) 0U | /* initial value */
FCUART_FIFO_TXEMPTY(0U) | /* Transmit Buffer/FIFO Empty */
FCUART_FIFO_RXEMPTY(0U) | /* Receive Buffer/FIFO Empty */
FCUART_FIFO_TXOF(0U) | /* Transmitter Buffer Overflow Flag */
FCUART_FIFO_RXUF(0U) | /* Receiver Buffer Underflow Flag */
FCUART_FIFO_TXFLUSH(1U) | /* Transmit FIFO/Buffer Flush */
FCUART_FIFO_RXFLUSH(1U) | /* Receive FIFO/Buffer Flush */
FCUART_FIFO_RXIDEN(pInitCfg->eFifoRxIdleCharNum) |
/* Receiver Idle Empty Enable */
FCUART_FIFO_TXOFIE(0U) | /* Transmit FIFO Overflow Interrupt Enable */
FCUART_FIFO_RXUFIE(0U) | /* Receive FIFO Underflow Interrupt Enable */
FCUART_FIFO_TXFEN(pInitCfg->bEnTxFifo) | /* Transmit FIFO Enable */
FCUART_FIFO_TXFIFODEP(1U) | /* Transmit FIFO Buffer Depth */
FCUART_FIFO_RXFEN(pInitCfg->bEnRxFifo) | /* Receive FIFO Enable, enable RX FIFO */
FCUART_FIFO_RXFIFODEP(1U); /* Receive FIFO Buffer Depth */
/* temporary WATERMARK register */
u32TempWatermarkReg = (uint32_t) 0U |/* initial value */
FCUART_WATERMARK_RXCOUNT(0U) |
/* Receive Counter */
FCUART_WATERMARK_RXWATER(pInitCfg->u8RxFifoWaterMark) |
/* Receive WaterMark, receive n-1 request interrupt or DMA */
FCUART_WATERMARK_TXCOUNT(0U) |
/* Transmit Counter */
FCUART_WATERMARK_TXWATER(
pInitCfg->u8TxFifoWaterMark); /* Transmit WaterMark */
/* temporary MODIR register */
u32TempModir = (uint32_t) 0U | /* initial value */
FCUART_MODIR_RXRTSCFG(0U) |
/* Receive RTS Configuration */
FCUART_MODIR_TXCTSSRC(0U) |
/* Transmit CTS Source */
FCUART_MODIR_TXCTSCFG(0U) |
/* Transmit CTS Configuration */
FCUART_MODIR_RXRTSEN(0U) | /* Receiver Request-to-Send Enable */
FCUART_MODIR_TXRTSPOL(0U) |
/* Transmitter Request-to-Send Polarity */
FCUART_MODIR_TXRTSEN(0U) | /* Transmitter Request-to-Send Enable */
FCUART_MODIR_TXCTSEN(
0U); /* Transmitter Clear-to-Send Enable */
/* write register with temporary data */
FCUART_HWA_SetBaud(pUart, u32TempBaudReg); /* 0x19000008; */
FCUART_HWA_SetFifo(pUart, u32TempFifoReg);
FCUART_HWA_SetWaterMark(pUart, u32TempWatermarkReg);
FCUART_HWA_SetModir(pUart, u32TempModir);
FCUART_HWA_SetCtrl(pUart, u32TempCtrlReg);
/* clear all status */
u32TempStat = FCUART_HWA_GetSTAT(pUart);
FCUART_HWA_WriteClearSTAT(pUart, u32TempStat);
FCUART_HWA_ClearFIFOErrorFlag(pUart);
/* instance used */
s_aFCUART_UartUsed[u8UartIndex] = 1U;
s_aFCUART_TransmitTimeout[u8UartIndex] =
pInitCfg->u32TransmitTimeout > 0U ? pInitCfg->u32TransmitTimeout : 3000U;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_FAILED;
}
}
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
return tRetVal;
}
/**
* @brief This Function is used to de-initial UART instance
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_DeInit(uint8_t u8UartIndex) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) && (s_aCurrentSequence[u8UartIndex] > FCUART_SEQUENCE_DEINIT)) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
/* set deinit state */
s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_DEINIT;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
FCUART_HWA_SetSoftWareReset(pUart);
}
return tRetVal;
}
FCUART_ErrorType FCUART_BufTransmitted(uint8_t u8UartIndex, FCUART_InterruptType *pInterruptCfg) {
FCUART_ErrorType tRetVal;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
(s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE)) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
s_aFCUART_TxMsg[u8UartIndex] = pInterruptCfg->pTxBuf;
s_aFCUART_TxEmptyNotifyTable[u8UartIndex] = pInterruptCfg->pTxEmptyNotify;
s_aFCUART_TxCompleteNotifyTable[u8UartIndex] = pInterruptCfg->pTxCompleteNotify;
return tRetVal;
}
/**
* @brief This Function is used to set UART interrupt
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pIntCfg contains callback functions
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_SetInterrupt(uint8_t u8UartIndex, FCUART_InterruptType *pInterruptCfg) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
(s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE)) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
if (pInterruptCfg != NULL) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* error interrupt */
if (true == pInterruptCfg->bEnErrorInterrupt) {
FCUART_HWA_EnableInterrupt(pUart, (uint32_t) (FCUART_INT_CTRL_ORIE | FCUART_INT_CTRL_NEIE |
FCUART_INT_CTRL_FEIE | FCUART_INT_CTRL_PEIE));
s_aFCUART_ErrorNotifyTable[u8UartIndex] = pInterruptCfg->pErrorNotify;
} else {
FCUART_HWA_DisableInterrupt(pUart, (uint32_t) (FCUART_INT_CTRL_ORIE | FCUART_INT_CTRL_NEIE |
FCUART_INT_CTRL_FEIE | FCUART_INT_CTRL_PEIE));
}
/* receive interrupt */
if (true == pInterruptCfg->bEnRxInterrupt) {
/* check buffer point if it is null */
if (pInterruptCfg->pRxBuf != NULL) {
FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_RIE);
s_aFCUART_RxMsg[u8UartIndex] = pInterruptCfg->pRxBuf;
s_aFCUART_RxNotifyTable[u8UartIndex] = pInterruptCfg->pRxNotify;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
} else {
FCUART_HWA_DisableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_RIE);
}
/* Transfer interrupt */
if (true == pInterruptCfg->bEnTxInterrupt) {
/* check buffer point if it is null */
if (pInterruptCfg->pTxBuf != NULL) {
FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TIE);
s_aFCUART_TxMsg[u8UartIndex] = pInterruptCfg->pTxBuf;
s_aFCUART_TxEmptyNotifyTable[u8UartIndex] = pInterruptCfg->pTxEmptyNotify;
s_aFCUART_TxCompleteNotifyTable[u8UartIndex] = pInterruptCfg->pTxCompleteNotify;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
} else {
FCUART_HWA_DisableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TIE);
}
/* Idle interrupt */
if (true == pInterruptCfg->bEnIdleInterrupt) {
FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_IIE);
s_aFCUART_IdleNotifyTable[u8UartIndex] = pInterruptCfg->pIdleNotify;
} else {
FCUART_HWA_DisableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_IIE);
}
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
} else {
/* No deal with */
}
return tRetVal;
}
/**
* @brief This Function is used to set UART WakeUp
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pWakeupCfg contains UART wake-up parameters
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_SetWakeup(uint8_t u8UartIndex, FCUART_WakeupType *pWakeupCfg) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
(s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE)) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (pWakeupCfg != NULL) {
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/*
* RWC MATCH0|MATCH1 MATCH_CFG [RSWMS,RWUID] Receiver Wakeup
0 0 X X Normal operation
1 0 00 00 Receiver wakeup on idle line, IDLE flag not set
1 0 00 01 Receiver wakeup on idle line, IDLE flag set
1 0 00 10 Receiver wakeup on address mark
1 1 11 10 Receiver wakeup on address match
0 1 00 X0 Address mark address match, IDLE flag not set for discarded characters
0 1 00 X1 Address mark address match, IDLE flag set for discarded characters
0 1 01 X0 Idle line address match
0 1 10 X0 Address match on and address match off, IDLE flag not set for discarded characters
0 1 10 X1 Address match on and address match off, IDLE flag set for discarded characters
*
*/
FCUART_HWA_AttachCtrl(pUart, FCUART_CTRL_RWC_MASK |
FCUART_CTRL_RSWMS_MASK); /* WakeUp enable and method select address-mark */
FCUART_HWA_AttachBaud(pUart, FCUART_BAUD_MATCH_CFG(3U) |
FCUART_BAUD_MAEN0(1U)); /* match0 data */
FCUART_HWA_AttachMatch(pUart, FCUART_MATCH_MATCH0(pWakeupCfg->u32WakeUpData)); /* set wake-up data*/
}
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
return tRetVal;
}
/**
* @brief This Function is used to start receiving
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_StartReceive(uint8_t u8UartIndex) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((FCUART_ErrorType) FCUART_ERROR_OK == tRetVal) {
if (s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
/* set started receive state */
s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_START_RECEIVE;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* start receive */
FCUART_HWA_SetRxTransfer(pUart, true);
} else {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
} else {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
return tRetVal;
}
/**
* @brief This Function is used to stop receiving
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_StopReceive(uint8_t u8UartIndex) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
((s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_START_RECEIVE) ||
(s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE))) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
/* set stop state */
s_aCurrentSequence[u8UartIndex] = FCUART_SEQUENCE_NOTSTART_RECEIVE;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* stop receive */
FCUART_HWA_SetRxTransfer(pUart, false);
}
return tRetVal;
}
/**
* @brief This Function is used to start transmit through interrupt
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_StartTransmit(uint8_t u8UartIndex) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((FCUART_ErrorType) FCUART_ERROR_OK == tRetVal) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* start transmit */
FCUART_HWA_SetTxTransfer(pUart, true);
if (false == FCUART_GetInterruptMode(u8UartIndex, (uint32_t) FCUART_INT_CTRL_TIE)) {
FCUART_HWA_EnableInterrupt(pUart, (uint32_t) FCUART_INT_CTRL_TIE);
}
} else {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
return tRetVal;
}
/**
* @brief This Function is used to stop transmitting
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_StopTransmit(uint8_t u8UartIndex) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* stop receive */
FCUART_HWA_SetTxTransfer(pUart, false);
} else {
/* No deal with */
}
return tRetVal;
}
/**
* @brief This Function is used to transmit UART data
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pUartData contains UART data and length
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_Transmit(uint8_t u8UartIndex, FCUART_DataType *pUartData) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
uint8_t *pData;
uint32_t u32DataLen;
uint8_t u8Index;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
((s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_START_RECEIVE) ||
(s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE))) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (pUartData != NULL) {
if (pUartData->pDatas != NULL) {
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pData = pUartData->pDatas;
u32DataLen = pUartData->u32DataLen;
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
for (u8Index = 0U; u8Index < u32DataLen; u8Index++) {
tRetVal |= FCUART_LL_Transmit_Char(pUart, pData[u8Index], s_aFCUART_TransmitTimeout[u8UartIndex]);
if (tRetVal != (FCUART_ErrorType) FCUART_ERROR_OK) {
break;
}
}
}
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
return tRetVal;
}
/**
* @brief Get Stat Flag
*
* @param u8UartIndex UART instance
* @param eStatusType stat type
* @return FCUART STAT status flag
*/
uint32_t FCUART_GetStatus(uint8_t u8UartIndex, FCUART_StatType eStatusType) {
FCUART_ErrorType tRetVal;
FCUART_Type *pUart;
uint32_t u32RetVal;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
u32RetVal = FCUART_HWA_GetStatus(pUart, eStatusType);
} else {
u32RetVal = 0U;
}
return u32RetVal;
}
/**
* @brief This Function is used to receive data when polling (not used when rx interrupt enabled)
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pRxMsg is data buffer address, and pDatas need to be initialed with external buffer
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_Receive_Polling(uint8_t u8UartIndex, FCUART_DataType *pRxMsg) {
FCUART_ErrorType tRetVal;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
(s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_START_RECEIVE)) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (pRxMsg != NULL) {
if (pRxMsg->pDatas != NULL) {
if (s_aFCUART_UartUsed[u8UartIndex] == 1U) {
tRetVal = FCUART_LL_Receive(u8UartIndex, pRxMsg);
}
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
return tRetVal;
}
/**
* @brief This Function is used to get error when polling (not used when error interrupt enabled)
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pErrorValue is error value
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_Error_Polling(uint8_t u8UartIndex, uint32_t *pErrorValue) {
FCUART_ErrorType tRetVal;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
(s_aCurrentSequence[u8UartIndex] >= FCUART_SEQUENCE_NOTSTART_RECEIVE)) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
if (s_aFCUART_UartUsed[u8UartIndex] == 1U) {
/* check error */
*pErrorValue = FCUART_LL_Error(u8UartIndex);
} else {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_FAILED;
}
}
return tRetVal;
}
/**
* @brief This Function is used to enable fcuart loop mode
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param bStatus enable/disable status of loop mode
* @return FCUART_ERROR_OK is ok, others are not ok
*
*/
FCUART_ErrorType FCUART_SetLoopMode(uint8_t u8UartIndex, bool bStatus) {
FCUART_Type *pUart;
FCUART_ErrorType tRetVal;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
if (true == bStatus) {
FCUART_HWA_EnableLoopMode(pUart);
} else {
FCUART_HWA_DisableLoopMode(pUart);
}
} else {
/* No deal with */
}
return tRetVal;
}
/**
* @brief This Function is used to send 9 bits data
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param u16Data data to send
* @return FCUART_ERROR_OK is ok, others are not ok
*
*/
FCUART_ErrorType FCUART_SendData_9Bits(uint8_t u8UartIndex, uint16_t u16Data) {
FCUART_Type *pUart;
FCUART_ErrorType tRetVal;
uint8_t u8SingleBit_8;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
u8SingleBit_8 = (uint8_t) ((u16Data >> 8U) & 1U);
/* Set bit8 */
FCUART_HWA_SetR9T8(pUart, u8SingleBit_8);
/* Set 0 ~ 7 bits */
FCUART_HWA_SetData(pUart, (uint8_t) u16Data);
} else {
/* No deal with */
}
return tRetVal;
}
/**
* @brief This Function is used to Get 9 bits data
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pData pointer to data
* @return FCUART_ERROR_OK is ok, others are not ok
*
*/
FCUART_ErrorType FCUART_GetData_9Bits(uint8_t u8UartIndex, uint16_t *pData) {
FCUART_Type *pUart;
FCUART_ErrorType tRetVal;
uint8_t u8SingleBit_8;
uint8_t u8Temp;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* Get bit8 */
u8SingleBit_8 = FCUART_HWA_GetR8T9(pUart);
/* Get 0 ~ 7 bits */
u8Temp = FCUART_HWA_GetData(pUart);
/* Get 0 ~ 8 bits */
*pData = (((uint16_t) u8SingleBit_8 << 8U) | (uint16_t) u8Temp);
} else {
/* No deal with */
}
return tRetVal;
}
/**
* @brief This Function is used to send 10 bits data
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param u16Data data to send
* @return FCUART_ERROR_OK is ok, others are not ok
*
*/
FCUART_ErrorType FCUART_SendData_10Bits(uint8_t u8UartIndex, uint16_t u16Data) {
FCUART_Type *pUart;
FCUART_ErrorType tRetVal;
uint8_t u8SingleBit_8;
uint8_t u8SingleBit_9;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
u8SingleBit_8 = (uint8_t) ((u16Data >> 8U) & 1U);
u8SingleBit_9 = (uint8_t) ((u16Data >> 9U) & 1U);
/* Set bit8 */
FCUART_HWA_SetR9T8(pUart, u8SingleBit_8);
/* Set bit9 */
FCUART_HWA_SetR8T9(pUart, u8SingleBit_9);
/* Set 0 ~ 7 bits */
FCUART_HWA_SetData(pUart, (uint8_t) u16Data);
} else {
/* No deal with */
}
return tRetVal;
}
/**
* @brief This Function is used to Get 10 bits data
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pData pointer to data
* @return FCUART_ERROR_OK is ok, others are not ok
*
*/
FCUART_ErrorType FCUART_GetData_10Bits(uint8_t u8UartIndex, uint16_t *pData) {
FCUART_Type *pUart;
FCUART_ErrorType tRetVal;
uint8_t u8SingleBit_8;
uint8_t u8SingleBit_9;
uint8_t u8Temp;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
/* Get bit8 */
u8SingleBit_8 = FCUART_HWA_GetR8T9(pUart);
/* Get bit9 */
u8SingleBit_9 = FCUART_HWA_GetR9T8(pUart);
/* Get 0 ~ 7 bits */
u8Temp = FCUART_HWA_GetData(pUart);
/* Get 0 ~ 9 bits */
*pData = (((uint16_t) u8SingleBit_8 << 8U) | ((uint16_t) u8SingleBit_9 << 9U) | (uint16_t) u8Temp);
} else {
/* No deal with */
}
return tRetVal;
}
/**
* @brief This Function is used to set bit mode,parity and stop bit
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pData pointer to data
* @return FCUART_ERROR_OK is ok, others are not ok
*
*/
FCUART_ErrorType FCUART_SetBitModeAndParity(uint8_t u8UartIndex,
FCUART_BitModeType eBitMode,
FCUART_StopBitNumType eStopBit,
FCUART_ParityType eParityType,
bool bParityEnable
) {
FCUART_Type *pUart;
FCUART_ErrorType tRetVal;
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
FCUART_HWA_SetBitMode(pUart, eBitMode);
FCUART_HWA_SetStopBit(pUart, eStopBit);
FCUART_HWA_SetParity(pUart, eParityType, bParityEnable);
} else {
/* No deal with */
}
return tRetVal;
}
/**
* @brief This Function is used to Get current interrupt mode
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param u32Data Interrupt type to get
* @return true/false
*
*/
bool FCUART_GetInterruptMode(uint8_t u8UartIndex, uint32_t u32Data) {
FCUART_ErrorType tTempVal;
bool bRetVal;
FCUART_Type *pUart;
uint32_t u32CtrlRegData;
/* check parameter */
tTempVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
u32CtrlRegData = FCUART_HWA_GetCtrl(pUart);
bRetVal = ((u32CtrlRegData & u32Data) > 0U) ? true : false;
} else {
bRetVal = false;
}
return bRetVal;
}
/**
* @brief This Function is used to assign data to send through interrupt
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param pData data pointer
* @param u32Length data length to send
* @return FCUART_ERROR_OK is ok, others are not ok
*
*/
FCUART_ErrorType FCUART_AssignTxInterruptData(uint8_t u8UartIndex, uint8_t *pData, uint32_t u32Length) {
FCUART_ErrorType tTempVal;
/* check parameter */
tTempVal = FCUART_LL_CheckInstance(u8UartIndex);
if (tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
if (pData != NULL) {
s_aFCUART_TxMsg[u8UartIndex]->pDatas = pData;
s_aFCUART_TxMsg[u8UartIndex]->u32DataLen = u32Length;
} else {
tTempVal = (FCUART_ErrorType) FCUART_ERROR_INVALID_PARAM;
}
} else {
/* No deal with */
}
return tTempVal;
}
/* ################################################################################## */
/* ############################## Interrupt Services ################################ */
/**
* @brief This Function is used to deal with FCUART TxRx interrupt
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
*
*/
void FCUARTN_RxTx_IRQHandler(uint8_t u8UartIndex) {
FCUART_ErrorType tTempVal;
FCUART_DataType *pRxMsgList;
FCUART_DataType *pTxMsgList;
uint32_t u32ErrorValue;
uint32_t u32CtrlRegData;
//Do not check instance because it should be checked before
u32CtrlRegData = FCUART_HWA_GetCtrl((FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex]);
/* Handle receive interrupt */
if (((uint32_t) FCUART_INT_CTRL_RIE) == (u32CtrlRegData & ((uint32_t) FCUART_INT_CTRL_RIE))) {
/* get buffer point and it stored when called SetInterrupt */
pRxMsgList = s_aFCUART_RxMsg[u8UartIndex];
/* check pUart receive data */
tTempVal = FCUART_LL_Receive(u8UartIndex, pRxMsgList);
/* check buffer valid */
if ((tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) && (pRxMsgList != NULL)) {
if (s_aFCUART_RxNotifyTable[u8UartIndex] != NULL) {
s_aFCUART_RxNotifyTable[u8UartIndex](u8UartIndex, pRxMsgList);
}
}
}
/* Handle transmit interrupt */
if (((uint32_t) FCUART_INT_CTRL_TIE) == (u32CtrlRegData & ((uint32_t) FCUART_INT_CTRL_TIE))) {
/* get buffer point and it stored when called SetInterrupt */
pTxMsgList = s_aFCUART_TxMsg[u8UartIndex];
/* transfer data */
tTempVal = FCUART_LL_Transmit_Empty(u8UartIndex, pTxMsgList);
if ((tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) && (pTxMsgList != NULL)) {
if (s_aFCUART_TxEmptyNotifyTable[u8UartIndex] != NULL) {
s_aFCUART_TxEmptyNotifyTable[u8UartIndex](u8UartIndex, pTxMsgList);
}
}
}
/* Handle transmit complete interrupt */
if (((uint32_t) FCUART_INT_CTRL_TCIE) == (u32CtrlRegData & ((uint32_t) FCUART_INT_CTRL_TCIE))) {
tTempVal = FCUART_LL_Transmit_Complete(u8UartIndex);
if ((tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
(s_aFCUART_TxCompleteNotifyTable[u8UartIndex] != NULL)) {
s_aFCUART_TxCompleteNotifyTable[u8UartIndex](u8UartIndex, NULL);
}
}
/* Handle idle interrupt */
if (((uint32_t) FCUART_INT_CTRL_IIE) == (u32CtrlRegData & ((uint32_t) FCUART_INT_CTRL_IIE))) {
tTempVal = FCUART_LL_Idle(u8UartIndex);
if ((tTempVal == (FCUART_ErrorType) FCUART_ERROR_OK) && (s_aFCUART_IdleNotifyTable[u8UartIndex] != NULL)) {
s_aFCUART_IdleNotifyTable[u8UartIndex](u8UartIndex);
}
}
/* Handle error interrupt */
if (0U != (u32CtrlRegData & ((uint32_t) (FCUART_INT_CTRL_ORIE | FCUART_INT_CTRL_NEIE | FCUART_INT_CTRL_FEIE |
FCUART_INT_CTRL_PEIE)))) {
/* check error */
u32ErrorValue = FCUART_LL_Error(u8UartIndex);
if ((u32ErrorValue != 0U) && (s_aFCUART_ErrorNotifyTable[u8UartIndex] != NULL)) {
s_aFCUART_ErrorNotifyTable[u8UartIndex](u8UartIndex, u32ErrorValue);
}
PROCESS_UNUSED_VAR(u32ErrorValue)
}
}
/************************ Uart Print Library ************************/
/**
* @brief This Function is used to print ASCII char from UART
*
* @param u8UartIndex is UART instance, 0U..(FCUART_INSTANCE_COUNT-1U)
* @param fmt is char format
* @return FCUART_ERROR_OK is ok, others are not ok
*/
FCUART_ErrorType FCUART_Printf(uint8_t u8UartIndex, char *fmt, ...) {
FCUART_Type *pUart;
FCUART_ErrorType tRetVal;
const char *pStr;
int i32Temp;
unsigned char TxData;
uint8_t u8Number;
uint8_t u8LenthNumber = 4U;
char TempBuffer[16];
va_list ap;
va_start(ap, fmt);
/* check parameter */
tRetVal = FCUART_LL_CheckInstance(u8UartIndex);
if ((tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) &&
((s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_START_RECEIVE) ||
(s_aCurrentSequence[u8UartIndex] == FCUART_SEQUENCE_NOTSTART_RECEIVE))) {
tRetVal = (FCUART_ErrorType) FCUART_ERROR_OK;
} else {
tRetVal |= (FCUART_ErrorType) FCUART_ERROR_INVALID_SEQUENCE;
}
if (tRetVal == (FCUART_ErrorType) FCUART_ERROR_OK) {
pUart = (FCUART_Type *) s_aFCUART_InstanceTable[u8UartIndex];
while (*fmt != (char) 0) {
/* Escape character */
if ((*fmt) == ESCAPE_CHARACTER) {
switch (*(++fmt)) {
case 'r': {
TxData = ENTER;
tRetVal = FCUART_LL_Transmit_Char(pUart, TxData, s_aFCUART_TransmitTimeout[u8UartIndex]);
fmt++;
}
break;
case 'n': {
TxData = NEW_LINE;
tRetVal = FCUART_LL_Transmit_Char(pUart, TxData, s_aFCUART_TransmitTimeout[u8UartIndex]);
fmt++;
}
break;
default:
fmt++;
break;
}
} else if ((*fmt) == (char) '%') {
switch (*(++fmt)) {
case 's': {
pStr = va_arg(ap, const char *);
for (; *pStr; pStr++) {
tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr),
s_aFCUART_TransmitTimeout[u8UartIndex]);
}
fmt++;
}
break;
case 'd': {
i32Temp = va_arg(ap, int);
if (0U == FCUART_Int2Char(i32Temp, TempBuffer, UART_PRINT_RADIX_DEC, false)) {
for (pStr = TempBuffer; *pStr; pStr++) {
tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr),
s_aFCUART_TransmitTimeout[u8UartIndex]);
}
}
fmt++;
}
break;
case 'x': {
i32Temp = va_arg(ap, int);
if (0U == FCUART_Int2Char(i32Temp, TempBuffer, UART_PRINT_RADIX_HEX, false)) {
for (pStr = TempBuffer; *pStr; pStr++) {
tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr),
s_aFCUART_TransmitTimeout[u8UartIndex]);
}
}
fmt++;
}
break;
case 'X': {
i32Temp = va_arg(ap, int);
if (0U == FCUART_Int2Char(i32Temp, TempBuffer, UART_PRINT_RADIX_HEX, true)) {
for (pStr = TempBuffer; *pStr; pStr++) {
tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr),
s_aFCUART_TransmitTimeout[u8UartIndex]);
}
}
fmt++;
}
break;
case '.': {
u8Number = (uint8_t) (*(++fmt) - '0');
if ((*(++fmt)) == 'f') {
double num = va_arg(ap, double);
if (0U == FCUART_Float2Char(num, TempBuffer, u8Number)) {
for (pStr = TempBuffer; *pStr; pStr++) {
tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr),
s_aFCUART_TransmitTimeout[u8UartIndex]);
}
}
fmt++;
}
}
break;
case 'f': {
double num = va_arg(ap, double);
if (0U == FCUART_Float2Char(num, TempBuffer, u8LenthNumber)) {
for (pStr = TempBuffer; *pStr; pStr++) {
tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) pStr),
s_aFCUART_TransmitTimeout[u8UartIndex]);
}
}
fmt++;
}
break;
default:
fmt++;
break;
}
} else {
tRetVal = FCUART_LL_Transmit_Char(pUart, *((unsigned char *) fmt),
s_aFCUART_TransmitTimeout[u8UartIndex]);
if (tRetVal != FCUART_ERROR_OK) {
break;
}
fmt++;
}
}
}
va_end(ap);
return tRetVal;
}
/**
* @brief Convert integer to char
*
* @param i32Value
* @param pOutStr
* @param eRadix
* @return 0 is ok
*/
static uint8_t FCUART_Int2Char(int i32Value, char *pOutStr, UART_PrintIntType eRadix, bool bHexUpper) {
uint8_t u8Retval;
char aCharListUpper[] = "0123456789ABCDEF";
char aCharListLower[] = "0123456789abcdef";
char aNumList[] = "0123456789";
char *pCharList;
uint32_t u32Temp;
uint8_t u8Index = 0U;
uint8_t u8ValueStart = 0U;
char Temp = 0;
uint32_t j;
if (NULL == pOutStr) {
u8Retval = 1U;
} else {
u8Retval = 0U;
if ((UART_PRINT_RADIX_DEC == eRadix) && (i32Value < 0)) {
// Decimal and negative
u32Temp = (uint32_t) (0 - i32Value);
pOutStr[u8Index++] = '-';
u8ValueStart = 1U;
pCharList = aNumList;
} else {
if (true == bHexUpper) {
pCharList = aCharListUpper;
} else {
pCharList = aCharListLower;
}
u32Temp = (uint32_t) i32Value;
}
// Data is converted to a string and stored in reverse order
do {
pOutStr[u8Index++] = pCharList[u32Temp % (uint8_t) eRadix];
u32Temp /= (uint8_t) eRadix;
} while (u32Temp);
pOutStr[u8Index] = '\0';
// Convert the string with reverse order to positive
for (j = u8ValueStart; j < (u8Index + u8ValueStart) / 2U; j++) {
Temp = pOutStr[j];
pOutStr[j] = pOutStr[u8Index - j - 1U + u8ValueStart];
pOutStr[u8Index - j - 1U + u8ValueStart] = Temp;
}
}
return u8Retval;
}
/**
* @brief Convert float to char
*
* @param Value
* @param pOutStr
* @param U32Eps
* @return 0 is ok
*/
static uint8_t FCUART_Float2Char(double Value, char *pOutStr, uint32_t u32Eps) {
uint32_t u32Integer;
double Decimal;
char aCharList[] = "0123456789";
uint8_t u8ValueStart = 0U;
uint32_t u32TempCnt = 1U;
char Temp = 0;
double TempFactor = 0.1;
uint8_t u8Index = 0U;
uint32_t u32TempDecimal;
uint8_t u8Retval;
uint32_t j;
if (NULL == pOutStr) {
u8Retval = 1U;
} else {
u8Retval = 0U;
// Extract integer and decimal from the input number
if (Value < FLOAT_ZERO) {
Decimal = (double) ((int32_t) Value - Value);
u32Integer = (uint32_t) (0.0 - Value);
pOutStr[u8Index++] = '-';
u8ValueStart = 1U;
} else {
u32Integer = (uint32_t) Value;
Decimal = (double) (Value - u32Integer);
}
// The integer part of the data is converted into a string and stored in reverse order
do {
pOutStr[u8Index++] = aCharList[u32Integer % 10U];
u32Integer /= 10U;
} while (0U != u32Integer);
pOutStr[u8Index] = '\0';
// Convert the string with reverse order to positive
for (j = u8ValueStart; j < (u8Index + u8ValueStart) / 2U; j++) {
Temp = pOutStr[j];
pOutStr[j] = pOutStr[u8Index - j - 1U + u8ValueStart];
pOutStr[u8Index - j - 1U + u8ValueStart] = Temp;
}
// Accuracy problem, preventing input 1.2 and output 1.19
for (j = 0U; j <= u32Eps; j++) {
TempFactor *= 0.1;
}
Decimal += TempFactor;
for (j = 0; j < u32Eps; j++) {
Decimal *= (double) 10.0;
u32TempCnt *= 10U;
}
u32TempDecimal = (uint32_t) Decimal;
pOutStr[u8Index++] = '.';
for (j = 0; j < u32Eps; j++) {
u32TempCnt /= 10U;
if (0U != u32TempCnt) {
pOutStr[u8Index++] = u32TempDecimal / u32TempCnt + '0';
u32TempDecimal %= u32TempCnt;
}
}
pOutStr[u8Index] = '\0';
}
return u8Retval;
}