RP2 - PIO 'remove_programs()' does not correctly remove/de-reference StateMachine code
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
RP2350: PIO2 State Machines do not work
Port, board and/or hardware
ports-rp2 Pico 2
MicroPython version
MicroPython v1.26.0-preview.251.g5ade8b705 on 2025-06-16; Raspberry Pi Pico2 with RP2350
Reproduction
pio_1hz.py from examples does not blink the LED or trigger the interrupt when switched to StateMachine IDs 8, 9, 10, or 11.
Expected behaviour
No response
Observed behaviour
What I've found so far:
PIO2_BASE + SM0_EXECCTRL is set incorrectly
PIO2 instruction memory is not loaded
Instruction start address is not set
Additional Information
This code mostly works.
The IRQ handler only triggers once, not repeatedly as expected.
import time
from machine import Pin
import rp2
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink_1hz():
# fmt: off
# Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000
irq(rel(0))
set(pins, 1)
set(x, 31) [5]
label("delay_high")
nop() [29]
jmp(x_dec, "delay_high")
# Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000
nop()
set(pins, 0)
set(x, 31) [5]
label("delay_low")
nop() [29]
jmp(x_dec, "delay_low")
# fmt: on
# Create the StateMachine with the blink_1hz program, outputting on Pin(25).
sm = rp2.StateMachine(8, blink_1hz, freq=2300, set_base=Pin(25))
# Set the IRQ handler to print the millisecond timestamp.
sm.irq(lambda p: print(time.ticks_ms()))
# -------- MANUAL REGISTER SETTING START -----------
import machine
PIO2_BASE = 0x50400000
SM0_EXECCTRL = 0xCC
INSTR_MEM0 = 0x48
SM0_INSTR = 0xD8
machine.mem32[PIO2_BASE + SM0_EXECCTRL] = 129920
instrs = [49168, 57345, 58687, 48450, 89, 41026, 57344, 58687, 48450, 94]
instr_start = 0x48 + (4 * (32-len(instrs)))
for idx,instr in enumerate(instrs):
machine.mem32[PIO2_BASE + instr_start + (idx*4)] = instr
machine.mem32[PIO2_BASE + SM0_INSTR]=32-len(instrs)
# -------- MANUAL REGISTER SETTING END -----------
# Start the StateMachine.
sm.active(1)
while(True):
pass
Code of Conduct
Yes, I agree