rp2: Reading pin value from IRQ hangs forver
from machine import Pin, idle, disable_irq, enable_irq
from time import sleep_ms
pin = Pin(1, Pin.IN)
def on_change(pin):
state = disable_irq()
pin.value()
enable_irq(state)
pin.irq(on_change, Pin.IRQ_RISING | Pin.IRQ_FALLING)
for i in range(1000):
idle()
sleep_ms(100)
print("WORKING")
It seems impossible to read the value of the pin object passed as an argument to the callback. As soon as it is triggered the RPI Pico stop working until I unplug/replug it. Using the pin from the global context works or even recreating a new Pin instance, but not using the one passed as an argument
firmware: rp2-pico-20230116-unstable-v1.19.1-803-g1583c1f67.uf2
rp2: Repl hangs when printing in scheduled generator
You can reproduce this bug constantly by using following code and please use a wire to shortcut GPIO 22 and 26
from machine import SPI, Pin
from micropython import schedule
import micropython
i = Pin(22, Pin.IN, Pin.PULL_UP)
o = Pin(26, Pin.OUT, Pin.PULL_UP)
led = Pin(25, Pin.OUT, value = 0)
class IRQMachine:
def __init__(self, irq_pin):
self.irq_pin = irq_pin
self.irq_queue = []
self._irq_executor_ref = self._irq_executor
self.irq_pin.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=lambda pin: schedule(self._irq_executor_ref, pin.irq().flags()))
def irq(self, func, *args):
gen = func(*args)
self.irq_queue.append(gen)
next(gen)
def _irq_executor(self, irq_flags):
for gen in self.irq_queue:
try:
gen.send(irq_flags)
except StopIteration:
self.irq_queue.remove(gen)
def print_something():
print("hello")
flags = yield
if flags & Pin.IRQ_FALLING:
print('pull down')
micropython.mem_info()
o.value(1)
machine = IRQMachine(i)
machine.irq(print_something)
o.value(0)
The code itself is a simple co-routine implementation based on generator, the method will stop execution on yield and restore execution when IRQ comes
After running the code, output will look like this, the pull down became unexpected red and REPL stops work
<img width="991" alt="image" src="https://user-images.githubusercontent.com/1770466/154853247-b58ea050-865c-4bf7-af6f-f79936a99609.png">
But if we remove print(), replace it with something like turn on the LED, it will work fine
Tested on Raspberry Pi Pico, not sure other ports/boards has same issue