pico-sdk icon indicating copy to clipboard operation
pico-sdk copied to clipboard

pio_encode_mov(pio_pindirs, pio_x) gives wrong value

Open PetteriAimonen opened this issue 1 month ago • 1 comments

When calling:

pio_encode_mov(pio_pindirs, pio_x);

it returns 0xA081, while according to datasheet the correct value would be 0xA061

I think this is a left-over bug from RP2040 which doesn't support pindirs as mov destination.

PetteriAimonen avatar Dec 08 '25 11:12 PetteriAimonen

I did a bit of digging, and it looks like you're right.

I compiled these tables of encoding bit-patterns from the PIO chapters of the RP2040 and RP2350 datasheets: (with bold highlighting where RP2350 differs from RP2040)

Chip Instruction Src or Dest 00 01 10 11
RP2040 WAIT Source GPIO PIN IRQ Reserved
RP2350 WAIT Source GPIO PIN IRQ JMPPIN
Chip Instruction Src or Dest 000 001 010 011 100 101 110 111
RP2040 IN Source PINS X Y NULL Reserved Reserved ISR OSR
RP2040 OUT Destination PINS X Y NULL PINDIRS PC ISR EXEC
RP2040 MOV Destination PINS X Y Reserved EXEC PC ISR OSR
RP2040 MOV Source PINS X Y NULL Reserved STATUS ISR OSR
RP2040 SET Destination PINS X Y Reserved PINDIRS Reserved Reserved Reserved
RP2350 IN Source PINS X Y NULL Reserved Reserved ISR OSR
RP2350 OUT Destination PINS X Y NULL PINDIRS PC ISR EXEC
RP2350 MOV Destination PINS X Y PINDIRS EXEC PC ISR OSR
RP2350 MOV Source PINS X Y NULL Reserved STATUS ISR OSR
RP2350 SET Destination PINS X Y Reserved PINDIRS Reserved Reserved Reserved

pio_encode_mov(enum pio_src_dest dest, enum pio_src_dest src) just does

return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest, src & 7u);

pio_src_dest is defined as:

enum pio_src_dest {
    pio_pins = 0u,
    pio_x = 1u,
    pio_y = 2u,
    pio_null = 3u | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
    pio_pindirs = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
    pio_exec_mov = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
    pio_status = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
    pio_pc = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
    pio_isr = 6u | _PIO_INVALID_SET_DEST,
    pio_osr = 7u | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST,
    pio_exec_out = 7u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
};

which explains why pio_encode_mov(pio_pindirs, pio_x); is encoding pio_pindirs as binary 100 instead of the binary 011 that the MOV instruction in RP2350's PIO expects.

So perhaps pio_src_dest needs to be tweaked to add:

#if PICO_PIO_VERSION > 0
    pio_pindirs_mov = 3u _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
#endif

and then your example-code would need to do pio_encode_mov(pio_pindirs_mov, pio_x); instead of pio_encode_mov(pio_pindirs, pio_x);.

lurch avatar Dec 08 '25 15:12 lurch