classe I2S – protocollo del bus Inter-IC Sound¶
La classe I2S pilota un bus Inter-IC Sound (I2S) in modalità controller – l’MCU genera il clock di bit (SCK) e il clock di selezione della parola (WS) e scambia i dati dei campioni sulla linea SD. Il driver supporta il DMA continuo in background, quindi il lato Python deve solo mantenere alimentato il buffer interno dei campioni. Le modalità periferica / solo-ricezione non sono supportate.
Disponibile sulle OpenMV cam STM32 che collegano una periferica I2S e sulla OpenMV Cam RT1062. Non esposto sulla OpenMV Cam AE3 (port alif).
I2S(2) sulle OpenMV cam STM32 condivide i suoi pin con SPI(2) – il clock di bit su P2 (SCK), la selezione della parola su P3 (NSS), e la linea dei dati seriali segue la convenzione di direzione dati di SPI: TX usa P0 (MOSI), RX usa P1 (MISO).
Esempio – uscita (TX). Costruisce un bus TX per pilotare un DAC audio esterno a 44,1 kHz, campioni mono a 16 bit, con un buffer di supporto DMA da 16384 byte (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,
)
Esempio – ingresso (RX). Costruisce un bus RX che acquisisce da un microfono a 22,05 kHz, stereo a 32 bit (sinistro + destro interlacciati), con un buffer di supporto DMA da 16384 byte (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,
)
I metodi di trasferimento possono essere usati in tre stili:
Bloccante – write() e readinto() ritornano solo una volta completata l’operazione:
num_written = audio_out.write(buf) # blocks until buf is drained
num_read = audio_in.readinto(buf) # blocks until buf is filled
Non bloccante – installa una callback con irq() e i metodi di trasferimento ritornano immediatamente. La callback viene eseguita dallo scheduler di MicroPython quando il DMA svuota il buffer TX o riempie il buffer 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
asyncio – I2S è uno stream e può essere incapsulato da 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)
Costruttore¶
- 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)¶
Costruisce un oggetto I2S con l’id specificato:
ididentifica un particolare bus I2S; dipende dalla scheda e dal port
Parametri solo per parola chiave supportati su tutti i port:
sckè un oggetto pin per la linea del clock serialewsè un oggetto pin per la linea di selezione della parolasdè un oggetto pin per la linea dei dati serialimckè un oggetto pin per la linea del clock master; la frequenza del clock master è frequenza di campionamento * 256modespecifica ricezione o trasmissionebitsspecifica la dimensione del campione (bit), 16 o 32formatspecifica il formato dei canali, STEREO o MONOratespecifica la frequenza di campionamento audio (Hz); questa è la frequenza del segnalewsibufspecifica la lunghezza del buffer interno (byte)
Su tutti i port, il DMA viene eseguito in modo continuo in background e consente alle applicazioni utente di eseguire altre operazioni mentre i dati dei campioni vengono trasferiti tra il buffer interno e l’unità periferica I2S. Aumentare la dimensione del buffer interno può aumentare il tempo durante il quale le applicazioni utente possono eseguire operazioni non I2S prima di un underflow (ad es. il metodo
write) o di un overflow (ad es. il metodoreadinto).Metodi¶
- init(*, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int) None¶
vedere il Costruttore per le descrizioni degli argomenti
- readinto(buf: bytearray) int¶
Legge i campioni audio nel buffer specificato da
buf.bufdeve supportare il protocollo buffer, come bytearray o array. L’ordinamento dei byte di «buf» è little-endian. Per il formato Stereo, il campione del canale sinistro precede quello del canale destro. Per il formato Mono, vengono usati i dati del campione del canale sinistro. Restituisce il numero di byte letti
- write(buf: bytes) int¶
Scrive i campioni audio contenuti in
buf.bufdeve supportare il protocollo buffer, come bytearray o array. L’ordinamento dei byte di «buf» è little-endian. Per il formato Stereo, il campione del canale sinistro precede quello del canale destro. Per il formato Mono, i dati del campione vengono scritti su entrambi i canali destro e sinistro. Restituisce il numero di byte scritti
- irq(handler: Callable[[I2S], None]) None¶
Imposta una callback.
handlerviene chiamato quandobufviene svuotato (metodowrite) o diventa pieno (metodoreadinto). Impostare una callback cambia i metodiwriteereadintoin operazioni non bloccanti.handlerviene chiamato nel contesto dello scheduler di MicroPython.
- static shift(*, buf: bytearray, bits: int, shift: int) None¶
scorrimento bit a bit di tutti i campioni contenuti in
buf.bitsspecifica la dimensione del campione in bit.shiftspecifica il numero di bit di cui scorrere ciascun campione. Positivo per lo scorrimento a sinistra, negativo per quello a destra. Tipicamente usato per il controllo del volume. Ogni scorrimento di un bit cambia il volume del campione di 6 dB.
Costanti¶