PeripheralDriver_Flagchip_F.../Src/module_driver_fcpit.c

493 lines
16 KiB
C

/**
* @file module_driver_fcpit.h
* @author Flagchip
* @brief FCPIT 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.
*
* @details
*/
/********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 31/12/2022 Flagchip071 N/A First version for FC7300
* 0.2.0 4/2/2022 Flagchip071 N/A 0.2.0 release
********************************************************************************/
#include "module_driver_fcpit.h"
#if FCPIT_INSTANCE_COUNT > 0U
#ifndef FCPIT_DEV_ERROR_REPORT
#define FCPIT_DEV_ERROR_REPORT STD_ON
#endif
#if FCPIT_DEV_ERROR_REPORT == STD_ON
#define FCPIT_ReportDevError(func, error) ReportDevError(FCPIT_MODULE_ID, func, error)
#endif
static FCPIT_Type * s_pFcpitPtrs[FCPIT_INSTANCE_COUNT] = FCPIT_BASE_PTRS;
/* global functions */
/**
* @brief Initialize Fcpit instance common feature.
* @param pFcpitHandle Fcpit processing handle
* @param pInitStruct Fcpit initialization structure
*/
void FCPIT_CommonInit(FCPIT_HandleType *pFcpitHandle,const FCPIT_CommonInitType * pInitStruct)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
/*Enable module clock*/
FCPIT_HWA_EnableModule(s_pFcpitPtr);
if (pInitStruct->bDebugEn)
{
FCPIT_HWA_SetChannelRunOnDebug(s_pFcpitPtr);
}
else
{
FCPIT_HWA_SetChannelStopOnDebug(s_pFcpitPtr);
}
if (pInitStruct->bLowPowerModeEn)
{
FCPIT_HWA_SetChannelRunOnLpm(s_pFcpitPtr);
}
else
{
FCPIT_HWA_SetChannelStopOnLpm(s_pFcpitPtr);
}
/*Send info to global handler*/
pFcpitHandle->bDebugEn = pInitStruct->bDebugEn;
pFcpitHandle->bLowPowerModeEn = pInitStruct->bLowPowerModeEn;
}
/* global functions */
/**
* @brief Initialize Fcpit instance.
* @param pFcpitHandle Fcpit processing handle
* @param pInitStruct Fcpit initialization structure
*/
void FCPIT_ChannelInit(FCPIT_HandleType *pFcpitHandle,const FCPIT_ChannelInitType * pInitStruct)
{
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if ((uint32_t)pInitStruct->eFcpitChannel >= FCPIT_CHANNEL_MAX)
{
FCPIT_ReportDevError(FCPIT_CHANNEL_INIT_ID, FCPIT_E_PARAM_CHANNEL);
}
else
{
#endif
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
/*Enable module clock*/
FCPIT_HWA_EnableModule(s_pFcpitPtr);
/* w1c , clear channel interrupt flag*/
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)1U << (uint32_t)pInitStruct->eFcpitChannel);
FCPIT_HWA_ConfigChannel(s_pFcpitPtr,pInitStruct->eFcpitChannel, (uint32_t)0U);
/*config mode*/
FCPIT_HWA_ConfigChannelMode(s_pFcpitPtr,pInitStruct->eFcpitChannel, pInitStruct->eMode);
if ((pInitStruct->eFcpitChannel > FCPIT_CHANNEL_0) && (pInitStruct->bChainModeEn))
{
FCPIT_HWA_EnableChannelChainMode(s_pFcpitPtr,pInitStruct->eFcpitChannel);
}
/*config value*/
FCPIT_HWA_SetChannelValue(s_pFcpitPtr,pInitStruct->eFcpitChannel, pInitStruct->u32TimerValue);
/*Send info to global handler*/
pFcpitHandle->tChannelStatus[(uint8_t)pInitStruct->eFcpitChannel].bChainModeEn = pInitStruct->bChainModeEn;
pFcpitHandle->tChannelStatus[(uint8_t)pInitStruct->eFcpitChannel].eMode = pInitStruct->eMode;
pFcpitHandle->tChannelStatus[(uint8_t)pInitStruct->eFcpitChannel].u32TimerValue = pInitStruct->u32TimerValue;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief Initialize Fcpit trigger configuration
* @param pFcpitHandle Fcpit processing handle
* @param pTrgStruct Fcpit trigger structure
*/
void FCPIT_InitTrigger(FCPIT_HandleType *pFcpitHandle,const FCPIT_TrggerType * pTrgStruct)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if (NULL == pTrgStruct)
{
FCPIT_ReportDevError(FCPIT_INIT_TRIGGER_ID, FCPIT_E_PARAM_POINTER);
}
else if((uint32_t)0U == FCPIT_HWA_ReadModuleEnable(s_pFcpitPtr))
{
FCPIT_ReportDevError(FCPIT_INIT_TRIGGER_ID, FCPIT_STATUS_FUNCTION_ERROR);
}
else
{
#endif
if (pTrgStruct->bStartOnTrigger)
{
FCPIT_HWA_SetChannelStartOnTrig(s_pFcpitPtr,pTrgStruct->eFcpitChannel);
}
else
{
FCPIT_HWA_ClearChannelStartOnTrig(s_pFcpitPtr,pTrgStruct->eFcpitChannel);
}
if (pTrgStruct->bStopOnInterrupt)
{
FCPIT_HWA_SetChannelStopOnInterrupt(s_pFcpitPtr,pTrgStruct->eFcpitChannel);
}
else
{
FCPIT_HWA_ClearChannelStopOnInterrupt(s_pFcpitPtr,pTrgStruct->eFcpitChannel);
}
if (pTrgStruct->bReloadOnTrigger)
{
FCPIT_HWA_SetChannelReloadOnTrig(s_pFcpitPtr,pTrgStruct->eFcpitChannel);
}
else
{
FCPIT_HWA_ClearChannelReloadOnTrig(s_pFcpitPtr,pTrgStruct->eFcpitChannel);
}
if (FCPIT_TRIGGER_EXTERNAL != pTrgStruct->eTriggerSel)
{
FCPIT_HWA_SetChannelTriggerSrc(s_pFcpitPtr,pTrgStruct->eFcpitChannel);
FCPIT_HWA_SelectChannelTrigger(s_pFcpitPtr,pTrgStruct->eFcpitChannel, pTrgStruct->eTriggerSel);
}
else
{
FCPIT_HWA_ClearChannelTriggerSrc(s_pFcpitPtr,pTrgStruct->eFcpitChannel);
FCPIT_HWA_SelectChannelTrigger(s_pFcpitPtr,pTrgStruct->eFcpitChannel, pTrgStruct->eFcpitChannel);
}
/*Send info to global handler*/
pFcpitHandle->tChannelStatus[(uint8_t)pTrgStruct->eFcpitChannel].bStartOnTrigger = pTrgStruct->bStartOnTrigger;
pFcpitHandle->tChannelStatus[(uint8_t)pTrgStruct->eFcpitChannel].bStopOnInterrupt = pTrgStruct->bStopOnInterrupt;
pFcpitHandle->tChannelStatus[(uint8_t)pTrgStruct->eFcpitChannel].bReloadOnTrigger = pTrgStruct->bReloadOnTrigger;
pFcpitHandle->tChannelStatus[(uint8_t)pTrgStruct->eFcpitChannel].eTriggerSel = pTrgStruct->eTriggerSel;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief De-initialize Fcpit instance.
* @param pFcpitHandle Fcpit processing handle
*/
void FCPIT_Deinit(FCPIT_HandleType *pFcpitHandle)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
uint8_t u8Index;
FCPIT_HWA_ConfigModule(s_pFcpitPtr,(uint32_t)FCPIT_MCR_M_CEN_MASK);
/*clear flag*/
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)(FCPIT_MSR_TIF3_MASK | FCPIT_MSR_TIF2_MASK | FCPIT_MSR_TIF1_MASK |
FCPIT_MSR_TIF0_MASK));
/*clear enable bit*/
FCPIT_HWA_DisableChannelsInterrupt(s_pFcpitPtr,(uint32_t)0xFU);
/*clear channel bit*/
for (u8Index = 0U; u8Index < MAX_FCPIT_CHANNEL_NUM; u8Index++)
{
FCPIT_HWA_ConfigChannel(s_pFcpitPtr,(FCPIT_ChannelType)u8Index, (uint32_t)0U);
FCPIT_HWA_SetChannelValue(s_pFcpitPtr,(FCPIT_ChannelType)u8Index, (uint32_t)0U);
/*clear info to global handler*/
pFcpitHandle->tChannelStatus[u8Index].eMode = FCPIT_CHANNEL_NOMODE;
pFcpitHandle->tChannelStatus[u8Index].bChainModeEn= false;
pFcpitHandle->tChannelStatus[u8Index].u32TimerValue = 0u;
pFcpitHandle->tChannelStatus[u8Index].bStartOnTrigger = false;
pFcpitHandle->tChannelStatus[u8Index].bStopOnInterrupt = false;
pFcpitHandle->tChannelStatus[u8Index].bReloadOnTrigger = false;
pFcpitHandle->tChannelStatus[u8Index].eTriggerSel = FCPIT_NO_TRIGGER;
pFcpitHandle->tChannelStatus[u8Index].bChannelIsrEn = false;
pFcpitHandle->tChannelStatus[u8Index].pChannelCallback = NULL;
pFcpitHandle->tChannelStatus[u8Index].bChannelStarted = false;
}
FCPIT_HWA_ConfigModule(s_pFcpitPtr,(uint32_t)0U);
pFcpitHandle->bDebugEn = false;
pFcpitHandle->bLowPowerModeEn = false;
}
/**
* @brief Initialize Fcpit interrupt functionality
* @param pFcpitHandle Fcpit processing handle
* @param pIntStruct Fcpit interrupt structure
* @note this function will stop timer
*/
void FCPIT_InitInterrupt(FCPIT_HandleType *pFcpitHandle,const FCPIT_IntType * pIntStruct)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if (NULL == pIntStruct)
{
FCPIT_ReportDevError(FCPIT_INIT_INTERRUPT_ID, FCPIT_E_PARAM_POINTER);
}
else if((uint32_t)0U == FCPIT_HWA_ReadModuleEnable(s_pFcpitPtr))
{
FCPIT_ReportDevError(FCPIT_INIT_INTERRUPT_ID, FCPIT_STATUS_FUNCTION_ERROR);
}
else
{
#endif
FCPIT_HWA_DisableChannel(s_pFcpitPtr,pIntStruct->eFcpitChannel);
/* w1c , clear channel interrupt flag*/
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)1U << (uint32_t)pIntStruct->eFcpitChannel);
if (pIntStruct->bChannelIsrEn)
{
FCPIT_HWA_EnableChannelsInterrupt(s_pFcpitPtr,(uint32_t)1U << (uint32_t)pIntStruct->eFcpitChannel);
pFcpitHandle->tChannelStatus[pIntStruct->eFcpitChannel].pChannelCallback = pIntStruct->pChannelCallback;
}
else
{
FCPIT_HWA_DisableChannelsInterrupt(s_pFcpitPtr,(uint32_t)1U << (uint32_t)pIntStruct->eFcpitChannel);
pFcpitHandle->tChannelStatus[pIntStruct->eFcpitChannel].pChannelCallback = NULL;
}
pFcpitHandle->tChannelStatus[pIntStruct->eFcpitChannel].bChannelIsrEn = pIntStruct->bChannelIsrEn;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief Enable Fcpit interrupt
* @param pFcpitHandle Fcpit processing handle
* @param eChannel Fcpit channel
*/
void FCPIT_EnableInterrupt(FCPIT_HandleType *pFcpitHandle,const FCPIT_ChannelType eChannel)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if (FCPIT_CHANNEL_MAX <= eChannel)
{
FCPIT_ReportDevError(FCPIT_ENABLE_INTERRUPT_ID, FCPIT_E_PARAM_CHANNEL);
}
else if((uint32_t)0U == FCPIT_HWA_ReadModuleEnable(s_pFcpitPtr))
{
FCPIT_ReportDevError(FCPIT_ENABLE_INTERRUPT_ID, FCPIT_STATUS_FUNCTION_ERROR);
}
else
{
#endif
FCPIT_HWA_DisableChannel(s_pFcpitPtr,eChannel);
/* w1c , clear channel interrupt flag*/
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)1U << (uint32_t)eChannel);
FCPIT_HWA_EnableChannelsInterrupt(s_pFcpitPtr,(uint32_t)1U << (uint32_t)eChannel);
FCPIT_HWA_EnableChannel(s_pFcpitPtr,eChannel);
pFcpitHandle->tChannelStatus[(uint8_t)eChannel].bChannelIsrEn = true;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief Disable Fcpit interrupt
* @param pFcpitHandle Fcpit processing handle
* @param eChannel Fcpit channel
*/
void FCPIT_DisableInterrupt(FCPIT_HandleType *pFcpitHandle,const FCPIT_ChannelType eChannel)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if (FCPIT_CHANNEL_MAX <= eChannel)
{
FCPIT_ReportDevError(FCPIT_DISABLE_INTERRUPT_ID, FCPIT_E_PARAM_CHANNEL);
}
else if((uint32_t)0U == FCPIT_HWA_ReadModuleEnable(s_pFcpitPtr))
{
FCPIT_ReportDevError(FCPIT_DISABLE_INTERRUPT_ID, FCPIT_STATUS_FUNCTION_ERROR);
}
else
{
#endif
FCPIT_HWA_DisableChannel(s_pFcpitPtr,eChannel);
/* w1c , clear channel interrupt flag*/
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)1U << (uint32_t)eChannel);
FCPIT_HWA_DisableChannelsInterrupt(s_pFcpitPtr,(uint32_t)1U << (uint32_t)eChannel);
FCPIT_HWA_EnableChannel(s_pFcpitPtr,eChannel);
pFcpitHandle->tChannelStatus[(uint8_t)eChannel].bChannelIsrEn = false;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief Fcpit start timer
* @param pFcpitHandle Fcpit processing handle
* @param eChannel Fcpit channel
*/
void FCPIT_Start(FCPIT_HandleType *pFcpitHandle,const FCPIT_ChannelType eChannel)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if (FCPIT_CHANNEL_MAX <= eChannel)
{
FCPIT_ReportDevError(FCPIT_START_ID, FCPIT_E_PARAM_CHANNEL);
}
else if((uint32_t)0U == FCPIT_HWA_ReadModuleEnable(s_pFcpitPtr))
{
FCPIT_ReportDevError(FCPIT_START_ID, FCPIT_STATUS_FUNCTION_ERROR);
}
else
{
#endif
FCPIT_HWA_EnableChannel(s_pFcpitPtr,eChannel);
pFcpitHandle->tChannelStatus[(uint8_t)eChannel].bChannelStarted = true;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief Fcpit stop
* @param pFcpitHandle Fcpit processing handle
* @param eChannel Fcpit channel
*/
void FCPIT_Stop(FCPIT_HandleType *pFcpitHandle,const FCPIT_ChannelType eChannel)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if (FCPIT_CHANNEL_MAX <= eChannel)
{
FCPIT_ReportDevError(FCPIT_STOP_ID, FCPIT_E_PARAM_CHANNEL);
}
else if((uint32_t)0U == FCPIT_HWA_ReadModuleEnable(s_pFcpitPtr))
{
FCPIT_ReportDevError(FCPIT_STOP_ID, FCPIT_STATUS_FUNCTION_ERROR);
}
else
{
#endif
FCPIT_HWA_DisableChannel(s_pFcpitPtr,eChannel);
pFcpitHandle->tChannelStatus[(uint8_t)eChannel].bChannelStarted = false;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief Immediately update Fcpit channel value
* @param pFcpitHandle Fcpit processing handle
* @param eChannel Fcpit channel
* @param u32ChannelValue in/Out value
*/
void FCPIT_ImmediateUpdateChannelValue(FCPIT_HandleType *pFcpitHandle,const FCPIT_ChannelType eChannel, const uint32_t u32ChannelValue)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if (FCPIT_CHANNEL_MAX <= eChannel)
{
FCPIT_ReportDevError(FCPIT_STOP_ID, FCPIT_E_PARAM_CHANNEL);
}
else if((uint32_t)0U == FCPIT_HWA_ReadModuleEnable(s_pFcpitPtr))
{
FCPIT_ReportDevError(FCPIT_STOP_ID, FCPIT_STATUS_FUNCTION_ERROR);
}
else
{
#endif
FCPIT_HWA_DisableChannel(s_pFcpitPtr,eChannel);
FCPIT_HWA_SetChannelValue(s_pFcpitPtr,eChannel, u32ChannelValue);
FCPIT_HWA_EnableChannel(s_pFcpitPtr,eChannel);
pFcpitHandle->tChannelStatus[(uint8_t)eChannel].u32TimerValue = u32ChannelValue;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief Update Fcpit channel value
* @param pFcpitHandle Fcpit processing handle
* @param eChannel Fcpit channel
* @param u32ChannelValue in/Out value
*/
void FCPIT_UpdateChannelValue(FCPIT_HandleType *pFcpitHandle,const FCPIT_ChannelType eChannel, const uint32_t u32ChannelValue)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
#if FCPIT_DEV_ERROR_REPORT == STD_ON
if (FCPIT_CHANNEL_MAX <= eChannel)
{
FCPIT_ReportDevError(FCPIT_STOP_ID, FCPIT_E_PARAM_CHANNEL);
}
else if((uint32_t)0U == FCPIT_HWA_ReadModuleEnable(s_pFcpitPtr))
{
FCPIT_ReportDevError(FCPIT_STOP_ID, FCPIT_STATUS_FUNCTION_ERROR);
}
else
{
#endif
FCPIT_HWA_SetChannelValue(s_pFcpitPtr,eChannel, u32ChannelValue);
pFcpitHandle->tChannelStatus[(uint8_t)eChannel].u32TimerValue = u32ChannelValue;
#if FCPIT_DEV_ERROR_REPORT == STD_ON
}
#endif
}
/**
* @brief fcpit interrupt function.
* @param pFcpitHandle Fcpit processing handle
*/
void FCPITn_IRQHandler(FCPIT_HandleType *pFcpitHandle)
{
FCPIT_Type *s_pFcpitPtr = s_pFcpitPtrs[pFcpitHandle->eInstance];
uint32_t u32TifValue = FCPIT_HWA_ReadEnableInterruptFlag(s_pFcpitPtr) & FCPIT_HWA_ReadInterruptFlag(s_pFcpitPtr);
if (u32TifValue & FCPIT_MSR_TIF0_MASK)
{
if(pFcpitHandle->tChannelStatus[0].pChannelCallback != NULL)
{
pFcpitHandle->tChannelStatus[0].pChannelCallback(pFcpitHandle,0U);
}
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)FCPIT_MSR_TIF0_MASK);
}
if (u32TifValue & FCPIT_MSR_TIF1_MASK)
{
if(pFcpitHandle->tChannelStatus[1].pChannelCallback != NULL)
{
pFcpitHandle->tChannelStatus[1].pChannelCallback(pFcpitHandle,1U);
}
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)FCPIT_MSR_TIF1_MASK);
}
if (u32TifValue & FCPIT_MSR_TIF2_MASK)
{
if(pFcpitHandle->tChannelStatus[2].pChannelCallback != NULL)
{
pFcpitHandle->tChannelStatus[2].pChannelCallback(pFcpitHandle,2U);
}
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)FCPIT_MSR_TIF2_MASK);
}
if (u32TifValue & FCPIT_MSR_TIF3_MASK)
{
if(pFcpitHandle->tChannelStatus[3].pChannelCallback != NULL)
{
pFcpitHandle->tChannelStatus[3].pChannelCallback(pFcpitHandle,3U);
}
FCPIT_HWA_ClearChannelsInterruptFlag(s_pFcpitPtr,(uint32_t)FCPIT_MSR_TIF3_MASK);
}
}
#endif /* #if FCPIT_INSTANCE_COUNT > 0U */