Closed coplate closed 2 years ago
Im having an hard time getting the script to work at all. Could you maybe send me your script and setup?
Here is my complete test case. I have wired 3 buttons to pins from 3V3_OUT to GP20, GP21, GP22. On test1 and test2, only pin GP20 will wake my device. ( using dormant_with_modes ). On test3 and test4, only GP21 will wake my device. ( using dormant_until_pins ). I am using a momentary button, so the button is reset during the flashing that occurs after waking, and my test is not misinterpreting the results be having the erroneous data go to the next call - but a more careful test could put a pause between them.
Edit: I added some log statement, to see what was being set in the registers, and I got this:
registers_events[en_reg] = registers_events[en_reg] + pin_mode << 4 * (gpio_pin % 8)
+ print(hex(en_reg))
+ print(hex(registers_events[en_reg]))
0x40014168 0xc00000 0x40014168 0xc0000c000000 0x40014168 0xc0000c00000c0000
That final log entry is 64 bits long, instead of the 32 bits that should be written to the register - I will move the rest of these notes to a new comment
from machine import Pin
from time import sleep
import lowpower
DORMANT_PIN_A = 20
DORMANT_PIN_B = 21
DORMANT_PIN_C = 22
LED_PIN = 25
busy_led = Pin(LED_PIN, Pin.OUT)
def blink_led():
for i in range(8):
busy_led.value(1)
sleep(0.03)
busy_led.value(0)
sleep(0.03)
#Test 1, only GP20 will wake the PI, which is the lowest, and the final in the list
def test1():
lowpower.dormant_with_modes({
DORMANT_PIN_C: (lowpower.EDGE_LOW | lowpower.EDGE_HIGH),
DORMANT_PIN_B: (lowpower.EDGE_LOW | lowpower.EDGE_HIGH),
DORMANT_PIN_A: (lowpower.EDGE_LOW | lowpower.EDGE_HIGH)
})
blink_led()
#Test 2, only GP20 will wake the PI, which is the lowest, and the first in the list
def test2():
lowpower.dormant_with_modes({
DORMANT_PIN_A: (lowpower.EDGE_LOW | lowpower.EDGE_HIGH),
DORMANT_PIN_B: (lowpower.EDGE_LOW | lowpower.EDGE_HIGH),
DORMANT_PIN_C: (lowpower.EDGE_LOW | lowpower.EDGE_HIGH)
})
blink_led()
#Test 3, onlt GP 21 will wake the Pi, which is the highest and the final in the list
def test3():
lowpower.dormant_until_pins([DORMANT_PIN_A, DORMANT_PIN_B], high=False)
blink_led()
#Test 3, onlt GP 21 will wake the Pi, which is the highest and the first in the list
def test4():
lowpower.dormant_until_pins([DORMANT_PIN_B, DORMANT_PIN_A ], high=False)
blink_led()
blink_led()
test1()
test2()
test3()
test4()
I added more logging and found the problem on this line:
registers_events[en_reg] = registers_events[en_reg] + pin_mode << 4 * (gpio_pin % 8)
It appears to be doing a concatenation on the version of micropython I have "MicroPython v1.18 on 2022-01-17; Raspberry Pi Pico with RP2040", instead of integer addition.
I changed it to a bitwise or |
, and got these results:
Adding pin: 21
0x40014168
0xc00000
0b110000000000000000000000
Adding pin: 22
0x40014168
0xcc00000
0b1100110000000000000000000000
Adding pin: 20
0x40014168
0xccc0000
0b1100110011000000000000000000
Those are the correct bits.
I have created Pull request https://github.com/tomjorquera/pico-micropython-lowpower-workaround/pull/10 for this.
Thanks for catching that @coplate! That was big one on my side.
Your PR is merged
I was looking at this to use to wake my pico, and noticed that only the highest pin in the list will trigger the wake. i.e.:
lowpower.dormant_until_pins([12, 13], high=False)
only pin 13 wakeslowpower.dormant_until_pins([13, 12 ], high=False)
pin 13 also wakeslowpower.dormant_until_pins([12 ], high=False)
pin 12 wakes properlyFor my use case it is fine, I will be feeding it with one pin from an RTC alarm, but I thought I would file the issue to let you know. I have not read deep into the documentation to really understand what is going on with the registers.