Building UIFlow against ESP-IDF v5.5.1 produces silent / constant
samples (-8 / -1) on the Cardputer-Adv's ES8311 codec. Same M5Unified
sources built against v5.4.2 work correctly. The regression is in
IDF v5.5.x's I2S driver / MCLK pin routing, not in M5Unified or
the codec init.
Switch IDF_PATH_PATCH_SERIES from 1005-idf_v5.5_freertos.patch to
1004-idf_v5.4_freertos.patch. Both patches already ship in
m5stack/patches/; this is a one-line selection change.
See FIX.md for the full bisect, build instructions, and verification.
Summary
Building UIFlow against ESP-IDF v5.5.1 produces silent / constant samples (
-8/-1) on the Cardputer-Adv's ES8311 microphone. The same M5Unified sources built against ESP-IDF v5.4.2 work correctly. The regression lives in IDF v5.5.x's I²S driver / MCLK GPIO routing — not in M5Unified, not in the codec init, not in MicroPython bindings.This PR switches
IDF_PATH_PATCH_SERIESfrom1005-idf_v5.5_freertos.patchto1004-idf_v5.4_freertos.patch. Both patch files already ship inm5stack/patches/; this is a one-line selection change.The bug
On M5Stack Cardputer-Adv (ESP32-S3 + ES8311 I²S audio codec), microphone capture via
M5.Mic.record()orM5.Mic.recordWavFile()returns constant samples:-8(16-bit signed, every sample identical) when the codec is in mic-ADC mode-1/0xFFFFFFFF(line floating high) when the I²S RX bus has no dataThe codec itself is healthy: I²C reads back all the expected ADC-chain register values after
M5.Mic.begin()(0x01=0xBA,0x0E=0x02,0x14=0x10,0x17=0xBF,0x1C=0x6A). BCK and WS clocks toggle. But no audio data ever reaches the SoC.Industry-wide, undiagnosed for months — see espressif/esp-idf#18621 for the upstream report and bisect.
Bisect — it's the IDF version
Built a standalone ESP-IDF project using stock M5Unified 0.2.10 and the documented Cardputer-Adv mic-init sequence. Same source, two IDF versions:
This rules out:
Mic_Class.cpp(identical between tests)The regression is in ESP-IDF v5.5.x's I²S driver / GPIO-matrix layer, almost certainly in MCLK pin routing. Without MCLK at 256×fs = 4.096 MHz, the ES8311 ADC PLL can't lock and outputs a DC-offset constant — matching every symptom observed across ~12 different test paths during investigation.
M5Stack's own ES8311 "User Demo" firmware on M5Burner uses the new
i2s_channel_*API (i2s_new_channel,i2s_std_set_clock,i2s_check_set_mclk) and works on v5.5; the Arduino M5Unified library uses the legacyi2s_driver_installAPI and breaks. Suggests the legacy shim's MCLK handling regressed.How to build
The build produces
build-M5STACK_CardputerADV/uiflow-<hash>.bin(~6.3 MB, app + bootloader + partition table + nvs + fs-system).The default packed binary excludes the
fs-userpartition by design. To ship a default/flash/filesystem (apps, boot.py, main.py) in one flash, also writebuild-M5STACK_CardputerADV/fs-user.binat offset0x641000:esptool.py --chip esp32s3 --port /dev/cu.usbmodemXXX --baud 1500000 write_flash \ 0x0 build-M5STACK_CardputerADV/uiflow-<hash>.bin \ 0x641000 build-M5STACK_CardputerADV/fs-user.binESP32-S3 native USB-CDC doesn't auto-DTR/RTS into download mode. Manual: unplug, hold the
G0(BOOT) button, plug in, releaseG0.What this fix is not
Verification
End-to-end test: built this branch, flashed to a Cardputer-Adv, ran a MicroPython app that calls
M5.Mic.recordWavFile("/flash/last.wav", 16000, 6), uploaded the WAV to OpenAI Whisper via a Cloudflare Worker, got a correct transcription back. The full STT pipeline produces real audio data, not the-8constant that v5.5.1 builds produce.Reverting to upstream
Test plan
make patchapplies cleanly against IDF v5.4.2make BOARD=M5STACK_CardputerADVproduces a working firmware imageM5.Mic.recordWavFile()captures real audio on Cardputer-Adv