clase I2S – protocolo de bus Inter-IC Sound¶
La clase I2S controla un bus Inter-IC Sound (I2S) en modo controlador: el MCU genera el reloj de bits (SCK) y el reloj de selección de palabra (WS) e intercambia datos de muestra en la línea SD. El controlador admite DMA continuo en segundo plano, por lo que la parte de Python solo necesita mantener alimentado el búfer interno de muestras. No se admiten los modos periférico ni solo receptor.
Disponible en las cámaras OpenMV STM32 que conectan un periférico I2S y en la OpenMV Cam RT1062. No está expuesto en la OpenMV Cam AE3 (puerto alif).
I2S(2) en las cámaras OpenMV STM32 comparte sus pines con SPI(2): el reloj de bits en P2 (SCK), la selección de palabra en P3 (NSS), y la línea de datos serie sigue la convención de dirección de datos de SPI: TX usa P0 (MOSI), RX usa P1 (MISO).
Ejemplo – salida (TX). Construye un bus TX para controlar un DAC de audio externo a 44,1 kHz, con muestras mono de 16 bits y un búfer de respaldo 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,
)
Ejemplo – entrada (RX). Construye un bus RX que captura desde un micrófono a 22,05 kHz, en estéreo de 32 bits (izquierda + derecha intercaladas), con un búfer de respaldo 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,
)
Los métodos de transferencia pueden usarse de tres maneras:
Bloqueante – write() y readinto() solo regresan una vez que la operación se completa:
num_written = audio_out.write(buf) # blocks until buf is drained
num_read = audio_in.readinto(buf) # blocks until buf is filled
No bloqueante – instala una función de retorno (callback) con irq() y los métodos de transferencia regresan de inmediato. La función de retorno se ejecuta desde el planificador de MicroPython cuando el DMA vacía el búfer TX o llena el búfer 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 es un flujo y puede envolverse con 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)¶
Construye un objeto I2S con el id dado:
ididentifica un bus I2S concreto; es específico de la placa y del puerto
Parámetros exclusivos por palabra clave que se admiten en todos los puertos:
sckes un objeto pin para la línea de reloj seriewses un objeto pin para la línea de selección de palabrasdes un objeto pin para la línea de datos seriemckes un objeto pin para la línea de reloj maestro; la frecuencia del reloj maestro es la frecuencia de muestreo * 256modeespecifica recepción o transmisiónbitsespecifica el tamaño de muestra (bits), 16 o 32formatespecifica el formato de canal, STEREO o MONOrateespecifica la frecuencia de muestreo de audio (Hz); esta es la frecuencia de la señalwsibufespecifica la longitud del búfer interno (bytes)
En todos los puertos, el DMA se ejecuta de forma continua en segundo plano y permite que las aplicaciones de usuario realicen otras operaciones mientras se transfieren los datos de muestra entre el búfer interno y la unidad periférica I2S. Aumentar el tamaño del búfer interno puede incrementar el tiempo durante el cual las aplicaciones de usuario pueden realizar operaciones ajenas a I2S antes de un subdesbordamiento (p. ej. el método
write) o un desbordamiento (p. ej. el 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¶
consulta el Constructor para ver las descripciones de los argumentos
- readinto(buf: bytearray) int¶
Lee muestras de audio en el búfer especificado por
buf.bufdebe admitir el protocolo de búfer, como bytearray o array. El orden de bytes de «buf» es little-endian. Para el formato estéreo, la muestra del canal izquierdo precede a la del canal derecho. Para el formato mono, se utilizan los datos de muestra del canal izquierdo. Devuelve el número de bytes leídos
- write(buf: bytes) int¶
Escribe las muestras de audio contenidas en
buf.bufdebe admitir el protocolo de búfer, como bytearray o array. El orden de bytes de «buf» es little-endian. Para el formato estéreo, la muestra del canal izquierdo precede a la del canal derecho. Para el formato mono, los datos de muestra se escriben en ambos canales, derecho e izquierdo. Devuelve el número de bytes escritos
- irq(handler: Callable[[I2S], None]) None¶
Establece una función de retorno (callback).
handlerse llama cuandobufse vacía (métodowrite) o se llena (métodoreadinto). Establecer una función de retorno cambia los métodoswriteyreadintoa un funcionamiento no bloqueante.handlerse llama en el contexto del planificador de MicroPython.
- static shift(*, buf: bytearray, bits: int, shift: int) None¶
desplazamiento de bits de todas las muestras contenidas en
buf.bitsespecifica el tamaño de muestra en bits.shiftespecifica el número de bits que se desplaza cada muestra. Positivo para desplazamiento a la izquierda, negativo para desplazamiento a la derecha. Normalmente se usa para el control de volumen. Cada desplazamiento de bit cambia el volumen de la muestra en 6 dB.
Constantes¶