clasa I2S – protocolul magistralei de sunet Inter-IC

Clasa I2S comandă o magistrală de sunet Inter-IC (I2S) în mod controler – MCU-ul generează ceasul de biți (SCK) și ceasul de selecție a cuvântului (WS) și schimbă date de eșantion pe linia SD. Driverul acceptă DMA continuu în fundal, astfel încât partea de Python trebuie doar să mențină alimentat tamponul intern de eșantioane. Modurile periferic / numai-receptor nu sunt acceptate.

Disponibil pe camerele STM32 OpenMV care conectează un periferic I2S și pe OpenMV Cam RT1062. Nu este expus pe OpenMV Cam AE3 (portul alif).

I2S(2) pe camerele STM32 OpenMV își partajează pinii cu SPI(2) – ceasul de biți pe P2 (SCK), selecția cuvântului pe P3 (NSS), iar linia de date seriale urmează convenția SPI privind direcția datelor: TX folosește P0 (MOSI), RX folosește P1 (MISO).

Exemplu – ieșire (TX). Se construiește o magistrală TX pentru a comanda un DAC audio extern la 44,1 kHz, eșantioane mono pe 16 biți, cu un tampon DMA de susținere de 16384 octeți (16 KiB):

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,
)

Exemplu – intrare (RX). Se construiește o magistrală RX care captează de la un microfon la 22,05 kHz, stereo pe 32 de biți (stânga + dreapta întrețesute), cu un tampon DMA de susținere de 16384 octeți (16 KiB):

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,
)

Metodele de transfer pot fi utilizate în trei stiluri:

Blocantwrite() și readinto() revin doar după ce operația se finalizează:

num_written = audio_out.write(buf)   # blocks until buf is drained
num_read = audio_in.readinto(buf)    # blocks until buf is filled

Neblocant – instalați o funcție de retroapelare (callback) cu irq(), iar metodele de transfer revin imediat. Funcția de retroapelare (callback) rulează din planificatorul MicroPython atunci când DMA golește tamponul TX sau umple tamponul RX:

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

asyncioI2S este un flux și poate fi încapsulat de asyncio.StreamReader / asyncio.StreamWriter

swriter = asyncio.StreamWriter(audio_out)
swriter.write(buf)
await swriter.drain()

sreader = asyncio.StreamReader(audio_in)
num_read = await sreader.readinto(buf)

Constructor

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)

Construiește un obiect I2S cu id-ul dat:

  • id identifică o anumită magistrală I2S; este specific plăcii și portului

Parametri exclusiv pe bază de cuvânt-cheie care sunt acceptați pe toate porturile:

  • sck este un obiect pin pentru linia de ceas serial

  • ws este un obiect pin pentru linia de selecție a cuvântului

  • sd este un obiect pin pentru linia de date seriale

  • mck este un obiect pin pentru linia de ceas master; frecvența ceasului master este rata de eșantionare * 256

  • mode specifică recepția sau transmisia

  • bits specifică dimensiunea eșantionului (biți), 16 sau 32

  • format specifică formatul canalului, STEREO sau MONO

  • rate specifică rata de eșantionare audio (Hz); aceasta este frecvența semnalului ws

  • ibuf specifică lungimea tamponului intern (octeți)

Pe toate porturile, DMA rulează continuu în fundal și permite aplicațiilor utilizator să efectueze alte operații în timp ce datele de eșantion sunt transferate între tamponul intern și unitatea periferică I2S. Mărirea dimensiunii tamponului intern poate crește timpul în care aplicațiile utilizator pot efectua operații non-I2S înainte de o subîncărcare (de exemplu metoda write) sau o supraîncărcare (de exemplu metoda readinto).

Metode

init(*, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int) None

consultați Constructorul pentru descrierea argumentelor

deinit() None

Dezinițializează magistrala I2S

readinto(buf: bytearray) int

Citește eșantioane audio în tamponul specificat de buf. buf trebuie să accepte protocolul de tampon, cum ar fi bytearray sau array. Ordinea octeților din „buf” este little-endian. Pentru formatul Stereo, eșantionul canalului stâng precedă eșantionul canalului drept. Pentru formatul Mono, se folosesc datele eșantionului canalului stâng. Returnează numărul de octeți citiți

write(buf: bytes) int

Scrie eșantioanele audio conținute în buf. buf trebuie să accepte protocolul de tampon, cum ar fi bytearray sau array. Ordinea octeților din „buf” este little-endian. Pentru formatul Stereo, eșantionul canalului stâng precedă eșantionul canalului drept. Pentru formatul Mono, datele eșantionului sunt scrise atât pe canalul drept, cât și pe cel stâng. Returnează numărul de octeți scriși

irq(handler: Callable[[I2S], None]) None

Setează o funcție de retroapelare (callback). handler este apelat când buf se golește (metoda write) sau devine plin (metoda readinto). Setarea unei funcții de retroapelare (callback) schimbă metodele write și readinto în operare neblocantă. handler este apelat în contextul planificatorului MicroPython.

static shift(*, buf: bytearray, bits: int, shift: int) None

deplasare pe biți a tuturor eșantioanelor conținute în buf. bits specifică dimensiunea eșantionului în biți. shift specifică numărul de biți cu care se deplasează fiecare eșantion. Pozitiv pentru deplasare la stânga, negativ pentru deplasare la dreapta. Folosit de obicei pentru controlul volumului. Fiecare deplasare cu un bit modifică volumul eșantionului cu 6dB.

Constante

RX: int

pentru inițializarea mode al magistralei I2S la recepție

TX: int

pentru inițializarea mode al magistralei I2S la transmisie

STEREO: int

pentru inițializarea format al magistralei I2S la stereo

MONO: int

pentru inițializarea format al magistralei I2S la mono