1769 lines
66 KiB
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;
|
|
}
|