Skip to content

fix(i2c): drain TX FIFO before a repeated START - #134

Merged
floitsch merged 1 commit into
patch-head-5.4.2from
floitsch/h2-i2c-repeated-start
Sep 20, 2026
Merged

floitsch merged 1 commit into
patch-head-5.4.2from
floitsch/h2-i2c-repeated-start

Conversation

@floitsch

@floitsch floitsch commented Sep 20, 2026 •

Copy link
Copy Markdown
Member

Long combined I2C write/read transactions on ESP32-H2 can NACK when the write fills the TX FIFO: the repeated-START handler queues the next address before the preceding data has drained. A 63-byte write reproduced the failure, while separate write/read transactions passed.

Extend the existing FIFO drain sequence for consecutive writes to also cover a following repeated START on targets without SOC_I2C_STOP_INDEPENDENT. This uses END to drain and resume; it does not insert a STOP, so the combined transaction is preserved. The shared command path handles synchronous and asynchronous transfers.

Validation:

  • ESP32-H2 asynchronous controller against an ESP32 target: 19 write sizes from 17 through 1024 bytes around FIFO boundaries, at both 50 and 100 kHz, followed by repeated-start reads.
  • Combined transfers in both controller/target roles, plus recovery after an address NACK.
  • ESP32-H2 and ESP32-C6 firmware builds passed.

The hardware regression is included in the companion Toit ESP32-H2 support PR: toitlang/toit#3240 (tests/hw/esp32h2/i2c-repeated-start.toit).

@floitsch
floitsch merged commit 6ebd845 into patch-head-5.4.2 Sep 20, 2026
1 of 2 checks passed
@floitsch
floitsch deleted the floitsch/h2-i2c-repeated-start branch September 20, 2026 14:28
floitsch added a commit to toitlang/toit that referenced this pull request Sep 20, 2026
Update `third_party/esp-idf` from
`1d89388f11383182b35c06fe44278847235b3a53` to
`bf81d4c8cdaeaee5a13feca0c8aea60988f12807`, incorporating two merged I2C
fixes:

- [toitware/esp-idf#134](toitware/esp-idf#134):
drain the controller TX FIFO before a repeated START so the next address
cannot overwrite pending write data.
- [toitware/esp-idf#135](toitware/esp-idf#135):
refresh the target RX FIFO count between interrupt causes, preventing a
20-byte write from being reported as 40 bytes with a corrupt suffix.
Includes a deterministic two-device Unity regression.
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