rp2: rp2.asm_pio_encode incorrectly accepts 'pins' as src for 'wait'
- https://docs.micropython.org/en/latest/library/rp2.html#module-rp2 specifies the pio asm syntax for 'wait' as
wait(polarity, src, index) where 'src' one of (gpio, pin, irq) - The rp2040-datasheet.pdf similary uses (GPIO, PIN, IRQ)
The bug is that rp2.asm_pio_encode silently accepts the invalid src value 'pins'. It should raise an exception.
Incidentaly it encodes "wait(1, pins, 0)" the same as "wait(1, gpio, 0)"
demo code
import rp2
try:
rp2.asm_pio_encode("wait(1, pins, 0)")
exception_raised = False
except Exception:
exception_raised = True
assert exception_raised
rp2: PIO does not output more than 8 bit parallel [PR made]
When trying to output more than 8 bit parallel to a set of gpio pins via PIO, the straight approach fails. Whenever I define more than 8 pins in out_init, only the first 8 are initialized for output. I traced that down to the function asm_pio_init_gpio() in rp2_pio.c. The number of pins and the pinmask have proper values. So it must be something in pio_sm_set_pindirs_with_mask() of pico_sdk's file pio.c
Sample code:
from machine import Pin, mem32
from time import sleep_us
import rp2
import array
@rp2.asm_pio(
sideset_init=(rp2.PIO.OUT_HIGH,) * 2,
out_init=(rp2.PIO.OUT_HIGH,) * 9,
out_shiftdir=rp2.PIO.SHIFT_RIGHT,
autopull=True,
pull_thresh=16)
def data9_write():
# fmt: off
wrap_target()
out(pins, 9) .side(0b10)
out(null, 7) .side(0b11)
wrap()
ar=array.array("H", [0x1ff if not (i & 1) else 0 for i in range(10)])
sm = rp2.StateMachine(0, data9_write, freq=25_000_000,
sideset_base=Pin(2), out_base=Pin(6))
sm.active(1)
sm.put(ar, 0)
If I change the PIO script into the code below, such that the first data word sets the pin mask, the 9th bit is properly configured, since the first data word has the value 0x1ff. So at least I have a workaround.
@rp2.asm_pio(
sideset_init=(rp2.PIO.OUT_HIGH,) * 2,
out_init=(rp2.PIO.OUT_HIGH,) * 9,
out_shiftdir=rp2.PIO.SHIFT_RIGHT,
autopull=True,
pull_thresh=16)
def data9_write():
# fmt: off
out(pindirs, 9) .side(0b00)
out(null, 7) .side(0b00)
wrap_target()
out(pins, 9) .side(0b10)
out(null, 7) .side(0b11)
wrap()