Skip to content

fix(esp32): Fix silent Spinel drops over USB - #79

Merged
puddly merged 1 commit into
devfrom
puddly/fix-esp32-lost-usb-bytes
Oct 31, 2026
Merged

puddly merged 1 commit into
devfrom
puddly/fix-esp32-lost-usb-bytes

Conversation

@puddly

@puddly puddly commented Oct 31, 2026

Copy link
Copy Markdown
Member

OpenThread in ESP-IDF implements UART writing via their POSIX-y write without checking the return code. This is pretty common in OpenThread implementations, I believe EFR32 does the same. Unfortunately, ESP-IDF also flags USB UARTs as suspended if a few cumulative 1ms stutters pile up, resulting in the very clean loss of a single Spinel HDLC frame during heavy traffic. Doubly unfortunately, Spinel does not have global sequence counters for notifications so this loss is entirely and completely silent.

This should affect stock OpenThread firmware on the ESP32 as well. I'll try to report this to Espressif.

Copilot AI balanced review requested due to automatic review settings October 31, 2026 15:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A critical transport bug can silently discard HDLC data when the USB ring fills while still signaling successful completion, so failed enqueues must be retried or explicitly fail the transport.

1 open issue
What changed in this PR

This PR addresses silent Spinel frame loss on ESP32-C6 by bypassing the console VFS and sending directly through the USB-Serial-JTAG driver.

Changes:

  • Route USB Spinel writes through the driver’s TX ring buffer.
  • Increase USB buffer sizes to accommodate HDLC chunks.
  • Replace inline component-editing scripts with patch files, preserving the Ziggurat NCP integration.
File Description
firmwares/​esp32-c6/​patches/​0002-send-spinel-through-the-usb-serial-jtag-driver.patch Routes USB writes directly to the driver with a bounded timeout.
firmwares/​esp32-c6/​patches/​0001-ziggurat-owns-the-ncp-vendor-hook.patch Preserves vendor-hook ownership and glue compilation as a patch.
firmwares/​esp32-c6/​main/​esp_ot_config.h Sets TX and RX buffers to 4096 and 2048 bytes.
firmwares/​esp32-c6/​build.sh Applies component patches instead of inline Python edits.

Review effort: Balanced

@MattWestb

Copy link
Copy Markdown

One PM if using ESP-IDF version pre some V6 beta have some very nasty bugs in the USB-UART that shall being fixed in the latest versions and its only USB-UART communication not normal UART.

@puddly

puddly commented Oct 31, 2026

Copy link
Copy Markdown
Member Author

I ran into this on v6.0.2 but I think this is still present in v6.1

@puddly

puddly commented Oct 31, 2026

Copy link
Copy Markdown
Member Author

I've reported it to Espressif. Hopefully they can fix it 😄

@puddly
puddly merged commit b23fe8c into dev Oct 31, 2026
2 checks passed
@MattWestb

Copy link
Copy Markdown

I was testing H2 with the S3 boar with eth an its using the normal UART so no problem but many in the community thread and it was fixed in one pre V6 beta but is the dictated Zigbee / thread repo not the general ide one an was not going there in the v6 release. Perhaps they have missing putting it in there.

As normal great . . . . done !!!!!

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.

3 participants