409 lines
11 KiB
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();
|
|
}
|