Klasse PIO – fortgeschrittene PIO-Nutzung

Die Klasse PIO kapselt einen der beiden Programmable-I/O-Blöcke (PIO) des RP2040. Jeder PIO-Block enthält einen Befehlsspeicher (32 Befehle), der von vier unabhängigen Zustandsautomaten gemeinsam genutzt wird, sowie eine private FIFO-Schnittstelle zu jedem Zustandsautomaten und einen IRQ-Controller.

Die meisten Skripte interagieren mit PIO über StateMachine – diese Klasse ist für fortgeschrittene Anwendungsfälle gedacht, die Folgendes benötigen:

  • Programme explizit über add_program() / remove_program() laden und entfernen.

  • Die GPIO-Basis des PIO über das 32-Pin-Fenster des Chips mittels gpio_base() verschieben.

  • Über irq() an blockweite IRQ-Flags anbinden.

Zum Assemblieren von PIO-Programmen siehe rp2.asm_pio().

Konstruktoren

class rp2.PIO(id: int)

Gibt das Singleton-Objekt PIO für den durch id identifizierten PIO-Block zurück. Der RP2040 hat zwei PIO-Blöcke, nummeriert mit 0 und 1. Löst für jede andere id ein ValueError aus.

Methoden

gpio_base(base: machine.Pin | int | None = None, /) int

Liest oder setzt die GPIO-Basis für diesen PIO-Block.

Der RP2040-PIO sieht ein 32-Pin-Fenster in den GPIO-Raum; das Fenster kann bei GPIO0 oder GPIO16 beginnen. Die Basis bestimmt, welches Fenster für alle Zustandsautomaten dieses PIO wirksam ist.

Ohne Argument wird die aktuelle Basis zurückgegeben (die GPIO-Pin-Nummer, 0 oder 16).

Mit einem Argument wird die Basis gesetzt. base kann eine machine.Pin-Instanz oder die ganzzahlige Pin-Nummer sein und muss zu GPIO0 oder GPIO16 aufgelöst werden. Die Basis muss gesetzt werden, bevor ein Programm hinzugefügt oder ein Zustandsautomat auf diesem PIO-Block erstellt wird.

add_program(program: Callable) None

Lädt program in den Befehlsspeicher dieses PIO. Das resultierende Speicherlayout wird über alle Zustandsautomaten dieses PIO-Blocks hinweg wiederverwendet.

Jeder PIO hat nur 32 Befehle Programmspeicher, die von allen Programmen gemeinsam genutzt werden; wenn das neue Programm nicht hineinpasst, löst diese Methode OSError(ENOMEM) aus. Dasselbe Programm kann auf beide PIO-Instanzen geladen werden, aber sie belegen getrennte Speicherbereiche.

remove_program(program: Callable | None = None, /) None

Entfernt program aus dem Befehlsspeicher dieses PIO und gibt damit Platz für neue Programme frei. Wenn program weggelassen wird, wird jedes aktuell auf diesem PIO geladene Programm entfernt.

Das Entfernen eines nicht geladenen Programms ist eine Leeroperation (keine Ausnahme).

state_machine(id: int, program: Callable | None = None, *args, **kwargs) StateMachine

Gibt eine der vier StateMachine-Instanzen zurück, die diesem PIO-Block gehören. id ist der lokale Zustandsautomaten-Index (03).

Wenn program angegeben wird, wird der Zustandsautomat so konfiguriert, dass er es ausführt – alle positionellen Argumente und Schlüsselwortargumente werden an StateMachine.init() weitergeleitet.

Beispiel:

>>> rp2.PIO(1).state_machine(3)
StateMachine(7)

Die globale Zustandsautomaten-ID des zurückgegebenen Objekts ist pio_id * 4 + sm_id.

irq(handler: Callable[[PIO], None] | None = None, trigger: int = IRQ_SM0 | IRQ_SM1 | IRQ_SM2 | IRQ_SM3, hard: bool = False) Callable

Liest oder konfiguriert den IRQ auf Blockebene für diesen PIO.

handler ist der Callback, der ausgelöst wird, wenn einer der angeforderten Zustandsautomaten-IRQs einrastet. Der Handler erhält diese PIO-Instanz als sein einziges Argument; innerhalb des Handlers können die auslösenden Zustandsautomaten über self.irq().flags() UND-verknüpft mit den Konstanten IRQ_SM* identifiziert werden.

trigger ist eine Bitmaske aus einem oder mehreren der Werte IRQ_SM0 .. IRQ_SM3. Der Standardwert löst bei jedem Zustandsautomaten aus.

hard=True registriert einen Hard-Interrupt-Handler (keine Heap-Allokation im Callback).

MicroPython belegt IRQ 0 auf jedem PIO-Block; IRQ 1 ist reserviert und nicht von Python aus zugänglich.

Konstanten

IN_LOW: int

An out_init / set_init / sideset_init von asm_pio() übergeben, sodass der Pin als auf Low getriebener Eingang startet (d. h. Tristate mit dem Ausgangspuffer auf 0).

IN_HIGH: int

An out_init / set_init / sideset_init von asm_pio() übergeben, sodass der Pin als Eingang mit dem Ausgangspuffer auf 1 startet.

OUT_LOW: int

An out_init / set_init / sideset_init von asm_pio() übergeben, sodass der Pin als getriebener Ausgang auf logisch 0 startet.

OUT_HIGH: int

An out_init / set_init / sideset_init von asm_pio() übergeben, sodass der Pin als getriebener Ausgang auf logisch 1 startet.

SHIFT_LEFT: int

An in_shiftdir / out_shiftdir von asm_pio() oder StateMachine.init() übergeben, sodass Verschiebungen die Bits in Richtung MSB bewegen.

SHIFT_RIGHT: int

An in_shiftdir / out_shiftdir von asm_pio() oder StateMachine.init() übergeben, sodass Verschiebungen die Bits in Richtung LSB bewegen.

JOIN_NONE: int

An fifo_join von asm_pio() übergeben, sodass der Zustandsautomat getrennte 4-Wort-TX- und -RX-FIFOs hat (der Standard).

JOIN_TX: int

An fifo_join von asm_pio() übergeben, sodass der TX-FIFO durch Aufnahme des RX-FIFO auf 8 Wörter verdoppelt wird. Der Zustandsautomat kann keine Daten mehr empfangen.

JOIN_RX: int

An fifo_join von asm_pio() übergeben, sodass der RX-FIFO durch Aufnahme des TX-FIFO auf 8 Wörter verdoppelt wird. Der Zustandsautomat kann keine Daten mehr senden.

IRQ_SM0: int

trigger-Flag von irq(): Zustandsautomat 0 hat seinen IRQ ausgelöst.

IRQ_SM1: int

trigger-Flag von irq(): Zustandsautomat 1 hat seinen IRQ ausgelöst.

IRQ_SM2: int

trigger-Flag von irq(): Zustandsautomat 2 hat seinen IRQ ausgelöst.

IRQ_SM3: int

trigger-Flag von irq(): Zustandsautomat 3 hat seinen IRQ ausgelöst.