classe I2S – protocole de bus Inter-IC Sound

La classe I2S pilote un bus Inter-IC Sound (I2S) en mode contrôleur – le MCU génère l’horloge de bits (SCK) et l’horloge de sélection de mot (WS) et échange les données d’échantillons sur la ligne SD. Le pilote prend en charge le DMA continu en arrière-plan, de sorte que le côté Python n’a qu’à maintenir le tampon d’échantillons interne alimenté. Les modes périphérique / réception seule ne sont pas pris en charge.

Disponible sur les caméras OpenMV STM32 qui câblent un périphérique I2S et sur l’OpenMV Cam RT1062. Non exposé sur l’OpenMV Cam AE3 (port alif).

I2S(2) sur les caméras OpenMV STM32 partage ses broches avec SPI(2) – horloge de bits sur P2 (SCK), sélection de mot sur P3 (NSS), et la ligne de données série suit la convention de direction des données SPI : la transmission utilise P0 (MOSI), la réception utilise P1 (MISO).

Exemple – sortie (TX). Construit un bus TX pour piloter un DAC audio externe à 44,1 kHz, échantillons mono 16 bits, avec un tampon DMA de 16384 octets (16 Kio):

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

Exemple – entrée (RX). Construit un bus RX qui capture depuis un microphone à 22,05 kHz, stéréo 32 bits (gauche + droite entrelacées), avec un tampon DMA de 16384 octets (16 Kio):

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

Les méthodes de transfert peuvent être utilisées selon trois styles :

Bloquantwrite() et readinto() ne retournent qu’une fois l’opération terminée:

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

Non bloquant – installez une fonction de rappel avec irq() et les méthodes de transfert retournent immédiatement. La fonction de rappel s’exécute depuis l’ordonnanceur de MicroPython lorsque le DMA vide le tampon TX ou remplit le tampon 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 est un flux et peut être encapsulé par 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)

Constructeur

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)

Construit un objet I2S avec l’id donné :

  • id identifie un bus I2S particulier ; il est spécifique à la carte et au port

Paramètres réservés aux mots-clés pris en charge sur tous les ports :

  • sck est un objet broche pour la ligne d’horloge série

  • ws est un objet broche pour la ligne de sélection de mot

  • sd est un objet broche pour la ligne de données série

  • mck est un objet broche pour la ligne d’horloge maître ; la fréquence de l’horloge maître est le taux d’échantillonnage * 256

  • mode spécifie la réception ou la transmission

  • bits spécifie la taille d’échantillon (bits), 16 ou 32

  • format spécifie le format de canal, STEREO ou MONO

  • rate spécifie le taux d’échantillonnage audio (Hz) ; il s’agit de la fréquence du signal ws

  • ibuf spécifie la longueur du tampon interne (octets)

Pour tous les ports, le DMA fonctionne en continu en arrière-plan et permet aux applications utilisateur d’effectuer d’autres opérations pendant que les données d’échantillons sont transférées entre le tampon interne et l’unité périphérique I2S. Augmenter la taille du tampon interne peut potentiellement accroître le temps pendant lequel les applications utilisateur peuvent effectuer des opérations non I2S avant un dépassement par le bas (p. ex. la méthode write) ou un dépassement par le haut (p. ex. la méthode readinto).

Méthodes

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

voir le Constructeur pour la description des arguments

deinit() None

Désinitialise le bus I2S

readinto(buf: bytearray) int

Lit des échantillons audio dans le tampon spécifié par buf. buf doit prendre en charge le protocole tampon, comme bytearray ou array. L’ordre des octets de « buf » est petit-boutiste. Pour le format Stéréo, l’échantillon du canal gauche précède celui du canal droit. Pour le format Mono, les données d’échantillon du canal gauche sont utilisées. Retourne le nombre d’octets lus

write(buf: bytes) int

Écrit les échantillons audio contenus dans buf. buf doit prendre en charge le protocole tampon, comme bytearray ou array. L’ordre des octets de « buf » est petit-boutiste. Pour le format Stéréo, l’échantillon du canal gauche précède celui du canal droit. Pour le format Mono, les données d’échantillon sont écrites à la fois sur le canal droit et le canal gauche. Retourne le nombre d’octets écrits

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

Définit une fonction de rappel. handler est appelé lorsque buf est vidé (méthode write) ou devient plein (méthode readinto). Définir une fonction de rappel fait passer les méthodes write et readinto en mode non bloquant. handler est appelé dans le contexte de l’ordonnanceur de MicroPython.

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

décalage binaire de tous les échantillons contenus dans buf. bits spécifie la taille d’échantillon en bits. shift spécifie le nombre de bits de décalage de chaque échantillon. Positif pour un décalage à gauche, négatif pour un décalage à droite. Généralement utilisé pour le contrôle du volume. Chaque décalage d’un bit modifie le volume de l’échantillon de 6 dB.

Constantes

RX: int

pour initialiser le mode du bus I2S en réception

TX: int

pour initialiser le mode du bus I2S en transmission

STEREO: int

pour initialiser le format du bus I2S en stéréo

MONO: int

pour initialiser le format du bus I2S en mono