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
Crash on RP2 with pin IRQ's
The problem has appeared on nightly builds since 20th Dec. This build fails: rp2-pico-20230120-unstable-v1.19.1-831-g4f3780a15.uf2. The following is the smallest repro I've come up with so far:
import uasyncio as asyncio
from machine import Pin
class Encoder:
def __init__(self):
pin_x = Pin(20, Pin.IN, Pin.PULL_UP)
pin_y = Pin(17, Pin.IN, Pin.PULL_UP)
self._x = 0
self._y = 0
self._v = 0
trig = Pin.IRQ_RISING | Pin.IRQ_FALLING
pin_x.irq(trigger=trig, handler=self._x_cb, hard=False)
pin_y.irq(trigger=trig, handler=self._y_cb, hard=False)
def _x_cb(self, pin_x):
print('x')
if (x := pin_x.value()) != self._x: # Crash seems to occur here
pass
def _y_cb(self, pin_y):
print('y')
if (y := pin_y.value()) != self._y: # or here
pass
async def main():
e = Encoder()
while True:
await asyncio.sleep(1)
print(e._v)
asyncio.run(main())
When either pin changes state the ISR prints then the board crashes. If I reduce the ISR's to just a print statement the code runs. Note hard and soft IRQ's behave similarly.