Skip to content

Fix: I2S TDM RX slot_bit_width set to 32BIT to prevent DMA out-of-bounds write - #17

Open
lvips wants to merge 1 commit into
m5stack:mainfrom
lvips:fix/i2s-tdm-slot-width
Open

Fix: I2S TDM RX slot_bit_width set to 32BIT to prevent DMA out-of-bounds write#17
lvips wants to merge 1 commit into
m5stack:mainfrom
lvips:fix/i2s-tdm-slot-width

Conversation

@lvips

@lvips lvips commented Aug 24, 2026

Copy link
Copy Markdown

Fix: I2S TDM RX slot_bit_width set to 32BIT to prevent DMA out-of-bounds write

Problem / 问题

On M5Stack Tab5, using the ES7210 codec in TDM mode for 4-microphone input causes a DMA out-of-bounds write that corrupts adjacent heap blocks, ultimately triggering CORRUPT HEAP panic and speaker popping/clicking noise.

在 M5Stack Tab5 上,ES7210 codec 以 TDM 模式采集 4 路麦克风时,会发生 DMA 越界写,腐蚀相邻 heap block,最终触发 CORRUPT HEAP panic 并伴随扬声器哒哒哒杂音。

Root Cause / 根因

The ES7210 outputs 32 bits per TDM slot, but the I2S RX channel was configured with slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO. ESP-IDF's auto-detection misinterprets this as 16-bit × 2-slot, causing the DMA intermediate buffer to be written with 86–588 extra bytes beyond its allocated size, overwriting the neighboring heap block.

ES7210 TDM 4mic 实际按 32bit/slot 输出,但 I2S RX 配置 slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO 被 ESP-IDF 误判为 16bit×2slot,DMA 中间 buffer 被多写入 86~588 字节,踩坏相邻 heap block。

Fix / 修复

In platforms/tab5/components/m5stack_tab5/m5stack_tab5.c, function bsp_audio_init():

Parameter Before After Reason
slot_bit_width I2S_SLOT_BIT_WIDTH_AUTO I2S_SLOT_BIT_WIDTH_32BIT Match ES7210 TDM actual 32bit/slot output
ws_width I2S_TDM_AUTO_WS_WIDTH 16 Explicit value, eliminate version ambiguity
dma_desc_num (default) 6 Increase DMA buffer headroom
dma_frame_num 480 256 Align to 64-byte boundary, eliminate auto-adjust warning
mic_selected ES7120_SEL_MIC1..4 ES7210_SEL_MIC1..4 Fix typo in macro name (ES7120→ES7210)

Code Diff / 代码差异

// slot_cfg: match ES7210 TDM 4mic actual 32bit/slot output
.slot_bit_width = I2S_SLOT_BIT_WIDTH_32BIT,  // was: I2S_SLOT_BIT_WIDTH_AUTO
.ws_width       = 16,                         // was: I2S_TDM_AUTO_WS_WIDTH

// DMA buffer sizing
chan_cfg.dma_desc_num  = 6;
chan_cfg.dma_frame_num = 256;  // aligned to 64-byte boundary

// typo fix
es7210_cfg.mic_selected = ES7210_SEL_MIC1 | ES7210_SEL_MIC2 | ES7210_SEL_MIC3 | ES7210_SEL_MIC4;
//                        ^^^^^ was: ES7120_SEL_MIC

Impact & Verification / 影响与验证

  • Tested on: M5Stack Tab5 with ES7210 4-mic TDM input

  • Before fix: CORRUPT HEAP panic after minutes of audio capture; speaker clicking

  • After fix: Stable operation for extended periods, no heap corruption, clean audio

  • Risk: Low — only affects Tab5 BSP audio init path; no API changes

  • 实测平台: M5Stack Tab5 + ES7210 4mic TDM

  • 修复前: 采集几分钟后 CORRUPT HEAP panic,扬声器哒哒哒

  • 修复后: 长时间稳定运行,无堆腐蚀,音频干净

  • 风险: 低 — 仅影响 Tab5 BSP 音频初始化路径,无 API 变更

Checklist

  • Tested on real Tab5 hardware
  • No API changes
  • Single commit, minimal diff (1 file, +8/-3 lines)

根因:ES7210 TDM 4mic 实际按 32bit/slot 输出,但 I2S RX 配
slot_bit_width=AUTO 被 ESP-IDF 误判为 16bit×2slot,DMA 中间
buffer 被多写入 86~588 字节踩坏相邻 heap block,触发
CORRUPT HEAP → panic → 扬声器哒哒哒。

修复 (m5stack_tab5.c bsp_audio_init):
- slot_bit_width: AUTO → I2S_SLOT_BIT_WIDTH_32BIT
- ws_width: AUTO → 16 (消除版本歧义)
- dma_frame_num: 480 → 256 (对齐 64B 边界,消除 auto-adjust 警告)
- ES7120_SEL_MIC → ES7210_SEL_MIC (宏名拼写纠正)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant