Skip to content

WIP: rp2: Enable GPIO wakeup from indefinite lightsleep, document sleep modes. - #16442

Draft
projectgus wants to merge 4 commits into
micropython:masterfrom
projectgus:bugfix/rp2_lightsleep_indefinite_wake
Draft

projectgus wants to merge 4 commits into
micropython:masterfrom
projectgus:bugfix/rp2_lightsleep_indefinite_wake

Conversation

@projectgus

@projectgus projectgus commented Dec 18, 2024 •

Copy link
Copy Markdown
Contributor

Summary

Make the Pin.irq() wakeup behaviour more consistent on rp2. Closes #7035 and Closes #16180 (the last part of that issue to need fixing.)

  • Make it so any pin which has a Pin.irq() trigger set will wake rp2 port from any machine.lightsleep() call. (Previously this only worked if lightsleep had a timeout and the IRQ had a handler set.)
  • Don't use the lowest power DORMANT mode if USB is active. Similar to rp2: Fix USB PLL glitch during wake from light sleep. #15301 it seems like disabling the USB clock while a device is enumerated leads to intermittent failures on wakeup. If USB is active then rp2 will now enter the higher level sleep mode only, the same one which is used if a timeout is set (in addition, the board is usually woken almost immediately by the USB host so this configuration doesn't save much power.)
  • Document the rp2 sleep and low power modes and their capabilities/limitations.
  • Add some notes in the machine documentation about sleep mode differences between ports.

TODOs

  • Waking from lightsleep appears to clobber the UART settings
  • Full testing

This work was funded through GitHub Sponsors.

Testing

  • TBD

Trade-offs and Alternatives

  • Instead of not allowing DORMANT mode when USB is active, we could first disable the USB device entirely (so the host sees it disconnect) and then go to DORMANT mode. Unclear if there's any use case that this would be useful for, though...?

@github-actions

github-actions Bot commented Dec 18, 2024 •

Copy link
Copy Markdown

Code size report:

Reference:  rp2: Run vm/gc/parse from SRAM by fixing linker object suffix. [f452dab]
Comparison: docs: Add notes about port-specific lightsleep() differences. [merge of 0b3ba3e]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@Gadgetoid

Copy link
Copy Markdown
Contributor

Just ran afoul of this while testing #16454 so I'm dropping a cross reference in for posterity.

Before this commit, a Pin with an irq() trigger is a wakeup source only
when machine.lightsleep(n) is used with a timeout, and only if an IRQ
handler is set.

After this commit:

- A Pin with an irq() trigger is a wakeup source from both
  indefinite machine.lightsleep() and machine.lightsleep(n) with
  a timeout.

- A Pin with an irq() trigger is a wakeup source even if no handler
  function is set.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <[email protected]>
Similar to disabling the USB clock for other light sleep modes,
the DORMANT mode seems to put an active USB peripheral into a bad
state at least some of the time. Workaround by not selecting DORMANT
mode in this case.

Also removes the unused use_timer_alarm flag. Can be added back in the
future if someone wants to implement RTC wakeup from light sleep.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <[email protected]>
@projectgus
projectgus force-pushed the bugfix/rp2_lightsleep_indefinite_wake branch from 450901a to d5b698a Compare July 2, 2026 07:16
@projectgus projectgus changed the title WIP: rp2: Make GPIO wakeup from lightsleep consistent. WIP: rp2: Enable GPIO wakeup from normal mode, document sleepmodes. Jul 2, 2026
These modes have significant limitations that until now haven't been
documented.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <[email protected]>
@projectgus
projectgus force-pushed the bugfix/rp2_lightsleep_indefinite_wake branch from d5b698a to 0b3ba3e Compare July 2, 2026 07:27
@projectgus projectgus changed the title WIP: rp2: Enable GPIO wakeup from normal mode, document sleepmodes. WIP: rp2: Enable GPIO wakeup from indefinite lightsleep, document sleep modes. Jul 2, 2026
@Gadgetoid

Copy link
Copy Markdown
Contributor

Does Pick SDK 2.3.0's pico_low_power have any bearing here?

Right now we're shouldering a near duplicate of runtime_init_clocks and it feels like there ought to be a way to... not do that 😆

@projectgus

Copy link
Copy Markdown
Contributor Author

Does Pick SDK 2.3.0's pico_low_power have any bearing here?

I hadn't seen this API, thanks @Gadgetoid! This does look like the way forward.

Right now we're shouldering a near duplicate of runtime_init_clocks and it feels like there ought to be a way to... not do that 😆

Yes. There's a ticket open on pico-sdk for this (raspberrypi/pico-sdk#1746) - but it looks like pico_low_power might be the solution for it, already shipping. 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lightsleep() not working properly Pi Pico WH v1.24.0 rp2: Can't wake from lightsleep with Pin IRQ

2 participants