PeripheralDriver_Flagchip_F.../Src/module_driver_fcsmu.c

918 lines
31 KiB
C

/**
* @file module_driver_fcsmu.c
* @author Flagchip0100
* @brief FCSMU module driver type definition and API
* @version 2.0.0
* @date 2024-08-20
*
* SDK Version: 2.6.0
*
* @copyright Copyright 2020-2024 Flagchip Semiconductors Co., Ltd.
*/
/*********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2022-11-18 Flagchip084 N/A First version for FC7xxx
* 0.2.0 2023-02-13 Flagchip084 N/A FC7xxx release version
* 2.0.0 2024-08-01 Flagchip0100 N/A SDK2.0 release version
*********************************************************************************/
#include "module_driver_fcsmu.h"
#include "HwA_csc.h"
#if (FCSMU_INSTANCE_COUNT > 0U)
/*******************************************************************************
* Definitions
******************************************************************************/
#ifndef FCSMU_DEV_ERROR_REPORT
#define FCSMU_DEV_ERROR_REPORT STD_OFF
#endif
#if FCSMU_DEV_ERROR_REPORT == STD_ON
#define FCSMU_ReportDevError(func, error) ReportDevError(FCSMU_MODULE_ID, func, error)
#endif
#define FCSMU_FST_UNLOCK_KEY 0x951413CFU
#define FCSMU_OPC1_UNLOCK_KEY 0xFC2020CFU
#define FCSMU_OPC2_UNLOCK_KEY 0x20FCCF20U
#define FCSMU_CONFIG_TMEP_UNLOCK_KEY 0xFCU
#define FCSMU_CONFIG_TMEP_LOCK_KEY 0xFFU
/*******************************************************************************
* Prototypes
******************************************************************************/
static FCSMU_StatusType FCSMU_TransStateNTC(FCSMU_Type *const pFcsmu);
static FCSMU_StatusType FCSMU_TransStateCTN(FCSMU_Type *const pFcsmu);
/*******************************************************************************
* Variables
******************************************************************************/
static FCSMU_Type *const s_apFcsmuBase[FCSMU_INSTANCE_COUNT] = FCSMU_BASE_PTRS;
/*******************************************************************************
* Code
******************************************************************************/
/**
* @brief Transitions the FCSMU module state to the configuration state.
*
* This function attempts to transition the FCSMU module state to the configuration state by setting the appropriate
* control registers and checking the operation status.
*
* @param pFcsmu Pointer to the FCSMU hardware abstraction layer (HAL) structure.
*
* @return FCSMU_StatusType Indicates the status of the state transition (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_TIMEOUT).
*
* @note The function retries the state transition up to 65535 times with a timeout mechanism to ensure the transition is successful.
*/
static FCSMU_StatusType FCSMU_TransStateNTC(FCSMU_Type *const pFcsmu)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_TIMEOUT;
uint32_t u32RetryTimes = 65535U;
uint32_t u32TimeoutTimes;
uint32_t u32Temp;
while (u32RetryTimes != 0U)
{
u32TimeoutTimes = 65535U;
u32Temp = FCSMU_HWA_GetCtrl(pFcsmu);
u32Temp |= (uint32_t)FCSMU_OP_CODE_MOVE_TO_CONFIG;
FCSMU_HWA_SetTempUnlk(pFcsmu, FCSMU_CONFIG_TMEP_UNLOCK_KEY);
FCSMU_HWA_SetOprk(pFcsmu, FCSMU_OPC1_UNLOCK_KEY);
FCSMU_HWA_SetCrtl(pFcsmu, u32Temp);
while (FCSMU_HWA_GetCtrlOps(pFcsmu) != (uint32_t)FCSMU_OP_STATE_SUCCESSFUL)
{
if (FCSMU_HWA_GetCtrlOps(pFcsmu) == (uint32_t)FCSMU_OP_STATE_BUSY)
{
u32TimeoutTimes--;
if (u32TimeoutTimes == 0U)
{
break;
}
}
else
{
break;
}
}
if (u32TimeoutTimes != 0U)
{
if (FCSMU_HWA_GetFcsmuState(pFcsmu) == (uint32_t)FCSMU_STATE_CONGIG)
{
break;
}
}
u32RetryTimes--;
}
if (u32RetryTimes != 0U)
{
eStatus = FCSMU_STATUS_SUCCESS;
}
return eStatus;
}
/**
* @brief Transitions the FCSMU module state to the normal state.
*
* This function attempts to transition the FCSMU module state to the normal state by setting the appropriate control registers
* and checking the operation status.
*
* @param pFcsmu Pointer to the FCSMU hardware abstraction layer (HAL) structure.
*
* @return FCSMU_StatusType Indicates the status of the state transition (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_TIMEOUT).
*
* @note The function retries the state transition up to 65535 times with a timeout mechanism to ensure the transition is successful.
* After a successful transition, it locks the temperature unlock key.
*/
static FCSMU_StatusType FCSMU_TransStateCTN(FCSMU_Type *const pFcsmu)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_TIMEOUT;
uint32_t u32RetryTimes = 65535U;
uint32_t u32TimeoutTimes;
uint32_t u32Temp;
while (u32RetryTimes != 0U)
{
u32TimeoutTimes = 65535U;
u32Temp = (uint32_t)FCSMU_HWA_GetCtrl(pFcsmu);
u32Temp |= (uint32_t)FCSMU_OP_CODE_MOVE_TO_NORMAL;
FCSMU_HWA_SetOprk(pFcsmu, FCSMU_OPC2_UNLOCK_KEY);
FCSMU_HWA_SetCrtl(pFcsmu, u32Temp);
while (FCSMU_HWA_GetCtrlOps(pFcsmu) != (uint32_t)FCSMU_OP_STATE_SUCCESSFUL)
{
u32TimeoutTimes--;
if (u32TimeoutTimes == 0U)
{
break;
}
}
if (u32TimeoutTimes != 0U)
{
if (FCSMU_HWA_GetFcsmuState(pFcsmu) == (uint32_t)FCSMU_STATE_NORMAL)
{
break;
}
}
u32RetryTimes--;
}
if (u32RetryTimes != 0U)
{
eStatus = FCSMU_STATUS_SUCCESS;
}
FCSMU_HWA_SetTempUnlk(pFcsmu, FCSMU_CONFIG_TMEP_LOCK_KEY);
return eStatus;
}
/**
* @brief Initializes the FCSMU module.
*
* This function initializes the specified FCSMU module instance by transitioning the state to the configuration state,
* configuring the module according to the provided initialization configuration, and then transitioning back to the normal state.
*
* @param pHandle Pointer to the FCSMU handle structure.
* @param pInitCfg Pointer to the FCSMU initialization configuration structure.
*
* @return FCSMU_StatusType Indicates the status of the initialization process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_FAIL).
*
* @note If the handle pointer, initialization configuration pointer, or instance index is invalid,
* a device error will be reported, and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_Init(FCSMU_HandleType *const pHandle, const FCSMU_InitCfgType *const pInitCfg)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_INIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pInitCfg == NULL)
{
FCSMU_ReportDevError(FCSMU_INIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_INIT_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
eStatus = FCSMU_TransStateNTC(pFcsmu);
if (eStatus == FCSMU_STATUS_SUCCESS)
{
if (pInitCfg->u32WarnTo > 204000U) //Max Warning time is 17ms
{
FCSMU_HWA_SetWarningTo(pFcsmu, 204000U);
}
else
{
FCSMU_HWA_SetWarningTo(pFcsmu, pInitCfg->u32WarnTo);
}
FCSMU_HWA_ClearCfgToIrq(pFcsmu);
FCSMU_HWA_SetWarningEn0(pFcsmu, pInitCfg->u32WarnChannel);
FCSMU_HWA_SetWarningIen0(pFcsmu, pInitCfg->u32WarnInterruptChannel);
FCSMU_HWA_SetFaultIen0(pFcsmu, pInitCfg->u32FaultInterruptChannel);
FCSMU_HWA_SetFrst0(pFcsmu, pInitCfg->u32FaultResetChannel);
FCSMU_HWA_SetFe0(pFcsmu, pInitCfg->u32FaultChannel);
FCSMU_HWA_SetFccr0(pFcsmu, pInitCfg->u32SoftwareClearedChannel);
eStatus = FCSMU_TransStateCTN(pFcsmu);
}
}
return eStatus;
}
/**
* @brief Deinitializes the FCSMU module.
*
* This function deinitializes the specified FCSMU module instance by transitioning the state to the configuration state,
* resetting the configuration settings, and then transitioning back to the normal state.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @return FCSMU_StatusType Indicates the status of the deinitialization process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_FAIL).
*
* @note If the handle pointer or instance index is invalid, a device error will be reported, and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_Deinit(FCSMU_HandleType *const pHandle)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_DEINIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_DEINIT_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
eStatus = FCSMU_TransStateNTC(pFcsmu);
if (eStatus == FCSMU_STATUS_SUCCESS)
{
FCSMU_HWA_SetFaultIen0(pFcsmu, 0U);
FCSMU_HWA_SetWarningIen0(pFcsmu, 0U);
FCSMU_HWA_SetFe0(pFcsmu, 0U);
FCSMU_HWA_SetWarningEn0(pFcsmu, 0U);
FCSMU_HWA_SetWarningTo(pFcsmu, 0x0003A980U);
FCSMU_HWA_ClearCfgToIrq(pFcsmu);
FCSMU_HWA_SetFrst0(pFcsmu, 0U);
FCSMU_HWA_SetFccr0(pFcsmu, 0xFFFFFFFFU);
eStatus = FCSMU_TransStateCTN(pFcsmu);
}
}
return eStatus;
}
/**
* @brief Initializes the status output configuration for the FCSMU module.
*
* This function initializes the status output configuration for the specified FCSMU module instance by transitioning the state
* to the configuration state, setting the status output control register, and then transitioning back to the normal state.
*
* @param pHandle Pointer to the FCSMU handle structure.
* @param pInitCfg Pointer to the FCSMU status output configuration structure.
*
* @return FCSMU_StatusType Indicates the status of the status output initialization process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_FAIL).
*
* @note If the handle pointer, initialization configuration pointer, or instance index is invalid, a device error will be reported,
* and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_StatusOutputInit(FCSMU_HandleType *const pHandle, const FCSMU_StatusOutputCfgType *const pInitCfg)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_STATUSOUTPUTINIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pInitCfg == NULL)
{
FCSMU_ReportDevError(FCSMU_STATUSOUTPUTINIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_STATUSOUTPUTINIT_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
uint32_t u32SoctrlValue, u32StmrValue;
if (pInitCfg->bFastMode == true)
{
if ((pInitCfg->u32Protocal != FCSMU_SOUT_PROTOCOL_DUAL_RAIL) &&
(pInitCfg->u32Protocal != FCSMU_SOUT_PROTOCOL_TIME_SWITCH))
{
eStatus = FCSMU_STATUS_FAIL;
}
}
if (eStatus == FCSMU_STATUS_SUCCESS)
{
u32SoctrlValue = FCSMU_SOCTRL_SOUT_PEN(pInitCfg->bEnable) |
FCSMU_SOCTRL_FASTEN(pInitCfg->bFastMode) |
FCSMU_SOCTRL_POLSW(pInitCfg->u8Polarity) |
FCSMU_SOCTRL_SOUT_PTC(pInitCfg->u32Protocal) |
FCSMU_SOCTRL_SOUT_CTRL(pInitCfg->u8SoutCtrl) |
FCSMU_SOCTRL_SOUT_DIV(pInitCfg->u32Divder) |
FCSMU_SOCTRL_SMRDT(pInitCfg->u32Delaytimer);
u32StmrValue = FCSMU_STMR_MINI_TIME(pInitCfg->u32SoutMinTmrInterval);
#ifdef FCSMU_SOCTRL_DIVEX_SUPPORT
u32SoctrlValue |= FCSMU_SOCTRL_DIVEX(pInitCfg->bDivex);
#endif
#ifdef FCSMU_STMR_FTTI_SUPPORT
u32StmrValue |= FCSMU_STMR_FTTI(pInitCfg->u8FttiTime);
#endif
#ifdef FCSMU_STMR_MTE_SUPPORT
u32StmrValue |= FCSMU_STMR_MTE(pInitCfg->bSoutMinTmr);
#endif
eStatus = FCSMU_TransStateNTC(pFcsmu);
if (eStatus == FCSMU_STATUS_SUCCESS)
{
FCSMU_HWA_SetSoctrl(pFcsmu, u32SoctrlValue);
FCSMU_HWA_SetStmr(pFcsmu, u32StmrValue);
FCSMU_HWA_SetSoutEn0(pFcsmu, pInitCfg->u32SoutChannel);
eStatus = FCSMU_TransStateCTN(pFcsmu);
}
}
}
return eStatus;
}
/**
* @brief Deinitializes the status output configuration for the FCSMU module.
*
* This function deinitializes the status output configuration for the specified FCSMU module instance by transitioning the state to the
* configuration state, clearing the status output control register, and then transitioning back to the normal state.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @return FCSMU_StatusType Indicates the status of the status output deinitialization process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_FAIL).
*
* @note If the handle pointer or instance index is invalid, a device error will be reported, and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_StatusOutputDeinit(FCSMU_HandleType *const pHandle)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_STATUSOUTPUTDEINIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_STATUSOUTPUTDEINIT_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
eStatus = FCSMU_TransStateNTC(pFcsmu);
if (eStatus == FCSMU_STATUS_SUCCESS)
{
FCSMU_HWA_SetSoctrl(pFcsmu, 0U);
FCSMU_HWA_SetSoutEn0(pFcsmu, 0U);
eStatus = FCSMU_TransStateCTN(pFcsmu);
}
}
return eStatus;
}
/**
* @brief Retrieves the fault channel for the specified FCSMU module.
*
* This function retrieves the fault channel for the specified FCSMU module instance.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @return uint32_t The fault channel number.
*
* @note If the handle pointer or instance index is invalid, a device error will be reported.
*/
uint32_t FCSMU_GetFaultChannel(FCSMU_HandleType *const pHandle)
{
uint32_t u32Channel = 0u;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_GETFAULTCHANNEL_ID, FCSMU_E_PARAM_NULLPTR);
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_GETFAULTCHANNEL_ID, FCSMU_E_PARAM_INSTANCE);
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
u32Channel = FCSMU_HWA_GetFst0(pFcsmu);
}
return u32Channel;
}
/**
* @brief Clears the fault flag for the specified fault channel in the FCSMU module.
*
* This function clears the fault flag for the specified fault channel in the specified FCSMU module instance by unlocking the fault clear
* mechanism, setting the fault channel to clear, and waiting for the operation to complete.
*
* @param pHandle Pointer to the FCSMU handle structure.
* @param u32FaultChannel The fault channel whose fault flag should be cleared.
*
* @return FCSMU_StatusType Indicates the status of the fault flag clearing process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_TIMEOUT).
*
* @note If the handle pointer or instance index is invalid, a device error will be reported, and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_ClearFaultFlag(FCSMU_HandleType *const pHandle, uint32_t u32FaultChannel)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_CLEARFAULT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_CLEARFAULT_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
uint32_t u32TimeoutTimes = 65535U;
FCSMU_HWA_SetFstUnlk(pFcsmu, FCSMU_FST_UNLOCK_KEY);
FCSMU_HWA_SetFst0(pFcsmu, u32FaultChannel);
while (FCSMU_HWA_GetCtrlOps(pFcsmu) != FCSMU_OP_STATE_SUCCESSFUL)
{
u32TimeoutTimes--;
if (u32TimeoutTimes == 0U)
{
eStatus = FCSMU_STATUS_TIMEOUT;
break;
}
}
/* Clear NTF/WTF/NTW/FTW register when no FST flag is set. */
if (eStatus == FCSMU_STATUS_SUCCESS)
{
if (FCSMU_HWA_GetFst0(pFcsmu) == 0U)
{
u32TimeoutTimes = (uint32_t)FCSMU_HWA_GetCtrl(pFcsmu);
u32TimeoutTimes |= (uint32_t)FCSMU_OP_CODE_CLEAR_FAULT_INFO;
FCSMU_HWA_SetCrtl(pFcsmu, u32TimeoutTimes);
u32TimeoutTimes = 65535U;
while (FCSMU_HWA_GetCtrlOps(pFcsmu) != FCSMU_OP_STATE_SUCCESSFUL)
{
u32TimeoutTimes--;
if (u32TimeoutTimes == 0U)
{
eStatus = FCSMU_STATUS_TIMEOUT;
break;
}
}
}
}
}
return eStatus;
}
/**
* @brief Injects a fault into the specified channel in the FCSMU module.
*
* This function injects a fault into the specified channel in the specified FCSMU module instance by setting the injection register.
*
* @param pHandle Pointer to the FCSMU handle structure.
* @param u32ChannelIndex The channel index where the fault should be injected.
*
* @return FCSMU_StatusType Indicates the status of the fault injection process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_FAIL).
*
* @note If the handle pointer or instance index is invalid, a device error will be reported, and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_InjectionFault(FCSMU_HandleType *const pHandle, uint32_t u32ChannelIndex)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_INJECTIONFAULT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_INJECTIONFAULT_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
FCSMU_HWA_SetInject(pFcsmu, u32ChannelIndex);
}
return eStatus;
}
/**
* @brief Initializes the CRC checker for the FCSMU module.
*
* This function initializes the CRC checker for the specified FCSMU module instance by generating a CRC, configuring the trigger mode
* and error request mode, and enabling the CRC checker and error output.
*
* @param pHandle Pointer to the FCSMU handle structure.
* @param pInitCfg Pointer to the FCSMU CRC configuration structure.
*
* @return FCSMU_StatusType Indicates the status of the CRC initialization process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_TIMEOUT).
*
* @note If the handle pointer, initialization configuration pointer, or instance index is invalid, a device error will be reported,
* and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_CrcInit(FCSMU_HandleType *const pHandle, const FCSMU_CrcCfgType *const pInitCfg)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_CRCINIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pInitCfg == NULL)
{
FCSMU_ReportDevError(FCSMU_CRCINIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_CRCINIT_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
uint32_t u32TimeoutTimes = 65535U;
FCSMU_HWA_GenerateCrc(pFcsmu);
while (FCSMU_HWA_GetCrcBusy(pFcsmu) == FCSMU_CRC_STATE_BUSY)
{
u32TimeoutTimes--;
if (u32TimeoutTimes == 0U)
{
eStatus = FCSMU_STATUS_TIMEOUT;
break;
}
}
if (eStatus == FCSMU_STATUS_SUCCESS)
{
#ifdef FCSMU_CRC_CTRL_DONE_SUPPORT
FCSMU_HWA_ClearCrcDoneFlag(pFcsmu);
#endif
if (pInitCfg->u16Mode == FCSMU_CRC_SW_MODE)
{
FCSMU_HWA_EnableTrigger(pFcsmu, false);
}
else{
FCSMU_HWA_EnableTrigger(pFcsmu, true);
}
#ifdef CSC0_SMU_CTRL4_SMU_RIE_MASK /* FC7240 is not same to others */
if (pInitCfg->u16ErrorReqMode == FCSMU_CRC_ERROR_REQ_MODE_IRQ)
{
u32TimeoutTimes = CSC0_HWA_Get_SMU_CTRL4() | CSC0_SMU_CTRL4_SMU_RIE(0U);
u32TimeoutTimes &= ~CSC0_SMU_CTRL4_SMU_RIE_MASK;
CSC0_HWA_Set_SMU_CTRL4(u32TimeoutTimes);
}
else if (pInitCfg->u16ErrorReqMode == FCSMU_CRC_ERROR_REQ_MODE_RST)
{
u32TimeoutTimes = CSC0_HWA_Get_SMU_CTRL4() | CSC0_SMU_CTRL4_SMU_RIE(2U);
u32TimeoutTimes &= ~CSC0_SMU_CTRL4_SMU_RIE_MASK;
CSC0_HWA_Set_SMU_CTRL4(u32TimeoutTimes);
}
else
{
u32TimeoutTimes = CSC0_HWA_Get_SMU_CTRL4();
u32TimeoutTimes &= ~(CSC0_SMU_CTRL4_SMU_RIE_MASK);
CSC0_HWA_Set_SMU_CTRL4(u32TimeoutTimes);
}
#else
if (pInitCfg->u16ErrorReqMode == FCSMU_CRC_ERROR_REQ_MODE_IRQ)
{
u32TimeoutTimes = CSC0_HWA_Get_SMU_CTRL4() | CSC0_SMU_CTRL4_SCF_IRQ_EN_MASK;
u32TimeoutTimes &= ~CSC0_SMU_CTRL4_SCF_RST_EN_MASK;
CSC0_HWA_Set_SMU_CTRL4(u32TimeoutTimes);
}
else if (pInitCfg->u16ErrorReqMode == FCSMU_CRC_ERROR_REQ_MODE_RST)
{
u32TimeoutTimes = CSC0_HWA_Get_SMU_CTRL4() | CSC0_SMU_CTRL4_SCF_RST_EN_MASK;
u32TimeoutTimes &= ~CSC0_SMU_CTRL4_SCF_IRQ_EN_MASK;
CSC0_HWA_Set_SMU_CTRL4(u32TimeoutTimes);
}
else
{
u32TimeoutTimes = CSC0_HWA_Get_SMU_CTRL4();
u32TimeoutTimes &= ~(CSC0_SMU_CTRL4_SCF_IRQ_EN_MASK | CSC0_SMU_CTRL4_SCF_RST_EN_MASK);
CSC0_HWA_Set_SMU_CTRL4(u32TimeoutTimes);
}
#endif
FCSMU_HWA_EnableErrorOutput(pFcsmu, true);
FCSMU_HWA_EnableCrcChecker(pFcsmu, true);
}
}
return eStatus;
}
/**
* @brief Deinitializes the CRC checker for the FCSMU module.
*
* This function deinitializes the CRC checker for the specified FCSMU module instance by clearing the CRC control register and the CRC error flag.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @return FCSMU_StatusType Indicates the status of the CRC deinitialization process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_FAIL).
*
* @note If the handle pointer or instance index is invalid, a device error will be reported, and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_CrcDeinit(FCSMU_HandleType *const pHandle)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_CRCDEINIT_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_CRCDEINIT_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
FCSMU_HWA_SetCrcCtrl(pFcsmu, 0U);
FCSMU_HWA_ClearCrcErrorFlag(pFcsmu);
#ifdef FCSMU_CRC_CTRL_DONE_SUPPORT
FCSMU_HWA_ClearCrcDoneFlag(pFcsmu);
#endif
}
return eStatus;
}
/**
* @brief Generates a CRC for the specified FCSMU module.
*
* This function generates a CRC for the specified FCSMU module instance by initiating the CRC generation process.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @return FCSMU_StatusType Indicates the status of the CRC generation process (FCSMU_STATUS_SUCCESS or FCSMU_STATUS_FAIL).
*
* @note If the handle pointer or instance index is invalid, a device error will be reported, and the function returns FCSMU_STATUS_FAIL.
*/
FCSMU_StatusType FCSMU_CrcGen(FCSMU_HandleType *const pHandle)
{
FCSMU_StatusType eStatus = FCSMU_STATUS_SUCCESS;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_CRCGEN_ID, FCSMU_E_PARAM_NULLPTR);
eStatus = FCSMU_STATUS_FAIL;
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_CRCGEN_ID, FCSMU_E_PARAM_INSTANCE);
eStatus = FCSMU_STATUS_FAIL;
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
FCSMU_HWA_GenerateCrc(pFcsmu);
}
return eStatus;
}
/**
* @brief Checks if the CRC generation process is busy for the specified FCSMU module.
*
* This function checks if the CRC generation process is currently busy for the specified FCSMU module instance.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @return bool Indicates whether the CRC generation process is busy (true) or not (false).
*
* @note If the handle pointer or instance index is invalid, a device error will be reported.
*/
bool FCSMU_CrcIsBusy(FCSMU_HandleType *const pHandle)
{
bool bIsBusy = false;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_CRCISBUSY_ID, FCSMU_E_PARAM_NULLPTR);
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_CRCISBUSY_ID, FCSMU_E_PARAM_INSTANCE);
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
bIsBusy = FCSMU_HWA_GetCrcBusy(pFcsmu);
}
return bIsBusy;
}
#ifdef FCSMU_CRC_CTRL_DONE_SUPPORT
/**
* @brief Clears the busy flag for the CRC generation process in the specified FCSMU module.
*
* This function clears the busy flag for the CRC generation process in the specified FCSMU module instance.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @note If the handle pointer or instance index is invalid, a device error will be reported.
*
* @note This function is specific to devices within the range FC7240F2MDS1P100T1A to FC7240F2MDS1P176T1A.
*/
void FCSMU_CrcClearBusy(FCSMU_HandleType *const pHandle)
{
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_CRCCLEARBUSY_ID, FCSMU_E_PARAM_NULLPTR);
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_CRCCLEARBUSY_ID, FCSMU_E_PARAM_INSTANCE);
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
FCSMU_HWA_ClearCrcDoneFlag(pFcsmu);
}
}
#endif
/**
* @brief Retrieves the result of the CRC calculation for the specified FCSMU module.
*
* This function retrieves the result of the CRC calculation for the specified FCSMU module instance.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @return uint32_t The result of the CRC calculation.
*
* @note If the handle pointer or instance index is invalid, a device error will be reported.
*/
uint32_t FCSMU_CrcGetResult(FCSMU_HandleType *const pHandle)
{
uint32_t u32Result = 0U;
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_CRCGETRESULT_ID, FCSMU_E_PARAM_NULLPTR);
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_CRCGETRESULT_ID, FCSMU_E_PARAM_INSTANCE);
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
u32Result = FCSMU_HWA_GetCrcResult(pFcsmu);
}
return u32Result;
}
/**
* @brief Handles common interrupts for the FCSMU module.
*
* This static function handles common interrupts for the specified FCSMU module instance. It processes fault, warning, and configuration
* timeout interrupts by retrieving relevant information and invoking appropriate callbacks.
*
* @param pHandle Pointer to the FCSMU handle structure.
*
* @note This function is intended for internal use only and should not be called directly.
*
* @note If the handle pointer or instance index is invalid, a device error will be reported.
*/
void FCSMU_CommonIRQHandler(FCSMU_HandleType *const pHandle)
{
#if FCSMU_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FCSMU_ReportDevError(FCSMU_COMMONIRQHANDLER_ID, FCSMU_E_PARAM_NULLPTR);
}
else if (pHandle->eInstance >= FCSMU_INSTANCE_COUNT)
{
FCSMU_ReportDevError(FCSMU_COMMONIRQHANDLER_ID, FCSMU_E_PARAM_INSTANCE);
}
else
#endif
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[pHandle->eInstance];
uint32_t u32IrqStat = FCSMU_HWA_GetIrqStat(pFcsmu);
uint32_t u32IrqChannelMask = FCSMU_HWA_GetFst0(pFcsmu);
if ((u32IrqStat & FCSMU_IRQ_STAT_FAULT_IRQ_MASK) == FCSMU_IRQ_STAT_FAULT_IRQ_MASK)
{
pHandle->tSettings.pFaultCallback(pHandle, u32IrqChannelMask);
}
else if ((u32IrqStat & FCSMU_IRQ_STAT_WARNING_IRQ_MASK) == FCSMU_IRQ_STAT_WARNING_IRQ_MASK)
{
pHandle->tSettings.pWarningCallback(pHandle, u32IrqChannelMask);
}
else if ((u32IrqStat & FCSMU_IRQ_STAT_CFG_TO_IRQ_MASK) == FCSMU_IRQ_STAT_CFG_TO_IRQ_MASK)
{
pHandle->tSettings.pTimeoutCallback(pHandle);
}
else
{
}
}
}
#endif /* (FCSMU_INSTANCE_COUNT > 0U) */