class I2S – Inter-IC Sound 버스 프로토콜

I2S 클래스는 Inter-IC Sound (I2S) 버스를 컨트롤러 모드로 구동합니다. MCU가 비트 클록(SCK)과 워드 선택 클록(WS)을 생성하고 SD 라인에서 샘플 데이터를 주고받습니다. 드라이버는 백그라운드에서 연속 DMA를 지원하므로 Python 측에서는 내부 샘플 버퍼를 계속 채워주기만 하면 됩니다. 주변장치/수신 전용 모드는 지원되지 않습니다.

I2S 주변장치를 연결한 STM32 OpenMV 카메라와 OpenMV Cam RT1062에서 사용할 수 있습니다. OpenMV Cam AE3 (alif 포트)에서는 제공되지 않습니다.

STM32 OpenMV 카메라에서 I2S(2)SPI(2)와 핀을 공유합니다. 비트 클록은 P2 (SCK), 워드 선택은 P3 (NSS)에 있으며, 시리얼 데이터 라인은 SPI 데이터 방향 규칙을 따릅니다. 즉 TX는 P0 (MOSI), RX는 P1 (MISO)을 사용합니다.

예제 – 출력(TX). 44.1 kHz, 16비트 모노 샘플로 외부 오디오 DAC를 구동하는 TX 버스를 16384바이트(16 KiB) DMA 백킹 버퍼와 함께 생성합니다:

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). 22.05 kHz, 32비트 스테레오(왼쪽 + 오른쪽 인터리브)로 마이크에서 캡처하는 RX 버스를 16384바이트(16 KiB) DMA 백킹 버퍼와 함께 생성합니다:

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()로 콜백을 설치하면 전송 메서드가 즉시 반환합니다. 콜백은 DMA가 TX 버퍼를 비우거나 RX 버퍼를 채울 때 MicroPython 스케줄러에서 실행됩니다:

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는 스트림이며 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)

주어진 id로 I2S 객체를 생성합니다:

  • id는 특정 I2S 버스를 식별하며, 보드와 포트에 따라 다릅니다

모든 포트에서 지원되는 키워드 전용 파라미터:

  • sck는 시리얼 클록 라인을 위한 핀 객체입니다

  • ws는 워드 선택 라인을 위한 핀 객체입니다

  • sd는 시리얼 데이터 라인을 위한 핀 객체입니다

  • mck는 마스터 클록 라인을 위한 핀 객체입니다. 마스터 클록 주파수는 샘플링 레이트 * 256입니다

  • mode는 수신 또는 송신을 지정합니다

  • bits는 샘플 크기(비트)를 지정하며, 16 또는 32입니다

  • format은 채널 형식을 지정하며, STEREO 또는 MONO입니다

  • rate는 오디오 샘플링 레이트(Hz)를 지정합니다. 이는 ws 신호의 주파수입니다

  • ibuf는 내부 버퍼 길이(바이트)를 지정합니다

모든 포트에서 DMA는 백그라운드에서 연속적으로 실행되며, 내부 버퍼와 I2S 주변장치 사이에서 샘플 데이터가 전송되는 동안 사용자 애플리케이션이 다른 작업을 수행할 수 있도록 합니다. 내부 버퍼의 크기를 늘리면 언더플로(예: write 메서드) 또는 오버플로(예: readinto 메서드)가 발생하기 전에 사용자 애플리케이션이 I2S 이외의 작업을 수행할 수 있는 시간이 늘어날 수 있습니다.

메서드

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

인수 설명은 생성자를 참조하세요

deinit() None

I2S 버스를 초기화 해제합니다

readinto(buf: bytearray) int

buf로 지정된 버퍼로 오디오 샘플을 읽어들입니다. buf는 bytearray나 array처럼 버퍼 프로토콜을 지원해야 합니다. “buf”의 바이트 순서는 리틀 엔디안입니다. 스테레오 형식의 경우 왼쪽 채널 샘플이 오른쪽 채널 샘플보다 앞에 옵니다. 모노 형식의 경우 왼쪽 채널 샘플 데이터가 사용됩니다. 읽은 바이트 수를 반환합니다

write(buf: bytes) int

buf에 담긴 오디오 샘플을 씁니다. buf는 bytearray나 array처럼 버퍼 프로토콜을 지원해야 합니다. “buf”의 바이트 순서는 리틀 엔디안입니다. 스테레오 형식의 경우 왼쪽 채널 샘플이 오른쪽 채널 샘플보다 앞에 옵니다. 모노 형식의 경우 샘플 데이터가 오른쪽과 왼쪽 채널 모두에 기록됩니다. 쓴 바이트 수를 반환합니다

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

콜백을 설정합니다. handlerbuf가 비워지거나(write 메서드) 가득 차게 될 때(readinto 메서드) 호출됩니다. 콜백을 설정하면 writereadinto 메서드가 논블로킹 동작으로 변경됩니다. handler는 MicroPython 스케줄러의 컨텍스트에서 호출됩니다.

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

buf에 담긴 모든 샘플을 비트 단위로 시프트합니다. bits는 샘플 크기를 비트로 지정합니다. shift는 각 샘플을 시프트할 비트 수를 지정합니다. 양수는 왼쪽 시프트, 음수는 오른쪽 시프트입니다. 일반적으로 볼륨 제어에 사용됩니다. 각 비트 시프트는 샘플 볼륨을 6dB만큼 변경합니다.

상수

RX: int

I2S 버스 mode를 수신으로 초기화하기 위한 값

TX: int

I2S 버스 mode를 송신으로 초기화하기 위한 값

STEREO: int

I2S 버스 format을 스테레오로 초기화하기 위한 값

MONO: int

I2S 버스 format을 모노로 초기화하기 위한 값