hardware_pio: fix pio_encode_mov(pio_pindirs, ...) on RP2350 #2946

Closed
anoshyn wants to merge 1 commit from fix-pio-mov-pindirs into develop
anoshyn commented 2026-05-16 06:16:16 -05:00 (Migrated from github.com)

Summary

Fixes #2754. On RP2350, pio_encode_mov(pio_pindirs, pio_x) returned 0xA081 (which is MOV EXEC, X) instead of the correct 0xA061 (MOV PINDIRS, X).

The PIO MOV destination encoding for PINDIRS differs from the SET/IN/OUT encoding:

  • SET/IN/OUT encode PINDIRS as field 4
  • MOV (RP2350 only) encodes PINDIRS as field 3; field 4 is reserved for EXEC

The pio_src_dest enum collapses both pio_pindirs and pio_exec_mov to low-3-bits = 4 because the SET/IN/OUT encoder is the original consumer. The MOV encoder needs to remap PINDIRS to 3 — but only for PINDIRS, not for EXEC. In release builds (NDEBUG), pio_pindirs and pio_exec_mov are numerically identical (the _PIO_INVALID_* flag bits are all zero), so a naive "dest == 4 → 3" remap would also break pio_encode_mov(pio_exec_mov, ...).

This PR adds a non-NDEBUG-gated marker bit (_PIO_MARKER_PINDIRS = 0x100) carried only by pio_pindirs. The new _pio_mov_dest_bits() helper checks the marker on PICO_PIO_VERSION > 0 and remaps to 3. All existing encoders already mask with & 7u before emitting the destination field, so the marker bit is discarded everywhere it isn't being checked — no other encoder is affected. The debug-mode _PIO_INVALID_MOV_DEST assertion is also dropped from pio_pindirs on RP2350.

Test plan

Host-side verification of the constant-folded encoding emitted by each pio_encode_*:

test RP2350 (v1) RP2040 (v0)
mov pindirs, x 0xA061 (fixed) 0xA081 (unchanged; invalid on RP2040)
mov exec_mov, x 0xA081 ✓ 0xA081 ✓
mov pc, x 0xA0A1 ✓ 0xA0A1 ✓
mov y, y (NOP) 0xA042 ✓ 0xA042 ✓
set pindirs, 1 0xE081 ✓ 0xE081 ✓
out pindirs, 1 0x6081 ✓ 0x6081 ✓
in pins, 1 0x4001 ✓ 0x4001 ✓
mov_not pindirs, x 0xA069 ✓ 0xA089 ✓
mov_reverse pindirs, x 0xA071 ✓ 0xA091 ✓
  • Full SDK build clean for PICO_PLATFORM=rp2040 PICO_BOARD=pico.
  • Full SDK build clean for PICO_PLATFORM=rp2350 PICO_BOARD=pico2.
  • CI to confirm broader configurations (RISC-V, alternate boards).
## Summary Fixes #2754. On RP2350, `pio_encode_mov(pio_pindirs, pio_x)` returned `0xA081` (which is `MOV EXEC, X`) instead of the correct `0xA061` (`MOV PINDIRS, X`). The PIO MOV destination encoding for PINDIRS differs from the SET/IN/OUT encoding: - SET/IN/OUT encode PINDIRS as field **4** - MOV (RP2350 only) encodes PINDIRS as field **3**; field 4 is reserved for EXEC The `pio_src_dest` enum collapses both `pio_pindirs` and `pio_exec_mov` to low-3-bits = 4 because the SET/IN/OUT encoder is the original consumer. The MOV encoder needs to remap PINDIRS to 3 — but only for PINDIRS, not for EXEC. In release builds (`NDEBUG`), `pio_pindirs` and `pio_exec_mov` are numerically identical (the `_PIO_INVALID_*` flag bits are all zero), so a naive "dest == 4 → 3" remap would also break `pio_encode_mov(pio_exec_mov, ...)`. This PR adds a non-`NDEBUG`-gated marker bit (`_PIO_MARKER_PINDIRS = 0x100`) carried only by `pio_pindirs`. The new `_pio_mov_dest_bits()` helper checks the marker on `PICO_PIO_VERSION > 0` and remaps to 3. All existing encoders already mask with `& 7u` before emitting the destination field, so the marker bit is discarded everywhere it isn't being checked — no other encoder is affected. The debug-mode `_PIO_INVALID_MOV_DEST` assertion is also dropped from `pio_pindirs` on RP2350. ## Test plan Host-side verification of the constant-folded encoding emitted by each `pio_encode_*`: | test | RP2350 (v1) | RP2040 (v0) | |---|---|---| | `mov pindirs, x` | **0xA061** (fixed) | 0xA081 (unchanged; invalid on RP2040) | | `mov exec_mov, x` | 0xA081 ✓ | 0xA081 ✓ | | `mov pc, x` | 0xA0A1 ✓ | 0xA0A1 ✓ | | `mov y, y` (NOP) | 0xA042 ✓ | 0xA042 ✓ | | `set pindirs, 1` | 0xE081 ✓ | 0xE081 ✓ | | `out pindirs, 1` | 0x6081 ✓ | 0x6081 ✓ | | `in pins, 1` | 0x4001 ✓ | 0x4001 ✓ | | `mov_not pindirs, x` | 0xA069 ✓ | 0xA089 ✓ | | `mov_reverse pindirs, x` | 0xA071 ✓ | 0xA091 ✓ | - [x] Full SDK build clean for `PICO_PLATFORM=rp2040 PICO_BOARD=pico`. - [x] Full SDK build clean for `PICO_PLATFORM=rp2350 PICO_BOARD=pico2`. - [ ] CI to confirm broader configurations (RISC-V, alternate boards).
anoshyn commented 2026-05-19 14:54:43 -05:00 (Migrated from github.com)

Force-pushed to drop the Co-Authored-By trailer. New HEAD: 6a990bbb.

Force-pushed to drop the `Co-Authored-By` trailer. New HEAD: 6a990bbb.
kilograham commented 2026-05-19 17:19:42 -05:00 (Migrated from github.com)

closed in favor of #2958

closed in favor of #2958

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-raspberrypi/pico-sdk!2946
No description provided.