classe I2S – protocolo de barramento Inter-IC Sound¶
A classe I2S controla um barramento Inter-IC Sound (I2S) no modo controlador – o MCU gera o clock de bits (SCK) e o clock de seleção de palavra (WS) e troca dados de amostras na linha SD. O driver suporta DMA contínuo em segundo plano, de modo que o lado Python só precisa manter o buffer interno de amostras abastecido. Os modos periférico / somente recepção não são suportados.
Disponível em câmeras OpenMV STM32 que conectam um periférico I2S e na OpenMV Cam RT1062. Não exposto na OpenMV Cam AE3 (porta alif).
I2S(2) em câmeras OpenMV STM32 compartilha seus pinos com SPI(2) – clock de bits em P2 (SCK), seleção de palavra em P3 (NSS), e a linha de dados serial segue a convenção de direção de dados do SPI: TX usa P0 (MOSI), RX usa P1 (MISO).
Exemplo – saída (TX). Construa um barramento TX para controlar um DAC de áudio externo a 44,1 kHz, amostras mono de 16 bits, com um buffer de DMA de 16384 bytes (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,
)
Exemplo – entrada (RX). Construa um barramento RX que captura de um microfone a 22,05 kHz, estéreo de 32 bits (esquerdo + direito intercalados), com um buffer de DMA de 16384 bytes (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,
)
Os métodos de transferência podem ser usados em três estilos:
Bloqueante – write() e readinto() retornam somente após a conclusão da operação:
num_written = audio_out.write(buf) # blocks until buf is drained
num_read = audio_in.readinto(buf) # blocks until buf is filled
Não bloqueante – instale um callback com irq() e os métodos de transferência retornam imediatamente. O callback é executado pelo escalonador do MicroPython quando o DMA esvazia o buffer TX ou enche o 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 é um stream e pode ser encapsulado por 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)
Construtor¶
- 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)¶
Constrói um objeto I2S com o id fornecido:
ididentifica um barramento I2S específico; é dependente da placa e da porta
Parâmetros somente por palavra-chave que são suportados em todas as portas:
scké um objeto pino para a linha de clock serialwsé um objeto pino para a linha de seleção de palavrasdé um objeto pino para a linha de dados serialmcké um objeto pino para a linha de clock mestre; a frequência do clock mestre é a taxa de amostragem * 256modeespecifica recepção ou transmissãobitsespecifica o tamanho da amostra (bits), 16 ou 32formatespecifica o formato do canal, STEREO ou MONOrateespecifica a taxa de amostragem de áudio (Hz); esta é a frequência do sinalwsibufespecifica o comprimento do buffer interno (bytes)
Em todas as portas, o DMA é executado continuamente em segundo plano e permite que as aplicações do usuário realizem outras operações enquanto os dados de amostra são transferidos entre o buffer interno e a unidade do periférico I2S. Aumentar o tamanho do buffer interno tem o potencial de aumentar o tempo que as aplicações do usuário podem realizar operações não relacionadas a I2S antes de um underflow (ex.: método
write) ou overflow (ex.: métodoreadinto).Métodos¶
- init(*, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int) None¶
veja o Construtor para as descrições dos argumentos
- readinto(buf: bytearray) int¶
Lê amostras de áudio para o buffer especificado por
buf.bufdeve suportar o protocolo de buffer, como bytearray ou array. A ordenação de bytes de “buf” é little-endian. Para o formato Estéreo, a amostra do canal esquerdo precede a amostra do canal direito. Para o formato Mono, os dados da amostra do canal esquerdo são usados. Retorna o número de bytes lidos
- write(buf: bytes) int¶
Escreve as amostras de áudio contidas em
buf.bufdeve suportar o protocolo de buffer, como bytearray ou array. A ordenação de bytes de “buf” é little-endian. Para o formato Estéreo, a amostra do canal esquerdo precede a amostra do canal direito. Para o formato Mono, os dados da amostra são escritos em ambos os canais, direito e esquerdo. Retorna o número de bytes escritos
- irq(handler: Callable[[I2S], None]) None¶
Define um callback.
handleré chamado quandobufé esvaziado (métodowrite) ou fica cheio (métodoreadinto). Definir um callback altera os métodoswriteereadintopara operação não bloqueante.handleré chamado no contexto do escalonador do MicroPython.
- static shift(*, buf: bytearray, bits: int, shift: int) None¶
deslocamento bit a bit de todas as amostras contidas em
buf.bitsespecifica o tamanho da amostra em bits.shiftespecifica o número de bits a deslocar cada amostra. Positivo para deslocamento à esquerda, negativo para deslocamento à direita. Tipicamente usado para controle de volume. Cada deslocamento de bit altera o volume da amostra em 6dB.
Constantes¶