Repository navigation
drivers: pwm: mcux_sctimer: counter stranded when device resumes before first channel config #111888
Description
Describe the bug
On frdm_rw612 (NXP RW612 SoC), using the MCUX SCTimer PWM driver
(drivers/pwm/pwm_mcux_sctimer.c), the SCTimer counter
can be left in a state where PWM output does not toggle for ~2 minutes after the
device resumes.
mcux_sctimer_pwm_pm_action() handles PM_DEVICE_ACTION_RESUME by
unconditionally starting the unified counter:
case PM_DEVICE_ACTION_RESUME:
#ifdef CONFIG_PM_DEVICE
SCTIMER_StartTimer(config->base, kSCTIMER_Counter_U);
#endifIf a resume occurs before any channel has been configured (i.e. before the
first pwm_set_cycles() call), no period match register and no counter-limit
event have been set up yet. The freshly started unified counter therefore
free-runs across its entire 32-bit range with nothing to reset it. A resume happens
at the start of the app even with CONFIG_PM=n
When a channel is subsequently configured, mcux_sctimer_new_channel() programs
the period match via the MCUX SDK (SCTIMER_SetupPwm) but does not clear the
current COUNT value. The SCTimer counter-limit only fires on exact equality
(COUNT == match). If the free-running counter has already advanced past the
newly programmed match value, the limit condition is missed and the counter must
climb all the way to 0xFFFFFFFF and wrap back to 0 before it can hit the
match. Until that wrap occurs the period/pulse events do not fire, so the PWM
output is stuck at its inactive level. On frdm_rw612 the 32-bit counter wraps
after roughly 2 minutes, at which point PWM output resumes normally.
- Target platform:
frdm_rw612(NXP RW612 SoC). This is the only platform on
which the failure has been confirmed. - Diagnosis: the stall window opens
PM_DEVICE_ACTION_RESUMEis
delivered ahead of the first channel configuration.
Regression
- This is a regression.
Steps to reproduce
Use the in-tree
samples/basic/blinky_pwm
sample. frdm_rw612 enables the &sctimer controller and defines a
pwm-0 = &sctimer alias, but it has no pwm-leds node and no pwm-led0 alias,
and the sample ships no frdm_rw612 overlay — so a consumer must be supplied to
exercise the driver at all (and to create the resume-before-first-channel
ordering).
-
Add
samples/basic/blinky_pwm/boards/frdm_rw612.overlay:/ { pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led0 { pwms = <&sctimer 0 PWM_USEC(100) PWM_POLARITY_NORMAL>; }; }; aliases { pwm-led0 = &pwm_led0; }; }; -
Build and flash the sample with PM enabled:
west build -b frdm_rw612 samples/basic/blinky_pwm -- -DCONFIG_PM=y -DCONFIG_PM_DEVICE=y west flash -
The SCTimer device resumes before the sample issues its first
pwm_set_cycles(). Observe (scope/logic analyzer on the PWM output) that the
output is held at its inactive level and does not toggle for ~2 minutes,
after which the 32-bit counter wraps and PWM output begins normally.
Relevant log output
Impact
Functional Limitation – Some features not working as expected, but system usable.
Environment
- OS: Windows
- Toolchain: Zephyr SDK
- Commit SHA or Version used: Zephyr v4.4
Additional Context
Fixed upstream by guarding the resume-path start so the counter only runs once at
least one channel is active:
case PM_DEVICE_ACTION_RESUME:
#ifdef CONFIG_PM_DEVICE
if (data->pwm_channel_active) {
SCTIMER_StartTimer(config->base, kSCTIMER_Counter_U);
}
#endif- PR: drivers: pwm: mcux_sctimer: guard counter start #111549
- The
pwm_channel_activeflag is set inmcux_sctimer_pwm_set_cycles()and was
already used to gate channel restore in thePM_DEVICE_ACTION_TURN_ONpath;
the fix reuses it to gate the resume-path counter start.
Activity
FelixWang47831 commentedon Jun 29, 2026
Close the issue as it has been fixed by #111549