Skip to content

Improve flash reliability at high baud rates; update stubs to v1.1.0 - #58

Merged
deadprogram merged 3 commits into
mainfrom
timeout-improved
Jul 25, 2026
Merged

Improve flash reliability at high baud rates; update stubs to v1.1.0#58
deadprogram merged 3 commits into
mainfrom
timeout-improved

Conversation

@deadprogram

Copy link
Copy Markdown
Member

This PR fixes intermittent flash failures (timeouts and data corruption) when flashing ESP32 at 460800 baud.

  • Update go.bug.st/serial to v1.8.0
  • Update esp-flasher-stub to v1.1.0 (adds blank-sector skip, UART clock boost, bug fixes)
  • Add port.Drain() after serial writes to ensure data reaches the USB-UART bridge before proceeding
  • Add post-process delay after each flash block ACK to prevent UART FIFO overflow while the stub writes to flash with interrupts disabled
  • Retry flash block writes on transient serial errors (timeouts, bad data length, bad checksum) with proper RX flushing between attempts
  • Decode v1.1.0 stub error codes for actionable error messages

Signed-off-by: deadprogram <ron@hybridgroup.com>
Signed-off-by: deadprogram <ron@hybridgroup.com>
The esp-flasher-stub v1.1.0 uses double-buffering: it ACKs each flash
data block immediately, then writes to flash as a post-process. During
flash writes the ESP32 ROM disables interrupts (SPI bus shared with
cache), causing the 128-byte UART FIFO to overflow if the next block
arrives too soon. Additionally, USB-UART bridges occasionally lose bytes
at 460800 baud, producing truncated SLIP frames.

Fix with three complementary changes:

- Add port.Drain() to sendCommand to ensure each frame is physically
  committed to the USB-UART bridge before proceeding.

- Add a post-process delay (waitForStubFlashWrite) after each flash
  block ACK proportional to the estimated page count, giving the stub
  time to finish its flash write before new data arrives.

- Retry flash block writes on both TimeoutError and retryable
  CommandErrors (bad data length / bad checksum), with RX buffer
  flushes between attempts to clear stale partial-frame responses.

Also update CommandError to decode the v1.1.0 stub's 16-bit big-endian
response codes (0xC000=bad data length, 0xC100=bad checksum, etc.) and
add IsRetryable() to distinguish transient serial errors from
device-side failures.

Signed-off-by: deadprogram <ron@hybridgroup.com>
@deadprogram
deadprogram merged commit 0795d39 into main Jul 25, 2026
3 checks passed
@deadprogram
deadprogram deleted the timeout-improved branch July 25, 2026 18:06
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