Klasse StateMachine – Zugriff auf die programmierbare I/O-Schnittstelle des RP2040

Die Klasse StateMachine bietet Zugriff auf die PIO-Schnittstelle (programmierbare I/O) des RP2040.

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

Konstruktoren

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

Ruft den Zustandsautomaten mit der Nummer id ab. Der RP2040 hat zwei identische PIO-Instanzen mit jeweils 4 Zustandsautomaten: Es gibt also insgesamt 8 Zustandsautomaten, nummeriert von 0 bis 7.

Optional kann er mit dem angegebenen Programm program initialisiert werden: siehe 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

Konfiguriert die Zustandsautomaten-Instanz so, dass sie das angegebene Programm program ausführt.

Das Programm wird dem Befehlsspeicher dieser PIO-Instanz hinzugefügt. Wenn der Befehlsspeicher dieses Programm bereits enthält, wird dessen Offset wiederverwendet, um Befehlsspeicher zu sparen.

  • freq ist die Frequenz in Hz, mit der der Zustandsautomat laufen soll. Standardmäßig die Systemtaktfrequenz.

    Der Taktteiler wird als system clock frequency / freq berechnet, sodass es zu leichten Rundungsfehlern kommen kann.

    Der kleinstmögliche Taktteiler ist ein 65536stel des Systemtakts: bei der standardmäßigen Systemtaktfrequenz von 125 MHz beträgt der Mindestwert von freq also 1908. Um Zustandsautomaten mit langsameren Frequenzen zu betreiben, müssen Sie die Systemtaktgeschwindigkeit mit machine.freq() reduzieren.

  • in_base ist der erste Pin, der für in()-Befehle verwendet wird.

  • out_base ist der erste Pin, der für out()-Befehle verwendet wird.

  • set_base ist der erste Pin, der für set()-Befehle verwendet wird.

  • jmp_pin ist der erste Pin, der für jmp(pin, ...)-Befehle verwendet wird.

  • sideset_base ist der erste Pin, der für Side-Setting verwendet wird.

  • in_shiftdir ist die Richtung, in die der ISR verschiebt, entweder PIO.SHIFT_LEFT oder PIO.SHIFT_RIGHT.

  • out_shiftdir ist die Richtung, in die der OSR verschiebt, entweder PIO.SHIFT_LEFT oder PIO.SHIFT_RIGHT.

  • push_thresh ist der Schwellenwert in Bits, bevor das automatische Pushen oder bedingte erneute Pushen ausgelöst wird.

  • pull_thresh ist der Schwellenwert in Bits, bevor das automatische Pullen oder bedingte erneute Pullen ausgelöst wird.

Hinweis: Pins, die für in_base verwendet werden, müssen manuell als Eingang (oder anderweitig) konfiguriert werden, damit der PIO das gewünschte Signal sehen kann (sie können Eingangspins, Ausgangspins oder mit einem anderen Peripheriegerät verbunden sein). Der jmp_pin kann ebenfalls manuell konfiguriert werden, ist aber standardmäßig ein Eingangspin.

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

Liest oder setzt, ob der Zustandsautomat derzeit läuft.

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

Startet den Zustandsautomaten neu und springt an den Anfang des Programms.

Diese Methode löscht den internen Zustand des Zustandsautomaten mithilfe des SM_RESTART-Registers des RP2040. Dazu gehören:

  • Eingangs- und Ausgangs-Verschiebungszähler

  • der Inhalt des Eingangs-Verschiebungsregisters

  • der Verzögerungszähler

  • der Zustand des Wartens auf einen IRQ

  • ein angehaltener Befehl, der mit StateMachine.exec() ausgeführt wird

exec(instr: str | int) None

Führt einen einzelnen PIO-Befehl aus.

Wenn instr eine Zeichenkette ist, wird asm_pio_encode verwendet, um den Befehl aus der angegebenen Zeichenkette zu codieren.

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

Wenn instr eine Ganzzahl ist, wird sie als bereits codierter PIO-Maschinencodebefehl behandelt, der ausgeführt werden soll.

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

Liest ein Wort aus dem RX-FIFO des Zustandsautomaten.

Wenn der FIFO leer ist, blockiert die Methode, bis Daten eintreffen (d. h. der Zustandsautomat ein Wort pusht).

Der Wert wird vor der Rückgabe um shift Bits nach rechts verschoben, d. h. der Rückgabewert ist word >> shift.

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

Schiebt Wörter in den TX-FIFO des Zustandsautomaten.

value kann eine Ganzzahl, ein Array vom Typ B, H oder I oder ein bytearray sein.

Diese Methode blockiert, bis alle Wörter in den FIFO geschrieben wurden. Wenn der FIFO voll ist oder voll wird, blockiert die Methode, bis der Zustandsautomat genügend Wörter abruft, um den Schreibvorgang abzuschließen.

Jedes Wort wird zuerst um shift Bits nach links verschoben, d. h. der Zustandsautomat empfängt word << shift.

rx_fifo() int

Gibt die Anzahl der Wörter im RX-FIFO des Zustandsautomaten zurück. Ein Wert von 0 zeigt an, dass der FIFO leer ist.

Nützlich, um vor dem Aufruf von StateMachine.get() zu prüfen, ob Daten zum Lesen bereitstehen.

tx_fifo() int

Gibt die Anzahl der Wörter im TX-FIFO des Zustandsautomaten zurück. Ein Wert von 0 zeigt an, dass der FIFO leer ist.

Nützlich, um zu prüfen, ob Platz vorhanden ist, um mit StateMachine.put() ein weiteres Wort zu pushen.

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

Gibt das IRQ-Objekt für den angegebenen StateMachine zurück.

Optional kann es konfiguriert werden.

Buffer-Protokoll

Die StateMachine-Klasse unterstützt das buffer protocol und ermöglicht so den direkten Zugriff auf die Sende- und Empfangs-FIFOs jedes Zustandsautomaten. Dies dient in erster Linie dazu, StateMachine-Objekte beim Konfigurieren eines rp2.DMA()-Kanals direkt als read- oder write-Parameter übergeben zu können.