คลาส I2S -- โปรโตคอลบัสเสียง Inter-IC

คลาส I2S ขับเคลื่อนบัสเสียง Inter-IC Sound (I2S) ในโหมดคอนโทรลเลอร์ -- MCU จะสร้างสัญญาณนาฬิกาบิต (SCK) และสัญญาณนาฬิกาเลือกคำ (WS) แล้วแลกเปลี่ยนข้อมูลตัวอย่างบนสาย SD ไดรเวอร์รองรับ DMA แบบต่อเนื่องในพื้นหลัง ทำให้ฝั่ง Python ต้องเพียงแค่คอยป้อนข้อมูลให้กับบัฟเฟอร์ตัวอย่างภายใน โหมด Peripheral/รับเท่านั้นไม่รองรับ

รองรับบน STM32 OpenMV cams ที่ต่อวงจร I2S peripheral และ OpenMV Cam RT1062 ไม่เปิดเผยบน OpenMV Cam AE3 (พอร์ต alif)

I2S(2) บน STM32 OpenMV cams ใช้พินร่วมกับ SPI(2) -- นาฬิกาบิตอยู่ที่ P2 (SCK), เลือกคำอยู่ที่ P3 (NSS) และสายข้อมูลอนุกรมเป็นไปตามแนวทาง SPI: TX ใช้ P0 (MOSI), RX ใช้ P1 (MISO)

ตัวอย่าง -- เอาต์พุต (TX) สร้างบัส TX เพื่อขับ DAC เสียงภายนอกที่ 44.1 kHz, 16 บิต mono พร้อมบัฟเฟอร์สำรอง DMA ขนาด 16384 ไบต์ (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,
)

ตัวอย่าง -- อินพุต (RX) สร้างบัส RX เพื่อรับสัญญาณจากไมโครโฟนที่ 22.05 kHz, 32 บิต stereo (ซ้าย + ขวาสลับกัน) พร้อมบัฟเฟอร์สำรอง DMA ขนาด 16384 ไบต์ (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,
)

เมธอดการถ่ายโอนสามารถใช้ได้สามรูปแบบ:

แบบบล็อก -- write() และ readinto() จะ return หลังจากการดำเนินการเสร็จสมบูรณ์เท่านั้น:

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

แบบไม่บล็อก -- ติดตั้งคอลแบ็กด้วย irq() และเมธอดการถ่ายโอนจะ return ทันที คอลแบ็กจะทำงานจาก MicroPython scheduler เมื่อ 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 เป็น stream และสามารถห่อด้วย 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)

สร้างออบเจ็กต์ I2S ตาม id ที่กำหนด:

  • id ระบุบัส I2S เฉพาะ ซึ่งขึ้นอยู่กับบอร์ดและพอร์ต

พารามิเตอร์แบบ keyword-only ที่รองรับในทุกพอร์ต:

  • sck คือออบเจ็กต์พินสำหรับสายนาฬิกาอนุกรม

  • ws คือออบเจ็กต์พินสำหรับสายเลือกคำ

  • sd คือออบเจ็กต์พินสำหรับสายข้อมูลอนุกรม

  • mck คือออบเจ็กต์พินสำหรับสายนาฬิกาหลัก ความถี่นาฬิกาหลักเท่ากับอัตราการสุ่มตัวอย่าง × 256

  • mode ระบุโหมดรับหรือส่ง

  • bits ระบุขนาดตัวอย่าง (บิต) ได้แก่ 16 หรือ 32

  • format ระบุรูปแบบช่อง ได้แก่ STEREO หรือ MONO

  • rate ระบุอัตราการสุ่มตัวอย่างเสียง (Hz) ซึ่งเป็นความถี่ของสัญญาณ ws

  • ibuf ระบุความยาวบัฟเฟอร์ภายใน (ไบต์)

สำหรับทุกพอร์ต DMA ทำงานต่อเนื่องในพื้นหลังและช่วยให้แอปพลิเคชันผู้ใช้สามารถทำการดำเนินการอื่นๆ ขณะที่ข้อมูลตัวอย่างถ่ายโอนระหว่างบัฟเฟอร์ภายในและหน่วย I2S peripheral การเพิ่มขนาดบัฟเฟอร์ภายในอาจเพิ่มเวลาที่แอปพลิเคชันผู้ใช้สามารถทำงานนอกเหนือจาก I2S ก่อนที่จะเกิด underflow (เช่น เมธอด write) หรือ overflow (เช่น เมธอด readinto)

Methods

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

ดูคำอธิบายอาร์กิวเมนต์ใน Constructor

deinit() None

ยกเลิกการเริ่มต้นบัส I2S

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 ถูกเรียกใน context ของ MicroPython scheduler

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

เลื่อนบิตของตัวอย่างทั้งหมดใน buf bits ระบุขนาดตัวอย่างเป็นบิต shift ระบุจำนวนบิตที่จะเลื่อนแต่ละตัวอย่าง บวกสำหรับเลื่อนซ้าย ลบสำหรับเลื่อนขวา โดยทั่วไปใช้สำหรับควบคุมระดับเสียง การเลื่อนหนึ่งบิตจะเปลี่ยนระดับเสียงตัวอย่าง 6dB

Constants

RX: int

สำหรับเริ่มต้นบัส I2S mode เป็นโหมดรับ

TX: int

สำหรับเริ่มต้นบัส I2S mode เป็นโหมดส่ง

STEREO: int

สำหรับเริ่มต้นบัส I2S format เป็น stereo

MONO: int

สำหรับเริ่มต้นบัส I2S format เป็น mono