← index #18646PR #18974
Related · medium · value 0.341
QUERY · ISSUE

RP2 - PIO 'remove_programs()' does not correctly remove/de-reference StateMachine code

openby mungewellopened 2026-01-06updated 2026-03-16
bugport-rp2

Port, board and/or hardware

rp2

MicroPython version

MicroPython v1.26.1 on 2025-09-11; Raspberry Pi Pico with RP2040

Reproduction

Minimal example showing issue:
pio_load_test.py.txt

Expected behaviour

When alternately loading PIO StateMachine code, microPython loads the wrong (previously loaded) code.

Example code alternates between 'mac-one' and 'mac-two'; on the 3rd iteration we expect 'mac-one' to be loaded, but instead 'mac-two' is placed (or left) in PIO address space... and that code loads '2' into the RX FIFO.

MicroPython v1.26.1 on 2025-09-11; Raspberry Pi Pico with RP2040
Type "help()" for more information.

>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
Loading primary: mac-one
0x502000d4 : 0x0000001c = 0x0000e021
0x502000ec : 0x0000000b = 0x00006026
0x50200104 : 0x00000006 = 0x00007e01
0x5020011c : 0x00000001 = 0x0000ae08
RX FIFO = 1

Loading alternate: mac-two
0x502000d4 : 0x0000001c = 0x0000e022
0x502000ec : 0x0000000b = 0x00006026
0x50200104 : 0x00000006 = 0x00007e01
0x5020011c : 0x00000001 = 0x0000ae08
RX FIFO = 2

Loading primary: mac-one
0x502000d4 : 0x0000001c = 0x0000e022
0x502000ec : 0x0000000b = 0x00006026
0x50200104 : 0x00000006 = 0x00007e01
0x5020011c : 0x00000001 = 0x0000ae08
RX FIFO = 2

The code also 'peeks' (mem32) the address space related to PIO0 and we can see the start address and the first instruction (as complied value).

>>> print("0x%8.8x" % rp2.asm_pio_encode("set(x,1)", 0))
0x0000e021
>>> print("0x%8.8x" % rp2.asm_pio_encode("set(x,2)", 0))
0x0000e022

Observed behaviour

Example code alternates between 'mac-one' and 'mac-two'; on the 3rd iteration we expect 'mac-one' to be loaded, but instead 'mac-two' is placed (or left) in PIO address space... and that code loads '2' into the RX FIFO.

Additional Information

As a workaround test script appears to correctly work if you implicitly specify the name of the StateMachine(s) to remove

    # clean-up
    rp2.PIO(0).remove_program(mac_one)
    rp2.PIO(0).remove_program(mac_two)
    rp2.PIO(0).remove_program()

Docs suggest this should not be necessary.
https://docs.micropython.org/en/latest/library/rp2.PIO.html#rp2.PIO.remove_program

Code of Conduct

Yes, I agree

CANDIDATE · PULL REQUEST

rp2: Add PIO assembler and StateMachine test suite.

openby bikeNomadopened 2026-03-21updated 2026-03-23
port-rp2

Tests cover asm_pio encoding (nop, wait, irq, mov, in_count, fifo_join including RP2350-specific modes), StateMachine hardware behavior (loopback, FIFO counts, exec, IRQ, restart, program memory reuse), and RP2350-specific features (3 PIO blocks, 12 SMs, PIO(2) loopback).

Summary

I wanted to update the RP2 PIO code to support the new RP2350 PIO changes.

To make sure that my changes were working, I created this test script to run from mpremote (similarly to rp2_dma.py).

Testing

I've run this on both a RPI_PICO2 board and a RPI_PICO board. I did discover an issue in the existing PIO code, which is fixed by #18976.

This issue causes test_restart to hang.

Some of the RP2350-specific tests depend on functionality that is not yet in mainline code; #18975 adds this functionality.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the
code and is responsible for the code and the description above.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied