/** * @file fc7xxx_driver_ftu.c * @author Flagchip * @brief FC7xxx FTU driver type definition and API * @version 0.1.0 * @date 2022-11-15 * * @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd. * * @details */ /* ******************************************************************************** * Revision History: * * Version Date Initials CR# Descriptions * --------- ---------- ------------ ---------- --------------- * 0.1.0 2022-11-15 Flagchip070 N/A First version for FC7300 ******************************************************************************** */ #include "fc7xxx_driver_ftu.h" #include "fc7xxx_driver_pcc.h" #include "interrupt_manager.h" #include "HwA_scm.h" /********* Local variable ************/ static const uint32_t s_aFtuMaxCounter[FTU_INSTANCE_COUNT] = {0xFFFFu, 0xFFFFFFu, 0xFFFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu, 0xFFFFu}; static FTU_Type * const s_pFtuBasePtrs[FTU_INSTANCE_COUNT] = FTU_BASE_PTRS; static FTU_ClkSrcType s_eFtuClkSrc[FTU_INSTANCE_COUNT] = {FTU_NO_CLK}; static FTU_ChannelCallBackType s_pChannelCallback[FTU_INSTANCE_COUNT] = {NULL}; static FTU_FaultCallBackType s_pFaultCallback[FTU_INSTANCE_COUNT] = {NULL}; static FTU_InterruptCallBackType s_pOverflowCallback[FTU_INSTANCE_COUNT] = {NULL}; static FTU_InterruptCallBackType s_pReloadPointCallback[FTU_INSTANCE_COUNT] = {NULL}; /***************** Local Prototype Functions *********************/ static void enable_sync_flag(FTU_Type *pFtu, uint16_t u16SyncFlag); static void disable_sync_flag(FTU_Type *pFtu, uint16_t u16SyncFlag); static void disable_reload_points(FTU_Type *pFtu, uint16_t u16ReloadPoints); static void enable_reload_points(FTU_Type *pFtu, uint16_t u16ReloadPoints); /********* Local Functions ************/ /** * @brief Configure the input capture edge of the selected FTU channel * * @param pFtu the base address of the FTU instance * @param u8Channel channel index of the FTU instance * @param eEdge input capture edge */ static void set_ftu_input_edge(FTU_Type *pFtu, uint8_t u8Channel, FTU_InputCapturePinModeType eEdge) { if (FTU_INPUT_RISING_EDGE == eEdge) { FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, FTU_CHANNEL_EDGE_RISING); } else if (FTU_INPUT_FALLING_EDGE == eEdge) { FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, FTU_CHANNEL_EDGE_FALLING); } else if (FTU_INPUT_BOTH_EDGE == eEdge) { FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, FTU_CHANNEL_EDGE_BOTH); } else { FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, FTU_CHANNEL_EDGE_NOT_USED); } } /** * @brief Enable the synchronization of the selected FTU instance * * @param pFtu the base address of the FTU instance * @param u16SyncFlag The synchronization flag */ static void enable_sync_flag(FTU_Type *pFtu, uint16_t u16SyncFlag) { uint32_t u32Loop; if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_FTUEN)) { FTU_HWA_SetModuleUpdateRegBySync(pFtu); } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_LDOK)) { FTU_HWA_SetPwmLoadEnable(pFtu); } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_CNTINC)) { FTU_HWA_SetCntinSync(pFtu); } for(u32Loop = 0; u32Loop < 4u; u32Loop++) { if(0u != (u16SyncFlag & (uint16_t)((uint16_t)FTU_SYNC_FLAG_SYNCEN01 << u32Loop))) { FTU_HWA_SetChannelSyncEnable(pFtu, u32Loop); } } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_PWMSYNC)) { FTU_HWA_SetPwmSyncMode(pFtu); } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_REINIT)) { FTU_HWA_SetReinitBySync(pFtu); } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_SYNCHOM)) { FTU_HWA_EnableOutputMaskBySync(pFtu); } } /** * @brief Disable the synchronization of the selected FTU instance * * @param pFtu the base address of the FTU instance * @param u16SyncFlag The synchronization flag */ static void disable_sync_flag(FTU_Type *pFtu, uint16_t u16SyncFlag) { uint32_t u32Loop; if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_FTUEN)) { FTU_HWA_ClearModuleUpdateRegBySync(pFtu); } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_LDOK)) { FTU_HWA_ClearPwmLoadEnable(pFtu); } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_CNTINC)) { FTU_HWA_ClearCntinSync(pFtu); } for(u32Loop = 0; u32Loop < 4u; u32Loop++) { if(0u != (u16SyncFlag & ((uint16_t)FTU_SYNC_FLAG_SYNCEN01 << u32Loop))) { FTU_HWA_ClearChannelSyncEnable(pFtu, u32Loop); } } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_PWMSYNC)) { FTU_HWA_ClearPwmSyncMode(pFtu); } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_REINIT)) { FTU_HWA_ClearReinitBySync(pFtu); } if(0u != (u16SyncFlag & (uint16_t)FTU_SYNC_FLAG_SYNCHOM)) { FTU_HWA_DisableOutputMaskBySync(pFtu); } } /** * @brief Disable the reload points of the selected FTU instance * * @param pFtu the base address of the FTU instance * @param u16ReloadPoints The reload points flag */ static void disable_reload_points(FTU_Type *pFtu, uint16_t u16ReloadPoints) { uint32_t u32Loop; if(0u != (u16ReloadPoints & (uint16_t)FTU_RELOAD_POINT_CNTMAX)) { /* Enables Maximum Loading Point */ FTU_HWA_DisableMaxLoadPoint(pFtu); } if(0u != (u16ReloadPoints & (uint16_t)FTU_RELOAD_POINT_CNTMIN)) { /* Disables Minimum Loading Point */ FTU_HWA_DisableMinLoadPoint(pFtu); } for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if(0u != (u16ReloadPoints & (uint16_t)((uint16_t)FTU_RELOAD_POINT_CHANNEL_0 << u32Loop))) { /* Channel match is not included as a reload opportunity */ FTU_HWA_DisableChannelMatchReload(pFtu, u32Loop); } } } /** * @brief Enable the reload points of the selected FTU instance * * @param pFtu the base address of the FTU instance * @param u16ReloadPoints The reload points flag */ static void enable_reload_points(FTU_Type *pFtu, uint16_t u16ReloadPoints) { uint32_t u32Loop; if(0u != (u16ReloadPoints & (uint32_t)FTU_RELOAD_POINT_CNTMAX)) { /* Enables Maximum Loading Point */ FTU_HWA_EnableMaxLoadPoint(pFtu); } if(0u != (u16ReloadPoints & (uint32_t)FTU_RELOAD_POINT_CNTMIN)) { /* Enables Minimum Loading Point */ FTU_HWA_EnableMinLoadPoint(pFtu); } for(u32Loop = 0; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if(0u != (u16ReloadPoints & ((uint32_t)FTU_RELOAD_POINT_CHANNEL_0 << u32Loop))) { /* Channel match is included as a reload opportunity */ FTU_HWA_EnableChannelMatchReload(pFtu, u32Loop); } } } /********* Global Functions ************/ /** * @brief Enable the reload points of the selected FTU instance * * @param eInstance the selected FTU instance * @param u16ReloadPoints The reload points flag * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_EnableReloadPoints(const FTU_InstanceType eInstance, uint16_t u16ReloadPoints) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { enable_reload_points(s_pFtuBasePtrs[eInstance], u16ReloadPoints); } return eStatus; } /** * @brief Disable the reload points of the selected FTU instance * * @param eInstance the selected FTU instance * @param u16ReloadPoints The reload points flag * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_DisableReloadPoints(const FTU_InstanceType eInstance, uint16_t u16ReloadPoints) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { disable_reload_points(s_pFtuBasePtrs[eInstance], u16ReloadPoints); } return eStatus; } /** * @brief enable the synchronization of the selected FTU * * @param eInstance the selected FTU instance * @param u16ReloadPoints The synchronization flag * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_EnableSync(const FTU_InstanceType eInstance, uint16_t u16SyncFlag) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { enable_sync_flag(s_pFtuBasePtrs[eInstance], u16SyncFlag); } return eStatus; } /** * @brief disable the synchronization of the selected FTU * * @param eInstance the selected FTU instance * @param u16ReloadPoints The synchronization flag * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_DisableSync(const FTU_InstanceType eInstance, uint16_t u16SyncFlag) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { disable_sync_flag(s_pFtuBasePtrs[eInstance], u16SyncFlag); } return eStatus; } /** * @brief Initialize FTU basic configuration * * @param eInstance the selected FTU instance * @param pCommonStruct the basic configurations of the FTU instance * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_CommonInit(const FTU_InstanceType eInstance, const FTU_CommonType *const pCommonStruct) { FTU_StatusType eRet = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eRet = FTU_STATUS_PARAM_INVALID; } else if (pCommonStruct->u32OverflowValue > s_aFtuMaxCounter[(uint32_t)eInstance]) { eRet = FTU_STATUS_PARAM_INVALID; } else { if (true == pCommonStruct->bGtbEnable) { FTU_HWA_EnableGlobalTimeBase(s_pFtuBasePtrs[eInstance]); } else { FTU_HWA_DisableGlobalTimeBase(s_pFtuBasePtrs[eInstance]); } FTU_HWA_DisableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); /* set FTU prescale */ FTU_HWA_SetModulePrescale(s_pFtuBasePtrs[eInstance], pCommonStruct->ePrescaler); /* configure fault filter prescaler */ FTU_HWA_ConfigModuleFilterPrescale(s_pFtuBasePtrs[eInstance], pCommonStruct->eFliterPrescaler); /*set the compare register as max value*/ FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], (uint32_t)pCommonStruct->u32OverflowValue); /*set initial value as 0*/ FTU_HWA_SetCounterInitialValue(s_pFtuBasePtrs[eInstance], 0u); /*set any value to clear the current counter register to initial value*/ FTU_HWA_ClearModuleCounter(s_pFtuBasePtrs[eInstance], (uint32_t)0x1U); /* set ftu OUTMASK sync mode, set bit SYNCHOM and OUTMASK register will update when then sync event happened */ FTU_HWA_EnableOutputMaskBySync(s_pFtuBasePtrs[eInstance]); /* set ftu debug mode */ FTU_HWA_ConfigDebugMode(s_pFtuBasePtrs[eInstance], (uint32_t)pCommonStruct->eDbgMode); /* Disable channel match trigger/interrupt when count-up/down in CPWM/QUAD mode */ FTU_HWA_ConfigUpDownDisable(s_pFtuBasePtrs[eInstance], pCommonStruct->eUpDownDisable); /*configure the synchronization*/ disable_sync_flag(s_pFtuBasePtrs[eInstance], ~pCommonStruct->u16SyncFlag); enable_sync_flag(s_pFtuBasePtrs[eInstance], pCommonStruct->u16SyncFlag); /*configure the reload points*/ disable_reload_points(s_pFtuBasePtrs[eInstance], ~pCommonStruct->u16ReloadPoints); enable_reload_points(s_pFtuBasePtrs[eInstance], pCommonStruct->u16ReloadPoints); /* configure hardware trigger mode */ FTU_HWA_ConfigTrigMode(s_pFtuBasePtrs[eInstance], pCommonStruct->eHwTrigMode); /* configure the frequency of the reload opportunities*/ FTU_HWA_ConfigFreqOfReloadOp(s_pFtuBasePtrs[eInstance], pCommonStruct->u8ReloadFreq); /* select clock source */ if (FTU_INTERNAL_CLK == pCommonStruct->eClkSrc) { s_eFtuClkSrc[eInstance] = FTU_INTERNAL_CLK; } else if (FTU_EXTERNAL_CLK0 == pCommonStruct->eClkSrc) { s_eFtuClkSrc[eInstance] = FTU_EXTERNAL_CLK0; FTU_HWA_ConfigExternalClkSrc(s_pFtuBasePtrs[eInstance], FTU_TCLK0_USED); } else if (FTU_EXTERNAL_CLK1 == pCommonStruct->eClkSrc) { s_eFtuClkSrc[eInstance] = FTU_EXTERNAL_CLK1; FTU_HWA_ConfigExternalClkSrc(s_pFtuBasePtrs[eInstance], FTU_TCLK1_USED); } else if (FTU_EXTERNAL_CLK2 == pCommonStruct->eClkSrc) { s_eFtuClkSrc[eInstance] = FTU_EXTERNAL_CLK2; FTU_HWA_ConfigExternalClkSrc(s_pFtuBasePtrs[eInstance], FTU_TCLK2_USED); } else { s_eFtuClkSrc[eInstance] = FTU_NO_CLK; } } return eRet; } /** * @brief De-initialize the FTU instance * * @param eInstance the selected FTU instance * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_DeInit(const FTU_InstanceType eInstance) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { s_eFtuClkSrc[eInstance] = FTU_NO_CLK; s_pChannelCallback[eInstance] = NULL; s_pFaultCallback[eInstance] = NULL; s_pOverflowCallback[eInstance] = NULL; s_pReloadPointCallback[eInstance] = NULL; FTU_HWA_ClearModuleRegister(s_pFtuBasePtrs[eInstance]); } return eStatus; } /** * @brief Fills in the FTU configuration structure with the default settings. * * @param pCommonStruct Pointer to the user configuration structure */ void FTU_GetDefaultInitCfg(FTU_CommonType *pCommonStruct) { DEV_ASSERT(NULL_PTR != pCommonStruct); pCommonStruct->ePrescaler = FTU_DIV_1; pCommonStruct->eFliterPrescaler = FTU_FLT_DIV_1; pCommonStruct->u32OverflowValue = 0xFFFF; pCommonStruct->eClkSrc = FTU_INTERNAL_CLK; pCommonStruct->u16ReloadPoints = (uint16_t)FTU_RELOAD_POINT_CNTMAX; pCommonStruct->u8ReloadFreq = 0; pCommonStruct->u16SyncFlag = 0; pCommonStruct->eHwTrigMode = FTU_CLEARS_TRIG_WHEN_DETECTED; pCommonStruct->eDbgMode = FTU_DBG_COUNTER_WORKS_CHN_WORKS; pCommonStruct->eUpDownDisable = FTU_DISABLE_TRIG_INTR_NONE; pCommonStruct->bGtbEnable = false; } /** * @brief Configure FTU to counter mode * * @param eInstance the selected FTU instance * @param pCounterStruct the configurations of the counter mode * @return FTU_StatusType whether the operation is successfully * @note This function will stop timer */ FTU_StatusType FTU_CounterModeInit(const FTU_InstanceType eInstance, const FTU_CounterModeType *const pCounterStruct) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else if ( (pCounterStruct->u32CounterValue > s_aFtuMaxCounter[(uint32_t)eInstance]) || (pCounterStruct->u32InitialValue > s_aFtuMaxCounter[(uint32_t)eInstance])) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* disable ftu timer */ FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_NO_CLK); /* set FTU MOD register value */ FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], (uint32_t)pCounterStruct->u32CounterValue); /*set initial value */ FTU_HWA_SetCounterInitialValue(s_pFtuBasePtrs[eInstance], (uint32_t)pCounterStruct->u32InitialValue); } return eStatus; } /** * @brief Update the duty cycle of the FTU instance * * @param eInstance the selected FTU instance * @param u8Channel the selected FTU channel * @param u32Duty duty cycle of the PWM mode * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_PwmUpdateDuty(const FTU_InstanceType eInstance, uint8_t u8Channel, uint32_t u32Duty) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; uint8_t u8CpwmFlag; if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || (u32Duty > s_aFtuMaxCounter[(uint32_t)eInstance])) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* get the cpwm flag*/ u8CpwmFlag = FTU_HWA_GetModuleCpwmMode(s_pFtuBasePtrs[eInstance]); if(0u != u8CpwmFlag) { /* Duty value div 2 if cpwm mode*/ FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, (uint32_t)u32Duty >> 1u); } else { FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, u32Duty); } } return eStatus; } static void set_deadtime(FTU_Type *pFtu, uint8_t u8Channel, uint32_t u32Deadtime, bool bPair) { /* enable channel deadtime, channel 0/1 2/3 4/5 6/7 are combined*/ FTU_HWA_EnableChannelDeadtime(pFtu, u8Channel); if(u32Deadtime < 1024u) { if(bPair) { /* PAIRDEADTIME has a high priority*/ FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, FTU_DEADTIME_PRESCALER_DIV_1); FTU_HWA_ConfigPairDeadtimeValue(pFtu, u8Channel, u32Deadtime); } else { /* DEADTIME shoud recover PAIRDEADTIME*/ FTU_HWA_ConfigDeadtimePrescaler(pFtu, FTU_DEADTIME_PRESCALER_DIV_1); FTU_HWA_ConfigDeadtimeValue(pFtu, u32Deadtime); } } else if(u32Deadtime < 4096u) { /*deadtime should multiply 2*/ if(bPair) { /* PAIRDEADTIME has a high priority*/ FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, FTU_DEADTIME_PRESCALER_DIV_4); FTU_HWA_ConfigPairDeadtimeValue(pFtu, (uint32_t)u8Channel, u32Deadtime >> 2u); } else { /* DEADTIME shoud recover PAIRDEADTIME*/ FTU_HWA_ConfigDeadtimePrescaler(pFtu, FTU_DEADTIME_PRESCALER_DIV_4); FTU_HWA_ConfigDeadtimeValue(pFtu, u32Deadtime >> 2u); } } else { /*deadtime should multiply 4*/ if(bPair) { /* PAIRDEADTIME has a high priority*/ FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, FTU_DEADTIME_PRESCALER_DIV_16); FTU_HWA_ConfigPairDeadtimeValue(pFtu, u8Channel, u32Deadtime >> 4u); } else { /* DEADTIME shoud recover PAIRDEADTIME*/ FTU_HWA_ConfigDeadtimePrescaler(pFtu, FTU_DEADTIME_PRESCALER_DIV_16); FTU_HWA_ConfigDeadtimeValue(pFtu, u32Deadtime >> 4u); } } } /** * @brief Configure FTU to PWM mode * * @param eInstance the selected FTU instance * @param pPwmModeStruct the configurations of the PWM mode * @return FTU_StatusType whether the operation is successfully * @note This function will stop timer */ FTU_StatusType FTU_PwmModeInit(const FTU_InstanceType eInstance, const FTU_PwmModeType *const pPwmModeStruct) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; uint8_t u8Channel; uint32_t u32Loop; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else if (pPwmModeStruct->u32PwmPeriod > s_aFtuMaxCounter[(uint32_t)eInstance]) { eStatus = FTU_STATUS_PARAM_INVALID; } for (u32Loop = 0u; u32Loop < pPwmModeStruct->u32ChannelCount; u32Loop++) { if (pPwmModeStruct->pPwmChannels[u32Loop].u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; break; } if ( (pPwmModeStruct->pPwmChannels[u32Loop].u32PwmDuty > s_aFtuMaxCounter[(uint32_t)eInstance]) || (pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift > s_aFtuMaxCounter[(uint32_t)eInstance])) { eStatus = FTU_STATUS_PARAM_INVALID; break; } if ( (FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) && (0u < pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift)) { eStatus = FTU_STATUS_PARAM_INVALID; break; } if ( (true == pPwmModeStruct->pPwmChannels[u32Loop].bLinkMode) && (0u < pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift)) { eStatus = FTU_STATUS_PARAM_INVALID; break; } if (( (true == pPwmModeStruct->pPwmChannels[u32Loop].bLinkMode) || (0u < pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift)) && (pPwmModeStruct->pPwmChannels[u32Loop].u8Channel & 1u)) { eStatus = FTU_STATUS_PARAM_INVALID; break; } } if (FTU_STATUS_SUCCESS == eStatus) { /* disable ftu timer */ FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_NO_CLK); if (FTU_EDGE_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) { FTU_HWA_DisableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], pPwmModeStruct->u32PwmPeriod); } else { FTU_HWA_EnableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], pPwmModeStruct->u32PwmPeriod >> 1u); } set_deadtime(s_pFtuBasePtrs[eInstance], 0u, pPwmModeStruct->u32PublicDeadtime, false); for (u32Loop = 0u; u32Loop < pPwmModeStruct->u32ChannelCount; u32Loop++) { FTU_PwmChannelType *pChannelCfg = &pPwmModeStruct->pPwmChannels[u32Loop]; u8Channel = pChannelCfg->u8Channel; if(pChannelCfg->bLinkMode) { /* set channel(n+1) complement of channel(n) output */ FTU_HWA_EnableChannelComplement(s_pFtuBasePtrs[eInstance], u8Channel); if (!pChannelCfg->bLinkChannelComplement) { FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << u8Channel); FTU_HWA_SetChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << (u8Channel + (uint8_t)1U)); } else { FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << u8Channel| (uint8_t)1U << (u8Channel + 1u)); } /*link mode, the u8Channel+1->csc.ELSB bit must be set*/ FTU_HWA_ConfigChannelPwmLinkMode(s_pFtuBasePtrs[eInstance], u8Channel + (uint8_t)1U); /* enable u8Channel sync function of the ftu*/ FTU_HWA_EnableChannelSync(s_pFtuBasePtrs[eInstance], u8Channel); /* configure pin output as channel mode*/ FTU_HWA_ConfigTrigOutputMode(s_pFtuBasePtrs[eInstance], u8Channel, FTU_TRIG_OUTPUT_AS_CHANNEL_MODE); FTU_HWA_ConfigTrigOutputMode(s_pFtuBasePtrs[eInstance], u8Channel + 1u, FTU_TRIG_OUTPUT_AS_CHANNEL_MODE); /* enable FTU output */ FTU_HWA_EnableChannelsOutput(s_pFtuBasePtrs[eInstance], (uint8_t)3U << u8Channel); } else { if (pChannelCfg->u32PhaseShift) { FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << (u8Channel + 1)); /* enable u8Channel sync function of the ftu*/ FTU_HWA_EnableChannelSync(s_pFtuBasePtrs[eInstance], u8Channel); /*Enable enhanced phase shift mode*/ FTU_HWA_EnableChannelPhase(s_pFtuBasePtrs[eInstance], u8Channel); FTU_HWA_EnableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], u8Channel); } else { /* enable u8Channel sync function of the ftu*/ FTU_HWA_DisableChannelSync(s_pFtuBasePtrs[eInstance], u8Channel); /*Enable enhanced phase shift mode*/ FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], u8Channel); FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], u8Channel); } /* disable channel(n+1) complement of channel(n) output */ FTU_HWA_DisableChannelComplement(s_pFtuBasePtrs[eInstance], u8Channel); FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << u8Channel); /* enable FTU output */ FTU_HWA_EnableChannelsOutput(s_pFtuBasePtrs[eInstance], (uint8_t)1U << u8Channel); /* configure pin output as channel mode*/ FTU_HWA_ConfigTrigOutputMode(s_pFtuBasePtrs[eInstance], u8Channel, FTU_TRIG_OUTPUT_AS_CHANNEL_MODE); } /* set FTU pwm mode */ if ( (FTU_PWM_HIGH_TRUE_PULSE == pChannelCfg->ePinMode) && (FTU_EDGE_ALIGNED_PWM == pPwmModeStruct->eAlignedMode)) { FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_MODE_EDGE_ALIGN_PWM); FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_PWM_HIGH_TRUE); } else if ( (FTU_PWM_LOW_TRUE_PULSE == pChannelCfg->ePinMode) && (FTU_EDGE_ALIGNED_PWM == pPwmModeStruct->eAlignedMode)) { FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_MODE_EDGE_ALIGN_PWM); FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_PWM_LOW_TRUE); } else if ( (FTU_PWM_HIGH_TRUE_PULSE == pChannelCfg->ePinMode) && (FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode)) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_PWM_HIGH_TRUE); } else if ( (FTU_PWM_LOW_TRUE_PULSE == pChannelCfg->ePinMode) && (FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode)) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], u8Channel, FTU_CHANNEL_PWM_LOW_TRUE); } if (pChannelCfg->bDeadtimeEnable) { FTU_HWA_EnableChannelDeadtime(s_pFtuBasePtrs[eInstance], u8Channel); } else { FTU_HWA_DisableChannelDeadtime(s_pFtuBasePtrs[eInstance], u8Channel); } /* set the period time and duty time */ if(FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) { FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, pChannelCfg->u32PwmDuty >> 1u); } else { if (pChannelCfg->u32PhaseShift) { FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, pChannelCfg->u32PhaseShift); if ((pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty) > pPwmModeStruct->u32PwmPeriod) { FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1, pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty - pPwmModeStruct->u32PwmPeriod - 1); } else { FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1, pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty); } } else { FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel, pChannelCfg->u32PwmDuty); } } set_deadtime(s_pFtuBasePtrs[eInstance], u8Channel, pChannelCfg->u32ChannelDeadtime, true); } } return eStatus; } /** * @brief Configure FTU to output compare mode * * @param eInstance the selected FTU instance * @param pOutputModeStruct the configurations of the output compare mode * @return FTU_StatusType whether the operation is successfully * @note This function will stop timer */ FTU_StatusType FTU_OutputCompareModeInit(const FTU_InstanceType eInstance, const FTU_OutputCompareModeType *const pOCConfig) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (pOCConfig->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT)) { eStatus = FTU_STATUS_PARAM_INVALID; } else if ( pOCConfig->u32CompareValue > s_aFtuMaxCounter[(uint32_t)eInstance]) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* disable ftu timer */ FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_NO_CLK); FTU_HWA_DisableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel); FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_MEASURE_MODE_OFF); FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_CHANNEL_MODE_OUTPUT_COMPARE); if (FTU_OUTPUT_TOGGLE_PIN == pOCConfig->eOutputMode) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_CHANNEL_OC_TOGGLE); } else if (FTU_OUTPUT_CLEAR_PIN == pOCConfig->eOutputMode) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_CHANNEL_OC_CLEAR); } else if (FTU_OUTPUT_SET_PIN == pOCConfig->eOutputMode) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_CHANNEL_OC_SET); } /* Disable Up-Down Mode*/ FTU_HWA_DisableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); /* enable FTU output */ FTU_HWA_EnableChannelsOutput(s_pFtuBasePtrs[eInstance], (uint8_t)1U << pOCConfig->u8Channel); /* configure initial level */ if (FTU_OUTPUT_CMP_INIT_LOW == pOCConfig->eInitLevel) { FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << pOCConfig->u8Channel); } else { FTU_HWA_SetChannelPolarity(s_pFtuBasePtrs[eInstance], (uint8_t)1U << pOCConfig->u8Channel); } /* configure pin output as channel mode*/ FTU_HWA_ConfigTrigOutputMode(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, FTU_TRIG_OUTPUT_AS_CHANNEL_MODE); /* set FTU CV register value*/ FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], pOCConfig->u8Channel, (uint32_t)pOCConfig->u32CompareValue); } return eStatus; } /** * @brief Enable the output trigger of the selected FTU instance * * @param eInstance the selected FTU instance * @param u32TriggerOutputMask the output trigger mask * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_EnableTriggerOutput(const FTU_InstanceType eInstance, uint32_t u32TriggerOutputMask) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* enable the channel match trigger */ FTU_HWA_EnableChannelTriggerOut(s_pFtuBasePtrs[eInstance], (uint8_t)(u32TriggerOutputMask & (uint32_t)FTU_TRIG_OUTPUT_MASK_ALL_CHANNEL_MATCH)); if (0u != (u32TriggerOutputMask & (uint32_t)FTU_TRIG_OUTPUT_MASK_RELOAD)) { /* enable reload trigger */ FTU_HWA_EnableReloadTrigger(s_pFtuBasePtrs[eInstance]); } } return eStatus; } /** * @brief Disable the output trigger of the selected FTU instance * * @param eInstance the selected FTU instance * @param u32TriggerOutputMask the output trigger mask * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_DisableTriggerOutput(const FTU_InstanceType eInstance, uint32_t u32TriggerOutputMask) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* disenable the channel match trigger */ FTU_HWA_DisableChannelTriggerOut(s_pFtuBasePtrs[eInstance], (uint8_t)(u32TriggerOutputMask & (uint32_t)FTU_TRIG_OUTPUT_MASK_ALL_CHANNEL_MATCH)); if (0u != (u32TriggerOutputMask & (uint32_t)FTU_TRIG_OUTPUT_MASK_RELOAD)) { /* disable reload trigger */ FTU_HWA_DisableReloadTrigger(s_pFtuBasePtrs[eInstance]); } } return eStatus; } /** * @brief Start the FTU instance * * @param eInstance the selected FTU instance * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_StartTimer(const FTU_InstanceType eInstance) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* set FTU module clock source */ if (s_eFtuClkSrc[eInstance] == FTU_NO_CLK) { eStatus = FTU_STATUS_NO_CLOCK_SOURCE; } else if(s_eFtuClkSrc[eInstance] == FTU_INTERNAL_CLK) { FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_INTERNAL_CLK); } else { FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_EXTERNAL_CLK); } } return eStatus; } /** * @brief Stop the FTU global time base * * @param u32InstanceMask The selected FTU, each bit represents an instance */ void FTU_StopGlobalTimeBase(uint32_t u32InstanceMask) { uint32_t u32GTB = 0u, u32Loop0; for (u32Loop0 = 0u; u32Loop0 < FTU_INSTANCE_COUNT; u32Loop0++) { uint32_t u32InstanceFlag = 1u << u32Loop0; if (0u != (u32InstanceMask & u32InstanceFlag)) { u32GTB |= u32InstanceFlag; SCM_HWA_ClearFtuGTBMask((uint8_t)u32Loop0); } } SCM_HWA_ClearFtuGTBSelect(u32GTB); } /** * @brief Start the FTU global time base * * @param u32InstanceMask The selected FTU, each bit represents an instance * @param u32StartMask Start time, refer to FTU_GlobalTimeBaseStartType */ void FTU_StartGlobalTimeBase(uint32_t u32InstanceMask, uint32_t u32StartMask) { uint32_t u32GTB = 0u, u32Loop0, u32Loop1; for (u32Loop0 = 0u; u32Loop0 < FTU_INSTANCE_COUNT; u32Loop0++) { uint32_t u32InstanceFlag = 1u << u32Loop0; if (0u != (u32InstanceMask & u32InstanceFlag)) { if (u32StartMask & FTU_GTB_START_AT_ONCE) { u32GTB |= u32InstanceFlag; } for (u32Loop1 = 0u; u32Loop1 < TSTMP_MODULATE_COUNT; u32Loop1++) { if (u32StartMask & (FTU_GTB_START_AT_TSTMP1_MOD0 << u32Loop1)) { SCM_HWA_ConfigFtuGTBMask((uint8_t)u32Loop0, (1u << u32Loop1)); } } } } SCM_HWA_SetFtuGTBSelect(u32GTB); } /** * @brief Stop the FTU instance * * @param eInstance the selected FTU instance * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_StopTimer(const FTU_InstanceType eInstance) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* clear FTU module clock source */ FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[eInstance], FTU_MODULE_NO_CLK); //FTU_HWA_ClearModuleCounter(s_pFtuBasePtrs[eInstance], 0); } return eStatus; } /** * @brief Ftu initialize interrupt function * * @param eInstance the selected FTU instance * @param pIntStruct the configurations of the interrupt * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_InterruptInit(const FTU_InstanceType eInstance, const FTU_InterruptType *const pIntrStruct) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; uint32_t u32Loop; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if (0u != (pIntrStruct->u32InterruptMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) { /* Enable Channel Interrupt */ FTU_HWA_EnableChannelInterrupt(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); } else { /* Disable Channel Interrupt */ FTU_HWA_DisableChannelInterrupt(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); } } if (0u != (pIntrStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) { /* Enable Overflow Interrupt */ FTU_HWA_EnableOverflowInterrupt(s_pFtuBasePtrs[eInstance]); } else { /* Disable Overflow Interrupt */ FTU_HWA_DisableOverflowInterrupt(s_pFtuBasePtrs[eInstance]); } if (0u != (pIntrStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) { /* Enable Fault Interrupt */ FTU_HWA_EnableModuleFaultInterrupt(s_pFtuBasePtrs[eInstance]); } else { /* Disable Fault Interrupt */ FTU_HWA_DisableModuleFaultInterrupt(s_pFtuBasePtrs[eInstance]); } if (0u != (pIntrStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) { /* Enable Reload Point Interrupt */ FTU_HWA_EnableReloadPointInterrupt(s_pFtuBasePtrs[eInstance]); } else { /* Disable Reload Point Interrupt */ FTU_HWA_DisableReloadPointInterrupt(s_pFtuBasePtrs[eInstance]); } /*register callback functions*/ s_pChannelCallback[eInstance] = pIntrStruct->pChannelCallback; s_pFaultCallback[eInstance] = pIntrStruct->pFaultCallback; s_pOverflowCallback[eInstance] = pIntrStruct->pOverflowCallback; s_pReloadPointCallback[eInstance] = pIntrStruct->pReloadPointCallback; } return eStatus; } /** * @brief initialize fault input of the selected Ftu instance * * @param eInstance the selected FTU instance * @param pFaultInit the fault configurations of the FTU instance * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_FaultInit(const FTU_InstanceType eInstance, const FTU_FaultInitType *const pFaultInit) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; uint32_t u32Loop, u32Temp; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* configure fault mode */ FTU_HWA_ConfigModuleFaultMode(s_pFtuBasePtrs[eInstance], pFaultInit->eFaultMode); /* Disable all fault inputs*/ u32Temp = FTU_HWA_GetFaultEnable(s_pFtuBasePtrs[eInstance]); FTU_HWA_DisableModuleFault(s_pFtuBasePtrs[eInstance], 0xFu); /* configure fault filter value */ FTU_HWA_SetModuleFaultFilterValue(s_pFtuBasePtrs[eInstance], pFaultInit->u8FilterValue); /* recover fault inputs*/ FTU_HWA_EnableModuleFault(s_pFtuBasePtrs[eInstance], (uint8_t)u32Temp); /* enables the fault control in channels */ for(u32Loop = 0u; u32Loop < FTU_FAULT_COUNT; u32Loop++) { if (0u != (pFaultInit->u8FaultChannelEnable & ((uint8_t)FTU_FAULT_FOR_CHANNEL01 << u32Loop))) { FTU_HWA_EnableChannelFault(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop << 1u); } else { FTU_HWA_DisableChannelFault(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop << 1u); } } /* set fault disable channel output delay value */ FTU_HWA_SetFaultDelay0(s_pFtuBasePtrs[eInstance], pFaultInit->u8FaultDisableDelay0); FTU_HWA_SetFaultDelay1(s_pFtuBasePtrs[eInstance], pFaultInit->u8FaultDisableDelay1); } return eStatus; } /** * @brief Select fault disable channel output delay value * * @param eInstance the selected FTU instance * @param u8Channel FTU channel number, range is 0-7. * @param eSelection Fault disable channel output delay value selection. * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_FaultSelectDelayValue(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_FaultDisableDelayType eDelaySelection) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else if (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_HWA_SelectFaultDelay(s_pFtuBasePtrs[eInstance], u8Channel, eDelaySelection); } return eStatus; } /** * @brief Enable a fault input * * @param eInstance the selected FTU instance * @param pFaultCtrl configurations of the fault input * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_FaultEnable(const FTU_InstanceType eInstance, const FTU_FaultControlType *const pFaultCtrl) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (pFaultCtrl->u8FaultIndex >= FTU_FAULT_COUNT)) { eStatus = FTU_STATUS_PARAM_INVALID; } else { /* configure fault input polarity */ FTU_HWA_ConfigFaultPolarity(s_pFtuBasePtrs[eInstance], pFaultCtrl->u8FaultIndex, (uint8_t)pFaultCtrl->eFaultPol); if(true == pFaultCtrl->bFaultFilterEnable) { FTU_HWA_EnableModuleFaultGlitchFilter(s_pFtuBasePtrs[eInstance], 1u << pFaultCtrl->u8FaultIndex); } else { FTU_HWA_DisableModuleFaultGlitchFilter(s_pFtuBasePtrs[eInstance], 1u << pFaultCtrl->u8FaultIndex); } /* enable fault input */ FTU_HWA_EnableModuleFault(s_pFtuBasePtrs[eInstance], 1u << pFaultCtrl->u8FaultIndex); } return eStatus; } /** * @brief Disable a fault input * * @param eInstance the selected FTU instance * @param u32FaultIndex index of the fault input * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_FaultDisable(const FTU_InstanceType eInstance, uint32_t u32FaultIndex) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (u32FaultIndex >= FTU_FAULT_COUNT)) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_HWA_DisableModuleFault(s_pFtuBasePtrs[eInstance], 0x1u << u32FaultIndex); } return eStatus; } /** * @brief initialize a input capture channel of the selected Ftu instance * * @param eInstance the selected FTU instance * @param pInputChannel configurations of the input capture channel * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_InputCaptureChannelInit(const FTU_InstanceType eInstance, const FTU_InputChannelType *const pInputChannel) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if (((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (pInputChannel->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT)) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_HWA_DisableQuadratureMode(s_pFtuBasePtrs[eInstance]); FTU_HWA_DisableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel); FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel, FTU_MEASURE_MODE_OFF); FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel, FTU_CHANNEL_MODE_INPUT); if(pInputChannel->u8Channel < FTU_INPUT_FILTER_COUNT) { /* set FTU input capture filter value */ FTU_HWA_ConfigInputCaptureFilter( s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel, pInputChannel->u8FilterValue); } set_ftu_input_edge(s_pFtuBasePtrs[eInstance], pInputChannel->u8Channel, pInputChannel->eInputMode); } return eStatus; } /** * @brief initialize the quadrature decoder mode * * @param eInstance the selected FTU instance * @param pQuadInit configurations of the quadrature decoder * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_QuadratureModeInit(const FTU_InstanceType eInstance, const FTU_QuadratureInitType *const pQuadInit) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if (((uint32_t)eInstance != FTU_INSTANCE_1) && ((uint32_t)eInstance != FTU_INSTANCE_2) && ((uint32_t)eInstance != FTU_INSTANCE_4) && ((uint32_t)eInstance != FTU_INSTANCE_5)) { /* Only FTU1/2/4/5 support quadrature decode*/ eStatus = FTU_STATUS_PARAM_INVALID; } else { /* set quadrature mode */ FTU_HWA_ConfigQuadratureMode(s_pFtuBasePtrs[eInstance], pQuadInit->eQuadMode); /* set PHA polarity*/ if(pQuadInit->bPhaInverted) { FTU_HWA_EnablePhaInv(s_pFtuBasePtrs[eInstance]); } else { FTU_HWA_DisablePhaInv(s_pFtuBasePtrs[eInstance]); } /* set PHB polarity*/ if(pQuadInit->bPhbInverted) { FTU_HWA_EnablePhbInv(s_pFtuBasePtrs[eInstance]); } else { FTU_HWA_DisablePhbInv(s_pFtuBasePtrs[eInstance]); } /* Set counter direction */ FTU_HWA_ConfigQuadDirection(s_pFtuBasePtrs[eInstance], pQuadInit->eQuadDirection); /* Set overflow direction */ FTU_HWA_ConfigTimerOverflowDir(s_pFtuBasePtrs[eInstance], pQuadInit->eOveflowDirection); /* set top value */ FTU_HWA_SetModuleCompareValue(s_pFtuBasePtrs[eInstance], pQuadInit->u16TopValue); /* set bottom value */ FTU_HWA_SetCounterInitialValue(s_pFtuBasePtrs[eInstance], pQuadInit->u16BottomValue); /* Set phase A glitch filter value */ if (0U != pQuadInit->u8PhaFilterVal) { FTU_HWA_ConfigChannelFilterValue(s_pFtuBasePtrs[eInstance], 0, pQuadInit->u8PhaFilterVal); FTU_HWA_EnablePhaGlitchFilter(s_pFtuBasePtrs[eInstance]); } else { FTU_HWA_DisablePhaGlitchFilter(s_pFtuBasePtrs[eInstance]); } /* Set phase B glitch filter value */ if (0U != pQuadInit->u8PhbFilterVal) { FTU_HWA_ConfigChannelFilterValue(s_pFtuBasePtrs[eInstance], 1, pQuadInit->u8PhbFilterVal); FTU_HWA_EnablePhbGlitchFilter(s_pFtuBasePtrs[eInstance]); } else { FTU_HWA_DisablePhbGlitchFilter(s_pFtuBasePtrs[eInstance]); } /* enable the quadrature*/ FTU_HWA_EnableQuadratureMode(s_pFtuBasePtrs[eInstance]); } return eStatus; } /** * @brief Enable FTU interrupt * * @param eInstance the selected FTU instance * @param u32InterruptMask interrupt enable mask * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_EnableInterrupt(const FTU_InstanceType eInstance, uint32_t u32InterruptMask) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; uint32_t u32Loop; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if (0u != (u32InterruptMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) { /* Enable Channel Interrupt */ FTU_HWA_EnableChannelInterrupt(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); } } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) { /* Enable Overflow Interrupt */ FTU_HWA_EnableOverflowInterrupt(s_pFtuBasePtrs[eInstance]); } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) { /* Enable Fault Interrupt */ FTU_HWA_EnableModuleFaultInterrupt(s_pFtuBasePtrs[eInstance]); } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) { /* Enable Reload Point Interrupt */ FTU_HWA_EnableReloadPointInterrupt(s_pFtuBasePtrs[eInstance]); } } return eStatus; } /** * @brief Disable FTU interrupt * * @param eInstance the selected FTU instance * @param u32InterruptMask interrupt disable mask * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_DisableInterrupt(const FTU_InstanceType eInstance, uint32_t u32InterruptMask) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; uint32_t u32Loop; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { for(u32Loop = 0; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if (0u != (u32InterruptMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) { /* Disable Channel Interrupt */ FTU_HWA_DisableChannelInterrupt(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); } } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) { /* Disable Overflow Interrupt */ FTU_HWA_DisableOverflowInterrupt(s_pFtuBasePtrs[eInstance]); } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) { /* Disable Fault Interrupt */ FTU_HWA_DisableModuleFaultInterrupt(s_pFtuBasePtrs[eInstance]); } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) { /* Disable Reload Point Interrupt */ FTU_HWA_DisableReloadPointInterrupt(s_pFtuBasePtrs[eInstance]); } } return eStatus; } /** * @brief Clear the fault flag of the FTU instance * * @param eInstance the selected FTU instance * @param u32FaultFlag flag to clear * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_ClearFault(const FTU_InstanceType eInstance, uint32_t u32FaultFlag) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_HWA_ClearModuleFaultFlag(s_pFtuBasePtrs[eInstance], (uint8_t)u32FaultFlag); } return eStatus; } /** * @brief Get the fault flag of the FTU instance * * @param eInstance the selected FTU instance * @return uint32_t the fault flag of the selected Ftu instance */ uint32_t FTU_GetFaultFlag(const FTU_InstanceType eInstance) { uint32_t u32FaultFlag = 0; if ((uint32_t)eInstance < FTU_INSTANCE_COUNT) { u32FaultFlag = FTU_HWA_ReadModuleFaultFlag(s_pFtuBasePtrs[eInstance]); } return u32FaultFlag; } /** * @brief Enable ftu channel DMA * * @param eInstance the selected FTU instance * @param u32DmaMask The dma channel mask. * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_EnableChannelDma(const FTU_InstanceType eInstance, uint32_t u32DmaMask) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; uint32_t u32Loop; if ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) { eStatus = FTU_STATUS_PARAM_INVALID; } else { for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if (0u != (u32DmaMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) { /* Enable Channel Interrupt */ FTU_HWA_EnableChannelDma(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); } } } return eStatus; } /** * @brief Initialize a Expect Edge Number Measurement channel * * @param eInstance the selected FTU instance * @param pExpectEdgeNumMeasure measurement configuration. * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_ExpectEdgeNumberMeasureChannelInit(const FTU_InstanceType eInstance, FTU_ExpectEdgeNumberMeasureType *pExpectEdgeNumMeasure) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (pExpectEdgeNumMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || (pExpectEdgeNumMeasure->u8Channel & 1u)) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel, FTU_CHANNEL_MODE_INPUT); set_ftu_input_edge(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel, pExpectEdgeNumMeasure->eEdgeMode); FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_NOT_USED); FTU_HWA_ConfigEdgeNumber(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel + 1, pExpectEdgeNumMeasure->u8ExpectEdgeNumber); if (FTU_MEASURE_CONTINUOUS_MODE == pExpectEdgeNumMeasure->eContinuouslyMode) { FTU_HWA_EnableMeasureContinous(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel); } else { FTU_HWA_DisableMeasureContinous(s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel); } /* Must put the ICM_MODE setting at the end, otherwise it will not be configured correctly. */ FTU_HWA_ConfigInputCaptureMeasureMode( s_pFtuBasePtrs[eInstance], pExpectEdgeNumMeasure->u8Channel, FTU_MEASURE_EXPECT_EDGE_NUMBER); } return eStatus; } /** * @brief Initialize a Edge Number Measurement channel * * @param eInstance the selected FTU instance * @param pEdgeNumMeasure measurement configuration. * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_EdgeNumberMeasureChannelInit(const FTU_InstanceType eInstance, FTU_EdgeNumberMeasureType *pEdgeNumMeasure) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (pEdgeNumMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || (pEdgeNumMeasure->u8Channel & 1u) || (pEdgeNumMeasure->u32StartWindow >= pEdgeNumMeasure->u32EndWindow) || (pEdgeNumMeasure->u32StartWindow > s_aFtuMaxCounter[eInstance])) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, FTU_CHANNEL_MODE_INPUT); set_ftu_input_edge(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, pEdgeNumMeasure->eEdgeMode); FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_NOT_USED); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, FTU_MEASURE_ICENM_WIND_WRITE); FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, pEdgeNumMeasure->u32StartWindow); FTU_HWA_SetChannelValue(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel + 1u, pEdgeNumMeasure->u32EndWindow); FTU_HWA_ConfigInputCaptureMeasureMode( s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel, FTU_MEASURE_EDGE_NUMBER); if (FTU_MEASURE_CONTINUOUS_MODE == pEdgeNumMeasure->eContinuouslyMode) { FTU_HWA_EnableMeasureContinous(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel); } else { FTU_HWA_DisableMeasureContinous(s_pFtuBasePtrs[eInstance], pEdgeNumMeasure->u8Channel); } } return eStatus; } /** * @brief Get the expect edge number result of the channel * * @param eInstance the selected FTU instance * @param u8Channel FTU channel number, range is 0-7. * @param pResult point to the result buffer. * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_GetExpectEdgeNumberResult(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_ExpectEdgeNumberResultType *pResult) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || (u8Channel & 1u)) { eStatus = FTU_STATUS_PARAM_INVALID; } else { pResult->u32FirstEdgeTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel); pResult->u32LastEdgeTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1); } return eStatus; } /** * @brief Get Edge number counter * * @param eInstance the selected FTU instance * @param u8Channel FTU channel number. * @return uint8_t Edge number counter */ uint8_t FTU_GetEdgeNumberCount(const FTU_InstanceType eInstance, uint8_t u8Channel) { uint8_t u8Count = 0; if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || (u8Channel & 1u)) { } else { u8Count = FTU_HWA_GetEdgeNumberCount(s_pFtuBasePtrs[eInstance], u8Channel); } return u8Count; } /** * @brief Initialize a signal measure channel * * @param eInstance the selected FTU instance * @param pMeasure measurement configuration. * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_SignalMeasureChannelInit(const FTU_InstanceType eInstance, FTU_SignalMeasureType *pMeasure) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (pMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || (pMeasure->u8Channel & 1u)) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_OFF); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_MEASURE_MODE_OFF); FTU_HWA_DisableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); FTU_HWA_DisableChannelEnhancedPhase(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u); FTU_HWA_DisableChannelPhase(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u); FTU_HWA_DisableModuleCpwmMode(s_pFtuBasePtrs[eInstance]); FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_MODE_INPUT); FTU_HWA_ConfigChannelMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_MODE_INPUT); if (FTU_SIGNAL_MEASURE_HIGH_TIME == pMeasure->eMeasureMode) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_FALLING); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_DUTY_CYCLE); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1, FTU_MEASURE_MODE_DUTY_CYCLE); FTU_HWA_SetChannelPolarity(s_pFtuBasePtrs[eInstance], 1u << pMeasure->u8Channel); } else if (FTU_SIGNAL_MEASURE_LOW_TIME == pMeasure->eMeasureMode) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_FALLING); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_DUTY_CYCLE); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_MEASURE_MODE_DUTY_CYCLE); FTU_HWA_ClearChannelPolarity(s_pFtuBasePtrs[eInstance], 1u << pMeasure->u8Channel); } else if (FTU_SIGNAL_MEASURE_PERIOD_RISING_EDGE == pMeasure->eMeasureMode) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_NOT_USED); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_PERIOD); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_MEASURE_MODE_PERIOD); } else if (FTU_SIGNAL_MEASURE_PERIOD_FALLING_EDGE == pMeasure->eMeasureMode) { FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_CHANNEL_EDGE_FALLING); FTU_HWA_ConfigChannelEdgeLevel(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_CHANNEL_EDGE_NOT_USED); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel, FTU_MEASURE_MODE_PERIOD); FTU_HWA_ConfigInputCaptureMeasureMode(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel + 1u, FTU_MEASURE_MODE_PERIOD); } if (FTU_MEASURE_CONTINUOUS_MODE == pMeasure->eContinuouslyMode) { FTU_HWA_EnableMeasureContinous(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); } else { FTU_HWA_DisableMeasureContinous(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); } if (FTU_MEASURE_START_IMMEDIATELY == pMeasure->eStartMode) { FTU_HWA_EnableMeasureStartImmd(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); } else { FTU_HWA_DisableMeasureStartImmd(s_pFtuBasePtrs[eInstance], pMeasure->u8Channel); } } return eStatus; } /** * @brief Re-start measurement when in single mode * * @param eInstance the selected FTU instance * @param u8Channel FTU channel number, range is 0-7. * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_SignalMeasureChannelSingle(const FTU_InstanceType eInstance, uint8_t u8Channel) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || (u8Channel & 1u)) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_HWA_SingleMeasurement(s_pFtuBasePtrs[eInstance], u8Channel); } return eStatus; } /** * @brief Get the measurement result of the channel * * @param eInstance the selected FTU instance * @param u8Channel FTU channel number, range is 0-7. * @param pResult point to the result buffer. * @return FTU_StatusType whether the operation is successfully */ FTU_StatusType FTU_GetSignalMeasureResult(const FTU_InstanceType eInstance, uint8_t u8Channel, FTU_SignalMeasureValueType *pResult) { FTU_StatusType eStatus = FTU_STATUS_SUCCESS; if ( ((uint32_t)eInstance >= FTU_INSTANCE_COUNT) || (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) || (u8Channel & 1u)) { eStatus = FTU_STATUS_PARAM_INVALID; } else { FTU_MeasurementModeType eMeasureMode = FTU_HWA_GetMeasureMode(s_pFtuBasePtrs[eInstance], u8Channel); if (FTU_MEASURE_MODE_DUTY_CYCLE == eMeasureMode) { if (FTU_HWA_GetChannelPolarity(s_pFtuBasePtrs[eInstance], 1u << u8Channel)) { pResult->u32StartTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel); pResult->u32EndTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1); } else { pResult->u32StartTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1); pResult->u32EndTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel); } } else if(FTU_MEASURE_MODE_PERIOD == eMeasureMode) { pResult->u32StartTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel + 1); pResult->u32EndTime = FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], u8Channel); } else { pResult->u32StartTime = 0u; pResult->u32EndTime = 0u; } } return eStatus; } /** * @brief Interrupt IRQ handle of FTU instance * * @param eInstance the selected FTU instance */ void FTUn_IRQHandler(const FTU_InstanceType eInstance) { uint32_t u32FaultFlag = 0u; uint8_t u8FaultEnable = FTU_HWA_ReadFaultIntrEnable(s_pFtuBasePtrs[eInstance]); uint8_t u8OverflowFlag = FTU_HWA_ReadModuleOverflowFlag(s_pFtuBasePtrs[eInstance]); uint8_t u8ReloadFlag = FTU_HWA_ReadReloadIntrEnable(s_pFtuBasePtrs[eInstance]); uint32_t u32Loop, u32ChannelIntrFlag = 0; uint16_t u16TimeStamp; u8OverflowFlag = FTU_HWA_ReadModuleOverflowIntrEnable(s_pFtuBasePtrs[eInstance]) & u8OverflowFlag; u8ReloadFlag = FTU_HWA_ReadModuleReloadFlag(s_pFtuBasePtrs[eInstance]) & u8ReloadFlag; if(0u != u8FaultEnable) { u32FaultFlag = FTU_HWA_ReadModuleFaultFlag(s_pFtuBasePtrs[eInstance]); } /* Clear interrupt flag*/ if (0u != u8OverflowFlag) { FTU_HWA_ClearOverflowFlag(s_pFtuBasePtrs[eInstance]); } if (0u != u8ReloadFlag) { FTU_HWA_ClearReloadFlag(s_pFtuBasePtrs[eInstance]); } for (u32Loop = 0U; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if ((0u != FTU_HWA_ReadChannelInterruptFlag(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop)) && (0u != FTU_HWA_ReadChannelInterruptEnableFlag(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop))) { FTU_HWA_ClearChannelInterruptFlag(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); u32ChannelIntrFlag |= (uint8_t)(1u << u32Loop); } } /* call callback functions*/ if ((0u != u8OverflowFlag) && (NULL != s_pOverflowCallback[eInstance])) { s_pOverflowCallback[eInstance](); } if ((0u != u8ReloadFlag) && (NULL != s_pReloadPointCallback[eInstance])) { s_pReloadPointCallback[eInstance](); } if ((0u != u32FaultFlag) && (NULL != s_pFaultCallback[eInstance])) { for (u32Loop = 0U; u32Loop < FTU_FAULT_COUNT; u32Loop++) { if (0u != (u32FaultFlag & ((uint32_t)1u << u32Loop))) { s_pFaultCallback[eInstance](u32Loop); } } } if ((0u != u32ChannelIntrFlag) && (NULL != s_pChannelCallback[eInstance])) { for (u32Loop = 0U; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if (0u != (u32ChannelIntrFlag & ((uint32_t)1u << u32Loop))) { u16TimeStamp = (uint16_t)FTU_HWA_GetChannelValue(s_pFtuBasePtrs[eInstance], (uint8_t)u32Loop); s_pChannelCallback[eInstance](u32Loop, u16TimeStamp); } } } }