PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_fcsmu.c

409 lines
11 KiB
C

/**
* @file fc7xxx_driver_fcsmu.c
* @author Flagchip
* @brief FC7xxx FCSMU driver type definition and API
* @version 0.1.0
* @date 2024-01-14
*
* @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd.
*
*/
/* ********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240
******************************************************************************** */
#include "fc7xxx_driver_fcsmu.h"
#include "HwA_csc.h"
/* ################################################################################## */
/* ####################################### Macro #################################### */
#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
/* ################################################################################## */
/* ################################### Type define ################################## */
/* ################################################################################## */
/* ################################ Local Variables ################################# */
static FCSMU_Type *const s_apFcsmuBase[FCSMU_INSTANCE_COUNT] = FCSMU_BASE_PTRS;
static FCSMU_ISRCallbackType s_apFcsmuISRCallback = NULL;
/* ################################################################################## */
/* ########################### Local Prototype Functions ############################ */
/* ################################################################################## */
/* ######################### Global prototype Functions ############################ */
void FCSMU0_IRQHandler(void);
/* ################################################################################## */
/* ################################ Local Functions ################################ */
/* ################################################################################## */
/* ################################ Global Functions ################################ */
FCSMU_StatusType FCSMU_init(const FCSMU_InitCfgType *pInitConfig)
{
DEV_ASSERT(pInitConfig != NULL);
FCSMU_StatusType eRet;
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
eRet = FCSMU_TransStateNTC();
if (eRet != FCSMU_STATUS_SUCCESS)
{
return eRet;
}
if (pInitConfig->u32WarnTo > 432000U)
{
FCSMU_HWA_SetWaringTo(pFcsmu, 432000U);
}
else
{
FCSMU_HWA_SetWaringTo(pFcsmu, pInitConfig->u32WarnTo);
}
FCSMU_HWA_ClearCfgToIrq(pFcsmu);
FCSMU_HWA_SetWarningEn0(pFcsmu, pInitConfig->u32WarnChannel);
FCSMU_HWA_SetWarningIen(pFcsmu, pInitConfig->u32WarnInterruptChannel);
FCSMU_HWA_SetFaultIen(pFcsmu, pInitConfig->u32FaultInterruptChannel);
FCSMU_HWA_SetFRST0(pFcsmu, pInitConfig->u32FaultResetChannel);
FCSMU_HWA_SetFe0(pFcsmu, pInitConfig->u32FaultChannel);
FCSMU_HWA_SetFccr0(pFcsmu, pInitConfig->u32SoftwareClearedChannel);
eRet = FCSMU_TransStateCTN();
FCSMU_HWA_SetTempUnlk(pFcsmu, 0xFFU);
s_apFcsmuISRCallback = pInitConfig->pISRCallback;
return eRet;
}
FCSMU_StatusType FCSMU_ConfigStatusOutput(FCSMU_StatusOutputConfigType *pInitConfig)
{
DEV_ASSERT(pInitConfig != NULL);
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
uint32_t u32TempValue;
FCSMU_StatusType eRet;
if (pInitConfig->eFastMode == true)
{
if (pInitConfig->eProtocal != FCSMU_SOUT_PROTOCOL_DUAL_RAIL && pInitConfig->eProtocal != FCSMU_SOUT_PROTOCOL_TIME_SWITCH)
{
return FCSMU_STATUS_ERROR;
}
}
u32TempValue = FCSMU_SOCTRL_SOUT_PEN(pInitConfig->bEnable) |
FCSMU_SOCTRL_FASTEN(pInitConfig->eFastMode) |
FCSMU_SOCTRL_POLSW(pInitConfig->ePolarity) |
FCSMU_SOCTRL_SOUT_PTC(pInitConfig->eProtocal) |
FCSMU_SOCTRL_DIVEX(pInitConfig->bDivex) |
FCSMU_SOCTRL_SOUT_CTRL(pInitConfig->eSoutCtrl) |
FCSMU_SOCTRL_SOUT_DIV(pInitConfig->u32Divder) |
FCSMU_SOCTRL_SMRDT(pInitConfig->u32Delaytimer);
eRet = FCSMU_TransStateNTC();
if (eRet != FCSMU_STATUS_SUCCESS)
{
return eRet;
}
FCSMU_HWA_SetSoctrl(pFcsmu, u32TempValue);
FCSMU_HWA_SetSoutEn(pFcsmu, pInitConfig->u32SoutChannel);
eRet = FCSMU_TransStateCTN();
return eRet;
}
void FCSMU_CrcGen(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
FCSMU_HWA_GenerateCrc(pFcsmu);
}
bool FCSMU_IsCrcBusy(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
return FCSMU_HWA_GetCrcBusy(pFcsmu);
}
FCSMU_StatusType FCSMU_CrcConfig(FCSMU_CrcModeType eMode)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
uint32_t u32TimeoutTimes = 65535U;
FCSMU_StatusType eRet = FCSMU_STATUS_SUCCESS;
FCSMU_HWA_GenerateCrc(pFcsmu);
while (FCSMU_HWA_GetCrcBusy(pFcsmu) == FCSMU_Crc_STATE_BUSY)
{
u32TimeoutTimes--;
if (u32TimeoutTimes == 0U)
{
eRet = FCSMU_STATUS_ERROR;
break;
}
}
if (eRet == FCSMU_STATUS_SUCCESS)
{
if (eMode == FCSMU_CRC_TRIGGER_MODE)
{
FCSMU_HWA_EnableTrigger(pFcsmu, true);
}
else
{
}
CSC0_HWA_CTRL4_EnableReqToSMU(CSC_SMU_SCF_IRQ);
FCSMU_HWA_EnableErrorOutput(pFcsmu, true);
FCSMU_HWA_EnableCrcChecker(pFcsmu, true);
}
return eRet;
}
FCSMU_StatusType FCSMU_ClearFaultFlag(uint32_t u32FaultChannel)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
uint32_t u32TimeoutTimes = 65535U;
FCSMU_StatusType eRet = FCSMU_STATUS_SUCCESS;
FCSMU_HWA_SetFunlk(pFcsmu, FCSMU_FST_UNLOCK_KEY);
FCSMU_HWA_SetFst0(pFcsmu, u32FaultChannel);
while (FCSMU_HWA_GetCtrlOps(pFcsmu) != (uint32_t)FCSMU_OP_STATE_SUCCESSFUL)
{
u32TimeoutTimes--;
if (u32TimeoutTimes == 0U)
{
eRet = FCSMU_STATUS_ERROR;
break;
}
}
return eRet;
}
FCSMU_StatusType FCSMU_TransStateCTN(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
uint32_t u32TimeoutTimes;
uint32_t u32RetryTimes = 65535U;
uint32_t u32Temp;
FCSMU_StatusType eRet = FCSMU_STATUS_ERROR;
while (u32RetryTimes != 0U)
{
u32TimeoutTimes = 65535U;
u32Temp = (uint32_t)FCSMU_HWA_GetCtrl(pFcsmu);
u32Temp |= (uint32_t)FCSMU_OPC_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_GetState(pFcsmu) == (uint32_t)FCSMU_STATE_NORMAL)
{
break;
}
}
u32RetryTimes--;
}
if (u32RetryTimes != 0U)
{
eRet = FCSMU_STATUS_SUCCESS;
}
return eRet;
}
FCSMU_StatusType FCSMU_TransStateNTC(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
uint32_t u32TimeoutTimes;
uint32_t u32RetryTimes = 65535U;
FCSMU_StatusType eRet = FCSMU_STATUS_ERROR;
uint32_t u32Temp;
while (u32RetryTimes != 0U)
{
u32TimeoutTimes = 65535U;
u32Temp = FCSMU_HWA_GetCtrl(pFcsmu);
u32Temp |= (uint32_t)FCSMU_OPC_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_GetState(pFcsmu) == (uint32_t)FCSMU_STATE_CONGIG)
{
break;
}
}
u32RetryTimes--;
}
if (u32RetryTimes != 0U)
{
eRet = FCSMU_STATUS_SUCCESS;
}
return eRet;
}
void FCSMU_InjectionFault(uint32_t u32ChannelIndex)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
FCSMU_HWA_SetInject(pFcsmu, u32ChannelIndex);
}
uint32_t FCSMU_GetFaultChannel(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
return FCSMU_HWA_GetFst0(pFcsmu);
}
uint32_t FCSMU_GetIrqState(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
return FCSMU_HWA_GetIrqStat(pFcsmu);
}
uint32_t FCSMU_GetNtfFlag(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
return FCSMU_HWA_GetNtf(pFcsmu);
}
uint32_t FCSMU_GetWtfFlag(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
return FCSMU_HWA_GetWtf(pFcsmu);
}
uint32_t FCSMU_GetNtwFlag(void)
{
FCSMU_Type *const pFcsmu = s_apFcsmuBase[FCSMU_INSTANCE_0];
return FCSMU_HWA_GetNtw(pFcsmu);
}
static void FCSMUn_IRQHandler(void)
{
uint32_t u32TempValue = FCSMU_GetIrqState();
uint32_t u32IrqChannel;
if ((FCSMU_IRQ_STAT_FAULT_IRQ_MASK & u32TempValue) == FCSMU_IRQ_STAT_FAULT_IRQ_MASK)
{
if ((FCSMU_GetNtfFlag() & FCSMU_NTF_FLAG_MASK) == FCSMU_NTF_FLAG_MASK)
{
u32IrqChannel = FCSMU_GetNtfFlag() & 0xFFU;
}
else
{
u32IrqChannel = FCSMU_GetWtfFlag() & 0xFFU;
}
if (u32IrqChannel == 0xFFU)
{
u32IrqChannel = FCSMU_GetFaultChannel();
}
else
{
if (u32IrqChannel > 0U && u32IrqChannel <= 32U)
{
u32IrqChannel = (uint32_t)1U << (u32IrqChannel - (uint32_t)1U);
}
else
{
u32IrqChannel = 0U;
}
}
s_apFcsmuISRCallback(FCSMU_FAULT_IRQ, u32IrqChannel);
}
else if ((FCSMU_IRQ_STAT_WARNING_IRQ_MASK & u32TempValue) == FCSMU_IRQ_STAT_WARNING_IRQ_MASK)
{
u32IrqChannel = FCSMU_GetNtwFlag() & 0xFFU;
if (u32IrqChannel == 0xFFU)
{
u32IrqChannel = FCSMU_GetFaultChannel();
}
else
{
if (u32IrqChannel > 0U && u32IrqChannel <= 32U)
{
u32IrqChannel = (uint32_t)1U << (u32IrqChannel - (uint32_t)1U);
}
else
{
u32IrqChannel = 0U;
}
}
s_apFcsmuISRCallback(FCSMU_WARNING_IRQ, u32IrqChannel);
}
else if ((FCSMU_IRQ_STAT_CFG_TO_IRQ_MASK & u32TempValue) == FCSMU_IRQ_STAT_CFG_TO_IRQ_MASK)
{
s_apFcsmuISRCallback(FCSMU_CFG_TIMEOUT, 0);
}
else
{
}
}
void FCSMU0_IRQHandler(void)
{
FCSMUn_IRQHandler();
}