背景:RP2350になってPIOの一部仕様が変わっている。RP2350ではPIOが3つに増えたり、IRQ(4)-IRQ(7)がマイコンに通知可能になったり、PIOを超えて隣のPIOにIRQを送ったりできる。
取り組み:仕様変更点をMicroPythonから確認する(PIO ASMの仕様制限から確認できない点もある)
結論:
- IRQ(4)~IRQ(7)もマイコン側に通知できるようになったと理解したが、MicroPythonでは対応しておらず、IRQ(4)を発生させても割り込みハンドラは呼び出されない。
- 3つの目のPIOに対応済み、SM:11を指定するとエラーなく動作(本当にSM_11が動いているのか?までは未確認)
- PIOを超えて隣のPIOにIRQを送るオプションに関して、PIO Assemblerの仕様では未対応
詳細:
RP2350ではIRQ4~IRQ7もマイコンに通知可能になったが、MicroPythonでも同じ動作になるか?
RP2350のDatasheetより
![]()
MicroPythonのIRQ仕様書

RP2350のPIO ASM IRQ命令仕様書

アセンブルすると、0xc004が生成される。indexのフィールドだけ使ってIRQ(4)を表現
>>> import rp2
>>> hex(rp2.asm_pio_encode('irq(4)',0))
'0xc004'以下のコードではMicroPythonの割込みハンドラ(pio_intr_handler)が呼び出されない。多分、割り込みハンドラ用レジスタに登録していないのでは?と思われる(ソース読んでないので想像)
import time
import micropython
import machine
import rp2
GP_IN_PIN = 0
STATE_MACHINE_ID = 0
sm0 = None
def pio_intr_handler(intr_sm):
micropython.schedule(pio_handler_scheduled, intr_sm)
def pio_handler_scheduled(intr_sm):
print('IRQ from SM:', intr_sm)
if intr_sm == sm0:
print('--------------------')
print('IRQ_SM0 is set')
else:
print('IRQ_SM0 is not set')
@rp2.asm_pio()
def only_irq():
#irq(0) # set IRQ(0) flag ... OK
irq(4) # set IRQ(4) flag ... OK??
def main():
global sm0
# to enable 2KHz to StateMachine, set systemclock to 125MHz
machine.freq(125_000_000)
sm0 = rp2.StateMachine(STATE_MACHINE_ID, only_irq, freq=2000)
sm0.irq(handler=pio_intr_handler)
sm0.active(1)
time.sleep(10)
sm0.active(0)
main()MicroPython側では、IRQ0-3までしか割込みハンドラの対応をしてくれなさそうだ。抜粋したコードは以下。IRQ0-IRQ3までしか対応してないように思える。もし修正するなら、ここをIRQ4-IRQ7までの分を足して、新しい割り込みハンドラ(pio0_irq1)を作り、割り込みベクタテーブルに登録する必要があると思われる。(このままでは不可と分かったので目的は達成したとする(さすがにソースコードは改修しない MergeRequest 出したら喜ばれるのか??多分そうはならないだろう))

https://github.com/micropython/micropython/blob/master/ports/rp2/rp2_pio.c
PIOが3系統になって、SM(8)-SM(11)は使えるか?
以下のLチカプログラムにおいて、StateMachineを11番で指定、rp2.StateMachine()を実行、正常に動作した(LEDが点滅)。だから、、SM8-SM11は指定可能。
#
# test program blink with wait loop
#
import machine
from machine import Pin
import rp2
STATE_MACHINE_ID = 11
SET_BASE_PIN=1
machine.freq(125_000_000) # set 125MHz to same RP2040
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink_w_wait():
set(pins, 1) # PIN1 <- 1
mov(x,y) # x <- y (0x0300)
label('wait_loop_0')
jmp(x_dec,'wait_loop_0') # while x--
set(pins, 0) # PIN1 <- 0
mov(x,y) # x <- y (0x0300)
label('wait_loop_1')
jmp(x_dec,'wait_loop_1') # while x--
#
# get value from scratch register [x] or [y]
#
def get_from_scratch_reg(sm, x_or_y):
sm.exec(f"mov(isr, {x_or_y})")
sm.exec("push()")
return sm.get()
#
# set value to scratch register [x] or [y]
#
def set_to_scratch_reg(sm, x_or_y, val):
sm.put(val)
sm.exec("pull()")
sm.exec(f"mov({x_or_y}, osr)")
sm = rp2.StateMachine(STATE_MACHINE_ID, blink_w_wait, freq=2_000, set_base=Pin(SET_BASE_PIN))
set_to_scratch_reg(sm, 'y', 0x0300)
#
# start StateMachine
#
sm.active(1)
■追記
RP2340 / MicroPython v1.28.0 on 2026-04-06 において、PIO(0)のState machine(1)において、IRQ(0)を発行しても割込みが発生しない。なぜ?
IRQ(1)にすると割込みが発生する。または、 irq(rel(0))でもOK。ステートマシンごとに使えるIRQが決まっている?? ソースから引用したstate_machine_objにおいて、SM番号と想定IRQを一意に決めてしまっている??