PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_fcuart.c

1947 lines
65 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;
}
/**
* @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;
}