WIP: rp2: Make GPIO wakeup from lightsleep consistent. #16442
+6
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Make the
Pin.irq()
wakeup behaviour more consistent on rp2. Closes #7035 and partial fix for #16180Goal is that any pin which has
Pin.irq()
and atrigger
set will wake rp2 port from anymachine.lightsleep()
call.Details
Currently:
machine.lightsleep(n)
is used with a timeout, and only if an IRQ handler is set.After this PR:
A Pin with an irq() trigger is a wakeup source from both indefinite
machine.lightsleep()
andmachine.lightsleep(n)
with a timeout.A Pin with an irq() trigger is a wakeup source even if no handler function is set.
TODOs
machine.lightsleep()
with no timeout and USB causes the USB connection to misbehave and eventually the CPU hangs. This is the same thing fixed for lightsleep with a timeout in rp2: Selectively leave the USB clocks enabled in light sleep. #15111 and rp2: Fix USB PLL glitch during wake from light sleep. #15301 . However, with no timeout argument the RP2 goes to the lower power "DORMANT" mode so keeping USB clock running isn't an option. Callingtud_disconnect()/tud_connect()
ortud_deinit()/tud_init()
before and after going to dormant mode doesn't seem to be enough to fix this. One heavy-handed workaround would be to not select DORMANT if USB is enabled, just call WFI instead. However, then the wakeup conditions are a lot different which may be confusing if developing and testing via USB and then deploying...This work was funded through GitHub Sponsors.
Testing
Trade-offs and Alternatives
machine.lightsleep()
has had very limited utility until now (i.e. no possible wake source?) so maybe we should refactor to only use DORMANT mode for deep sleep where we don't have to worry about recovering the USB peripheral. Keeping clocks running does increase consumption, though.