PIO: where am I going wrong? [SOLVED-ish]
Posted: Tue Feb 23, 2021 9:26 am
As a first attempt with the PIO I wrote a script to measure the period of a square wave on a pin. This worked after a fashion, producing correct results initially but they gradually "went off" becoming less and less accurate. I've produced this minimal version which only measures the mark time. The square wave is produced by a timer, and viewed on a scope looks perfect with no measurable jitter. I suspect I'm misunderstanding something about the FIFO.
This minimal script runs for a while producing a correct maximum but rubbish minimums before eventually locking up completely.
You'll probably spot my mistake without needing to run it, but to run, link 16 and 17 and paste.
This minimal script runs for a while producing a correct maximum but rubbish minimums before eventually locking up completely.
You'll probably spot my mistake without needing to run it, but to run, link 16 and 17 and paste.
Code: Select all
from machine import Pin, Timer
from rp2 import PIO, StateMachine, asm_pio
import time
@rp2.asm_pio(set_init=rp2.PIO.IN_LOW, autopush=True, push_thresh=32)
def mark():
wrap_target()
set(x, 0)
wait(0, pin, 0) # Wait for pin to go low
wait(1, pin, 0) # Low to high transition
label('low_high')
jmp(x_dec, 'next') # unconditional
label('next')
jmp(pin, 'low_high') # while pin is high
in_(x, 32) # Auto push: SM stalls if FIFO full
wrap()
pin16 = Pin(16, Pin.IN, Pin.PULL_UP)
sm0 = rp2.StateMachine(0, mark, in_base=pin16, jmp_pin=pin16)
_ = sm0.active(1)
pin17 = Pin(17, Pin.OUT)
tim = Timer(freq=1000, mode=Timer.PERIODIC, callback=lambda _: pin17(not pin17()))
maxval = 0
minval = 1000_000
while True:
# _ = sm0.active(1)
a = sm0.get()
# _ = sm0.active(0)
a = 1 + (a ^ 0xffffffff) # 2's complement
maxval = max(maxval, a)
minval = min(minval, a)
print(a, maxval, minval)
time.sleep_ms(200)