10000 rp2: Can't wake from lightsleep with Pin IRQ · Issue #7035 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

rp2: Can't wake from lightsleep with Pin IRQ #7035

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
peterhinch opened this issue Mar 15, 2021 · 28 comments · May be fixed by #16442
Open

rp2: Can't wake from lightsleep with Pin IRQ #7035

peterhinch opened this issue Mar 15, 2021 · 28 comments · May be fixed by #16442

Comments

@peterhinch
Copy link
Contributor

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.

@cipy
Copy link
cipy commented Mar 21, 2021

well, it looks like the docs is a bit ahead of its time. also there is no wake or priority parameter to .irq()

import machine
dir(machine)
['class', 'name', 'ADC', 'I2C', 'PWM', 'PWRON_RESET', 'Pin', 'SPI', 'SoftI2C', 'SoftSPI', 'Timer', 'UART', 'WDT', 'WDT_RESET', 'bootloader', 'deepsleep', 'disable_irq', 'enable_irq', 'freq', 'idle', 'lightsleep', 'mem16', 'mem32', 'mem8', 'reset', 'reset_cause', 'soft_reset', 'time_pulse_us', 'unique_id']

@tomjorquera
Copy link

For what I have seen, support does not seems implemented yet for the pico.

From my experiments, it seems that in the meantime you could try experimenting with using a function such as

@micropython.asm_thumb
def my_lightsleep():
    wfi()

wfi puts the pico into a suspended state until any interrupt is received (see https://docs.micropython.org/en/latest/reference/asm_thumb2_misc.html).

In itself it may not save a lot of energy, but it could serve as a workaround.

For my use case, I want to use the deepsleep mode, which does not seems to be supported yet either. So I have started cobbling together a small experimental lib to use while waiting for the feature to be added in micropython. If any tinkerer feels adventurous and want to give it a run and help improving things they are very welcome:

https://github.com/tomjorquera/pico-micropython-lowpower-workaround

@jmfloyd
Copy link
jmfloyd commented Apr 16, 2021

I have been looking at this, and have found that the raspberrypi/pic--extras repository has the code to activate dormant mode in the hardware_rosc module. It should be accompanied by a method to check that wake_irqs are set before calling the dormant mode.

My cloned repository jf-micropython-pico which also uses jf-pico-sdk repo shows how I implemented and use it. Wake on irq works well using micropython. This is just a proof of concept example. Where this code goes would be up for discusion by more knowledgable persons. I have some code in gpio and some in Pin. The code also needs to be extended to be workable with xosc, and allow transparent use depending on rosc or xosc being used. The repositories may not necessarily be up to date with the originals but still shows that dormant mode can easily be implemented.

@kevindawson
Copy link
  • lightsleep(int) - works
  • wake does not exist
  • machine.sleep() - This function is deprecated, use lightsleep() instead with no arguments.
  • Pin.irq - wake selects the power mode in which this interrupt can wake up the system. It can be machine.IDLE, machine.SLEEP or machine.DEEPSLEEP. These values can also be OR’ed together to make a pin generate interrupts in more than one power mode.

How about a disclaimer machine.Pin rp2 not fully implemented

@cipy
Copy link
cipy commented Apr 29, 2021

Hi @kevindawson

is there a new microPython build available for Pico?

the old/current one doesn't have .IDLE, .SLEEP, .DEEPSLEEP as I quoted above in this thread

@kevindawson
Copy link

@cipy
I was using rp2-pico-20210418-v1.15.uf2
are you saying I should be using
rp2-pico-20210427-unstable-v1.15-14-g65b90cd0f.uf2 (latest)

@cipy
Copy link
cipy commented Apr 29, 2021 via email

@kevindawson
Copy link

@cipy from: rp2-pico-20210418-v1.15.uf2

machine ['class', 'name', 'ADC', 'I2C', 'PWM', 'PWRON_RESET', 'Pin', 'SPI', 'Signal', 'SoftI2C', 'SoftSPI', 'Timer', 'UART', 'WDT', 'WDT_RESET', 'bootloader', 'deepsleep', 'disable_irq', 'enable_irq', 'freq', 'idle', 'lightsleep', 'mem16', 'mem32', 'mem8', 'reset', 'reset_cause', 'soft_reset', 'time_pulse_us', 'unique_id']

is this of any help

@jmfloyd
Copy link
jmfloyd commented Apr 29, 2021

Not much has changed with 1.15 and definitely nothing to do with sleep and wake.

Which is why I started looking at what was involved to implement a basic form of wake on pin interrupt. See my discussions previously.

@kevindawson
Copy link

@jmfloyd Thanks I will go and read

@industrialinternet
Copy link
industrialinternet commented May 7, 2021

@tomjorquera many thanks for this: pico-micropython-lowpower-workaround
Crude test with multi meter when in dormant on following rp2040 boards
Tiny 2040 2.9 mA
Feather 2040 1.7 mA

Though the Feather 2040 doesn't always restart when running lowpower_example.py

@tomjorquera
Copy link

Good to know @industrialinternet !

I don't have a feather, so I can't reproduce the issue you describe atm, but I created an an issue on my workaround repo.

@industrialinternet
Copy link

@tomjorquera I've got some TPL5111 Low Power Timers on order
I hoping that a cleaner electronic edge might be better that my glitch-ee human applied rising might resolve.
We chose the Feather as it has on-board charger.

I'm new to micropython but have done Squirrel & JavaScript on arm mcu's for IoT proof of concepts.
So I'm more used to call backs for serial coms & timers etc. but loving the experience to date.
I have a simple bme680 talking to long range wireless (LoRaWAN) and to the cloud for storage and viz.

@Herbert0209
Copy link

I was testing machine.deepsleep on Pico and it does not save any power, same as machine.sleep. However the lowpower.py works great for me. The powerconsumtion goes from 20mA to 1.1mA. Next step is to connect the DS3231

@peterhinch
Copy link
Contributor Author
peterhinch commented Jun 16, 2022

Problem with sleep now raised as #8770.

@Plaque-fcc
Copy link
Plaque-fcc commented Aug 13, 2022

Hi @kevindawson

is there a new microPython build available for Pico?

the old/current one doesn't have .IDLE, .SLEEP, .DEEPSLEEP as I quoted above in this thread

It's not even implemented in 1.19.1:


dir(machine)
['class', 'name', 'ADC', 'I2C', 'I2S', 'PWM', 'PWRON_RESET', 'Pin', 'RTC', 'SPI', 'Signal', 'SoftI2C', 'SoftSPI', 'Timer', 'UART', 'WDT', 'WDT_RESET', 'bitstream', 'bootloader', 'deepsleep', 'disable_irq', 'enable_irq', 'freq', 'idle', 'lightsleep', 'mem16', 'mem32', 'mem8', 'reset', 'reset_cause', 'soft_reset', 'time_pulse_us', 'unique_id']


(name='micropython', version=(1, 19, 1), _machine='Raspberry Pi Pico with RP2040', _mpy=4102)

@kevindawson
Copy link
kevindawson commented Aug 15, 2022

@tomjorquera
Copy link

Hey folks, and thank for the mention @kevindawson.

Sorry to kind of highjacking the topic, but I happen to be in the process of adding a fix made by another people for an issue reported by some user with the pico not going out of dormant mode.

It's currently in the following branch https://github.com/tomjorquera/pico-micropython-lowpower-workaround/tree/clear-clocks

I could not reproduce the bug myself, so if some folks want to help test things (and especially this new branch), while waiting for official support... 😉

@kevindawson
Copy link

@tomjorquera you are welcome
if i can find some time i will take a look
other wise I will eagerly await updates here ;)

