490 lines
14 KiB
C
490 lines
14 KiB
C
/**
|
|
* @file module_driver_ism.c
|
|
* @author Flagchip
|
|
* @brief ISM driver type definition and API
|
|
* @version 2.0.0
|
|
* @date 2024-08-20
|
|
*
|
|
* SDK Version: 2.6.0
|
|
*
|
|
|
|
* @copyright Copyright (c) 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
|
|
******************************************************************************** */
|
|
#include "module_driver_ism.h"
|
|
|
|
#if ISM_INSTANCE_COUNT > 0U
|
|
|
|
#ifndef ISM_DEV_ERROR_REPORT
|
|
#define ISM_DEV_ERROR_REPORT STD_OFF
|
|
#endif
|
|
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
#define ISM_ReportDevError(func, error) ReportDevError(ISM_MODULE_ID, func, error)
|
|
#endif
|
|
|
|
/* ################################################################################## */
|
|
/* ####################################### Macro #################################### */
|
|
|
|
/* ################################################################################## */
|
|
/* ################################### Type define ################################## */
|
|
|
|
/* ################################################################################## */
|
|
/* ################################ Local Variables ################################# */
|
|
static ISM_Type *const s_apIsmBase[ISM_INSTANCE_COUNT] = ISM_BASE_PTRS;
|
|
|
|
/* ################################################################################## */
|
|
/* ########################### Local Prototype Functions ############################ */
|
|
/* ################################################################################## */
|
|
/* ################################ Local Functions ################################ */
|
|
|
|
/* ################################################################################## */
|
|
/* ################################ Global Functions ################################ */
|
|
|
|
/**
|
|
* @brief Init the ISM.
|
|
* @param pIsmHandle Ism processing handle
|
|
* @param pInitConfig ISMInstance initial configuration.
|
|
*/
|
|
void ISM_CommonInit(ISM_HandleType *pIsmHandle,const ISM_InitCfgType *pInitConfig)
|
|
{
|
|
ISM_Type *pIsm = ISM;
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
|
|
if ((ISM_HWA_PARAM_ECMC(pIsm) != ECM_INSTANCE_COUNT)||(ISM_HWA_PARAM_FPC(pIsm) != FPC_INSTANCE_COUNT)||(ISM_HWA_PARAM_LAM(pIsm) != LAM_INSTANCE_COUNT))
|
|
{
|
|
ISM_ReportDevError(ISM_COMMON_INIT_ID, ISM_E_PARAM_INVALID);
|
|
}
|
|
else if (NULL == pInitConfig)
|
|
{
|
|
ISM_ReportDevError(ISM_COMMON_INIT_ID, ISM_E_PARAM_POINTER);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
ISM_HWA_Enable(pIsm, pInitConfig->bIsmEnable);
|
|
ISM_HWA_InterruptEnable(pIsm, pInitConfig->bIntEnable);
|
|
|
|
|
|
/*Send info to global handler*/
|
|
pIsmHandle->bEnable = pInitConfig->bIntEnable;
|
|
pIsmHandle->bIntEnable = pInitConfig->bIntEnable;
|
|
pIsmHandle->pEventIsrCalllback = pInitConfig->pEventIsrCalllback;
|
|
pIsmHandle->pEcmEventIsrCalllback = pInitConfig->pEcmEventIsrCalllback;
|
|
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Config the FPC channel.
|
|
*
|
|
* @param pIsmHandle Ism processing handle.
|
|
* @param u8FpcIndex FPC index.
|
|
* @param pConfig FPC configuration.
|
|
*/
|
|
void ISM_FpcConfig(ISM_HandleType *pIsmHandle,uint8_t u8FpcIndex, const ISM_FpcCfgType *pConfig)
|
|
{
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
if(u8FpcIndex > FPC_INSTANCE_COUNT)
|
|
{
|
|
ISM_ReportDevError(ISM_FPC_CONFIG_ID, ISM_E_PARAM_CHANNEL);
|
|
}
|
|
else if (NULL == pConfig)
|
|
{
|
|
ISM_ReportDevError(ISM_FPC_CONFIG_ID, ISM_E_PARAM_POINTER);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
uint32_t u32TempValue = 0;
|
|
FPC_Type *pFpc;
|
|
pFpc = ISM_HWA_GetFpc(ISM, u8FpcIndex);
|
|
ISM_HWA_SetFpcCtrlIen(pFpc, pConfig->bGlitchIntEnable);
|
|
u32TempValue |= ISM_FPC_CONFIG_FED(pConfig->eFallingDelayNode);
|
|
u32TempValue |= ISM_FPC_CONFIG_FEG(pConfig->eFallingDetectMode);
|
|
u32TempValue |= ISM_FPC_CONFIG_RED(pConfig->eRisingDelayNode);
|
|
u32TempValue |= ISM_FPC_CONFIG_REG(pConfig->eRisingDetectMode);
|
|
u32TempValue |= ISM_FPC_CONFIG_CMP(pConfig->u32ThresholdValue);
|
|
ISM_HWA_SetFpcConfig(pFpc, u32TempValue);
|
|
/*Send info to global handler*/
|
|
pIsmHandle->tIsmFpcChannelStatus[u8FpcIndex].bGlitchIntEnable = pConfig->bGlitchIntEnable;
|
|
pIsmHandle->tIsmFpcChannelStatus[u8FpcIndex].eFallingDelayNode = pConfig->eFallingDelayNode;
|
|
pIsmHandle->tIsmFpcChannelStatus[u8FpcIndex].eFallingDetectMode = pConfig->eFallingDetectMode;
|
|
pIsmHandle->tIsmFpcChannelStatus[u8FpcIndex].eRisingDelayNode = pConfig->eRisingDelayNode;
|
|
pIsmHandle->tIsmFpcChannelStatus[u8FpcIndex].eRisingDetectMode = pConfig->eRisingDetectMode;
|
|
pIsmHandle->tIsmFpcChannelStatus[u8FpcIndex].u32ThresholdValue = pConfig->u32ThresholdValue;
|
|
pIsmHandle->tIsmFpcChannelStatus[u8FpcIndex].pFpcChannelCalllback = pConfig->pFpcChannelCalllback;
|
|
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Enable FPC channel.
|
|
*
|
|
* @param pIsmHandle Ism processing handle.
|
|
* @param u8FpcIndex FPC index.
|
|
* @param bEnable Enable value.
|
|
*/
|
|
void ISM_FpcEnable(ISM_HandleType *pIsmHandle,uint8_t u8FpcIndex, bool bEnable)
|
|
{
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
if(u8FpcIndex > FPC_INSTANCE_COUNT)
|
|
{
|
|
ISM_ReportDevError(ISM_FPC_ENABLE_ID, ISM_E_PARAM_CHANNEL);
|
|
}
|
|
else if (NULL == pIsmHandle)
|
|
{
|
|
ISM_ReportDevError(ISM_FPC_ENABLE_ID, ISM_E_PARAM_POINTER);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
FPC_Type *pFpc;
|
|
pFpc = ISM_HWA_GetFpc(ISM, u8FpcIndex);
|
|
ISM_HWA_SetFpcCtrlEn(pFpc, bEnable);
|
|
/*Send info to global handler*/
|
|
pIsmHandle->tIsmFpcChannelStatus[u8FpcIndex].bFpcChannelEn = bEnable;
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Config the LAM channel.
|
|
*
|
|
* @param pIsmHandle Ism processing handle.
|
|
* @param u8LamIndex LAM index.
|
|
* @param pConfig LAM configuration.
|
|
*/
|
|
void ISM_LamConfig(ISM_HandleType *pIsmHandle,uint8_t u8LamIndex, const ISM_LamCfgType *pConfig)
|
|
{
|
|
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
if(u8LamIndex > LAM_INSTANCE_COUNT)
|
|
{
|
|
ISM_ReportDevError(ISM_LAM_CONFIG_ID, ISM_E_PARAM_CHANNEL);
|
|
}
|
|
else if (NULL == pConfig)
|
|
{
|
|
ISM_ReportDevError(ISM_LAM_CONFIG_ID, ISM_E_PARAM_POINTER);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
uint32_t u32TempValue = 0;
|
|
LAM_Type *pLam;
|
|
pLam = ISM_HWA_GetLam(ISM, u8LamIndex);
|
|
|
|
ISM_HWA_SetLamCtrIen(pLam, pConfig->bOvflIntEnable);
|
|
ISM_HWA_SetLamCounter(pLam, pConfig->u32EvtCntThreshold);
|
|
u32TempValue |= ISM_LAM_CONFIG_RCS(pConfig->u8RcsSel);
|
|
u32TempValue |= ISM_LAM_CONFIG_MCS(pConfig->u8MonSel);
|
|
u32TempValue |= ISM_LAM_CONFIG_IVW(pConfig->eInvWin);
|
|
u32TempValue |= ISM_LAM_CONFIG_EDS(pConfig->eWinEdgSel);
|
|
u32TempValue |= ISM_LAM_CONFIG_EWS(pConfig->eEvtWinSel);
|
|
u32TempValue |= ISM_LAM_CONFIG_RMS(pConfig->eRunMode);
|
|
u32TempValue |= ISM_LAM_CONFIG_MOS(pConfig->eMonSrcSel);
|
|
u32TempValue |= ISM_LAM_CONFIG_IVM(pConfig->eInvMon);
|
|
u32TempValue |= ISM_LAM_CONFIG_IVR(pConfig->eInvRef);
|
|
ISM_HWA_SetLamConfig(pLam, u32TempValue);
|
|
/*Send info to global handler*/
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].bOvflIntEnable = pConfig->bOvflIntEnable;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].eEvtWinSel = pConfig->eEvtWinSel;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].eInvMon = pConfig->eInvMon;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].eInvRef =pConfig->eInvRef;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].eInvWin =pConfig->eInvWin;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].eMonSrcSel =pConfig->eMonSrcSel;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].eRunMode =pConfig->eRunMode ;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].eWinEdgSel =pConfig->eWinEdgSel;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].u32EvtCntThreshold =pConfig->u32EvtCntThreshold;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].u8MonSel =pConfig->u8MonSel;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].u8RcsSel =pConfig->u8RcsSel;
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].pLamChannelOverCalllback = pConfig->pLamChannelOverCalllback;
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Enable LAM Channel.
|
|
*
|
|
* @param pIsmHandle Ism processing handle.
|
|
* @param u8LamIndex LAM index.
|
|
* @param bEnable Enable value.
|
|
*/
|
|
void ISM_LamEnable(ISM_HandleType *pIsmHandle,uint8_t u8LamIndex, bool bEnable)
|
|
{
|
|
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
if(u8LamIndex > LAM_INSTANCE_COUNT)
|
|
{
|
|
ISM_ReportDevError(ISM_LAM_ENABLE_ID, ISM_E_PARAM_CHANNEL);
|
|
}
|
|
else if (NULL == pIsmHandle)
|
|
{
|
|
ISM_ReportDevError(ISM_LAM_ENABLE_ID, ISM_E_PARAM_POINTER);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
LAM_Type *pLam;
|
|
|
|
|
|
pLam = ISM_HWA_GetLam(ISM, u8LamIndex);
|
|
|
|
ISM_HWA_SetLamCtrEn(pLam, bEnable);
|
|
/*Send info to global handler*/
|
|
pIsmHandle->tIsmLamChannelStatus[u8LamIndex].bLamChannelEn = bEnable;
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Enable LAM system event
|
|
*
|
|
* @param pIsmHandle Ism processing handle.
|
|
* @param u32LamIndex Lam channel index.
|
|
* @param u32EcmIndex Ecm channel index.
|
|
* @param u8EventCount Threshold of the ECM channel counter value.
|
|
*/
|
|
void ISM_EcmEventConfig(ISM_HandleType *pIsmHandle,uint8_t u8LamIndex, uint8_t u8EcmIndex, uint8_t u8EventCount)
|
|
{
|
|
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
if(u8LamIndex > LAM_INSTANCE_COUNT)
|
|
{
|
|
ISM_ReportDevError(ISM_ECM_CONFIG_ID, ISM_E_PARAM_CHANNEL);
|
|
}
|
|
|
|
else if (u8EcmIndex == ECM_INSTANCE_COUNT)
|
|
{
|
|
ISM_ReportDevError(ISM_ECM_CONFIG_ID, ISM_E_PARAM_COUNT);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
ISM_Type *pIsm = ISM;
|
|
if (u8EcmIndex == 0U)
|
|
{
|
|
ISM_HWA_SetEcm0EcCtrl(pIsm, u8EventCount, u8LamIndex);
|
|
}
|
|
else if (u8EcmIndex == 1U)
|
|
{
|
|
ISM_HWA_SetEcm1EcCtrl(pIsm, u8EventCount, u8LamIndex);
|
|
}
|
|
else if (u8EcmIndex == 2U)
|
|
{
|
|
ISM_HWA_SetEcm2EcCtrl(pIsm, u8EventCount, u8LamIndex);
|
|
}
|
|
else if (u8EcmIndex == 3U)
|
|
{
|
|
ISM_HWA_SetEcm3EcCtrl(pIsm, u8EventCount, u8LamIndex);
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
/*Send info to global handler*/
|
|
pIsmHandle->tEcmEventStatus[u8EcmIndex].u32Value = u8EventCount;
|
|
pIsmHandle->tEcmEventStatus[u8EcmIndex].u32LamChannelRouter = u8LamIndex;
|
|
|
|
#if ISM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
uint8_t ISM_GetEcmEventHappenedChannels(void)
|
|
{
|
|
ISM_Type *pIsm = ISM;
|
|
return (uint8_t)ISM_HWA_GetEcs(pIsm);
|
|
}
|
|
|
|
uint16_t ISM_GetLamEventHappenedChannels(void)
|
|
{
|
|
ISM_Type *pIsm = ISM;
|
|
|
|
return ISM_HWA_GetEs(pIsm);
|
|
}
|
|
|
|
void ISM_ClearEcmEventHappenedChannels(uint8_t u8Channels)
|
|
{
|
|
ISM_Type *pIsm = ISM;
|
|
ISM_HWA_ClearEcs(pIsm, (uint32_t)u8Channels);
|
|
}
|
|
|
|
void ISM_ClearLamEventHappenedChannels(uint16_t u16Channels)
|
|
{
|
|
ISM_Type *pIsm = ISM;
|
|
ISM_HWA_ClearEs(pIsm, (uint32_t)u16Channels);
|
|
}
|
|
|
|
|
|
void ISM_EnableEcmSystemEvent(uint32_t u32Channels, bool bEnable)
|
|
{
|
|
ISM_Type *pIsm = ISM;
|
|
|
|
ISM_HWA_EnableEcmSystemEvent(pIsm, u32Channels, bEnable);
|
|
}
|
|
|
|
|
|
void ISM_EnableLamSystemEvent(uint32_t u32Channels, bool bEnable)
|
|
{
|
|
ISM_Type *pIsm = ISM;
|
|
|
|
ISM_HWA_EnableLamSystemEvent(pIsm, u32Channels, bEnable);
|
|
}
|
|
|
|
|
|
void ISM_ClearLamStatusCounter(uint8_t u8LamIndex)
|
|
{
|
|
LAM_Type *pLam;
|
|
|
|
pLam = ISM_HWA_GetLam(ISM, u8LamIndex);
|
|
|
|
ISM_HWA_ClearLamStatusCounter(pLam);
|
|
}
|
|
|
|
uint32_t ISM_GetLamStatusCounter(uint8_t u8LamIndex)
|
|
{
|
|
LAM_Type *pLam;
|
|
|
|
|
|
|
|
pLam = ISM_HWA_GetLam(ISM, u8LamIndex);
|
|
|
|
return ISM_HWA_GetLamStatusCounter(pLam);
|
|
}
|
|
|
|
void ISM_ClearLamStatusOvfl(uint8_t u8LamIndex)
|
|
{
|
|
LAM_Type *pLam;
|
|
|
|
pLam = ISM_HWA_GetLam(ISM, u8LamIndex);
|
|
|
|
ISM_HWA_ClearLamStatusOvfl(pLam);
|
|
}
|
|
|
|
bool ISM_GetLamStatusOvfl(uint8_t u8LamIndex)
|
|
{
|
|
LAM_Type *pLam;
|
|
|
|
pLam = ISM_HWA_GetLam(ISM, u8LamIndex);
|
|
|
|
return ISM_HWA_GetLamStatusOvfl(pLam);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param pIsmHandle Ism processing handle.
|
|
* @brief ISM Interrupt Process Function.
|
|
*/
|
|
void ISMn_IRQHandler(ISM_HandleType *pIsmHandle)
|
|
{
|
|
uint8_t u8i =0;
|
|
FPC_Type *pFpc;
|
|
LAM_Type *pLam;
|
|
uint8_t u8EcmFlags;
|
|
uint16_t u16LamFlags;
|
|
ISM_Type *pIsm = s_apIsmBase[ISM_INSTANCE_0];
|
|
|
|
u8EcmFlags = ISM_HWA_GetEcs(pIsm)&ISM_HWA_GetEnabledEcmSystemEvent(pIsm);
|
|
u16LamFlags = ISM_HWA_GetEs(pIsm)&ISM_HWA_GetEnabledLamSystemEvent(pIsm);
|
|
|
|
|
|
|
|
/*ECM event callback*/
|
|
for (u8i = 0; u8i < ECM_INSTANCE_COUNT; u8i++)
|
|
{
|
|
if(((0x1<<u8i)&u8EcmFlags)!=0U)
|
|
{
|
|
if( pIsmHandle->pEcmEventIsrCalllback != NULL)
|
|
{
|
|
pIsmHandle->pEcmEventIsrCalllback(pIsmHandle,u8EcmFlags);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*Event callback*/
|
|
for (u8i = 0; u8i < LAM_INSTANCE_COUNT; u8i++)
|
|
{
|
|
if(((0x1<<u8i)&u16LamFlags)!=0U)
|
|
{
|
|
if (pIsmHandle->pEventIsrCalllback !=NULL)
|
|
{
|
|
pIsmHandle->pEventIsrCalllback(pIsmHandle,u16LamFlags);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*FPC callback*/
|
|
for (u8i = 0; u8i < FPC_INSTANCE_COUNT; u8i++)
|
|
{
|
|
pFpc = ISM_HWA_GetFpc(pIsm, u8i);
|
|
if (ISM_HWA_GetFpcCtrlIen(pFpc))
|
|
{
|
|
uint32_t u32Status = 0U;
|
|
if (ISM_HWA_GetFpcRgd(pFpc))
|
|
{
|
|
u32Status |= (uint32_t)FPC_RISING_GLITCH_DETECTED;
|
|
}
|
|
if (ISM_HWA_GetFpcFgd(pFpc))
|
|
{
|
|
u32Status |= (uint32_t)FPC_FALLING_GLITCH_DETECTED;
|
|
}
|
|
if( pIsmHandle->tIsmFpcChannelStatus[u8i].pFpcChannelCalllback != NULL)
|
|
{
|
|
pIsmHandle->tIsmFpcChannelStatus[u8i].pFpcChannelCalllback(pIsmHandle,u8i);
|
|
}
|
|
if ((u32Status & (uint32_t)FPC_RISING_GLITCH_DETECTED) == (uint32_t)FPC_RISING_GLITCH_DETECTED)
|
|
{
|
|
ISM_HWA_ClearFpcRgd(pFpc);
|
|
}
|
|
if ((u32Status & (uint32_t)FPC_FALLING_GLITCH_DETECTED) == (uint32_t)FPC_FALLING_GLITCH_DETECTED)
|
|
{
|
|
ISM_HWA_ClearFpcFgd(pFpc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*LAM overflow callback*/
|
|
for (u8i = 0; u8i < LAM_INSTANCE_COUNT; u8i++)
|
|
{
|
|
pLam = ISM_HWA_GetLam(pIsm, u8i);
|
|
if (ISM_HWA_GetLamCtrIen(pLam))
|
|
{
|
|
if (ISM_HWA_GetLamStatusOvfl(pLam))
|
|
{
|
|
if( pIsmHandle->tIsmLamChannelStatus[u8i].pLamChannelOverCalllback != NULL)
|
|
{
|
|
pIsmHandle->tIsmLamChannelStatus[u8i].pLamChannelOverCalllback(pIsmHandle,u8i);
|
|
}
|
|
}
|
|
ISM_HWA_ClearLamStatusOvfl(pLam);
|
|
}
|
|
}
|
|
|
|
ISM_HWA_ClearEcs(pIsm, u8EcmFlags);
|
|
ISM_HWA_ClearEs(pIsm, u16LamFlags);
|
|
|
|
}
|
|
|
|
#endif /* #if ISM_INSTANCE_COUNT > 0U */
|