1132 lines
41 KiB
C
1132 lines
41 KiB
C
/**
|
|
* @file module_driver_eftu_dtm.c
|
|
* @author flagchip
|
|
* @brief EFTU_DTM driver source code
|
|
* @version 2.0.0
|
|
* @date 2024-11-07
|
|
*
|
|
* SDK Version: 2.6.0
|
|
*
|
|
|
|
* @copyright Copyright (c) 2020-2024 Flagchip Semiconductors Co., Ltd.
|
|
*
|
|
*/
|
|
/* ********************************************************************************
|
|
* Revision History:
|
|
*
|
|
* Version Date Initials CR# Descriptions
|
|
* --------- ---------- ------------ ---------- ---------------
|
|
* 0.1.0 2024-11-07 Flagchip070 N/A First version for FC7300
|
|
* 2.6.0 2026-01-23 Flagchip070 N/A Fix phase shift channel POL issue
|
|
******************************************************************************** */
|
|
|
|
#include "module_driver_eftu_tom.h"
|
|
|
|
#if defined(EFTU_INSTANCE_COUNT) && (EFTU_INSTANCE_COUNT > 0)
|
|
#ifndef EFTU_TOM_DEV_ERROR_REPORT
|
|
#define EFTU_TOM_DEV_ERROR_REPORT STD_OFF
|
|
#endif
|
|
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
#define EftuTom_ReportDevError(func, error) ReportDevError(EFTU_TOM_MODULE_ID, func, error)
|
|
#endif
|
|
|
|
#define EFTU_TOM_CHANNEL(h) (h)->tStatus.pTOM, (h)->tStatus.u8HwChannel
|
|
|
|
#define EFTU_TOM_CONFIG_CLOCK(h, c) (h)->pCmuHandle->tStatus.fCmuClock[(h->eEftuInstance)][(c)->eClockSource]
|
|
#define EFTU_TOM_CONFIG_CLOCK_COUNT(h, c, t) ((uint32_t)((t) * EFTU_TOM_CONFIG_CLOCK(h, c) + 0.5f))
|
|
#define EFTU_TOM_HANDLE_CLOCK_COUNT(h, t) ((uint32_t)((t) * (h)->tStatus.fClock + 0.5f))
|
|
|
|
/******* Local Function Prototype *********/
|
|
static void EFTU_TOM_InitHwChannelStatus(EFTU_Tom_ChannelHandleType *pHandle);
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
static bool EFTU_TOM_VerifyHandle(EFTU_Tom_ChannelHandleType *pHandle, uint32_t u32FuncId);
|
|
static bool EFTU_TOM_VerifyHandleWithMode(EFTU_Tom_ChannelHandleType *pHandle, uint32_t u32FuncId, EFTU_Tom_ModeType eMode);
|
|
static bool EFTU_TOM_CheckInited(EFTU_Tom_ChannelHandleType *pHandle, uint32_t u32FuncId);
|
|
|
|
/********* Local Functions ************/
|
|
/**
|
|
* @brief Verify the validity of an EFTU_Tom channel handle.
|
|
*
|
|
* @param pHandle Pointer to the EFTU_Tom channel handle.
|
|
* @param u32FuncId The function ID of the higher-level function calling this validation function.
|
|
* @return bool Returns TRUE if the handle is valid, otherwise returns FALSE.
|
|
*/
|
|
static bool EFTU_TOM_VerifyHandle(EFTU_Tom_ChannelHandleType *pHandle, uint32_t u32FuncId)
|
|
{
|
|
bool bValid = TRUE;
|
|
/* Check if the EFTU instance exceeds the maximum value */
|
|
if (((uint32_t)pHandle->eEftuInstance) >= (uint32_t)EFTU_INSTANCE_COUNT)
|
|
{
|
|
EftuTom_ReportDevError(u32FuncId, EFTU_TOM_E_PARAM_INSTANCE);
|
|
bValid = FALSE;
|
|
}
|
|
/* Check if the channel number is out of range */
|
|
else if (pHandle->u8Channel >= (EFTU_TOM_CHANNEL_COUNT * 2U))
|
|
{
|
|
EftuTom_ReportDevError(u32FuncId, EFTU_TOM_E_PARAM_CHANNEL);
|
|
bValid = FALSE;
|
|
}
|
|
|
|
return bValid;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if the EFTU_Tom channel has been initialized.
|
|
*
|
|
* @param pHandle Pointer to the EFTU_Tom channel handle.
|
|
* @param u32FuncId The function ID of the higher-level function calling this validation function.
|
|
* @return bool Returns TRUE if the channel is initialized, otherwise returns FALSE.
|
|
*/
|
|
static bool EFTU_TOM_CheckInited(EFTU_Tom_ChannelHandleType *pHandle, uint32_t u32FuncId)
|
|
{
|
|
bool bValid = FALSE;
|
|
uint32_t u32Loop;
|
|
/* Iterate through all EFTU instances to check if the channel is initialized */
|
|
for (u32Loop = 0; u32Loop < EFTU_INSTANCE_COUNT; u32Loop++)
|
|
{
|
|
if ( ((uint32_t)pHandle->tStatus.pTOM == (g_aEftuBaseAddress[u32Loop] + EFTU_TOM0_BASE))
|
|
|| ((uint32_t)pHandle->tStatus.pTOM == (g_aEftuBaseAddress[u32Loop] + EFTU_TOM1_BASE)))
|
|
{
|
|
bValid = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
/* Log an error if the channel is not initialized */
|
|
if (FALSE == bValid)
|
|
{
|
|
EftuTom_ReportDevError(u32FuncId, EFTU_TOM_E_UNINITED);
|
|
}
|
|
return bValid;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Verify the EFTU_Tom channel handle and mode.
|
|
*
|
|
* @param pHandle Pointer to the EFTU_Tom channel handle.
|
|
* @param u32FuncId The function ID of the higher-level function calling this validation function.
|
|
* @param eMode The expected channel mode.
|
|
* @return bool Returns TRUE if the handle is valid and the mode matches, otherwise returns FALSE.
|
|
*/
|
|
static bool EFTU_TOM_VerifyHandleWithMode(EFTU_Tom_ChannelHandleType *pHandle, uint32_t u32FuncId, EFTU_Tom_ModeType eMode)
|
|
{
|
|
bool bValid = EFTU_TOM_VerifyHandle(pHandle, u32FuncId);
|
|
/* If the handle is valid, further check if it is initialized */
|
|
if (TRUE == bValid)
|
|
{
|
|
bValid = EFTU_TOM_CheckInited(pHandle, u32FuncId);
|
|
|
|
/* Check if the channel mode matches the expected mode */
|
|
if((TRUE == bValid) && pHandle->tStatus.eMode != eMode)
|
|
{
|
|
EftuTom_ReportDevError(u32FuncId, EFTU_TOM_E_CHANNEL_MODE);
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
return bValid;
|
|
}
|
|
|
|
#endif
|
|
|
|
/**
|
|
* @brief Initialize hardware channel status
|
|
*
|
|
* @param pHandle Pointer to the channel handle, containing channel-related information
|
|
*/
|
|
static void EFTU_TOM_InitHwChannelStatus(EFTU_Tom_ChannelHandleType *pHandle)
|
|
{
|
|
/**
|
|
* Check if the channel number is within the range of the first TOM module
|
|
*/
|
|
if (pHandle->u8Channel < EFTU_TOM_CHANNEL_COUNT)
|
|
{
|
|
/**
|
|
* Set the base address of TOM module 0
|
|
*/
|
|
pHandle->tStatus.pTOM = (EFTU_TOM_Type * )(g_aEftuBaseAddress[pHandle->eEftuInstance] + EFTU_TOM0_BASE);
|
|
|
|
/**
|
|
* Set the hardware channel number
|
|
*/
|
|
pHandle->tStatus.u8HwChannel = pHandle->u8Channel;
|
|
}
|
|
else
|
|
{
|
|
/**
|
|
* If the channel number is not within the range of the first TOM module,
|
|
* set the base address of TOM module 1
|
|
*/
|
|
pHandle->tStatus.pTOM = (EFTU_TOM_Type * )(g_aEftuBaseAddress[pHandle->eEftuInstance] + EFTU_TOM1_BASE);
|
|
|
|
/**
|
|
* Calculate and set the hardware channel number by subtracting the number of channels in the first TOM module
|
|
*/
|
|
pHandle->tStatus.u8HwChannel = (uint8_t)(pHandle->u8Channel - EFTU_TOM_CHANNEL_COUNT);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize the EFTU Timer Channel
|
|
*
|
|
* @param pHandle Pointer to the timer channel handle, used to operate a specific timer channel
|
|
* @param pConfig Pointer to the timer configuration structure, containing the configuration information for the timer
|
|
*/
|
|
void EFTU_TOM_InitTimerChannel(EFTU_Tom_ChannelHandleType *pHandle, EFTU_Tom_TimerConfigType *pConfig)
|
|
{
|
|
/** In case the development error reporting feature is enabled, validate the handle */
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
bool bValid = EFTU_TOM_VerifyHandle(pHandle, EFTU_TOM_TIMER_INIT_ID);
|
|
|
|
if (TRUE == bValid)
|
|
{
|
|
/** Check if the configured clock source is out of valid range */
|
|
if (((uint32_t)pConfig->eClockSource) > (uint32_t)EFTU_TOM_CLK_SRC_CMU_CLK_7)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_TIMER_INIT_ID, EFTU_TOM_E_CLOCK_SRC_INVALID);
|
|
}
|
|
/** Check if the configured timer count exceeds hardware limitations */
|
|
else if ((EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fTimeout)) > 0xFFFFFF)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_TIMER_INIT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
/** Initialize the hardware channel status */
|
|
EFTU_TOM_InitHwChannelStatus(pHandle);
|
|
|
|
/** Set the channel mode to timer mode */
|
|
pHandle->tStatus.eMode = EFTU_TOM_MODE_TIMER;
|
|
/** Set the CCU0 callback function */
|
|
pHandle->tStatus.tCallback.pCcu0 = pConfig->pTimeoutCallback;
|
|
/** Set the CCU1 callback function to NULL as it is not used in timer mode */
|
|
pHandle->tStatus.tCallback.pCcu1 = NULL;
|
|
/** Calculate and set the timer clock */
|
|
pHandle->tStatus.fClock = EFTU_TOM_CONFIG_CLOCK(pHandle, pConfig);
|
|
|
|
/** Set the hardware channel mode to PWM mode */
|
|
EFTU_TOM_HWA_SetChannelMode(EFTU_TOM_CHANNEL(pHandle), EFTU_TOM_CHANNEL_MODE_PWM);
|
|
/** Set the hardware channel clock source */
|
|
EFTU_TOM_HWA_SetShadowClockSource(EFTU_TOM_CHANNEL(pHandle), (uint8_t)pConfig->eClockSource);
|
|
/** Set the shadow register 0 value for timer counting */
|
|
EFTU_TOM_HWA_SetShadowValue0(EFTU_TOM_CHANNEL(pHandle), (uint32_t)(pConfig->fTimeout * pHandle->tStatus.fClock + 0.5f));
|
|
|
|
/** Enable the CCU0 interrupt */
|
|
EFTU_TOM_HWA_EnableCCU0Interrupt(EFTU_TOM_CHANNEL(pHandle));
|
|
|
|
/** Enable force update, set host trigger request, then disable force update */
|
|
EFTU_TOM_HWA_EnableForceUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
EFTU_TOM_HWA_SetHostTriggerRequest(pHandle->tStatus.pTOM);
|
|
EFTU_TOM_HWA_DisableForceUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Start the timer channel.
|
|
*
|
|
* @param pHandle Pointer to the timer channel handle.
|
|
*/
|
|
void EFTU_TOM_StartTimerChannel(EFTU_Tom_ChannelHandleType *pHandle)
|
|
{
|
|
/**
|
|
* When device error reporting is enabled, verify the handle.
|
|
*/
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
if (TRUE == EFTU_TOM_VerifyHandleWithMode(pHandle, EFTU_TOM_START_TIMER_CHANNEL_ID, EFTU_TOM_MODE_TIMER))
|
|
{
|
|
#endif
|
|
/**
|
|
* Enable the channel's update trigger functionality.
|
|
*/
|
|
EFTU_TOM_HWA_EnableChannelOnUpdateTrig(EFTU_TOM_CHANNEL(pHandle));
|
|
|
|
/**
|
|
* Enable the timer channel.
|
|
*/
|
|
EFTU_TOM_HWA_EnableChannel(EFTU_TOM_CHANNEL(pHandle));
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Stops the timer channel.
|
|
*
|
|
* @param pHandle Pointer to the channel handle, used to identify and control a specific timer channel.
|
|
*/
|
|
void EFTU_TOM_StopTimerChannel(EFTU_Tom_ChannelHandleType *pHandle)
|
|
{
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
/**
|
|
* Verify the handle if device error reporting is enabled.
|
|
*/
|
|
if (TRUE == EFTU_TOM_VerifyHandleWithMode(pHandle, EFTU_TOM_STOP_TIMER_CHANNEL_ID, EFTU_TOM_MODE_TIMER))
|
|
{
|
|
#endif
|
|
/**
|
|
* Disable the channel's update trigger to prevent it from being triggered during the stop process.
|
|
*/
|
|
EFTU_TOM_HWA_DisableChannelOnUpdateTrig(EFTU_TOM_CHANNEL(pHandle));
|
|
|
|
/**
|
|
* Completely disable the channel to stop its operation.
|
|
*/
|
|
EFTU_TOM_HWA_DisableChannel(EFTU_TOM_CHANNEL(pHandle));
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* Function to initialize the PWM channel with the given configuration.
|
|
*
|
|
* @param pHandle Pointer to the EFTU TOM handle structure.
|
|
* @param pConfig Pointer to the EFTU TOM configuration structure.
|
|
* @return None
|
|
*/
|
|
void EFTU_TOM_InitPwmChannel(EFTU_Tom_ChannelHandleType *pHandle, EFTU_Tom_PwmConfigType *pConfig)
|
|
{
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
bool bValid = EFTU_TOM_VerifyHandle(pHandle, EFTU_TOM_PWM_INIT_ID);
|
|
|
|
if (TRUE == bValid)
|
|
{
|
|
if (((uint32_t)pConfig->eClockSource) > (uint32_t)EFTU_TOM_CLK_SRC_CMU_CLK_7)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_CLOCK_SRC_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
else if ((TRUE == pConfig->bPhaseShiftEnable) && (TRUE == pConfig->bUpDownMode))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_PARAM_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
else if ( (TRUE == pConfig->bHrpwmSupport)
|
|
&& (
|
|
(pHandle->eEftuInstance != EFTU_INSTANCE_0)
|
|
|| (pHandle->u8Channel >= 8U)
|
|
|| ( fabsf(pHandle->pCmuHandle->fBusClock
|
|
- EFTU_TOM_CONFIG_CLOCK(pHandle, pConfig))
|
|
> 1.0f)
|
|
)
|
|
)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_PARAM_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
#endif
|
|
else if (FALSE == pConfig->bPhaseShiftEnable)
|
|
{
|
|
if (pConfig->fDuty > pConfig->fPeriod)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
else if (FALSE == pConfig->bUpDownMode)
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pConfig->bHrpwmSupport)
|
|
{
|
|
#endif
|
|
if ( (EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fDuty) > 0xFFFFFF)
|
|
|| (EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fPeriod) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
if ( (EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fDuty * 32.0f) > 0xFFFFFF)
|
|
|| (EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fPeriod * 32.0f) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
else /* (TRUE == pConfig->bUpDownMode) */
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
/** Check for non-phase shift mode and validate PWM parameters */
|
|
if (FALSE == pConfig->bHrpwmSupport)
|
|
{
|
|
#endif
|
|
/** Validate ordinary PWM duty and period */
|
|
if ( ((EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fDuty) >> 1U) > 0xFFFFFF)
|
|
|| ((EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fPeriod - pConfig->fDuty) >> 1U) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
/** Validate high-resolution PWM duty and period */
|
|
if ( ((EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fDuty * 32.0f) >> 1U) > 0xFFFFFF)
|
|
|| ((EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, (pConfig->fPeriod - pConfig->fDuty) * 32.0f) >> 1U) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
else /* if (TRUE == pConfig->bPhaseShiftEnable) */
|
|
{
|
|
/** Check for phase shift mode and validate PWM parameters */
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pConfig->bHrpwmSupport)
|
|
{
|
|
/** Validate ordinary PWM phase shift, duty, and period */
|
|
if ( (EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fPhaseShift) > 0xFFFFFF)
|
|
|| (EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fPhaseShift + pConfig->fDuty) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
/** Validate high-resolution PWM phase shift, duty, and period */
|
|
if ( (EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, pConfig->fPhaseShift * 32.0f) > 0xFFFFFF)
|
|
|| (EFTU_TOM_CONFIG_CLOCK_COUNT(pHandle, pConfig, (pConfig->fPhaseShift + pConfig->fDuty) * 32.0f) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_PWM_INIT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
}
|
|
/** If the configuration is valid, initialize the PWM channel */
|
|
if (TRUE == bValid)
|
|
{
|
|
#endif
|
|
EFTU_TOM_InitHwChannelStatus(pHandle);
|
|
pHandle->tStatus.eMode = EFTU_TOM_MODE_PWM;
|
|
pHandle->tStatus.tPwm.eUpdateMode = pConfig->eUpdateMode;
|
|
pHandle->tStatus.tPwm.bPhaseShiftEnable = pConfig->bPhaseShiftEnable;
|
|
pHandle->tStatus.tPwm.bUpDownMode = pConfig->bUpDownMode;
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
pHandle->tStatus.tPwm.bHrpwmSupport = pConfig->bHrpwmSupport;
|
|
#endif
|
|
EFTU_TOM_HWA_SetChannelMode(EFTU_TOM_CHANNEL(pHandle), EFTU_TOM_CHANNEL_MODE_PWM);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if ( (pHandle->eEftuInstance == EFTU_INSTANCE_0)
|
|
&& (pHandle->u8Channel < 8U))
|
|
{
|
|
EFTU_TOM_HWA_SetHRPWMSupport(EFTU_TOM_CHANNEL(pHandle), pConfig->bHrpwmSupport);
|
|
}
|
|
#endif
|
|
pHandle->tStatus.fClock = EFTU_TOM_CONFIG_CLOCK(pHandle, pConfig);
|
|
uint32_t u32Cm0, u32Cm1;
|
|
if (TRUE == pConfig->bPhaseShiftEnable)
|
|
{
|
|
/** Set reset source and signal level for phase shift mode */
|
|
EFTU_TOM_HWA_SetCCU0ResetSource(EFTU_TOM_CHANNEL(pHandle), EFTU_TOM_RESET_CN0_ON_TRIGGER);
|
|
pHandle->tStatus.tPwm.fDuty = pConfig->fDuty;
|
|
pHandle->tStatus.tPwm.fPeriodPhaseShift = pConfig->fPhaseShift;
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pConfig->bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fPhaseShift);
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fDuty + pConfig->fPhaseShift);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fPhaseShift * 32.0f);
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fDuty + pConfig->fPhaseShift * 32.0f);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
/** Set reset source and signal level for non-phase shift mode */
|
|
EFTU_TOM_HWA_SetCCU0ResetSource(EFTU_TOM_CHANNEL(pHandle), EFTU_TOM_RESET_CN0_ON_MATCHING_CM0);
|
|
pHandle->tStatus.tPwm.fDuty = pConfig->fDuty;
|
|
pHandle->tStatus.tPwm.fPeriodPhaseShift = pConfig->fPeriod;
|
|
if (TRUE == pConfig->bUpDownMode)
|
|
{
|
|
/** Configure up-down counting mode */
|
|
EFTU_TOM_HWA_SetUpDownMode(EFTU_TOM_CHANNEL(pHandle), EFTU_TOM_UP_DOWN_MODE_UPDATE_CN0_REACH_0);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pConfig->bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fPeriod) >> 1U;
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fPeriod - pConfig->fDuty) >> 1U;
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fPeriod * 32.0f) >> 1U;
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, (pConfig->fPeriod - pConfig->fDuty) * 32.0f) >> 1U;
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
/** Configure up-mode counting mode */
|
|
EFTU_TOM_HWA_SetUpDownMode(EFTU_TOM_CHANNEL(pHandle), EFTU_TOM_UP_MODE);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pConfig->bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fPeriod);
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fDuty);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fPeriod * 32.0f);
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pConfig->fDuty * 32.0f);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/** Configure clock source */
|
|
EFTU_TOM_HWA_SetShadowClockSource(EFTU_TOM_CHANNEL(pHandle), (uint8_t)pConfig->eClockSource);
|
|
EFTU_TOM_HWA_SetClockSource(EFTU_TOM_CHANNEL(pHandle), (uint8_t)pConfig->eClockSource);
|
|
|
|
/** Configure shadow registers */
|
|
EFTU_TOM_HWA_SetShadowInitialSignalLevel(EFTU_TOM_CHANNEL(pHandle), pConfig->eActiveLevel);
|
|
EFTU_TOM_HWA_SetShadowValue0(EFTU_TOM_CHANNEL(pHandle), u32Cm0);
|
|
EFTU_TOM_HWA_SetShadowValue1(EFTU_TOM_CHANNEL(pHandle), u32Cm1);
|
|
if (EFTU_TOM_PWM_UPDATE_SYNC == pConfig->eUpdateMode)
|
|
{
|
|
EFTU_TOM_HWA_EnableChannelUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
}
|
|
|
|
/** Enable force update, set host trigger request, then disable force update */
|
|
EFTU_TOM_HWA_EnableForceUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
EFTU_TOM_HWA_SetHostTriggerRequest(pHandle->tStatus.pTOM);
|
|
EFTU_TOM_HWA_DisableForceUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
|
|
/** Configure and enable CCU0 interrupt if required */
|
|
if (TRUE == pConfig->bCcu0IrqEnable)
|
|
{
|
|
pHandle->tStatus.tCallback.pCcu0 = pConfig->pCcu0Callback;
|
|
EFTU_TOM_HWA_EnableCCU0Interrupt(EFTU_TOM_CHANNEL(pHandle));
|
|
}
|
|
/** Configure and enable CCU1 interrupt if required */
|
|
if (TRUE == pConfig->bCcu1IrqEnable)
|
|
{
|
|
pHandle->tStatus.tCallback.pCcu1 = pConfig->pCcu1Callback;
|
|
EFTU_TOM_HWA_EnableCCU1Interrupt(EFTU_TOM_CHANNEL(pHandle));
|
|
}
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Set the trigger output of the TOM channel.
|
|
*
|
|
* @param pHandle Pointer to the PWM channel handle, containing necessary channel information.
|
|
* @param eTrigOutput Trigger outut selection.
|
|
*/
|
|
void EFTU_TOM_SetTrigOutput(EFTU_Tom_ChannelHandleType *pHandle, EFTU_TOM_TrigOutSelectionType eTrigOutput)
|
|
{
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
/* Verify the handle during development to ensure its validity. */
|
|
if (TRUE == EFTU_TOM_VerifyHandle(pHandle, EFTU_TOM_SET_TRIG_OUT_ID))
|
|
{
|
|
if ((uint8_t)eTrigOutput > (uint8_t)EFTU_TOM_TRIG_OUT_USE_TRIG_CCU0)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_SET_TRIG_OUT_ID, EFTU_TOM_E_PARAM_INVALID);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
EFTU_TOM_HWA_SetTriggerOut(EFTU_TOM_CHANNEL(pHandle), eTrigOutput);
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Start the PWM channel.
|
|
*
|
|
* @param pHandle Pointer to the PWM channel handle, containing necessary channel information.
|
|
* @param bImmediate Boolean value indicating whether to immediately start the PWM output.
|
|
*/
|
|
void EFTU_TOM_StartPwmChannel(EFTU_Tom_ChannelHandleType *pHandle, bool bImmediate)
|
|
{
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
/* Verify the handle during development to ensure its validity. */
|
|
if (TRUE == EFTU_TOM_VerifyHandle(pHandle, EFTU_TOM_START_TIMER_CHANNEL_ID))
|
|
{
|
|
#endif
|
|
/* Enable the channel's update trigger, which is a necessary condition for starting the PWM output. */
|
|
EFTU_TOM_HWA_EnableChannelOnUpdateTrig(EFTU_TOM_CHANNEL(pHandle));
|
|
|
|
EFTU_TOM_HWA_EnableChannelOutputOnUpdateTrig(EFTU_TOM_CHANNEL(pHandle));
|
|
|
|
/* If immediate start is required, enable the channel. */
|
|
if (TRUE == bImmediate)
|
|
{
|
|
/* Set the host trigger request, which is another necessary condition for starting the PWM output. */
|
|
EFTU_TOM_HWA_SetHostTriggerRequest(pHandle->tStatus.pTOM);
|
|
}
|
|
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Stop the PWM channel.
|
|
*
|
|
* @param pHandle Pointer to the PWM channel handle, containing necessary channel information.
|
|
* @param bImmediate Boolean value indicating whether to immediately stop the PWM output.
|
|
*/
|
|
void EFTU_TOM_StopPwmChannel(EFTU_Tom_ChannelHandleType *pHandle, bool bImmediate)
|
|
{
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
/* Verify the handle during development to ensure its validity. */
|
|
if (TRUE == EFTU_TOM_VerifyHandle(pHandle, EFTU_TOM_START_TIMER_CHANNEL_ID))
|
|
{
|
|
#endif
|
|
/* Disable the channel's update trigger, which is a necessary condition for stopping the PWM output. */
|
|
EFTU_TOM_HWA_DisableChannelOnUpdateTrig(EFTU_TOM_CHANNEL(pHandle));
|
|
EFTU_TOM_HWA_DisableChannelOutputOnUpdateTrig(EFTU_TOM_CHANNEL(pHandle));
|
|
/* If immediate stop is required, disable the channel. */
|
|
if (TRUE == bImmediate)
|
|
{
|
|
EFTU_TOM_HWA_SetHostTriggerRequest(pHandle->tStatus.pTOM);
|
|
}
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Update the PWM period and duty cycle
|
|
*
|
|
* @param pHandle Pointer to the channel handle, containing channel status and configuration information
|
|
* @param fPeriod New PWM period in seconds
|
|
* @param fDuty New PWM duty cycle in seconds
|
|
* @param bUpdate Flag indicating whether to immediately update the hardware registers
|
|
*/
|
|
void EFTU_TOM_UpdatePwmPeriodAndDuty(EFTU_Tom_ChannelHandleType *pHandle, float fPeriod, float fDuty, bool bUpdate)
|
|
{
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
/**
|
|
* Verify handle validity and mode
|
|
*/
|
|
if (TRUE == EFTU_TOM_VerifyHandleWithMode(pHandle, EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_MODE_PWM))
|
|
{
|
|
/**
|
|
* Check if phase shift is enabled, report error if true
|
|
*/
|
|
if (TRUE == pHandle->tStatus.tPwm.bPhaseShiftEnable)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_E_PWM_MODE);
|
|
}
|
|
/**
|
|
* Check if duty cycle is greater than period, report error if true
|
|
*/
|
|
else if (fDuty > fPeriod)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_E_TIME_INVALID);
|
|
}
|
|
/**
|
|
* Check if the calculated period exceeds the hardware counter range for different modes and configurations
|
|
*/
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
else if( ((FALSE == pHandle->tStatus.tPwm.bUpDownMode) && (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport))
|
|
#else
|
|
else if( (FALSE == pHandle->tStatus.tPwm.bUpDownMode)
|
|
#endif
|
|
&& (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPeriod) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_E_TIME_INVALID);
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
else if( ((FALSE == pHandle->tStatus.tPwm.bUpDownMode) && (TRUE == pHandle->tStatus.tPwm.bHrpwmSupport))
|
|
&& (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPeriod * 32.0f) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_E_TIME_INVALID);
|
|
}
|
|
#endif
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
else if( ((TRUE == pHandle->tStatus.tPwm.bUpDownMode) && (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport))
|
|
#else
|
|
else if( (TRUE == pHandle->tStatus.tPwm.bUpDownMode)
|
|
#endif
|
|
&& ((EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPeriod) >> 1U) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_E_TIME_INVALID);
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
else if( ((TRUE == pHandle->tStatus.tPwm.bUpDownMode) && (TRUE == pHandle->tStatus.tPwm.bHrpwmSupport))
|
|
&& ((EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPeriod * 32.0f) >> 1U) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_E_TIME_INVALID);
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
#endif
|
|
uint32_t u32Cm0, u32Cm1;
|
|
/**
|
|
* Update the period and duty cycle values in the handle
|
|
*/
|
|
pHandle->tStatus.tPwm.fPeriodPhaseShift = fPeriod;
|
|
pHandle->tStatus.tPwm.fDuty = fDuty;
|
|
/**
|
|
* Calculate CM0 and CM1 values based on up/down count mode and HRPWM support
|
|
*/
|
|
if (TRUE == pHandle->tStatus.tPwm.bUpDownMode)
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPeriod) >> 1U;
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, (fPeriod - fDuty)) >> 1U;
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPeriod * 32.0f) >> 1U;
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, (fPeriod - fDuty) * 32.0f) >> 1U;
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPeriod);
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPeriod * 32.0f);
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty * 32.0f);
|
|
}
|
|
#endif
|
|
}
|
|
/**
|
|
* Write the calculated values to the hardware registers based on the update mode
|
|
*/
|
|
if (EFTU_TOM_PWM_UPDATE_SYNC == pHandle->tStatus.tPwm.eUpdateMode)
|
|
{
|
|
EFTU_TOM_HWA_DisableChannelUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
EFTU_TOM_HWA_SetShadowValue0(EFTU_TOM_CHANNEL(pHandle), u32Cm0);
|
|
EFTU_TOM_HWA_SetShadowValue1(EFTU_TOM_CHANNEL(pHandle), u32Cm1);
|
|
if (TRUE == bUpdate)
|
|
{
|
|
EFTU_TOM_HWA_EnableChannelUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
EFTU_TOM_HWA_SetCCU0Compare(EFTU_TOM_CHANNEL(pHandle), u32Cm0);
|
|
EFTU_TOM_HWA_SetCCU1Counter(EFTU_TOM_CHANNEL(pHandle), u32Cm1);
|
|
}
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Updates the PWM duty cycle for a given channel handle.
|
|
*
|
|
* @param pHandle Pointer to the PWM channel handle structure containing the channel status and configuration.
|
|
* @param fDuty The new duty cycle value to be set.
|
|
* @param bUpdate A boolean flag indicating whether to immediately update the hardware.
|
|
*/
|
|
void EFTU_TOM_UpdatePwmDuty(EFTU_Tom_ChannelHandleType *pHandle, float fDuty, bool bUpdate)
|
|
{
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
/**
|
|
* Verify the validity of the channel handle.
|
|
*/
|
|
if (TRUE == EFTU_TOM_VerifyHandleWithMode(pHandle, EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_MODE_PWM))
|
|
{
|
|
bool bValid = TRUE;
|
|
/**
|
|
* Check if phase shift is enabled.
|
|
*/
|
|
if (TRUE == pHandle->tStatus.tPwm.bPhaseShiftEnable)
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
/**
|
|
* Check if HRPWM support is enabled.
|
|
*/
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
/**
|
|
* Ensure the new duty cycle plus phase shift does not exceed the counter range.
|
|
*/
|
|
if (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty + pHandle->tStatus.tPwm.fPeriodPhaseShift) > 0xFFFFFF)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_DUTY_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
/**
|
|
* Ensure the new duty cycle plus phase shift does not exceed the HRPWM counter range.
|
|
*/
|
|
if (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, (fDuty + pHandle->tStatus.tPwm.fPeriodPhaseShift) * 32.0f) > 0xFFFFFF)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_DUTY_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
/**
|
|
* Ensure the phase shift is not less than the duty cycle.
|
|
*/
|
|
else if (pHandle->tStatus.tPwm.fPeriodPhaseShift < fDuty)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_DUTY_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
else
|
|
{
|
|
/**
|
|
* Check if up-down mode is enabled.
|
|
*/
|
|
if (TRUE == pHandle->tStatus.tPwm.bUpDownMode)
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
/**
|
|
* Ensure the new duty cycle does not exceed the counter range in up-down mode.
|
|
*/
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
if ((EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty) >> 1U) > 0xFFFFFF)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_DUTY_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
if ((EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty * 32.0f) >> 1U) > 0xFFFFFF)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_DUTY_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
/**
|
|
* Ensure the new duty cycle does not exceed the counter range.
|
|
*/
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
if (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty) > 0xFFFFFF)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_DUTY_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
if (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty * 32.0f) > 0xFFFFFF)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_DUTY_ID, EFTU_TOM_E_TIME_INVALID);
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If all checks pass, update the PWM configuration.
|
|
*/
|
|
if (TRUE == bValid)
|
|
{
|
|
#endif
|
|
uint32_t u32Cm1;
|
|
/**
|
|
* Update the duty cycle in the channel status.
|
|
*/
|
|
pHandle->tStatus.tPwm.fDuty = fDuty;
|
|
/**
|
|
* Calculate the new counter value based on the configuration.
|
|
*/
|
|
if (TRUE == pHandle->tStatus.tPwm.bPhaseShiftEnable)
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty + pHandle->tStatus.tPwm.fPeriodPhaseShift);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, (fDuty + pHandle->tStatus.tPwm.fPeriodPhaseShift) * 32.0f);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if (TRUE == pHandle->tStatus.tPwm.bUpDownMode)
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pHandle->tStatus.tPwm.fPeriodPhaseShift - fDuty) >> 1U;
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, (pHandle->tStatus.tPwm.fPeriodPhaseShift - fDuty) * 32.0f) >> 1U;
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fDuty * 32.0f);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update the hardware based on the update mode.
|
|
*/
|
|
if (EFTU_TOM_PWM_UPDATE_SYNC == pHandle->tStatus.tPwm.eUpdateMode)
|
|
{
|
|
/**
|
|
* Update the hardware based on the update mode.
|
|
*/
|
|
EFTU_TOM_HWA_DisableChannelUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
EFTU_TOM_HWA_SetShadowValue1(EFTU_TOM_CHANNEL(pHandle), u32Cm1);
|
|
if (TRUE == bUpdate)
|
|
{
|
|
EFTU_TOM_HWA_EnableChannelUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/**
|
|
* Directly set the counter value.
|
|
*/
|
|
EFTU_TOM_HWA_SetCCU1Counter(EFTU_TOM_CHANNEL(pHandle), u32Cm1);
|
|
}
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Update the PWM phase shift for a given channel.
|
|
*
|
|
* This function updates the phase shift of the PWM output for a specified channel. Before performing the update,
|
|
* it checks the validity of the phase shift based on different conditions. It calculates the corresponding clock counts
|
|
* based on whether the channel supports HRPWM (High-Resolution PWM) or not. Finally, it updates the PWM output either
|
|
* synchronously or asynchronously based on the update mode.
|
|
*
|
|
* @param pHandle Pointer to the channel handle, containing configuration and status information.
|
|
* @param fPhaseShift The phase shift value to be updated.
|
|
* @param bUpdate Flag indicating whether to immediately update the channel configuration.
|
|
*/
|
|
void EFTU_TOM_UpdatePwmPhaseShfit(EFTU_Tom_ChannelHandleType *pHandle, float fPhaseShift, bool bUpdate)
|
|
{
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
/**
|
|
* Verify the channel handle and ensure the channel is in the correct mode.
|
|
*/
|
|
if (TRUE == EFTU_TOM_VerifyHandleWithMode(pHandle, EFTU_TOM_UPDATE_PWM_PERIOD_ID, EFTU_TOM_MODE_PWM))
|
|
{
|
|
/**
|
|
* Check if phase shift is enabled.
|
|
*/
|
|
if (TRUE != pHandle->tStatus.tPwm.bPhaseShiftEnable)
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PHASESHIFT_ID, EFTU_TOM_E_PWM_MODE);
|
|
}
|
|
/**
|
|
* For channels that do not support HRPWM, check if the sum of phase shift and duty cycle exceeds the maximum count.
|
|
*/
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
else if ( (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
&& (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPhaseShift + pHandle->tStatus.tPwm.fDuty) > 0xFFFFFF))
|
|
#else
|
|
else if (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPhaseShift + pHandle->tStatus.tPwm.fDuty) > 0xFFFFFF)
|
|
#endif
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PHASESHIFT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
}
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
/**
|
|
* For channels that support HRPWM, perform a similar check but multiply the count by 32.
|
|
*/
|
|
else if ( (TRUE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
&& (EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, (fPhaseShift + pHandle->tStatus.tPwm.fDuty) * 32.0f) > 0xFFFFFF))
|
|
{
|
|
EftuTom_ReportDevError(EFTU_TOM_UPDATE_PWM_PHASESHIFT_ID, EFTU_TOM_E_TIME_INVALID);
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
#endif
|
|
uint32_t u32Cm1, u32Cm0;
|
|
/**
|
|
* Update the phase shift value.
|
|
*/
|
|
pHandle->tStatus.tPwm.fPeriodPhaseShift = fPhaseShift;
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
/**
|
|
* Calculate CM0 and CM1 values based on whether HRPWM is supported.
|
|
*/
|
|
if (FALSE == pHandle->tStatus.tPwm.bHrpwmSupport)
|
|
{
|
|
#endif
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPhaseShift);
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, pHandle->tStatus.tPwm.fDuty + fPhaseShift);
|
|
#if defined(HRPWM_INSTANCE_COUNT) && (HRPWM_INSTANCE_COUNT > 0U)
|
|
}
|
|
else
|
|
{
|
|
u32Cm0 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, fPhaseShift * 32.0f);
|
|
u32Cm1 = EFTU_TOM_HANDLE_CLOCK_COUNT(pHandle, (pHandle->tStatus.tPwm.fDuty + fPhaseShift) * 32.0f);
|
|
}
|
|
#endif
|
|
/**
|
|
* Update the PWM output based on the update mode.
|
|
*/
|
|
if (EFTU_TOM_PWM_UPDATE_SYNC == pHandle->tStatus.tPwm.eUpdateMode)
|
|
{
|
|
EFTU_TOM_HWA_DisableChannelUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
EFTU_TOM_HWA_SetShadowValue0(EFTU_TOM_CHANNEL(pHandle), u32Cm0);
|
|
EFTU_TOM_HWA_SetShadowValue1(EFTU_TOM_CHANNEL(pHandle), u32Cm1);
|
|
if (TRUE == bUpdate)
|
|
{
|
|
EFTU_TOM_HWA_EnableChannelUpdate(EFTU_TOM_CHANNEL(pHandle));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
EFTU_TOM_HWA_SetCCU0Compare(EFTU_TOM_CHANNEL(pHandle), u32Cm0);
|
|
EFTU_TOM_HWA_SetCCU1Counter(EFTU_TOM_CHANNEL(pHandle), u32Cm1);
|
|
}
|
|
#if EFTU_TOM_DEV_ERROR_REPORT == STD_ON
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Synchronizes and updates the control registers of the EFTU TOM module.
|
|
*
|
|
* This function updates the global control registers of the EFTU TOM module based on the update mask.
|
|
* It processes the update mask to determine which configuration bits need to be updated and applies
|
|
* the changes to the appropriate control registers.
|
|
*
|
|
* @param eEftuInstance The instance type of the EFTU device.
|
|
* @param u16UpdateMask A 16-bit update mask where each bit represents a configuration item to be updated.
|
|
*/
|
|
void EFTU_TOM_SyncUpdate(EFTU_InstanceType eEftuInstance, uint16_t u16UpdateMask)
|
|
{
|
|
uint32_t u32Mask = 0U, u32Loop;
|
|
uint32_t u32TempMask;
|
|
|
|
/* Build the mask for the updates */
|
|
for (u32Loop = 0U; u32Loop < 16U; u32Loop++)
|
|
{
|
|
if (u16UpdateMask & (1U << u32Loop))
|
|
{
|
|
u32Mask |= (2U << (u32Loop << 1U));
|
|
}
|
|
}
|
|
|
|
/* Process updates for TOM0 */
|
|
u32TempMask = (u32Mask & 0xFFFFU) << EFTU_TOM_TGC_GLB_CTRL_UPEN_CTRL0_SHIFT;
|
|
if (0U != u32TempMask)
|
|
{
|
|
EFTU_TOM_Type *pTOM = (EFTU_TOM_Type * )(g_aEftuBaseAddress[eEftuInstance] + EFTU_TOM0_BASE);
|
|
uint32_t u32Value = EFTU_TOM_HWA_GetGlobalControl(pTOM);
|
|
u32Value = (u32Value & 0x0000FFFF) | u32TempMask;
|
|
EFTU_TOM_HWA_SetGlobalControl(pTOM, u32Value);
|
|
}
|
|
|
|
/* Process updates for TOM1 */
|
|
u32TempMask = u32Mask & 0xFFFF0000;
|
|
if (0U != u32TempMask)
|
|
{
|
|
EFTU_TOM_Type *pTOM = (EFTU_TOM_Type * )(g_aEftuBaseAddress[eEftuInstance] + EFTU_TOM1_BASE);
|
|
uint32_t u32Value = EFTU_TOM_HWA_GetGlobalControl(pTOM);
|
|
u32Value = (u32Value & 0x0000FFFF) | u32TempMask;
|
|
EFTU_TOM_HWA_SetGlobalControl(pTOM, u32Value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Interrupt service routine for the EFTU TOM channel.
|
|
*
|
|
* This function handles the interrupt requests for the EFTU TOM channel. It retrieves the interrupt flags,
|
|
* clears them, and then calls the appropriate callback functions if the corresponding interrupt flags are set
|
|
* and the callbacks are not null.
|
|
*
|
|
* @param pHandle Pointer to the handle of the EFTU TOM channel.
|
|
*/
|
|
void EFTUn_TOM_IRQHandler(EFTU_Tom_ChannelHandleType *pHandle)
|
|
{
|
|
uint32_t u32Flag = EFTU_TOM_HWA_GetInterruptFlag(EFTU_TOM_CHANNEL(pHandle));
|
|
EFTU_TOM_HWA_ClearInterruptFlag(EFTU_TOM_CHANNEL(pHandle), u32Flag);
|
|
|
|
/* Check and call CCU0 interrupt callback if set */
|
|
if ((u32Flag & EFTU_TOM_CHn_IRQ_ST_CCU0TC_MASK) && (pHandle->tStatus.tCallback.pCcu0 != NULL))
|
|
{
|
|
pHandle->tStatus.tCallback.pCcu0(pHandle);
|
|
}
|
|
|
|
/* Check and call CCU1 interrupt callback if set */
|
|
if ((u32Flag & EFTU_TOM_CHn_IRQ_ST_CCU1TC_MASK) && (pHandle->tStatus.tCallback.pCcu1 != NULL))
|
|
{
|
|
pHandle->tStatus.tCallback.pCcu1(pHandle);
|
|
}
|
|
}
|
|
|
|
#endif /* defined(EFTU_INSTANCE_COUNT) && (EFTU_INSTANCE_COUNT > 0) */
|