rp2: Can't wake from lightsleep with Pin IRQ
On a pin change this code sample toggles the LED but never outputs "got here".
from machine import Pin, lightsleep
p25 = Pin(25, Pin.OUT)
p0 = Pin(0, Pin.IN, Pin.PULL_UP)
def foo(_):
p25(not p25()) # Toggle the LED
p0.irq(foo, trigger=Pin.IRQ_FALLING)
while True:
lightsleep()
print('Got here')
The docs indicate that to fix this, the IRQ should be instantiated with wake=machine.SLEEP. Unfortunately this constant does not exist.
Zephyr: Allow machine.lightsleep() to be interruptable by Pin IRQs.
Summary
This PR builds on the machine.lightsleep() work by @ThinkTransit (#16864) by adding the ability for GPIO interrupts to interrupt lightsleep().
This allows Pin.irq() configured interrupts to wake the system from
lightsleep mode, enabling efficient low-power applications that respond
to external events like button presses, or other
GPIO-based wake sources.
It also enables efficient low-power sensor applications where accelerometers,
gyroscopes, and other sensors can wake the system on motion, threshold
crossing, or data ready events.
Testing
I've tested this on the XIAO BLE NRF52840 board. I did find that because the REPL was disabled during machine.lightsleep() it was difficult or impossible to interrupt my test program with the keyboard.
Trade-offs and Alternatives
The prior machine.lightsleep() PR (#16864) adds 1312 bytes of flash and 128 bytes of RAM.
This PR alone adds 56 bytes of flash and 0 bytes of RAM.