← index #9006PR #16431
Related · high · value 1.029
QUERY · ISSUE

Lightsleep with sleep period set to a value never waking

openby guillochonopened 2022-08-01updated 2026-03-09
bugport-rp2

I'm currently running a program on a Pico W where I am trying to lightsleep(5000). Unfortunately, the program seems to never wake up again after this call. Using a time.sleep instead and the Pico does wake up as expected, but of course with much more power draw.

I am running this nightly: https://micropython.org/resources/firmware/rp2-pico-w-20220729-unstable-v1.19.1-223-g963e599ec.uf2

CANDIDATE · PULL REQUEST

rp2: Fix soft timer expiry waking early from lightsleep.

closedby projectgusopened 2024-12-17updated 2025-03-17
bugport-rp2

Summary

Fixes #16181 and partial fix for #16180. Specifically: bug where PICO-W build won't lightsleep() for more than 64ms.

Details

This is a regression introduced in 74fb42a (#13329) when we switched away from the pico-sdk alarm pool for soft timers and accidentally made soft timer expiry a wakeup source.

Before 74fb42a (including V1.23), both the pico-sdk alarm pool and the lightsleep wakeup timer uses alarm 3. The lightsleep timer would quietly clobber alarm 3's timeout, meaning softtimer events wouldn't wake the chip from lightsleep.

After 74fb42a (including V1.24), soft timer wakeup happens on timer alarm 2 so this interrupt can wake the chip from light sleep. On PICO-W builds this happens every lwIP tick (64ms) which is unexpected.

The change here is to go back to using the same timer alarm for both lightsleep wakeup and soft timer, but now being explicit about lightsleep wakeup clobbering any soft timer wakeup. Also adds a "catch up" call to soft timer handler as it's not currently there.

This also reworks the changes added in 19844b4 to enable the timer IRQ on CPU1. The functionality is basically the same, just being a bit more explicit and by reworking this and the other code there's no more "magic IRQ number 3" in this code.

Thanks to @cpottle9 for investigating this issue and pinpointing 74fb42a as the regression commit. :pray:

This work was funded through GitHub Sponsors.

Testing

  • Basic test case on PICO-W.
  • Unit tests pass on PICO-W.
  • Test wakeup from pin IRQ as also reported in #16180 (might need to be fixed separately). (Note: Tested this works provided timeout is provided, issue without timeout is tracked in #7035)
  • Test on RP2350 (help wanted, have ordered hardware but probably won't get until next year).
  • Add unit test for light sleep running from thread on core1.
  • Add unit test verifying that soft timer callbacks resume after waking from lightsleep. EDIT: Can't do this actually, as machine.Timer() uses the alarm pool. However, lightsleep and Wi-Fi are compatible so soft timer is resuming OK.
  • Test Wi-Fi stays valid after lightsleep (with a timeout).

Trade-offs and Alternatives

  • We were hoping to go back to the pico-sdk alarm pool rather than using our own hardware timer alarm now that https://github.com/raspberrypi/pico-sdk/issues/1812 is closed, however @dpgeorge mentioned here that the new version of the alarm pool may have another bug - maybe the one fixed in https://github.com/raspberrypi/pico-sdk/pull/2127 ?
  • In general, it might be expected that soft timers added by Python code can wake the rp2 from lightsleep. In that case, we could fix this by disabling the 64ms lwIP tick wakeup timer before going to lightsleep. Lightsleep wakeup could then be just another soft timer entry.
  • More extreme analysis would be that lwIP tick should wake from lightsleep so that TCP connections can stay up, etc. I'm not sure I buy this one as the rp2 port is already tickless so "idle" is close to this behaviour, but you could make the case. If doing that instead then we should at least disable the lwIP tick while no network interface is up, though.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied