Skip to content

fix(i2s): ESP32 reset_tx/reset_rx too fast for hardware#5609

Open
okhsunrog wants to merge 1 commit into
esp-rs:mainfrom
okhsunrog:fix/esp32-i2s-reset-tx
Open

fix(i2s): ESP32 reset_tx/reset_rx too fast for hardware#5609
okhsunrog wants to merge 1 commit into
esp-rs:mainfrom
okhsunrog:fix/esp32-i2s-reset-tx

Conversation

@okhsunrog
Copy link
Copy Markdown
Contributor

@okhsunrog okhsunrog commented May 27, 2026

On ESP32, reset_tx() and reset_rx() use toggle() which asserts
and deasserts the reset bits in two back-to-back modify() calls.
The pulse is too short for the I2S peripheral to register, leaving
the DMA engine in a stale state and causing tx_start() to hang on
subsequent transfers.

Fix by replacing toggle() with explicit assert → register read-back
→ deassert. The read-back acts as a bus round-trip delay, ensuring
the reset is registered before it is released.

Tested on ESP32-D0WDQ6-V3 (M5Stack Core2 v1.1) with IMA ADPCM audio
playback over I2S1 + NS4168 speaker amplifier — 20+ consecutive
write_words() calls succeed, three different audio clips play
back-to-back without hangs.

Closes #5608

Changelog

esp-hal

  • Fixed: ESP32 I2S reset_tx()/reset_rx() hanging on subsequent transfers due to reset pulse being too short for hardware

@okhsunrog okhsunrog force-pushed the fix/esp32-i2s-reset-tx branch from bfe813f to 221fa4c Compare May 27, 2026 00:09
On ESP32, `reset_tx()` and `reset_rx()` use `toggle()` which asserts
and deasserts the reset bits (tx_reset, tx_fifo_reset, out_rst) in
back-to-back register writes. The hardware does not register the reset
pulse, causing `tx_start()` to hang forever on the next transfer.

Replace `toggle()` with explicit assert → read-back barrier → deassert.
The register read forces the bus write to complete before the clear,
giving the hardware enough time to process the reset.

Tested on M5Stack Core2 v1.1 (ESP32-D0WDQ6-V3): 20+ consecutive
`write_words()` calls succeed with this fix (previously hung on the
2nd call). Full reproduction and PAC-based workaround:
https://github.com/okhsunrog/m5core2v1-1_demo_rust

Fixes esp-rs#5608
@okhsunrog okhsunrog force-pushed the fix/esp32-i2s-reset-tx branch from 221fa4c to 886e1a2 Compare May 27, 2026 00:27
@bugadani
Copy link
Copy Markdown
Contributor

I would like to see a test case covering this, even though i2s tests are disabled for esp32

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.

ESP32: I2sTx::write_words() hangs on second call — reset_tx() toggle too fast

2 participants