class I2S -- Giao thức bus âm thanh Inter-IC

Lớp I2S điều khiển bus âm thanh Inter-IC (I2S) ở chế độ bộ điều khiển -- MCU tạo ra xung nhịp bit (SCK) và xung nhịp chọn từ (WS), đồng thời trao đổi dữ liệu mẫu trên đường SD. Driver hỗ trợ DMA liên tục chạy nền để phía Python chỉ cần duy trì việc cung cấp dữ liệu cho bộ đệm mẫu nội bộ. Các chế độ ngoại vi / chỉ nhận không được hỗ trợ.

Khả dụng trên các camera OpenMV STM32 có kết nối ngoại vi I2S và OpenMV Cam RT1062. Không hiển thị trên OpenMV Cam AE3 (cổng alif).

I2S(2) trên các camera OpenMV STM32 dùng chung chân (pin) với SPI(2) -- xung nhịp bit trên P2 (SCK), chọn từ trên P3 (NSS), và đường dữ liệu nối tiếp tuân theo quy ước hướng dữ liệu SPI: TX dùng P0 (MOSI), RX dùng P1 (MISO).

Ví dụ -- đầu ra (TX). Khởi tạo bus TX để điều khiển DAC âm thanh ngoài ở 44.1 kHz, mẫu mono 16-bit, với bộ đệm DMA nền 16384 byte (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,
)

Ví dụ -- đầu vào (RX). Khởi tạo bus RX để thu từ microphone ở 22.05 kHz, stereo 32-bit (trái + phải xen kẽ), với bộ đệm DMA nền 16384 byte (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,
)

Các phương thức truyền có thể được sử dụng theo ba kiểu:

Chặn (Blocking) -- write()readinto() chỉ trả về sau khi thao tác hoàn tất:

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

Không chặn (Non-blocking) -- cài đặt hàm gọi lại bằng irq() và các phương thức truyền sẽ trả về ngay lập tức. Hàm gọi lại chạy từ bộ lập lịch MicroPython khi DMA làm rỗng bộ đệm TX hoặc làm đầy bộ đệm 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 là một luồng và có thể được bọc bởi 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)

Hàm khởi tạo

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)

Khởi tạo một đối tượng I2S với id cho trước:

  • id xác định một bus I2S cụ thể; giá trị này phụ thuộc vào bo mạch và cổng

Các tham số chỉ từ khóa được hỗ trợ trên mọi cổng:

  • sck là đối tượng chân (pin) cho đường xung nhịp nối tiếp

  • ws là đối tượng chân (pin) cho đường chọn từ

  • sd là đối tượng chân (pin) cho đường dữ liệu nối tiếp

  • mck là đối tượng chân (pin) cho đường xung nhịp chính; tần số xung nhịp chính bằng tần số lấy mẫu * 256

  • mode chỉ định chế độ nhận hoặc phát

  • bits chỉ định kích thước mẫu (bits), 16 hoặc 32

  • format chỉ định định dạng kênh, STEREO hoặc MONO

  • rate chỉ định tần số lấy mẫu âm thanh (Hz); đây là tần số của tín hiệu ws

  • ibuf chỉ định độ dài bộ đệm nội bộ (byte)

Trên tất cả các cổng, DMA chạy liên tục ở nền và cho phép ứng dụng người dùng thực hiện các thao tác khác trong khi dữ liệu mẫu được truyền giữa bộ đệm nội bộ và đơn vị ngoại vi I2S. Tăng kích thước bộ đệm nội bộ có khả năng tăng thời gian ứng dụng người dùng có thể thực hiện các thao tác không liên quan đến I2S trước khi xảy ra tràn dưới (ví dụ phương thức write) hoặc tràn trên (ví dụ phương thức readinto).

Các phương thức

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

xem phần Hàm khởi tạo để biết mô tả các tham số

deinit() None

Hủy khởi tạo bus I2S

readinto(buf: bytearray) int

Đọc các mẫu âm thanh vào bộ đệm được chỉ định bởi buf. buf phải hỗ trợ giao thức bộ đệm, chẳng hạn bytearray hoặc array. Thứ tự byte của "buf" là little-endian. Với định dạng Stereo, mẫu kênh trái đứng trước mẫu kênh phải. Với định dạng Mono, dữ liệu mẫu kênh trái được sử dụng. Trả về số byte đã đọc

write(buf: bytes) int

Ghi các mẫu âm thanh chứa trong buf. buf phải hỗ trợ giao thức bộ đệm, chẳng hạn bytearray hoặc array. Thứ tự byte của "buf" là little-endian. Với định dạng Stereo, mẫu kênh trái đứng trước mẫu kênh phải. Với định dạng Mono, dữ liệu mẫu được ghi vào cả kênh phải và kênh trái. Trả về số byte đã ghi

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

Đặt hàm gọi lại. handler được gọi khi buf bị làm rỗng (phương thức write) hoặc bị làm đầy (phương thức readinto). Việc đặt hàm gọi lại sẽ chuyển các phương thức writereadinto sang chế độ không chặn. handler được gọi trong ngữ cảnh của bộ lập lịch MicroPython.

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

dịch chuyển bit của tất cả các mẫu chứa trong buf. bits chỉ định kích thước mẫu theo bit. shift chỉ định số bit cần dịch chuyển mỗi mẫu. Dương cho dịch trái, âm cho dịch phải. Thường dùng để điều chỉnh âm lượng. Mỗi lần dịch một bit sẽ thay đổi âm lượng mẫu 6dB.

Hằng số

RX: int

để khởi tạo bus I2S mode ở chế độ nhận

TX: int

để khởi tạo bus I2S mode ở chế độ phát

STEREO: int

để khởi tạo bus I2S format ở chế độ stereo

MONO: int

để khởi tạo bus I2S format ở chế độ mono