Hi,
Finally, I get the root cause of the issue, the sctimer driver has problem.
Pls use the following code I modified, I have tested, it works well.
the cause of the issue is that the pulsePeriod variable is 0x75300 at most in 100Hz PWM signal, when it use the macro SCT_MATCHREL_RELOADn_L(pulsePeriod); high half word 0x7 will be removed, it results problem obviously. But when the pulsePeriod is less than 0xFFFF, no problem.
#if 0
base->MATCH[pulseMatchReg] = SCT_MATCH_MATCHn_L(pulsePeriod);
base->MATCHREL[pulseMatchReg] = SCT_MATCHREL_RELOADn_L(pulsePeriod);
#else
base->MATCH[pulseMatchReg] = pulsePeriod;
base->MATCHREL[pulseMatchReg] = pulsePeriod;
#endif
Pls modify the function in fsl_sctimer.c
BR
XiangJun Rong
/*!
* brief Updates the duty cycle of an active PWM signal.
*
* Before calling this function, the counter is set to operate as one 32-bit counter (unify bit is set to 1).
*
* param base SCTimer peripheral base address
* param output The output to configure
* param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100
* param event Event number associated with this PWM signal. This was returned to the user by the
* function SCTIMER_SetupPwm().
*/
void SCTIMER_UpdatePwmDutycycle(SCT_Type *base, sctimer_out_t output, uint8_t dutyCyclePercent, uint32_t event)
{
assert(dutyCyclePercent <= 100U);
assert((uint32_t)output < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS);
assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK));
uint32_t periodMatchReg, pulseMatchReg;
uint32_t pulsePeriod = 0, period;
/* 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;
period = base->MATCH[periodMatchReg];
/* Calculate pulse width and period match value:
* For EdgeAlignedPwm, "pulsePeriod = 0" results in 0% dutycyle, "pulsePeriod = period - 1U" results in 100%
* dutycyle. For CenterAlignedPwm, , "pulsePeriod = 0" results in 0% dutycyle, "pulsePeriod = period + 2U"
* results in 100% dutycyle.
*/
pulsePeriod = (uint32_t)(((uint64_t)period * dutyCyclePercent) / 100U);
if (dutyCyclePercent == 100U)
{
if (0U == (base->CTRL & SCT_CTRL_BIDIR_L_MASK))
{
pulsePeriod = period + 2U;
}
else
{
pulsePeriod = period - 1U;
}
}
/* Stop the counter before updating match register */
SCTIMER_StopTimer(base, (uint32_t)kSCTIMER_Counter_U);
/* Update dutycycle */
//////////Rong wrote, pls modify
#if 0
base->MATCH[pulseMatchReg] = SCT_MATCH_MATCHn_L(pulsePeriod);
base->MATCHREL[pulseMatchReg] = SCT_MATCHREL_RELOADn_L(pulsePeriod);
#else
base->MATCH[pulseMatchReg] = pulsePeriod;
base->MATCHREL[pulseMatchReg] = pulsePeriod;
#endif
/* Restart the counter */
SCTIMER_StartTimer(base, (uint32_t)kSCTIMER_Counter_U);
}