Klasse I2S – Inter-IC-Sound-Bus-Protokoll¶
Die Klasse I2S steuert einen Inter-IC-Sound-Bus (I2S) im Controller-Modus – der MCU erzeugt den Bittakt (SCK) und den Word-Select-Takt (WS) und tauscht die Sample-Daten auf der Leitung SD aus. Der Treiber unterstützt kontinuierliches DMA im Hintergrund, sodass die Python-Seite nur den internen Sample-Puffer gefüllt halten muss. Peripherie- bzw. reine Empfangsmodi werden nicht unterstützt.
Verfügbar auf STM32-OpenMV-Cams, die ein I2S-Peripheriegerät verdrahten, sowie auf der OpenMV Cam RT1062. Nicht verfügbar auf der OpenMV Cam AE3 (Alif-Port).
I2S(2) auf STM32-OpenMV-Cams teilt sich seine Pins mit SPI(2) – der Bittakt liegt auf P2 (SCK), das Word-Select auf P3 (NSS), und die serielle Datenleitung folgt der Konvention für die SPI-Datenrichtung: TX nutzt P0 (MOSI), RX nutzt P1 (MISO).
Beispiel – Ausgabe (TX). Konstruieren eines TX-Busses, um einen externen Audio-DAC mit 44,1 kHz und 16-Bit-Mono-Samples anzusteuern, mit einem 16384 Byte (16 KiB) großen DMA-Stützpuffer:
from machine import I2S, Pin
audio_out = I2S(
2,
sck=Pin("P2"), ws=Pin("P3"), sd=Pin("P0"),
mode=I2S.TX,
bits=16,
format=I2S.MONO,
rate=44100,
ibuf=16384,
)
Beispiel – Eingabe (RX). Konstruieren eines RX-Busses, der von einem Mikrofon mit 22,05 kHz und 32-Bit-Stereo (links + rechts verschachtelt) aufnimmt, mit einem 16384 Byte (16 KiB) großen DMA-Stützpuffer:
from machine import I2S, Pin
audio_in = I2S(
2,
sck=Pin("P2"), ws=Pin("P3"), sd=Pin("P1"),
mode=I2S.RX,
bits=32,
format=I2S.STEREO,
rate=22050,
ibuf=16384,
)
Die Übertragungsmethoden können in drei Stilen verwendet werden:
Blockierend – write() und readinto() kehren erst zurück, wenn der Vorgang abgeschlossen ist:
num_written = audio_out.write(buf) # blocks until buf is drained
num_read = audio_in.readinto(buf) # blocks until buf is filled
Nicht-blockierend – installieren Sie einen Callback mit irq(), und die Übertragungsmethoden kehren sofort zurück. Der Callback wird vom MicroPython-Scheduler ausgeführt, wenn das DMA den TX-Puffer leert oder den RX-Puffer füllt:
audio_out.irq(i2s_callback)
num_written = audio_out.write(buf) # returns immediately
audio_in.irq(i2s_callback)
num_read = audio_in.readinto(buf) # returns immediately
asyncio – I2S ist ein Stream und kann von asyncio.StreamReader / asyncio.StreamWriter umhüllt werden:
swriter = asyncio.StreamWriter(audio_out)
swriter.write(buf)
await swriter.drain()
sreader = asyncio.StreamReader(audio_in)
num_read = await sreader.readinto(buf)
Konstruktor¶
- class machine.I2S(id: int, *, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int)¶
Konstruiert ein I2S-Objekt mit der angegebenen id:
ididentifiziert einen bestimmten I2S-Bus; es ist board- und portspezifisch
Keyword-only-Parameter, die auf allen Ports unterstützt werden:
sckist ein Pin-Objekt für die serielle Taktleitungwsist ein Pin-Objekt für die Word-Select-Leitungsdist ein Pin-Objekt für die serielle Datenleitungmckist ein Pin-Objekt für die Master-Clock-Leitung; die Master-Clock-Frequenz ist Abtastrate * 256modelegt Empfangen oder Senden festbitslegt die Sample-Größe (Bits) fest, 16 oder 32formatlegt das Kanalformat fest, STEREO oder MONOratelegt die Audio-Abtastrate (Hz) fest; dies ist die Frequenz desws-Signalsibuflegt die interne Pufferlänge (Bytes) fest
Auf allen Ports läuft das DMA kontinuierlich im Hintergrund und erlaubt es Benutzeranwendungen, andere Operationen durchzuführen, während Sample-Daten zwischen dem internen Puffer und der I2S-Peripherieeinheit übertragen werden. Eine Vergrößerung des internen Puffers kann die Zeit erhöhen, in der Benutzeranwendungen Nicht-I2S-Operationen durchführen können, bevor es zu einem Underflow (z. B.
write-Methode) oder Overflow (z. B.readinto-Methode) kommt.Methoden¶
- init(*, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int) None¶
siehe Konstruktor für die Beschreibung der Argumente
- readinto(buf: bytearray) int¶
Liest Audio-Samples in den durch
bufangegebenen Puffer.bufmuss das Pufferprotokoll unterstützen, etwa bytearray oder array. Die Byte-Reihenfolge von „buf“ ist Little-Endian. Beim Stereoformat geht das Sample des linken Kanals dem des rechten Kanals voraus. Beim Monoformat werden die Sample-Daten des linken Kanals verwendet. Gibt die Anzahl der gelesenen Bytes zurück
- write(buf: bytes) int¶
Schreibt die in
bufenthaltenen Audio-Samples.bufmuss das Pufferprotokoll unterstützen, etwa bytearray oder array. Die Byte-Reihenfolge von „buf“ ist Little-Endian. Beim Stereoformat geht das Sample des linken Kanals dem des rechten Kanals voraus. Beim Monoformat werden die Sample-Daten sowohl in den rechten als auch in den linken Kanal geschrieben. Gibt die Anzahl der geschriebenen Bytes zurück
- irq(handler: Callable[[I2S], None]) None¶
Setzt einen Callback.
handlerwird aufgerufen, wennbufgeleert wird (write-Methode) oder voll wird (readinto-Methode). Das Setzen eines Callbacks ändert diewrite- undreadinto-Methoden in einen nicht-blockierenden Betrieb.handlerwird im Kontext des MicroPython-Schedulers aufgerufen.
- static shift(*, buf: bytearray, bits: int, shift: int) None¶
Bitweise Verschiebung aller in
bufenthaltenen Samples.bitslegt die Sample-Größe in Bits fest.shiftlegt die Anzahl der Bits fest, um die jedes Sample verschoben wird. Positiv für Linksverschiebung, negativ für Rechtsverschiebung. Wird typischerweise zur Lautstärkeregelung verwendet. Jede Bitverschiebung ändert die Sample-Lautstärke um 6 dB.
Konstanten¶