Closed dmcomm closed 3 years ago
Reviewing what I did in MicroPython, it was the "wait pin" version. The following program needs to be restarted to return to the waiting state. This program was waiting when it was supposed to in MicroPython and not in CircuitPython.
.program samples
wait 0 pin 0
loop:
in pins 1
jmp loop
import array
import board
import time
import rp2pio
import adafruit_pioasm
pinIn = board.GP1
asm = """
wait 0 pin 0
loop:
in pins 1
jmp loop
"""
program = adafruit_pioasm.assemble(asm)
sm = rp2pio.StateMachine(
program,
frequency=1_000_000,
first_in_pin=pinIn,
auto_push=True,
pull_in_pin_up=1,
)
buffer=array.array("L", [0] * 4)
while True:
time.sleep(1)
sm.restart()
sm.clear_rxfifo()
while sm.in_waiting < 4:
pass
sm.readinto(buffer)
for item in buffer:
b = bin(item)
print("0" * (34 - len(b)) + b[2:], end=" ")
print()
Hmm. It looks like this issue relates to the functionality of the SDK's pio_sm_restart() call. According to the Pico documentation, "This method clears the ISR, shift counters, clock divider counter pin write flags, delay counter, latched EXEC instruction,and IRQ wait condition."
Notably, it does not reset the program counter. Thus it will not execute the "wait 0 pin 0" instruction from the example. We might need to decide whether following the SDK is the right thing to do, or if calling sm.restart() should reset the program counter as well.
How bizarre. And I'd just assumed it was the same issue.
Looks like MicroPython noticed this and decided that their restart function will go to the start of the program: https://github.com/micropython/micropython/blob/e3291e1801f27e49ac0e6be275c742777507207f/ports/rp2/rp2_pio.c#L605
Edit: Though I have to wonder if that's actually safe. The PIO program might do something between the restart and exec calls, so the things reset by the restart call might not be clean any more. Edit2: And sounds like this doesn't reset OSR/X/Y either.
Added code to reset the State Machine program counter to the initial offset during a restart. There is not a way in the SDK to reset X,Y, or OSR. If those are of concern you might have to put in a PUSH to the register(s) at the start of your PIO code.
Right, normally the PIO program would put something into X/Y/OSR.
Fixed!
CircuitPython version
Code/REPL
Behavior
When the pin is grounded, as expected:
When the pin is tied to 3V3:
Description
No response
Additional information
This doesn't seem to happen in MicroPython. Edit: Though actually, my program isn't quite doing the same thing, so I should check that a bit more.