Hello,
I am working with SCTimer to generate a PWM signal.
This signal I need to change the period and duty cycle frequently.
I have created a function in fs_timer library using the code of " SCTIMER_UpdatePwmDutycycle".
The function works when stepping in debug mode step by step, but when runing normal it stops generating the pulses. I am missing abything needed to change the match register and do not break anything?
The following is the function code used:
void SCTIMER_UpdatePwmPeriod(SCT_Type *base, sctimer_out_t output,
sctimer_pwm_mode_t mode,
uint32_t pwmFreq_Hz,
uint8_t dutyCyclePercent,
uint32_t srcClock_Hz,
uint32_t event)
{
assert(0U != srcClock_Hz);
assert(0U != pwmFreq_Hz);
assert((uint32_t)output < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS);
assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK));
status_t status = kStatus_Fail;
status_t status2;
uint32_t period, pulsePeriod = 0;
uint32_t sctClock = srcClock_Hz / (((base->CTRL & SCT_CTRL_PRE_L_MASK) >> SCT_CTRL_PRE_L_SHIFT) + 1U);
uint32_t periodEvent = 0, pulseEvent = 0;
uint32_t reg;
uint32_t periodMatchReg, pulseMatchReg;
bool isHighTrue = (0U != (base->OUT[output].CLR & (1UL << (event + 1U))));
if ((s_currentEvent + 2U) <= (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS)
{
/* Calculate PWM period match value */
if (mode == kSCTIMER_EdgeAlignedPwm)
{
period = (sctClock / pwmFreq_Hz) - 1U;
}
else
{
period = sctClock / (pwmFreq_Hz * 2U);
}
/* For 100% dutycyle, make pulse period greater than period so the event will never occur */
if (dutyCyclePercent >= 100U)
{
pulsePeriod = period + 2U;
/* Set the initial output level base on output mode */
if (isHighTrue)
{
base->OUTPUT |= (1UL << (uint32_t)output);
}
else
{
base->OUTPUT &= ~(1UL << (uint32_t)output);
}
}
else
{
pulsePeriod = (uint32_t)(((uint64_t)period * dutyCyclePercent) / 100U);
}
/* Retrieve the match register number for the PWM period */
periodMatchReg = base->EV[event].CTRL & SCT_EV_CTRL_MATCHSEL_MASK;
/* Retrieve the match register number for the PWM pulse period */
pulseMatchReg = base->EV[event + 1U].CTRL & SCT_EV_CTRL_MATCHSEL_MASK;
/* Stop the counter before updating match register */
SCTIMER_StopTimer(base, (uint32_t)kSCTIMER_Counter_U);
/* Update dutycycle */
base->MATCH[periodMatchReg] = period;
base->MATCHREL[periodMatchReg] = period;
base->MATCH[pulseMatchReg] = pulsePeriod;
base->MATCHREL[pulseMatchReg] = pulsePeriod;
/* Restart the counter */
SCTIMER_StartTimer(base, (uint32_t)kSCTIMER_Counter_U);
}
}
Hello @luimarma
How about low the change frequency, it means delay the time before change period.
BR
Alice