Flash or recover over UART
Goal: Flash the firmware over UART, or recover a board that no longer boots.
You need: Start here done and a firmware build for your board.
Run every command from the project root (~/CrossPad, Windows C:\CrossPad\firmware), with ESP-IDF loaded as in 2. Build the firmware and the crosspad-hil venv from 1. Set up the toolchain active (one-line installer: crosspad-hil already works). Used the one-line installer? Use crosspad-idf in place of idf.py.
A UART flash writes everything (bootloader, partition table, firmware, assets) and resets the boot selection, so it also works when the board cannot start its USB connection. Steps 2 and 3 are for a v2 board (PCB r20), steps 4 and 5 for a v1 board (PCB r16 / r19).
-
Identify the ports
The STM32 bridge port (
0483:5740) is the console and the UART flash port on a v2 board; a v1 board is flashed on the ESP USB port in ROM bootloader mode (step 5). List the ports with their USB IDs and note the one you need.Terminal window python3 -m serial.tools.list_ports -vTerminal window python -m serial.tools.list_ports -vYou should see: one entry per port, each with a
hwid:line. On a v2 board one of them readsUSB VID:PID=0483:5740 …; that port is the STM32 bridge port. The ESP USB port (303A:3456) shows only while the board is in USB serial mode.<port>desc: …hwid: USB VID:PID=0483:5740 SER=… LOCATION=……… ports found -
Flash a v2 board (PCB r20) through the STM32 bridge port
esptool resets the ESP through the bridge by itself, so no bootloader request is needed; if it cannot sync, hold BOOT while resetting. Use the build of the board’s revision.
Terminal window idf.py -B build_v2 -DSDKCONFIG=sdkconfig.v2 -p <port> -b 460800 flashTerminal window idf.py -B build_v2 "-DSDKCONFIG=sdkconfig.v2" -p COMx -b 460800 flashDo not add
monitorhere:-bwould open it at the flash speed instead of 115200 baud.You should see: esptool connects, then writes five images (bootloader, partition table, OTA data,
CrossPad.bin,assets.bin), each ending withHash of data verified.;idf.pyends withDone.Connecting....…Hash of data verified.…DoneIf not: esptool cannot connect over UART. If the port is held by another program: Serial port is busy.
-
Recover a boot-looping v2 board
This re-flashes everything over the STM32 bridge port, then checks that the board answers again. crosspad-hil finds the port; without it the script falls back to
/dev/ttyACM0, so on macOS and Windows add--port <port>.Terminal window python3 tools/bench.py recover --build build_v2Terminal window python tools\bench.py recover --build build_v2 --port COMxYou should see:
recovering over <port> from build_v2 (sdkconfig sdkconfig.v2)Connecting....…Hash of data verified.…If not: Board boot-loops after a flash. If it says
UART flash failed: esptool cannot connect over UART. If it saysidf.py not on PATH: idf.py command not found. -
Put a v1 board (PCB r16 / r19) into the bootloader
On a v1 board, ask the ESP to enter its ROM bootloader first. The script asks over the ESP USB port in USB serial mode, then over MIDI, and waits for the ESP USB port to come back in ROM bootloader mode.
Terminal window python3 tools/requestBootloader.py --method cdc,midiTerminal window python tools\requestBootloader.py --method cdc,midiYou should see:
=== MIDI SYSEX/USB CDC Bootloader Request ===…✓ Bootloader request sent successfully!…✓ Device entered bootloader mode on: <port>If the board was already in its bootloader, it prints
✓ Device is already in Espressif bootloader mode!and the port. Note the port for step 5. -
Flash the v1 board on the ESP USB port
Use the port the previous step printed and keep
--after watchdog_reset, or the chip stays in ROM. The command runs in the v1 build folder, because the file names are relative to it, andcd ..returns to the project folder.Terminal window cd build_v1python3 -m esptool --chip esp32s3 -p <port> -b 460800 --before default_reset --after watchdog_reset write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m 0x0 bootloader/bootloader.bin 0x8000 partition_table/partition-table.bin 0x10000 ota_data_initial.bin 0x20000 CrossPad.bin 0x720000 assets.bincd ..Terminal window cd build_v1python -m esptool --chip esp32s3 -p COMx -b 460800 --before default_reset --after watchdog_reset write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m 0x0 bootloader/bootloader.bin 0x8000 partition_table/partition-table.bin 0x10000 ota_data_initial.bin 0x20000 CrossPad.bin 0x720000 assets.bincd ..You should see:
Connecting..., thenHash of data verified.once for each of the five files. The board then restarts into the new firmware.If not: esptool cannot connect over UART
Check it worked
Section titled “Check it worked”On a v2 board, open the console on the STM32 bridge port (115200 baud, Ctrl+] to exit) and wait for the success line:
idf.py -B build_v2 -DSDKCONFIG=sdkconfig.v2 -p <port> monitoridf.py -B build_v2 "-DSDKCONFIG=sdkconfig.v2" -p COMx monitorYou should see: I (…) crosspad_main: All systems operational - Crosspad ready
If not: No boot log on the console