Wind-stormger pushed a commit to BPI-STEAM/micropython that referenced this issue Oct 13, 2022
…n-main

Translations update from Hosted Weblate
@vrcoelho
Copy link

Are there any alternatives for nodemcu (esp8266)? The pico workaround does not seem to apply.

I wanted to use lightsleep in my application but once the microcontroller goes to that state, I can't not wake him up anymore. Waking up from deepsleep works fine.

@Plaque-fcc
Copy link

@Plaque-fcc

* have you looked at: https://github.com/tomjorquera/pico-micropython-lowpower-workaround by @tomjorquera see above?

* have you looked in here -> https://github.com/pimoroni/pimoroni-pico/releases

Thanks for these links. In fact, I was trying to have MicroPython on RP0204 waking up from lightsleep on interrupt from timer initialized according to the value passed to lightsleep. Waking from lightsleep or deepsleep on pin interrupt and saving power is a good thing to have, but this is a related (as I see it) problem, yet not the one I need to solve now.
Nevertheless, when I get to wake-from-pin interrupts, I'm gonna try the options you mentioned (unless the problem has been already fixed to that moment).

@Informaticore
Copy link

This is still not possible right? At least machine.SLEEP does still not exist but the documentation says so :(

@robert-hh
Copy link
Contributor
robert-hh commented Aug 23, 2023

The documentation tells about machine.sleep(): "This function is deprecated, use lightsleep() instead with no arguments."
But indeed, as told and documented, lightsleep without arguments never terminates.

@Informaticore
Copy link

The documentation tells about machine.sleep(): "This function is deprecated, use lightsleep() instead with no arguments." But indeed, as told, lightsleep without arguments never terminates.

I was talking about the Pin IRQ Wake - sorry if that was not clear enough.
Like in self.interrupt_pin.irq(trigger=Pin.IRQ_FALLING, handler=interrupt_handler, wake=machine.SLEEP)
machine.SLEEP does not exist so I can still not wake the RP2040 using an external pin input.

@robert-hh
Copy link
Contributor

That's right. At RP2 one cannot stop machine.lightsleep() or machine.deepsleep() with a Pin IRQ.

67E6

@Informaticore
Copy link

After some tests it seems that the RP2040 does at least react to IRQs (without setting them up with a wake flag). But somehow the IRQ only fires once in a while. I have sensors which trigger the IRQ and if the RP2 runs normal without sleep, it works as expected. If I set it to lightsleep it only gets like 30% of the interrupts.. which is a bit weird tbh.

So the IRQ works with lightsleep but not 100%, anyone else has this experiences?

@Tico06
Copy link
Tico06 commented Jan 4, 2024

Hi All,
I am interested in this fix, I subscribed to the thread. Hopefully it'll be fixed soon.

Thanks an Reg
Eric.

@projectgus projectgus linked a pull request Dec 18, 2024 that will close this issue
3 tasks
@projectgus
Copy link
Contributor < 99C8 /span>
projectgus commented Dec 18, 2024

I was looking into this just now, as a secondary issue to the regression reported in #16181.

I think the current situation for RP2040 is that Pin.irq(...) can wake the CPU from lightsleep, but only when two conditions are true:

  1. A timeout is passed to lightsleep, i.e. machine.lightsleep(120000) but not machine.lightsleep().
  2. A handler function is set (it can be an empty function, but something has to be set).

I've opened draft PR #16442 to make this more consistent, but there still a couple of things that need resolving before that's ready.

The docs indicate that to fix this, the IRQ should be instantiated with wake=machine.SLEEP. Unfortunately this constant does not exist.

FWIW, I think the only port with an irq(wake=) arg that matches the Pin docs is the cc3200 port. The immediate "fix" is probably to update the docs so they reflect the current heterogeneous pin wake-up behaviour, and then maybe aim for a new common wake-up API in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

0