class StateMachine -- 存取 RP2040 的可程式化 I/O 介面

StateMachine 類別提供對 RP2040 的 PIO(可程式化 I/O)介面的存取。

關於組譯 PIO 程式,請參閱 rp2.asm_pio()

建構子

class rp2.StateMachine(id: int, program: Callable | None = None, *args, **kwargs)

取得編號為 id 的狀態機。RP2040 有兩個相同的 PIO 實例,每個各有 4 個狀態機:因此總共有 8 個狀態機,編號從 0 到 7。

可選擇性地以指定的程式 program 將其初始化:請參閱 StateMachine.init

init(program: Callable, freq: int = -1, *, in_base: machine.Pin | None = None, out_base: machine.Pin | None = None, set_base: machine.Pin | None = None, jmp_pin: machine.Pin | None = None, sideset_base: machine.Pin | None = None, in_shiftdir: int | None = None, out_shiftdir: int | None = None, push_thresh: int | None = None, pull_thresh: int | None = None) None

設定狀態機實例以執行指定的 program

該程式會被新增到此 PIO 實例的指令記憶體中。若指令記憶體中已包含此程式,則會重複使用其偏移量,以節省指令記憶體。

  • freq 是狀態機執行的頻率,以 Hz 為單位。預設為系統時脈頻率。

    時脈分頻值的計算方式為 system clock frequency / freq,因此可能會有些微的捨入誤差。

    最小的可能時脈分頻值為系統時脈的 65536 分之一:因此在預設的 125MHz 系統時脈頻率下,freq 的最小值為 1908。若要以更慢的頻率執行狀態機,您需要使用 machine.freq() 來降低系統時脈速度。

  • in_base 是供 in() 指令使用的第一個接腳。

  • out_base 是供 out() 指令使用的第一個接腳。

  • set_base 是供 set() 指令使用的第一個接腳。

  • jmp_pin 是供 jmp(pin, ...) 指令使用的第一個接腳。

  • sideset_base 是供 side-set 使用的第一個接腳。

  • in_shiftdir 是 ISR 移位的方向,為 PIO.SHIFT_LEFTPIO.SHIFT_RIGHT

  • out_shiftdir 是 OSR 移位的方向,為 PIO.SHIFT_LEFTPIO.SHIFT_RIGHT

  • push_thresh 是觸發自動推送或條件式重新推送之前的閾值,以位元為單位。

  • pull_thresh 是觸發自動拉取或條件式重新拉取之前的閾值,以位元為單位。

注意:供 in_base 使用的接腳需要手動設定為輸入(或其他方式),以便 PIO 能看到所需的訊號(它們可以是輸入接腳、輸出接腳,或連接到不同的周邊裝置)。jmp_pin 也可以手動設定,但預設會是輸入接腳。

active(value: bool | int | None = None, /) bool

取得或設定狀態機目前是否正在執行。

>>> sm.active()
True
>>> sm.active(0)
False
restart() None

重新啟動狀態機並跳到程式的開頭。

此方法使用 RP2040 的 SM_RESTART 暫存器來清除狀態機的內部狀態。這包括:

  • 輸入與輸出移位計數器

  • 輸入移位暫存器的內容

  • 延遲計數器

  • 等待 IRQ 的狀態

  • 使用 StateMachine.exec() 執行的已停滯指令

exec(instr: str | int) None

執行單一 PIO 指令。

instr 是字串,則使用 asm_pio_encode 從指定的字串編碼該指令。

>>> sm.exec("set(0, 1)")

instr 是整數,則將其視為一條已編碼的 PIO 機器碼指令來執行。

>>> sm.exec(rp2.asm_pio_encode("out(y, 8)", 0))
get(buf: 'bytearray | array | None' = None, shift: int = 0) int

從狀態機的 RX FIFO 拉取一個字組。

若 FIFO 為空,則會阻塞直到資料到達(即狀態機推送一個字組)。

傳回前該值會先向右移位 shift 個位元,即傳回值為 word >> shift

put(value: 'int | bytes | bytearray | array', shift: int = 0) None

將字組推送到狀態機的 TX FIFO。

value 可以是整數、型別為 BHI 的陣列,或是 bytearray

此方法會阻塞直到所有字組都已寫入 FIFO。若 FIFO 已滿或變滿,此方法會阻塞直到狀態機拉取足夠的字組以完成寫入。

每個字組會先向左移位 shift 個位元,即狀態機接收到的是 word << shift

rx_fifo() int

傳回狀態機 RX FIFO 中的字組數量。值為 0 表示 FIFO 為空。

在呼叫 StateMachine.get() 之前,可用於檢查是否有資料正等待被讀取。

tx_fifo() int

傳回狀態機 TX FIFO 中的字組數量。值為 0 表示 FIFO 為空。

在使用 StateMachine.put() 推送另一個字組之前,可用於檢查是否有空間。

irq(handler: Callable[[StateMachine], None] | None = None, trigger: int = 0 | 1, hard: bool = False) Callable

傳回指定 StateMachine 的 IRQ 物件。

可選擇性地對其進行設定。

緩衝區協定

StateMachine 類別支援 buffer protocol,允許直接存取每個狀態機的傳送與接收 FIFO。這主要是為了讓 StateMachine 物件在設定 rp2.DMA() 通道時能直接作為 read 或 write 參數傳遞。