/** * @file module_driver_ftu.c * @author flagchip * @brief FTU 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 * --------- ---------- ------------ ---------- --------------- * 00.02.01 2022-02-21 Flagchip032 N/A FC7xxx internal release version * 01.00.00 2022-04-19 Flagchip032 N/A FC7300 release version * 01.00.00 2022-08-19 Flagchip070 N/A Support FC7300 2M and 1M * 01.01.00 2022-11-10 Flagchip070 N/A Release version 1.1.0 * 01.02.00 2022-11-10 Flagchip032 N/A Refactor ftu driver ********************************************************************************/ #include "module_driver_ftu.h" #if FTU_INSTANCE_COUNT > 0U #include "module_driver_pcc.h" #ifndef FTU_TCKSEL_EXIST #include "module_driver_smisc.h" #endif #ifndef FTU_DEV_ERROR_REPORT #define FTU_DEV_ERROR_REPORT STD_OFF #endif #if FTU_DEV_ERROR_REPORT == STD_ON #define FTU_ReportDevError(func, error) ReportDevError(FTU_MODULE_ID, func, error) #endif /********* Local variable ************/ static FTU_Type * const s_pFtuBasePtrs[FTU_INSTANCE_COUNT] = FTU_BASE_PTRS; /********* Local Functions ************/ /********* Global Functions ************/ /** * @brief Initialize FTU basic configuration * * @param pFtuHandle FTU processing handle * @param pCommonStruct the basic configurations of the FTU instance */ void FTU_CommonInit(FTU_HandleType *pFtuHandle, const FTU_CommonType *const pCommonStruct) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_COMMON_INIT_ID, FTU_E_PARAM_INSTANCE); } else if (pCommonStruct->u32OverflowValue > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_COMMON_INIT_ID, FTU_E_PARAM_COUNT); } #ifdef FTU_CNT_SEL_EXIST else if ( (pCommonStruct->eClkSrc == FTU_EFTU_CNT) && ( (pFtuHandle->eInstance != FTU_INSTANCE_1) && (pFtuHandle->eInstance != FTU_INSTANCE_2))) { FTU_ReportDevError(FTU_COMMON_INIT_ID, FTU_E_PARAM_INSTANCE); } #endif else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; uint32_t u32Loop; if (true == pCommonStruct->bGtbEnable) { FTU_HWA_EnableGlobalTimeBase(pFtu); } else { FTU_HWA_DisableGlobalTimeBase(pFtu); } FTU_HWA_DisableModuleCpwmMode(pFtu); /* set FTU prescale */ FTU_HWA_SetModulePrescale(pFtu, pCommonStruct->ePrescaler); /* configure fault filter prescaler */ FTU_HWA_ConfigModuleFilterPrescale(pFtu, pCommonStruct->eFliterPrescaler); /*set the compare register as max value*/ FTU_HWA_SetModuleCompareValue(pFtu, (uint32_t)pCommonStruct->u32OverflowValue); /*set initial value as 0*/ FTU_HWA_SetCounterInitialValue(pFtu, 0u); /*set any value to clear the current counter register to initial value*/ FTU_HWA_ClearModuleCounter(pFtu, (uint32_t)0x1U); /* set ftu OUTMASK sync mode, set bit SYNCHOM and OUTMASK register will update when then sync event happened */ FTU_HWA_EnableOutputMaskBySync(pFtu); /* set ftu debug mode */ FTU_HWA_ConfigDebugMode(pFtu, (uint32_t)pCommonStruct->eDbgMode); #ifdef FTU_UPDOWN_DIS_FEATURE /* Disable channel match trigger/interrupt when count-up/down in CPWM/QUAD mode */ FTU_HWA_ConfigUpDownDisable(s_pFtuBasePtrs[pFtuHandle->eInstance], pCommonStruct->eUpDownDisable); #endif /* configure hardware trigger mode */ FTU_HWA_ConfigTrigMode(pFtu, pCommonStruct->eHwTrigMode); /* configure the frequency of the reload opportunities*/ FTU_HWA_ConfigFreqOfReloadOp(pFtu, pCommonStruct->u8ReloadFreq); pFtuHandle->tStatus.pChannelCallback = NULL; pFtuHandle->tStatus.pFaultCallback = NULL; pFtuHandle->tStatus.pOverflowCallback = NULL; pFtuHandle->tStatus.pReloadPointCallback = NULL; /* select clock source */ if (FTU_INTERNAL_CLK == pCommonStruct->eClkSrc) { pFtuHandle->tStatus.eFtuClkSrc = FTU_INTERNAL_CLK; } else if (FTU_EXTERNAL_CLK0 == pCommonStruct->eClkSrc) { pFtuHandle->tStatus.eFtuClkSrc = FTU_EXTERNAL_CLK0; #ifdef FTU_TCKSEL_EXIST FTU_HWA_ConfigExternalClkSrc(pFtu, FTU_TCLK0_USED); #else SMISC_HWA_SetFtuExternalClkSrc(pFtuHandle->eInstance, FTU_TCLK0_USED); #endif } else if (FTU_EXTERNAL_CLK1 == pCommonStruct->eClkSrc) { pFtuHandle->tStatus.eFtuClkSrc = FTU_EXTERNAL_CLK1; #ifdef FTU_TCKSEL_EXIST FTU_HWA_ConfigExternalClkSrc(pFtu, FTU_TCLK1_USED); #else SMISC_HWA_SetFtuExternalClkSrc(pFtuHandle->eInstance, FTU_TCLK1_USED); #endif } else if (FTU_EXTERNAL_CLK2 == pCommonStruct->eClkSrc) { pFtuHandle->tStatus.eFtuClkSrc = FTU_EXTERNAL_CLK2; #ifdef FTU_TCKSEL_EXIST FTU_HWA_ConfigExternalClkSrc(pFtu, FTU_TCLK2_USED); #else SMISC_HWA_SetFtuExternalClkSrc(pFtuHandle->eInstance, FTU_TCLK2_USED); #endif } else { pFtuHandle->tStatus.eFtuClkSrc = pCommonStruct->eClkSrc; } for(u32Loop = 0u; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if (0u != (pCommonStruct->u32InterruptMask & ((uint32_t)FTU_INTR_MASK_CHANNEL_0 << u32Loop))) { /* Enable Channel Interrupt */ FTU_HWA_EnableChannelInterrupt(pFtu, (uint8_t)u32Loop); } else { /* Disable Channel Interrupt */ FTU_HWA_DisableChannelInterrupt(pFtu, (uint8_t)u32Loop); } } if (0u != (pCommonStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) { /* Enable Overflow Interrupt */ FTU_HWA_EnableOverflowInterrupt(pFtu); } else { /* Disable Overflow Interrupt */ FTU_HWA_DisableOverflowInterrupt(pFtu); } if (0u != (pCommonStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) { /* Enable Fault Interrupt */ FTU_HWA_EnableModuleFaultInterrupt(pFtu); } else { /* Disable Fault Interrupt */ FTU_HWA_DisableModuleFaultInterrupt(pFtu); } if (0u != (pCommonStruct->u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) { /* Enable Reload Point Interrupt */ FTU_HWA_EnableReloadPointInterrupt(pFtu); } else { /* Disable Reload Point Interrupt */ FTU_HWA_DisableReloadPointInterrupt(pFtu); } /*register callback functions*/ pFtuHandle->tStatus.pChannelCallback = pCommonStruct->pChannelCallback; pFtuHandle->tStatus.pFaultCallback = pCommonStruct->pFaultCallback; pFtuHandle->tStatus.pOverflowCallback = pCommonStruct->pOverflowCallback; pFtuHandle->tStatus.pReloadPointCallback = pCommonStruct->pReloadPointCallback; #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief De-initialize the FTU instance * * @param pFtuHandle FTU processing handle */ void FTU_DeInit(FTU_HandleType *pFtuHandle) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_DEINIT_ID, FTU_E_PARAM_INSTANCE); } else { #endif pFtuHandle->tStatus.eFtuClkSrc = FTU_NO_CLK; pFtuHandle->tStatus.pChannelCallback = NULL; pFtuHandle->tStatus.pFaultCallback = NULL; pFtuHandle->tStatus.pOverflowCallback = NULL; pFtuHandle->tStatus.pReloadPointCallback = NULL; FTU_HWA_ClearModuleRegister(s_pFtuBasePtrs[pFtuHandle->eInstance]); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @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) { #if FTU_DEV_ERROR_REPORT == STD_ON if(NULL_PTR == pCommonStruct) { FTU_ReportDevError(FTU_GET_DEFAULT_INIT_CFG_ID, FTU_E_PARAM_POINTER); } else { #endif pCommonStruct->ePrescaler = FTU_DIV_1; pCommonStruct->eFliterPrescaler = FTU_FLT_DIV_1; pCommonStruct->u32OverflowValue = 0xFFFF; pCommonStruct->eClkSrc = FTU_INTERNAL_CLK; pCommonStruct->u8ReloadFreq = 0; pCommonStruct->eHwTrigMode = FTU_CLEARS_TRIG_WHEN_DETECTED; pCommonStruct->eDbgMode = FTU_DBG_COUNTER_STOP_CHN_WORKS; #ifdef FTU_UPDOWN_DIS_FEATURE pCommonStruct->eUpDownDisable = FTU_DISABLE_TRIG_INTR_NONE; #endif pCommonStruct->bGtbEnable = false; pCommonStruct->u32InterruptMask = 0u; pCommonStruct->pChannelCallback = NULL; pCommonStruct->pFaultCallback = NULL; pCommonStruct->pOverflowCallback = NULL; pCommonStruct->pReloadPointCallback = NULL; #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Configure FTU to counter mode * * @param pFtuHandle FTU processing handle * @param pCounterStruct the configurations of the counter mode * @note This function will stop timer */ void FTU_CounterModeInit(FTU_HandleType *pFtuHandle, const FTU_CounterModeType *const pCounterStruct) { #if FTU_DEV_ERROR_REPORT == STD_ON if (((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT)) { FTU_ReportDevError(FTU_COUNTER_INIT_ID, FTU_E_PARAM_INSTANCE); } else if ( (pCounterStruct->u32CounterValue > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) || (pCounterStruct->u32InitialValue > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) ) { FTU_ReportDevError(FTU_COUNTER_INIT_ID, FTU_E_PARAM_COUNT); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* disable ftu timer */ FTU_HWA_ConfigModuleClkSrc(pFtu, FTU_MODULE_NO_CLK); /* set FTU MOD register value */ FTU_HWA_SetModuleCompareValue(pFtu, (uint32_t)pCounterStruct->u32CounterValue); /*set initial value */ FTU_HWA_SetCounterInitialValue(pFtu, (uint32_t)pCounterStruct->u32InitialValue); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Update the duty cycle of the FTU Channel * * @param pFtuHandle FTU processing handle * @param pConfig The configuration option for update PWM Duty */ void FTU_PwmUpdateDuty(FTU_HandleType *pFtuHandle, FTU_PwmDutyUpdateType *pConfig) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_PWM_UPDATE_DUTY_ID, FTU_E_PARAM_INSTANCE); } else if (pConfig->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_PWM_UPDATE_DUTY_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* get the cpwm flag*/ if(pFtuHandle->tStatus.aPwmAlignedMode == FTU_CENTER_ALIGNED_PWM) { /* Duty value div 2 if cpwm mode*/ FTU_HWA_SetChannelValue(pFtu, pConfig->u8Channel, (uint32_t)pConfig->u32Duty >> 1u); } else { if (pFtuHandle->tStatus.u8PhaseShiftEnable & (1u << pConfig->u8Channel)) { #if FTU_DEV_ERROR_REPORT == STD_ON if (pConfig->u32PhaseShift > pFtuHandle->tStatus.u32PwmPeriod) { FTU_ReportDevError(FTU_PWM_UPDATE_DUTY_ID, FTU_E_PARAM_PHASE_SHIFT); } else { #endif FTU_HWA_SetChannelValue(pFtu, pConfig->u8Channel, pConfig->u32PhaseShift); if ((pConfig->u32PhaseShift + pConfig->u32Duty) > pFtuHandle->tStatus.u32PwmPeriod) { FTU_HWA_SetChannelValue(pFtu, (uint8_t)(pConfig->u8Channel + 1u), pConfig->u32PhaseShift + pConfig->u32Duty - pFtuHandle->tStatus.u32PwmPeriod - 1); } else { FTU_HWA_SetChannelValue(pFtu, (uint8_t)(pConfig->u8Channel + 1), pConfig->u32PhaseShift + pConfig->u32Duty); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } else { FTU_HWA_SetChannelValue(pFtu, pConfig->u8Channel, pConfig->u32Duty); } } if (pFtuHandle->tStatus.aPwmUpdateMode != FTU_PWM_UPDATE_IMMEDIATELY) { if (true == pConfig->bUpdate) { FTU_HWA_GenerateSwSync(pFtu); } } else { FTU_HWA_GenerateSwSync(pFtu); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Update the Period cycle of the FTU instance * * @param pFtuHandle FTU processing handle * @param u32Period period of the PWM mode */ void FTU_PwmUpdatePeriod(FTU_HandleType *pFtuHandle, uint32_t u32Period, bool bUpdate) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_PWM_UPDATE_PERIOD_ID, FTU_E_PARAM_INSTANCE); } else if (u32Period > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_PWM_UPDATE_PERIOD_ID, FTU_E_PARAM_COUNT); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* get the cpwm flag*/ if(pFtuHandle->tStatus.aPwmAlignedMode == FTU_CENTER_ALIGNED_PWM) { /* Period value div 2 if cpwm mode*/ FTU_HWA_SetModuleCompareValue(pFtu, u32Period >> 1); } else { FTU_HWA_SetModuleCompareValue(pFtu, u32Period); } if (pFtuHandle->tStatus.aPwmUpdateMode != FTU_PWM_UPDATE_IMMEDIATELY) { if (true == bUpdate) { FTU_HWA_GenerateSwSync(pFtu); } } else { FTU_HWA_GenerateSwSync(pFtu); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Synchronous update cycle and period of the FTU instance * * @param pFtuHandle FTU processing handle */ void FTU_PwmSyncUpdate(FTU_HandleType *pFtuHandle) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_PWM_SYNC_UPDATE_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_HWA_GenerateSwSync(s_pFtuBasePtrs[pFtuHandle->eInstance]); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } static void set_deadtime(FTU_Type *pFtu, uint8_t u8Channel, uint32_t u32Deadtime) { if(u32Deadtime < 1024u) { FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, FTU_DEADTIME_PRESCALER_DIV_1); FTU_HWA_ConfigPairDeadtimeValue(pFtu, u8Channel, u32Deadtime); } else if(u32Deadtime < 4096u) { /*deadtime should multiply 2*/ FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, FTU_DEADTIME_PRESCALER_DIV_4); FTU_HWA_ConfigPairDeadtimeValue(pFtu, (uint32_t)u8Channel, u32Deadtime >> 2u); } else { /*deadtime should multiply 4*/ FTU_HWA_ConfigPairDeadtimePrescaler(pFtu, u8Channel, FTU_DEADTIME_PRESCALER_DIV_16); FTU_HWA_ConfigPairDeadtimeValue(pFtu, u8Channel, u32Deadtime >> 4u); } } /** * @brief Configure FTU to PWM mode * * @param pFtuHandle FTU processing handle * @param pPwmModeStruct the configurations of the PWM mode * @note This function will stop timer */ void FTU_PwmModeInit(FTU_HandleType *pFtuHandle, const FTU_PwmModeType *const pPwmModeStruct) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_INSTANCE); } else if (pPwmModeStruct->u32PwmPeriod > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_COUNT); } else { #endif uint8_t u8Channel; uint32_t u32Loop; FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; pFtuHandle->tStatus.u32PwmPeriod = pPwmModeStruct->u32PwmPeriod; pFtuHandle->tStatus.u8PhaseShiftEnable = 0u; pFtuHandle->tStatus.aPwmAlignedMode = pPwmModeStruct->eAlignedMode; pFtuHandle->tStatus.aPwmUpdateMode = pPwmModeStruct->eUpdateMode; FTU_HWA_SetModuleUpdateRegBySync(pFtu); FTU_HWA_ClearPwmSyncMode(pFtu); if (pPwmModeStruct->eUpdateMode == FTU_PWM_UPDATE_HALF_PERIOD) { FTU_HWA_EnableMaxLoadPoint(pFtu); } else if (pPwmModeStruct->eUpdateMode == FTU_PWM_UPDATE_END_PERIOD) { FTU_HWA_EnableMinLoadPoint(pFtu); } else if (pPwmModeStruct->eUpdateMode == FTU_PWM_UPDATE_BOTH_HALF_AND_END_PERIOD) { FTU_HWA_EnableMaxLoadPoint(pFtu); FTU_HWA_EnableMinLoadPoint(pFtu); } else { FTU_HWA_SetReinitBySync(pFtu); } /* disable ftu timer */ FTU_HWA_ConfigModuleClkSrc(pFtu, FTU_MODULE_NO_CLK); if (FTU_EDGE_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) { FTU_HWA_DisableModuleCpwmMode(pFtu); FTU_HWA_SetModuleCompareValue(pFtu, pPwmModeStruct->u32PwmPeriod); } else { FTU_HWA_EnableModuleCpwmMode(pFtu); FTU_HWA_SetModuleCompareValue(pFtu, pPwmModeStruct->u32PwmPeriod >> 1u); #ifdef FTU_FDUTYCTL_EXIST /* Set whether to generate a channel flag when CPWM full duty cycle */ if (true == pPwmModeStruct->bFullDutyCycleIntrEnable) { FTU_HWA_EnableFullDutyIntrEnable(pFtu); } else { FTU_HWA_DisableFullDutyIntrEnable(pFtu); } #endif } for (u32Loop = 0u; u32Loop < pPwmModeStruct->u32ChannelCount; u32Loop++) { #if FTU_DEV_ERROR_REPORT == STD_ON if (pPwmModeStruct->pPwmChannels[u32Loop].u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_PwmChannelType *pChannelCfg = &pPwmModeStruct->pPwmChannels[u32Loop]; u8Channel = pChannelCfg->u8Channel; #if FTU_DEV_ERROR_REPORT == STD_ON if (pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift >= FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_PHASE_SHIFT); } else { #endif if (pChannelCfg->u32PhaseShift) { #if FTU_DEV_ERROR_REPORT == STD_ON if((pPwmModeStruct->pPwmChannels[u32Loop].u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_INVALID_CHANNEL); } else { #endif /*Enable enhanced phase shift mode*/ FTU_HWA_EnableChannelPhase(pFtu, u8Channel); FTU_HWA_EnableChannelEnhancedPhase(pFtu, u8Channel); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } else { /*Enable enhanced phase shift mode*/ FTU_HWA_DisableChannelPhase(pFtu, u8Channel); FTU_HWA_DisableChannelEnhancedPhase(pFtu, u8Channel); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif if(pChannelCfg->bLinkMode) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((pPwmModeStruct->pPwmChannels[u32Loop].u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_INVALID_CHANNEL); } else { #endif /* set channel(n+1) complement of channel(n) output */ FTU_HWA_EnableChannelComplement(pFtu, u8Channel); if (!pChannelCfg->bLinkChannelComplement) { FTU_HWA_ClearChannelPolarity(pFtu, (uint8_t)(1U << u8Channel)); FTU_HWA_SetChannelPolarity(pFtu, (uint8_t)(1U << (u8Channel + (uint8_t)1U))); } else { FTU_HWA_ClearChannelPolarity(pFtu, (uint8_t)(1U << u8Channel) | (uint8_t)(1U << (u8Channel + 1u))); } /*link mode, the u8Channel+1->csc.ELSB bit must be set*/ FTU_HWA_ConfigChannelPwmLinkMode(pFtu, (uint8_t)(u8Channel + (uint8_t)1U)); /* enable FTU output */ FTU_HWA_EnableChannelsOutput(pFtu, (uint8_t)(3U << u8Channel)); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } else { FTU_HWA_ClearChannelPolarity(pFtu, (uint8_t)(1U << u8Channel)); /* disable channel(n+1) complement of channel(n) output */ FTU_HWA_DisableChannelComplement(pFtu, u8Channel); /* enable FTU output */ FTU_HWA_EnableChannelsOutput(pFtu, (uint8_t)(1U << u8Channel)); } /* enable u8Channel sync function of the ftu*/ FTU_HWA_EnableChannelSync(pFtu, u8Channel); /* set FTU pwm mode */ if (FTU_EDGE_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) { FTU_HWA_ConfigChannelMode(pFtu, u8Channel, FTU_CHANNEL_MODE_EDGE_ALIGN_PWM); } FTU_HWA_ConfigChannelEdgeLevel(pFtu, u8Channel, (FTU_ChannelEdgeLevelType)pChannelCfg->ePinMode); if (pChannelCfg->bDeadtimeEnable) { FTU_HWA_EnableChannelDeadtime(pFtu, u8Channel); } else { FTU_HWA_DisableChannelDeadtime(pFtu, u8Channel); } /* set the period time and duty time */ if(FTU_CENTER_ALIGNED_PWM == pPwmModeStruct->eAlignedMode) { #if FTU_DEV_ERROR_REPORT == STD_ON if (0u != pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_PHASE_SHIFT); } else { #endif FTU_HWA_SetChannelValue(pFtu, u8Channel, pChannelCfg->u32PwmDuty >> 1u); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } else { #if FTU_DEV_ERROR_REPORT == STD_ON if (pPwmModeStruct->pPwmChannels[u32Loop].u32PhaseShift > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_PHASE_SHIFT); } else { #endif if (pChannelCfg->u32PhaseShift) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((pPwmModeStruct->pPwmChannels[u32Loop].u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_PWM_MODE_INIT_ID, FTU_E_PARAM_PHASE_SHIFT); } else { #endif pFtuHandle->tStatus.u8PhaseShiftEnable |= (uint8_t)(1u << u8Channel); FTU_HWA_SetChannelValue(pFtu, u8Channel, pChannelCfg->u32PhaseShift); if ((pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty) > pPwmModeStruct->u32PwmPeriod) { FTU_HWA_SetChannelValue(pFtu, (uint8_t)(u8Channel + 1), pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty - pPwmModeStruct->u32PwmPeriod - 1); } else { FTU_HWA_SetChannelValue(pFtu, (uint8_t)(u8Channel + 1), pChannelCfg->u32PhaseShift + pChannelCfg->u32PwmDuty); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } else { FTU_HWA_SetChannelValue(pFtu, u8Channel, pChannelCfg->u32PwmDuty); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } set_deadtime(pFtu, u8Channel, pChannelCfg->u32ChannelDeadtime); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Update the behavior of Output compare channel * * @param pFtuHandle FTU processing handle * @param pOutputModeStruct the configurations of the output compare mode */ void FTU_OutputCompareUpdate(FTU_HandleType *pFtuHandle, const FTU_OutputCompareModeType *const pOCConfig) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_OC_MODE_UPDATE_ID, FTU_E_PARAM_INSTANCE); } else if (pOCConfig->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_OC_MODE_UPDATE_ID, FTU_E_PARAM_CHANNEL); } else if (pOCConfig->u32CompareValue > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_OC_MODE_UPDATE_ID, FTU_E_PARAM_INVALID); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; FTU_HWA_ConfigChannelEdgeLevel(pFtu, pOCConfig->u8Channel, (FTU_ChannelEdgeLevelType)pOCConfig->eOutputMode); /* set FTU CV register value*/ FTU_HWA_SetChannelValue(pFtu, pOCConfig->u8Channel, (uint32_t)pOCConfig->u32CompareValue); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Configure FTU to output compare mode * * @param pFtuHandle FTU processing handle * @param pOutputModeStruct the configurations of the output compare mode * @note This function will stop timer */ void FTU_OutputCompareModeInit(FTU_HandleType *pFtuHandle, const FTU_OutputCompareModeType *const pOCConfig) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_OC_MODE_INIT_ID, FTU_E_PARAM_INSTANCE); } else if (pOCConfig->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_OC_MODE_INIT_ID, FTU_E_PARAM_CHANNEL); } else if (pOCConfig->u32CompareValue > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_OC_MODE_INIT_ID, FTU_E_PARAM_INVALID); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* disable ftu timer */ FTU_HWA_ConfigModuleClkSrc(pFtu, FTU_MODULE_NO_CLK); FTU_HWA_DisableChannelEnhancedPhase(pFtu, pOCConfig->u8Channel); FTU_HWA_DisableChannelPhase(pFtu, pOCConfig->u8Channel); #ifdef FTU_ICM_FEATURE FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, pOCConfig->u8Channel, FTU_MEASURE_MODE_OFF); #endif FTU_HWA_ConfigChannelMode(pFtu, pOCConfig->u8Channel, FTU_CHANNEL_MODE_OUTPUT_COMPARE); FTU_HWA_ConfigChannelEdgeLevel(pFtu, pOCConfig->u8Channel, (FTU_ChannelEdgeLevelType)pOCConfig->eOutputMode); /* Disable Up-Down Mode*/ FTU_HWA_DisableModuleCpwmMode(pFtu); /* enable FTU output */ FTU_HWA_EnableChannelsOutput(pFtu, (uint8_t)(1U << pOCConfig->u8Channel)); /* set FTU CV register value*/ FTU_HWA_SetChannelValue(pFtu, pOCConfig->u8Channel, (uint32_t)pOCConfig->u32CompareValue); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Get the value of the FTU Channel * * @param pFtuHandle FTU processing handle * @param u32Channel FTU Channel * @return the value of the FTU Channel */ uint32_t FTU_GetChannelValue(FTU_HandleType *pFtuHandle, uint32_t u32Channel) { uint32_t u32ChannelValue; #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { u32ChannelValue = 0; FTU_ReportDevError(FTU_GET_CHANNEL_VALUE_ID, FTU_E_PARAM_INSTANCE); } else if (u32Channel >= FTU_CHANNEL_CONTROLS_COUNT) { u32ChannelValue = 0; FTU_ReportDevError(FTU_GET_CHANNEL_VALUE_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; u32ChannelValue = FTU_HWA_GetChannelValue(pFtu, (uint8_t)u32Channel); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif return u32ChannelValue; } /** * @brief Get the value of the FTU counter * * @param pFtuHandle FTU processing handle * @return the counter of the FTU */ uint32_t FTU_GetCounter(FTU_HandleType *pFtuHandle) { uint32_t u32Counter; #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { u32Counter = 0; FTU_ReportDevError(FTU_GET_COUNTER_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; u32Counter = FTU_HWA_GetCounterValue(pFtu); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif return u32Counter; } /** * @brief Set the value of the FTU Channel * * @param pFtuHandle FTU processing handle * @param u32Channel FTU Channel * @param u32Value the value to set */ void FTU_SetChannelValue(FTU_HandleType *pFtuHandle, uint32_t u32Channel, uint32_t u32Value) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_SET_CHANNEL_VALUE_ID, FTU_E_PARAM_INSTANCE); } else if (u32Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_SET_CHANNEL_VALUE_ID, FTU_E_PARAM_CHANNEL); } else if (u32Value > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_SET_CHANNEL_VALUE_ID, FTU_E_PARAM_COUNT); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; FTU_HWA_SetChannelValue(pFtu, (uint8_t)u32Channel, u32Value); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Enable the output trigger of the selected FTU instance * * @param pFtuHandle FTU processing handle * @param u32TriggerOutputMask the output trigger mask */ void FTU_EnableTriggerOutput(FTU_HandleType *pFtuHandle, uint32_t u32TriggerOutputMask) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_ENABLE_TRIG_OUT_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* enable the channel match trigger */ FTU_HWA_EnableChannelTriggerOut(pFtu, (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(pFtu); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Disable the output trigger of the selected FTU instance * * @param pFtuHandle FTU processing handle * @param u32TriggerOutputMask the output trigger mask */ void FTU_DisableTriggerOutput(FTU_HandleType *pFtuHandle, uint32_t u32TriggerOutputMask) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_DISABLE_TRIG_OUT_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* disable the channel match trigger */ FTU_HWA_DisableChannelTriggerOut(pFtu, (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(pFtu); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Start the FTU instance * * @param pFtuHandle FTU processing handle */ void FTU_StartTimer(FTU_HandleType *pFtuHandle) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_START_TIMER_ID, FTU_E_PARAM_INSTANCE); } else if (pFtuHandle->tStatus.eFtuClkSrc == FTU_NO_CLK) { FTU_ReportDevError(FTU_START_TIMER_ID, FTU_E_PARAM_INVALID); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* set FTU module clock source */ if (pFtuHandle->tStatus.eFtuClkSrc == FTU_INTERNAL_CLK) { #ifdef FTU_CNT_SEL_EXIST FTU_HWA_ConfigFTUCntSel(pFtu, FTU_CNT_SEL_INTERNAL_CNT); #endif FTU_HWA_ConfigModuleClkSrc(pFtu, FTU_MODULE_INTERNAL_CLK); } #ifdef FTU_CNT_SEL_EXIST else if (pFtuHandle->tStatus.eFtuClkSrc == FTU_EFTU_CNT) { FTU_HWA_ConfigFTUCntSel(pFtu, FTU_CNT_SEL_EXTERNAL_CNT); FTU_HWA_ConfigModuleClkSrc(pFtu, FTU_MODULE_INTERNAL_CLK); } #endif else { #ifdef FTU_CNT_SEL_EXIST FTU_HWA_ConfigFTUCntSel(pFtu, FTU_CNT_SEL_INTERNAL_CNT); #endif FTU_HWA_ConfigModuleClkSrc(pFtu, FTU_MODULE_EXTERNAL_CLK); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } #ifdef FTU_GTB_ADVANCED_CTRL /** * @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 < 4U; u32Loop1++) { if (u32StartMask & (uint32_t)(FTU_GTB_START_AT_TSTMP1_MOD0 << u32Loop1)) { SCM_HWA_ConfigFtuGTBMask((uint8_t)u32Loop0, (1u << u32Loop1)); } } } } SCM_HWA_SetFtuGTBSelect(u32GTB); } #endif /** * @brief Stop the FTU instance * * @param pFtuHandle FTU processing handle */ void FTU_StopTimer(FTU_HandleType *pFtuHandle) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_STOP_TIMER_ID, FTU_E_PARAM_INSTANCE); } else { #endif /* clear FTU module clock source */ FTU_HWA_ConfigModuleClkSrc(s_pFtuBasePtrs[pFtuHandle->eInstance], FTU_MODULE_NO_CLK); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief initialize fault input of the selected Ftu instance * * @param pFtuHandle FTU processing handle * @param pFaultInit the fault configurations of the FTU instance */ void FTU_FaultInit(FTU_HandleType *pFtuHandle, const FTU_FaultInitType *const pFaultInit) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_FAULT_INIT_ID, FTU_E_PARAM_INSTANCE); } else { #endif uint32_t u32Loop, u32Temp; FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* configure fault mode */ FTU_HWA_ConfigModuleFaultMode(pFtu, pFaultInit->eFaultMode); /* Disable all fault inputs*/ u32Temp = FTU_HWA_GetFaultEnable(pFtu); FTU_HWA_DisableModuleFault(pFtu, 0xFu); /* configure fault filter value */ FTU_HWA_SetModuleFaultFilterValue(pFtu, pFaultInit->u8FilterValue); /* recover fault inputs*/ FTU_HWA_EnableModuleFault(pFtu, (uint8_t)u32Temp); /* enables the fault control in channels */ for(u32Loop = 0u; u32Loop < FTU_FAULT_CHANNEL_COUNT; u32Loop++) { if (0u != (pFaultInit->u8FaultChannelEnable & ((uint8_t)FTU_FAULT_FOR_CHANNEL01 << u32Loop))) { FTU_HWA_EnableChannelFault(pFtu, (uint8_t)(u32Loop << 1u)); } else { FTU_HWA_DisableChannelFault(pFtu, (uint8_t)(u32Loop << 1u)); } } #ifdef FTU_FAULT_DIS_DELAY_FEATURE /* set fault disable channel output delay value */ FTU_HWA_SetFaultDelay0(pFtu, pFaultInit->u8FaultDisableDelay0); FTU_HWA_SetFaultDelay1(pFtu, pFaultInit->u8FaultDisableDelay1); #endif #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } #ifdef FTU_FAULT_DIS_DELAY_FEATURE /** * @brief Select fault disable channel output delay value * * @param pFtuHandle FTU processing handle * @param u8Channel FTU channel number, range is 0-7. * @param eSelection Fault disable channel output delay value selection. */ void FTU_FaultSelectDelayValue(FTU_HandleType *pFtuHandle, uint8_t u8Channel, FTU_FaultDisableDelayType eDelaySelection) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_FAULT_SEL_DELAY_ID, FTU_E_PARAM_INSTANCE); } else if (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_FAULT_SEL_DELAY_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_HWA_SelectFaultDelay(s_pFtuBasePtrs[pFtuHandle->eInstance], u8Channel, eDelaySelection); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } #endif /** * @brief Enable a fault input * * @param pFtuHandle FTU processing handle * @param pFaultCtrl configurations of the fault input */ void FTU_FaultEnable(FTU_HandleType *pFtuHandle, const FTU_FaultControlType *const pFaultCtrl) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_FAULT_ENABLE_ID, FTU_E_PARAM_INSTANCE); } else if (pFaultCtrl->u8FaultIndex >= FTU_FAULT_INPUT_COUNT(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_FAULT_ENABLE_ID, FTU_E_PARAM_INVALID); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* configure fault input polarity */ FTU_HWA_ConfigFaultPolarity(pFtu, pFaultCtrl->u8FaultIndex, (uint8_t)pFaultCtrl->eFaultPol); if(true == pFaultCtrl->bFaultFilterEnable) { FTU_HWA_EnableModuleFaultGlitchFilter(pFtu, (uint8_t)(1u << pFaultCtrl->u8FaultIndex)); } else { FTU_HWA_DisableModuleFaultGlitchFilter(pFtu, (uint8_t)(1u << pFaultCtrl->u8FaultIndex)); } /* enable fault input */ FTU_HWA_EnableModuleFault(pFtu, (uint8_t)(1u << pFaultCtrl->u8FaultIndex)); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Disable a fault input * * @param pFtuHandle FTU processing handle * @param u32FaultIndex index of the fault input */ void FTU_FaultDisable(FTU_HandleType *pFtuHandle, uint32_t u32FaultIndex) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_FAULT_DISABLE_ID, FTU_E_PARAM_INSTANCE); } else if (u32FaultIndex >= FTU_FAULT_INPUT_COUNT(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_FAULT_DISABLE_ID, FTU_E_PARAM_INVALID); } else { #endif FTU_HWA_DisableModuleFault(s_pFtuBasePtrs[pFtuHandle->eInstance], (uint8_t)(0x1u << u32FaultIndex)); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief initialize a input capture channel of the selected Ftu instance * * @param pFtuHandle FTU processing handle * @param pInputChannel configurations of the input capture channel */ void FTU_InputCaptureChannelInit(FTU_HandleType *pFtuHandle, const FTU_InputChannelType *const pInputChannel) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_IC_CHANNEL_INIT_ID, FTU_E_PARAM_INSTANCE); } else if (pInputChannel->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_IC_CHANNEL_INIT_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; FTU_HWA_DisableQuadratureMode(pFtu); FTU_HWA_DisableChannelEnhancedPhase(pFtu, pInputChannel->u8Channel); FTU_HWA_DisableChannelPhase(pFtu, pInputChannel->u8Channel); #ifdef FTU_ICM_FEATURE FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, pInputChannel->u8Channel, FTU_MEASURE_MODE_OFF); #endif FTU_HWA_ConfigChannelMode(pFtu, pInputChannel->u8Channel, FTU_CHANNEL_MODE_INPUT); if(pInputChannel->u8Channel < FTU_INPUT_FILTER_COUNT) { /* set FTU input capture filter value */ FTU_HWA_ConfigInputCaptureFilter( pFtu, pInputChannel->u8Channel, pInputChannel->u8FilterValue); } FTU_HWA_ConfigChannelEdgeLevel(pFtu, pInputChannel->u8Channel, (FTU_ChannelEdgeLevelType)pInputChannel->eInputMode); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief initialize the quadrature decoder mode * * @param pFtuHandle FTU processing handle * @param pQuadInit configurations of the quadrature decoder */ void FTU_QuadratureModeInit(FTU_HandleType *pFtuHandle, const FTU_QuadratureInitType *const pQuadInit) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_QD_MODE_INIT_ID, FTU_E_PARAM_INSTANCE); } else if (0U == FTU_INSTANCE_QD_SUPPORT(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_QD_MODE_INIT_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; /* set quadrature mode */ FTU_HWA_ConfigQuadratureMode(pFtu, pQuadInit->eQuadMode); /* set PHA polarity*/ if(pQuadInit->bPhaInverted) { FTU_HWA_EnablePhaInv(pFtu); } else { FTU_HWA_DisablePhaInv(pFtu); } /* set PHB polarity*/ if(pQuadInit->bPhbInverted) { FTU_HWA_EnablePhbInv(pFtu); } else { FTU_HWA_DisablePhbInv(pFtu); } /* prescale should not be set in QD mode */ FTU_HWA_SetModulePrescale(pFtu, FTU_DIV_1); /* set top value */ FTU_HWA_SetModuleCompareValue(pFtu, pQuadInit->u16TopValue); /* set bottom value */ FTU_HWA_SetCounterInitialValue(pFtu, pQuadInit->u16BottomValue); /* Set phase A glitch filter value */ if (0U != pQuadInit->u8PhaFilterVal) { FTU_HWA_ConfigChannelFilterValue(pFtu, 0, pQuadInit->u8PhaFilterVal); FTU_HWA_EnablePhaGlitchFilter(pFtu); } else { FTU_HWA_DisablePhaGlitchFilter(pFtu); } /* Set phase B glitch filter value */ if (0U != pQuadInit->u8PhbFilterVal) { FTU_HWA_ConfigChannelFilterValue(pFtu, 1, pQuadInit->u8PhbFilterVal); FTU_HWA_EnablePhbGlitchFilter(pFtu); } else { FTU_HWA_DisablePhbGlitchFilter(pFtu); } /* enable the quadrature*/ FTU_HWA_EnableQuadratureMode(pFtu); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Enable FTU interrupt * * @param pFtuHandle FTU processing handle * @param u32InterruptMask interrupt enable mask */ void FTU_EnableInterrupt(FTU_HandleType *pFtuHandle, uint32_t u32InterruptMask) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_ENABLE_INTR_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; uint32_t u32Loop; 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(pFtu, (uint8_t)u32Loop); } } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) { /* Enable Overflow Interrupt */ FTU_HWA_EnableOverflowInterrupt(pFtu); } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) { /* Enable Fault Interrupt */ FTU_HWA_EnableModuleFaultInterrupt(pFtu); } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) { /* Enable Reload Point Interrupt */ FTU_HWA_EnableReloadPointInterrupt(pFtu); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Disable FTU interrupt * * @param pFtuHandle FTU processing handle * @param u32InterruptMask interrupt disable mask */ void FTU_DisableInterrupt(FTU_HandleType *pFtuHandle, uint32_t u32InterruptMask) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_DISABLE_INTR_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; uint32_t u32Loop; 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(pFtu, (uint8_t)u32Loop); } } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_OVERFLOW)) { /* Disable Overflow Interrupt */ FTU_HWA_DisableOverflowInterrupt(pFtu); } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_FAULT)) { /* Disable Fault Interrupt */ FTU_HWA_DisableModuleFaultInterrupt(pFtu); } if (0u != (u32InterruptMask & (uint32_t)FTU_INTR_MASK_RELOAD_POINT)) { /* Disable Reload Point Interrupt */ FTU_HWA_DisableReloadPointInterrupt(pFtu); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Clear the fault flag of the FTU instance * * @param pFtuHandle FTU processing handle * @param u32FaultFlag flag to clear */ void FTU_ClearFault(FTU_HandleType *pFtuHandle, uint32_t u32FaultFlag) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_CLEAR_FAULT_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_HWA_ClearModuleFaultFlag(s_pFtuBasePtrs[pFtuHandle->eInstance], (uint8_t)u32FaultFlag); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Get the fault flag of the FTU instance * * @param pFtuHandle FTU processing handle * @return uint32_t the fault flag of the selected Ftu instance */ uint32_t FTU_GetFaultFlag(FTU_HandleType *pFtuHandle) { uint32_t u32FaultFlag = 0; #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_GET_FAULT_FLAG_ID, FTU_E_PARAM_INSTANCE); } else { #endif u32FaultFlag = FTU_HWA_ReadModuleFaultFlag(s_pFtuBasePtrs[pFtuHandle->eInstance]); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif return u32FaultFlag; } /** * @brief Enable ftu channel DMA * * @param pFtuHandle FTU processing handle * @param u32DmaMask The dma channel mask. */ void FTU_EnableChannelDma(FTU_HandleType *pFtuHandle, uint32_t u32Channel) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_ENABLE_CHANNEL_DMA_ID, FTU_E_PARAM_INSTANCE); } else { #endif FTU_HWA_EnableChannelDma(s_pFtuBasePtrs[pFtuHandle->eInstance], (uint8_t)u32Channel); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } #ifdef FTU_ICM_FEATURE /** * @brief Initialize a Expect Edge Number Measurement channel * * @param pFtuHandle FTU processing handle * @param pExpectEdumMeasure measurement configuration. */ void FTU_ExpectEdgeNumberMeasureChannelInit(FTU_HandleType *pFtuHandle, FTU_ExpectEdgeNumberMeasureType *pExpectEdgeNumMeasure) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_IC_EXPENM_INIT_ID, FTU_E_PARAM_INSTANCE); } else if (pExpectEdgeNumMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_IC_EXPENM_INIT_ID, FTU_E_PARAM_CHANNEL); } else if ((pExpectEdgeNumMeasure->u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_IC_EXPENM_INIT_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; FTU_HWA_ConfigChannelMode(pFtu, pExpectEdgeNumMeasure->u8Channel, FTU_CHANNEL_MODE_INPUT); FTU_HWA_ConfigChannelEdgeLevel(pFtu, pExpectEdgeNumMeasure->u8Channel, (FTU_ChannelEdgeLevelType)pExpectEdgeNumMeasure->eEdgeMode); FTU_HWA_ConfigChannelEdgeLevel(pFtu, (uint8_t)(pExpectEdgeNumMeasure->u8Channel + 1u), FTU_CHANNEL_EDGE_NOT_USED); FTU_HWA_ConfigEdgeNumber(pFtu, (uint8_t)(pExpectEdgeNumMeasure->u8Channel + (uint8_t)1u), pExpectEdgeNumMeasure->u8ExpectEdgeNumber); if (FTU_MEASURE_CONTINUOUS_MODE == pExpectEdgeNumMeasure->eContinuouslyMode) { FTU_HWA_EnableMeasureContinous(pFtu, pExpectEdgeNumMeasure->u8Channel); } else { FTU_HWA_DisableMeasureContinous(pFtu, pExpectEdgeNumMeasure->u8Channel); } /* Must put the ICM_MODE setting at the end, otherwise it will not be configured correctly. */ FTU_HWA_ConfigInputCaptureMeasureMode( pFtu, pExpectEdgeNumMeasure->u8Channel, FTU_MEASURE_EXPECT_EDGE_NUMBER); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Initialize a Edge Number Measurement channel * * @param pFtuHandle FTU processing handle * @param pEdgeNumMeasure measurement configuration. */ void FTU_EdgeNumberMeasureChannelInit(FTU_HandleType *pFtuHandle, FTU_EdgeNumberMeasureType *pEdgeNumMeasure) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_IC_ENM_INIT_ID, FTU_E_PARAM_INSTANCE); } else if (pEdgeNumMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_IC_ENM_INIT_ID, FTU_E_PARAM_CHANNEL); } else if ((pEdgeNumMeasure->u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_IC_ENM_INIT_ID, FTU_E_PARAM_CHANNEL); } else if (pEdgeNumMeasure->u32StartWindow >= pEdgeNumMeasure->u32EndWindow) { FTU_ReportDevError(FTU_IC_ENM_INIT_ID, FTU_E_PARAM_INVALID); } else if (pEdgeNumMeasure->u32EndWindow > FTU_GET_MAX_COUNTER(s_pFtuBasePtrs[pFtuHandle->eInstance])) { FTU_ReportDevError(FTU_IC_ENM_INIT_ID, FTU_E_PARAM_COUNT); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; FTU_HWA_ConfigChannelMode(pFtu, pEdgeNumMeasure->u8Channel, FTU_CHANNEL_MODE_INPUT); FTU_HWA_ConfigChannelEdgeLevel(pFtu, pEdgeNumMeasure->u8Channel, (FTU_ChannelEdgeLevelType)pEdgeNumMeasure->eEdgeMode); FTU_HWA_ConfigChannelEdgeLevel(pFtu, (uint8_t)(pEdgeNumMeasure->u8Channel + 1u), FTU_CHANNEL_EDGE_NOT_USED); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, pEdgeNumMeasure->u8Channel, FTU_MEASURE_ICENM_WIND_WRITE); FTU_HWA_SetChannelValue(pFtu, pEdgeNumMeasure->u8Channel, pEdgeNumMeasure->u32StartWindow); FTU_HWA_SetChannelValue(pFtu, (uint8_t)(pEdgeNumMeasure->u8Channel + 1u), pEdgeNumMeasure->u32EndWindow); FTU_HWA_ConfigInputCaptureMeasureMode( pFtu, pEdgeNumMeasure->u8Channel, FTU_MEASURE_EDGE_NUMBER); if (FTU_MEASURE_CONTINUOUS_MODE == pEdgeNumMeasure->eContinuouslyMode) { FTU_HWA_EnableMeasureContinous(pFtu, pEdgeNumMeasure->u8Channel); } else { FTU_HWA_DisableMeasureContinous(pFtu, pEdgeNumMeasure->u8Channel); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Get the expect edge number result of the channel * * @param pFtuHandle FTU processing handle * @param u8Channel FTU channel number, range is 0-7. * @param pResult point to the result buffer. */ void FTU_GetExpectEdgeNumberResult(FTU_HandleType *pFtuHandle, uint8_t u8Channel, FTU_ExpectEdgeNumberResultType *pResult) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_IC_EXPENM_GET_ID, FTU_E_PARAM_INSTANCE); } else if (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_IC_EXPENM_GET_ID, FTU_E_PARAM_CHANNEL); } else if ((u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_IC_EXPENM_GET_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; pResult->u32FirstEdgeTime = FTU_HWA_GetChannelValue(pFtu, u8Channel); pResult->u32LastEdgeTime = FTU_HWA_GetChannelValue(pFtu, (uint8_t)(u8Channel + 1u)); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Get Edge number counter * * @param pFtuHandle FTU processing handle * @param u8Channel FTU channel number. * @return uint8_t Edge number counter */ uint8_t FTU_GetEdgeNumberCount(FTU_HandleType *pFtuHandle, uint8_t u8Channel) { uint8_t u8Count; #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { u8Count = 0; FTU_ReportDevError(FTU_IC_ENM_GET_ID, FTU_E_PARAM_INSTANCE); } else if (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { u8Count = 0; FTU_ReportDevError(FTU_IC_ENM_GET_ID, FTU_E_PARAM_CHANNEL); } else if ((u8Channel & 1u) != 0u) { u8Count = 0; FTU_ReportDevError(FTU_IC_ENM_GET_ID, FTU_E_PARAM_CHANNEL); } else { #endif u8Count = FTU_HWA_GetEdgeNumberCount(s_pFtuBasePtrs[pFtuHandle->eInstance], u8Channel); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif return u8Count; } /** * @brief Initialize a signal measure channel * * @param pFtuHandle FTU processing handle * @param pMeasure measurement configuration. */ void FTU_SignalMeasureChannelInit(FTU_HandleType *pFtuHandle, FTU_SignalMeasureType *pMeasure) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_IC_SIG_MEAS_INIT_ID, FTU_E_PARAM_INSTANCE); } else if (pMeasure->u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_IC_SIG_MEAS_INIT_ID, FTU_E_PARAM_CHANNEL); } else if ((pMeasure->u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_IC_SIG_MEAS_INIT_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, pMeasure->u8Channel, FTU_MEASURE_MODE_OFF); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_MEASURE_MODE_OFF); FTU_HWA_DisableChannelEnhancedPhase(pFtu, pMeasure->u8Channel); FTU_HWA_DisableChannelPhase(pFtu, pMeasure->u8Channel); FTU_HWA_DisableChannelEnhancedPhase(pFtu, (uint8_t)(pMeasure->u8Channel + 1u)); FTU_HWA_DisableChannelPhase(pFtu, (uint8_t)(pMeasure->u8Channel + 1u)); FTU_HWA_DisableModuleCpwmMode(pFtu); FTU_HWA_ConfigChannelMode(pFtu, pMeasure->u8Channel, FTU_CHANNEL_MODE_INPUT); FTU_HWA_ConfigChannelMode(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_CHANNEL_MODE_INPUT); if (FTU_SIGNAL_MEASURE_HIGH_TIME == pMeasure->eMeasureMode) { FTU_HWA_ConfigChannelEdgeLevel(pFtu, pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); FTU_HWA_ConfigChannelEdgeLevel(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_CHANNEL_EDGE_FALLING); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, pMeasure->u8Channel, FTU_MEASURE_MODE_DUTY_CYCLE); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, (uint8_t)(pMeasure->u8Channel + 1), FTU_MEASURE_MODE_DUTY_CYCLE); FTU_HWA_SetChannelPolarity(pFtu, (uint8_t)(1u << pMeasure->u8Channel)); } else if (FTU_SIGNAL_MEASURE_LOW_TIME == pMeasure->eMeasureMode) { FTU_HWA_ConfigChannelEdgeLevel(pFtu, pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); FTU_HWA_ConfigChannelEdgeLevel(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_CHANNEL_EDGE_FALLING); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, pMeasure->u8Channel, FTU_MEASURE_MODE_DUTY_CYCLE); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_MEASURE_MODE_DUTY_CYCLE); FTU_HWA_ClearChannelPolarity(pFtu, (uint8_t)(1u << pMeasure->u8Channel)); } else if (FTU_SIGNAL_MEASURE_PERIOD_RISING_EDGE == pMeasure->eMeasureMode) { FTU_HWA_ConfigChannelEdgeLevel(pFtu, pMeasure->u8Channel, FTU_CHANNEL_EDGE_RISING); FTU_HWA_ConfigChannelEdgeLevel(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_CHANNEL_EDGE_NOT_USED); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, pMeasure->u8Channel, FTU_MEASURE_MODE_PERIOD); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_MEASURE_MODE_PERIOD); } else if (FTU_SIGNAL_MEASURE_PERIOD_FALLING_EDGE == pMeasure->eMeasureMode) { FTU_HWA_ConfigChannelEdgeLevel(pFtu, pMeasure->u8Channel, FTU_CHANNEL_EDGE_FALLING); FTU_HWA_ConfigChannelEdgeLevel(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_CHANNEL_EDGE_NOT_USED); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, pMeasure->u8Channel, FTU_MEASURE_MODE_PERIOD); FTU_HWA_ConfigInputCaptureMeasureMode(pFtu, (uint8_t)(pMeasure->u8Channel + 1u), FTU_MEASURE_MODE_PERIOD); } if (FTU_MEASURE_CONTINUOUS_MODE == pMeasure->eContinuouslyMode) { FTU_HWA_EnableMeasureContinous(pFtu, pMeasure->u8Channel); } else { FTU_HWA_DisableMeasureContinous(pFtu, pMeasure->u8Channel); } if (FTU_MEASURE_START_IMMEDIATELY == pMeasure->eStartMode) { FTU_HWA_EnableMeasureStartImmd(pFtu, pMeasure->u8Channel); } else { FTU_HWA_DisableMeasureStartImmd(pFtu, pMeasure->u8Channel); } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Re-start measurement when in single mode * * @param pFtuHandle FTU processing handle * @param u8Channel FTU channel number, range is 0-7. */ void FTU_SignalMeasureChannelSingle(FTU_HandleType *pFtuHandle, uint8_t u8Channel) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_IC_SIG_MEAS_SINGLE_ID, FTU_E_PARAM_INSTANCE); } else if (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_IC_SIG_MEAS_SINGLE_ID, FTU_E_PARAM_CHANNEL); } else if ((u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_IC_SIG_MEAS_SINGLE_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_HWA_SingleMeasurement(s_pFtuBasePtrs[pFtuHandle->eInstance], u8Channel); #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } /** * @brief Get the measurement result of the channel * * @param pFtuHandle FTU processing handle * @param u8Channel FTU channel number, range is 0-7. * @param pResult point to the result buffer. */ void FTU_GetSignalMeasureResult(FTU_HandleType *pFtuHandle, uint8_t u8Channel, FTU_SignalMeasureValueType *pResult) { #if FTU_DEV_ERROR_REPORT == STD_ON if ((uint32_t)pFtuHandle->eInstance >= FTU_INSTANCE_COUNT) { FTU_ReportDevError(FTU_IC_SIG_MEAS_GET_ID, FTU_E_PARAM_INSTANCE); } else if (u8Channel >= FTU_CHANNEL_CONTROLS_COUNT) { FTU_ReportDevError(FTU_IC_SIG_MEAS_GET_ID, FTU_E_PARAM_CHANNEL); } else if ((u8Channel & 1u) != 0u) { FTU_ReportDevError(FTU_IC_SIG_MEAS_GET_ID, FTU_E_PARAM_CHANNEL); } else { #endif FTU_Type * const pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; FTU_MeasurementModeType eMeasureMode = FTU_HWA_GetMeasureMode(pFtu, u8Channel); if (FTU_MEASURE_MODE_DUTY_CYCLE == eMeasureMode) { if (FTU_HWA_GetChannelPolarity(pFtu, (uint8_t)(1u << u8Channel))) { pResult->u32StartTime = FTU_HWA_GetChannelValue(pFtu, u8Channel); pResult->u32EndTime = FTU_HWA_GetChannelValue(pFtu, (uint8_t)(u8Channel + 1u)); } else { pResult->u32StartTime = FTU_HWA_GetChannelValue(pFtu, (uint8_t)(u8Channel + 1u)); pResult->u32EndTime = FTU_HWA_GetChannelValue(pFtu, u8Channel); } } else if(FTU_MEASURE_MODE_PERIOD == eMeasureMode) { pResult->u32StartTime = FTU_HWA_GetChannelValue(pFtu, (uint8_t)(u8Channel + 1u)); pResult->u32EndTime = FTU_HWA_GetChannelValue(pFtu, u8Channel); } else { pResult->u32StartTime = 0u; pResult->u32EndTime = 0u; } #if FTU_DEV_ERROR_REPORT == STD_ON } #endif } #endif /** * @brief Interrupt IRQ handle of FTU instance * * @param eInstance the selected FTU instance */ void FTUn_IRQHandler(FTU_HandleType *pFtuHandle) { FTU_Type *pFtu = s_pFtuBasePtrs[pFtuHandle->eInstance]; uint32_t u32FaultFlag = 0u; uint8_t u8FaultEnable = FTU_HWA_ReadFaultIntrEnable(pFtu); uint8_t u8OverflowFlag = FTU_HWA_ReadModuleOverflowFlag(pFtu); uint8_t u8ReloadFlag = FTU_HWA_ReadReloadIntrEnable(pFtu); uint32_t u32Loop, u32ChannelIntrFlag = 0, u32TimeStamp; u8OverflowFlag = FTU_HWA_ReadModuleOverflowIntrEnable(pFtu) & u8OverflowFlag; u8ReloadFlag = FTU_HWA_ReadModuleReloadFlag(pFtu) & u8ReloadFlag; if(0u != u8FaultEnable) { u32FaultFlag = FTU_HWA_ReadModuleFaultFlag(pFtu); } /* Clear interrupt flag*/ if (0u != u8OverflowFlag) { FTU_HWA_ClearOverflowFlag(pFtu); } if (0u != u8ReloadFlag) { FTU_HWA_ClearReloadFlag(pFtu); } for (u32Loop = 0U; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if ((0u != FTU_HWA_ReadChannelInterruptFlag(pFtu, (uint8_t)u32Loop)) && (0u != FTU_HWA_ReadChannelInterruptEnableFlag(pFtu, (uint8_t)u32Loop))) { FTU_HWA_ClearChannelInterruptFlag(pFtu, (uint8_t)u32Loop); u32ChannelIntrFlag |= (uint8_t)(1u << u32Loop); } } /* call callback functions*/ if ((0u != u8OverflowFlag) && (NULL != pFtuHandle->tStatus.pOverflowCallback)) { pFtuHandle->tStatus.pOverflowCallback(pFtuHandle); } if ((0u != u8ReloadFlag) && (NULL != pFtuHandle->tStatus.pReloadPointCallback)) { pFtuHandle->tStatus.pReloadPointCallback(pFtuHandle); } if ((0u != u32FaultFlag) && (NULL != pFtuHandle->tStatus.pFaultCallback)) { uint32_t u32FaultInputCount = FTU_FAULT_INPUT_COUNT(s_pFtuBasePtrs[pFtuHandle->eInstance]); for (u32Loop = 0U; u32Loop < u32FaultInputCount; u32Loop++) { if (0u != (u32FaultFlag & ((uint32_t)1u << u32Loop))) { pFtuHandle->tStatus.pFaultCallback(pFtuHandle, u32Loop); } } } if ((0u != u32ChannelIntrFlag) && (NULL != pFtuHandle->tStatus.pChannelCallback)) { for (u32Loop = 0U; u32Loop < FTU_CHANNEL_CONTROLS_COUNT; u32Loop++) { if (0u != (u32ChannelIntrFlag & ((uint32_t)1u << u32Loop))) { u32TimeStamp = FTU_HWA_GetChannelValue(pFtu, (uint8_t)u32Loop); pFtuHandle->tStatus.pChannelCallback(pFtuHandle, u32Loop, u32TimeStamp); } } } } #endif