Skip to content

feat: add USB CDC support, ReadFlash, and ESP32-S3 post-connect#22

Closed
jgangemi wants to merge 1 commit intotinygo-org:mainfrom
jgangemi:jae/upstream-usb-cdc
Closed

feat: add USB CDC support, ReadFlash, and ESP32-S3 post-connect#22
jgangemi wants to merge 1 commit intotinygo-org:mainfrom
jgangemi:jae/upstream-usb-cdc

Conversation

@jgangemi
Copy link
Copy Markdown
Contributor

@jgangemi jgangemi commented Apr 9, 2026

Summary

Full USB CDC device support for ESP32-S3 (and similar chips with USB-OTG or USB-JTAG/Serial interfaces):

  • Chunk SLIP writes to 64 bytes for USB CDC endpoint compatibility
  • Use 1KB RAM upload blocks for USB connections (vs 6KB default)
  • Detect USB-OTG and USB-JTAG/Serial interfaces on ESP32-S3 via UART_DEV_BUF_NO register
  • Disable RTC WDT and enable SWD auto-feed when connected via USB-JTAG/Serial
  • Add ReadFlash protocol with SLIP-framed data blocks and cumulative ACKs
  • Add SLIP leftover buffer for multi-frame USB transfers
  • Add port re-open recovery for TinyUSB CDC re-enumeration during reset

Motivation

USB CDC endpoints (TinyUSB on ESP32-S3, for example) have limited buffer sizes. Without chunking, large SLIP frames overflow the endpoint buffer and cause data loss. The upstream stub loader's 6KB RAM upload blocks also time out on USB CDC — 1KB blocks resolve this. Device-tested on LILYGO T-Dongle S3 (USB-OTG via TinyUSB CDC).

Known limitation: ESP32-S3 only

The PostConnect hook and USB interface detection are currently implemented only for ESP32-S3. Other chips with USB interfaces (ESP32-S2, ESP32-C3, ESP32-C6, ESP32-H2) would benefit from similar treatment — each has its own UART_DEV_BUF_NO register address and watchdog registers. The PostConnect field on chipDef is designed to support this; I only have ESP32-S3 hardware to test on currently. Happy to add the other targets in a follow-up if someone can verify on those chips.

Note: CLI subcommands for ReadFlash will be submitted as a follow-up PR after the library changes are accepted.

Test plan

  • go test -v ./pkg/espflasher/... — all tests pass
  • TestSendCommandChunking verifies 64-byte write chunks
  • TestUploadToRAMUSBBlockSize verifies 1KB blocks for USB
  • TestReadFlashRequiresStub verifies stub guard
  • TestESP32S3PostConnect* tests USB-JTAG, USB-OTG, and UART detection paths
  • golangci-lint run ./pkg/espflasher/... — no new issues
  • Device tested: stub loads, flash MD5, read flash on T-Dongle S3 via USB CDC

@jgangemi jgangemi force-pushed the jae/upstream-usb-cdc branch from 5d0323c to 5558114 Compare April 11, 2026 01:06
- chunk SLIP writes to 64 bytes for USB CDC endpoint compatibility
- use 1KB RAM upload blocks for USB connections
- detect USB-OTG and USB-JTAG/Serial interfaces on ESP32-S3
- disable RTC WDT and enable SWD auto-feed for USB-JTAG/Serial
- add ReadFlash protocol with SLIP-framed blocks and cumulative ACKs
- add SLIP leftover buffer for multi-frame USB transfers
- add port re-open recovery for TinyUSB CDC re-enumeration
@jgangemi jgangemi force-pushed the jae/upstream-usb-cdc branch from 5558114 to 41716e8 Compare April 11, 2026 15:08
@deadprogram
Copy link
Copy Markdown
Member

Hello @jgangemi

Happy to add the other targets in a follow-up if someone can verify on those chips.

I think it would better to add that support in this PR, probably. If you were to add the implementations I am sure there are people who would help test, including myself.

@jgangemi
Copy link
Copy Markdown
Contributor Author

closing this in favor of breaking it apart further for easier review. #24 supersedes this and will need to be merged before the individual chip PRs are submitted so we don't get merge conflicts

@jgangemi jgangemi closed this Apr 11, 2026
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.

2 participants