класс I2S – протокол шины Inter-IC Sound¶
Класс I2S управляет шиной Inter-IC Sound (I2S) в режиме контроллера – MCU генерирует тактовый сигнал битов (SCK) и тактовый сигнал выбора слова (WS) и обменивается данными сэмплов по линии SD. Драйвер поддерживает непрерывный DMA в фоновом режиме, поэтому со стороны Python требуется лишь поддерживать заполнение внутреннего буфера сэмплов. Режимы периферийного устройства / только приёма не поддерживаются.
Доступно на STM32 OpenMV cam, у которых разведена периферия I2S, и на OpenMV Cam RT1062. Не предоставляется на OpenMV Cam AE3 (порт alif).
I2S(2) на STM32 OpenMV cam использует те же выводы, что и SPI(2) – тактовый сигнал битов на P2 (SCK), выбор слова на P3 (NSS), а линия последовательных данных следует соглашению о направлении данных SPI: TX использует P0 (MOSI), RX использует P1 (MISO).
Пример – вывод (TX). Создание шины TX для управления внешним аудио-DAC на частоте 44.1 кГц, 16-битные моно-сэмплы, с резервным DMA-буфером размером 16384 байта (16 КиБ):
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,
)
Пример – ввод (RX). Создание шины RX, захватывающей данные с микрофона на частоте 22.05 кГц, 32-битное стерео (левый + правый, чередующиеся), с резервным DMA-буфером размером 16384 байта (16 КиБ):
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,
)
Методы передачи можно использовать тремя способами:
Блокирующий – write() и readinto() возвращают управление только после завершения операции:
num_written = audio_out.write(buf) # blocks until buf is drained
num_read = audio_in.readinto(buf) # blocks until buf is filled
Неблокирующий – установите функцию обратного вызова с помощью irq(), и методы передачи вернут управление немедленно. Функция обратного вызова вызывается из планировщика MicroPython, когда DMA опустошает буфер TX или заполняет буфер 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 является потоком и может быть обёрнут в 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)
Конструктор¶
- 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)¶
Создаёт объект I2S с заданным id:
idидентифицирует конкретную шину I2S; зависит от платы и порта
Параметры, передаваемые только по ключевому слову, которые поддерживаются на всех портах:
sck– объект вывода для линии последовательного тактового сигналаws– объект вывода для линии выбора словаsd– объект вывода для линии последовательных данныхmck– объект вывода для линии основного тактового сигнала; частота основного тактового сигнала равна частоте дискретизации * 256modeзадаёт приём или передачуbitsзадаёт размер сэмпла (биты), 16 или 32formatзадаёт формат каналов, STEREO или MONOrateзадаёт частоту дискретизации аудио (Гц); это частота сигналаwsibufзадаёт длину внутреннего буфера (байты)
Для всех портов DMA работает непрерывно в фоновом режиме и позволяет пользовательским приложениям выполнять другие операции, пока данные сэмплов передаются между внутренним буфером и периферийным блоком I2S. Увеличение размера внутреннего буфера потенциально увеличивает время, в течение которого пользовательские приложения могут выполнять операции, не связанные с I2S, до возникновения недополнения (например, метод
write) или переполнения (например, методreadinto).Методы¶
- init(*, sck: Pin, ws: Pin, sd: Pin, mck: Pin | None = None, mode: int, bits: int, format: int, rate: int, ibuf: int) None¶
описания аргументов см. в разделе Конструктор
- readinto(buf: bytearray) int¶
Считывает аудио-сэмплы в буфер, заданный параметром
buf.bufдолжен поддерживать протокол буфера, например bytearray или array. Порядок байтов «buf» – little-endian. Для формата Stereo сэмпл левого канала предшествует сэмплу правого канала. Для формата Mono используются данные сэмпла левого канала. Возвращает количество прочитанных байтов
- write(buf: bytes) int¶
Записывает аудио-сэмплы, содержащиеся в
buf.bufдолжен поддерживать протокол буфера, например bytearray или array. Порядок байтов «buf» – little-endian. Для формата Stereo сэмпл левого канала предшествует сэмплу правого канала. Для формата Mono данные сэмпла записываются как в правый, так и в левый канал. Возвращает количество записанных байтов
- irq(handler: Callable[[I2S], None]) None¶
Устанавливает функцию обратного вызова.
handlerвызывается, когдаbufопустошается (методwrite) или становится заполненным (методreadinto). Установка функции обратного вызова переводит методыwriteиreadintoв неблокирующий режим работы.handlerвызывается в контексте планировщика MicroPython.
- static shift(*, buf: bytearray, bits: int, shift: int) None¶
побитовый сдвиг всех сэмплов, содержащихся в
buf.bitsзадаёт размер сэмпла в битах.shiftзадаёт количество битов для сдвига каждого сэмпла. Положительное значение – для сдвига влево, отрицательное – для сдвига вправо. Обычно используется для управления громкостью. Каждый сдвиг на один бит изменяет громкость сэмпла на 6 дБ.
Константы¶