Monday, July 25, 2022

RP2040 Micropython PIO - Part 3 - Pushing pins only on changes

 In order to check for changes to the pins, each time we read the pins values, we can compare them to previous values stored in the x or y scratch registers. 

So the statemachine records the pin state in y when it starts, pushes y so python has the initial state as well, and then the state machine keeps checking the pins until the pin values cached in x aren't equal to y.  Then it pushes x, copies x to y, and starts checking again. 

for n in range(32):
try:
Pin(n, Pin.IN, Pin.PULL_UP)
except:
print("Couldn't initialize pin:", n)

@rp2.asm_pio( set_init=[PIO.IN_HIGH]*32 )
def echo_pins_changes():
mov(y, pins)
#in_(y, 32)
mov(isr, y)
push()

wrap_target()
label("read loop")
mov(x, pins)

jmp(x_not_y, "exit read loop")
jmp("read loop")
label("exit read loop")
mov(isr, x)
mov(y, x)
push()

wrap()

sm = rp2.StateMachine(0, pio_junk.echo_pins_changes,
freq=2000, in_base=Pin(0))

sm.active(1)
for n in range(10):
out = sm.get()
print(f'{n}, {out:>032b}')
sm.active(0)

Next step is setting an irq to tell python it's time to pull a value from the fifo.  

And maybe later some time, we can implement matrix scanning!  I'm not too sure how that would work since we'd need to potentially track the state of more than 32 keys...  maybe we'd use separate state machines for each row of the keyboard!

No comments: