1947 lines
65 KiB
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;
|
|
}
|