Skip to content

firmware flash: reach a native-USB ESP32 through its ROM port; take --before/--after - #211

Merged
bdbarnett merged 3 commits into
mainfrom
fix-firmware-flash
Nov 5, 2026
Merged

bdbarnett merged 3 commits into
mainfrom
fix-firmware-flash

Conversation

@bdbarnett

@bdbarnett bdbarnett commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

mpftp firmware flash on an ESP32-S2/S3 running MicroPython on its native USB (TinyUSB CDC, 303a:4001) no longer fails with "Invalid head of packet". That port ignores DTR and RTS, so esptool's reset never reached the ROM. Flash now sends the board to its bootloader the way mpftp bootloader does, waits up to 20 s for the ROM's USB-Serial/JTAG port (303a:1001) whose serial number carries the same MAC (or, on an S2, the new ROM USB port 303a:0002, whose serial number has no MAC), and flashes there. A UART bridge, a port already in the ROM, and --before no-reset are flashed where they are; if no ROM port appears, it stops with the BOOT+RESET instructions instead of flashing a port that has gone.

firmware flash also accepts --before and --after now and passes them to the engine, which already took them.

I flashed an ESP32-S3 (LILYGO T-Display-S3) from its running app with an app-only write at 0x10000 and no manual bootloader step: it went to its bootloader, mpftp picked the ROM port by MAC, esptool wrote and verified 5.1 MB, and the board came back on its native USB running the same build with its files in place. New unit tests (cli/tests/test_flash_native_usb.py) cover the port matching, the fallbacks, a failed bootloader, and the option passthrough; they fail without the change. Not checked: an ESP32-S2 on native USB through this path, and the extension, which has its own handoff and doesn't go through this code.

Closes #208
Closes #209

…-before/--after

A board running MicroPython on its native USB shows TinyUSB's CDC (303a:4001),
which ignores DTR and RTS, so esptool's default reset kept talking to the
interpreter and failed with "Invalid head of packet". firmware flash now sends
such a board to its bootloader the way `mpftp bootloader` does, waits for the
ROM's USB-Serial/JTAG port (303a:1001) whose serial number carries the same
MAC, and flashes there. A UART bridge, a board already in its ROM, and
--before no-reset are flashed where they are.

The outer firmware flash parser now declares --before and --after and passes
them to the engine, which already accepted them.

Checked on an ESP32-S3 running MicroPython on native USB: an app-only flash
from its running state went to the ROM port, wrote and verified, and the board
booted back to its app with its files in place. Unit tests cover the port
matching, the fallbacks and the option passthrough.

Closes #208
Closes #209
@bdbarnett
bdbarnett merged commit 1e791a4 into main Nov 5, 2026
9 checks passed
@bdbarnett
bdbarnett deleted the fix-firmware-flash branch November 5, 2026 23:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

firmware flash rejects --before and --after firmware flash can't reach a running ESP32-S3 on its native USB port

1 participant