M5Stack Cardputer ADV · Volume 8

M5Stack Cardputer ADV Volume 8 — Flashing and Updating Firmware

M5Burner + web flashers + esptool.py + OTA + factory backup + recovery from crash-loop

Contents

SectionTopic
1About this volume
2Web flashers (zero-install path)
3M5Burner desktop app
4esptool.py (CLI path)
5Factory firmware backup (do this before anything)
6OTA — over-the-air firmware update
7M5Launcher catalog flashing
8Recovery — when device is in crash-loop
9Bootloader-mode entry walkthrough
10Common flash gotchas
11Resources

1. About this volume

Vol 8 covers flashing and updating firmware on the Cardputer ADV — five paths, recovery story, common gotchas. The Cardputer ADV is essentially un-brickable by firmware mistakes thanks to the ESP32-S3’s mask-ROM bootloader — but the discipline matters to keep firmware experimentation cheap and recoverable.

The five paths, in order of typical first-use:

  1. Web flashers — easiest. Chrome / Edge + USB-C + click. ~2 min.
  2. M5Burner desktop — when web flashers aren’t available, or for fleet flashing.
  3. esptool.py CLI — for scripting + recovery.
  4. OTA — for updates once a firmware is installed and on-Wi-Fi.
  5. M5Launcher catalog — the day-to-day path once M5Launcher is installed in app0.

2. Web flashers (zero-install path)

Requirements: Chromium-family browser (Chrome / Edge / Brave / Arc / Opera). Web Serial API is the underlying tech. Firefox / Safari do NOT support Web Serial — those browsers will show “Connect” buttons but they won’t work.

Major web flashers for Cardputer ADV:

FirmwareURL
M5Launcher (the recommended first install)https://bmorcelli.github.io/Launcher/
Meshtastichttps://flasher.meshtastic.org/
Brucehttps://bruce.computer/
Various via ESP Web Toolshttps://esphome.github.io/esp-web-tools/

Process:

  1. Plug Cardputer ADV into computer via USB-C.
  2. Open web flasher URL in Chrome / Edge.
  3. Click “Connect” — browser pops a serial-port picker. Select the Cardputer’s port (typically labeled “USB JTAG/serial debug unit” on Linux, or by board name on macOS).
  4. Select board variant: “Cardputer ADV” or “M5StampS3-Cardputer-Adv” — explicitly the ADV variant, not the original Cardputer.
  5. Pick the firmware version (latest is typically pre-selected).
  6. Click “Flash” / “Install”.
  7. Wait ~2 minutes. Device reboots into the freshly flashed firmware.

Tip: bookmark the M5Launcher flasher. You’ll come back to it whenever you want to switch base firmware.


3. M5Burner desktop app

Download: https://docs.m5stack.com/en/download. Available for Windows / macOS / Linux.

Process:

  1. Plug Cardputer ADV via USB-C.
  2. Open M5Burner.
  3. Hold G0 (boot button) on the device while connecting USB (or while clicking “Connect” in M5Burner). Release G0 after connection. This puts the ESP32-S3 in download mode.
  4. M5Burner’s left sidebar groups firmwares by board family. Select “StampS3 for Cardputer” or “Cardputer-Adv” category.
  5. Search for the firmware you want (Bruce, NEMO, Meshtastic, M5Launcher, factory restore).
  6. Click “Download” → “Burn”. Set:
    • COM port: auto-detect or pick manually
    • Baud rate: 1500000 (default; some hardware needs 921600)
  7. Wait ~3-5 minutes.
  8. Device reboots.

Use cases for M5Burner over web flasher:

  • Fleet flashing — M5Burner handles multiple devices in sequence with progress UI.
  • When Web Serial isn’t available (Firefox-only computer, locked-down environment).
  • When the firmware you want isn’t on any web flasher but is in M5Burner’s catalog.
  • For factory-firmware restore (M5Burner has the official factory builds).

4. esptool.py (CLI path)

Setup: pip install esptool.

Read flash (backup):

esptool.py --chip esp32s3 -p /dev/ttyACM0 -b 1500000 \
    read_flash 0 0x800000 cardputer_backup.bin

This reads the entire 8 MB flash to cardputer_backup.bin. Save this file as your factory-state baseline.

Write a single binary:

esptool.py --chip esp32s3 -p /dev/ttyACM0 -b 1500000 \
    --before default_reset --after hard_reset \
    write_flash -z 0x0 firmware.bin

The -z flag enables compression — speeds up flashing.

Write a complete M5Launcher install (bootloader + partitions + boot_app0 + app):

esptool.py --chip esp32s3 -p /dev/ttyACM0 -b 1500000 \
    --before default_reset --after hard_reset \
    write_flash -z \
        0x0 bootloader.bin \
        0x8000 partitions.bin \
        0xe000 boot_app0.bin \
        0x10000 Launcher.bin

Address conventions:

  • 0x0: bootloader
  • 0x8000: partition table
  • 0xe000: boot_app0 (OTA selector)
  • 0x10000: app (M5Launcher, or first OTA slot if Launcher already installed)

Erase entire flash (nuclear option):

esptool.py --chip esp32s3 -p /dev/ttyACM0 erase_flash

After erase, the device is in a “no firmware” state. Reboot it → enter download mode → flash something via esptool / M5Burner / web flasher.

Use cases for esptool over web flasher / M5Burner:

  • Scripting / CI / automation
  • Recovery when other tools fail
  • Firmware development (pio run -t upload uses esptool internally; understanding esptool helps debug flash issues)
  • Flashing custom binaries not in any catalog

5. Factory firmware backup (do this before anything)

First-time discipline: before flashing anything new to a fresh Cardputer ADV, back up the original factory firmware.

esptool.py --chip esp32s3 -p /dev/ttyACM0 -b 1500000 \
    read_flash 0 0x800000 stock_backup_$(date +%Y%m%d).bin

Stash on a NAS / cloud backup / external drive. If anything subsequently goes wrong (M5Launcher itself misbehaves, partition gets corrupted, you want to sell the device as “factory original”), you can restore with:

esptool.py --chip esp32s3 -p /dev/ttyACM0 -b 1500000 \
    write_flash 0x0 stock_backup_YYYYMMDD.bin

The backup takes ~30 seconds. Skipping this step is a regret-creator. Don’t.


6. OTA — over-the-air firmware update

Most community firmwares support OTA (over-the-air updates). The Cardputer ADV connects to Wi-Fi and updates without USB cable.

Three OTA paths:

  1. Captive web server — firmware hosts a web UI; you upload .bin via browser. Common for Marauder, NEMO.
  2. Firmware-author’s OTA endpoint — firmware checks a HTTPS URL for new version, downloads, applies. Common for Bruce.
  3. GitHub Releases auto-pull — firmware fetches the latest release from GitHub and applies. M5Launcher uses this for its catalog firmwares.

Meshtastic also supports BLE OTA from the phone app (no Wi-Fi or USB needed) — useful for field updates.

OTA partition discipline: under M5Launcher’s default scheme there is one OTA app slot — app1 / ota_0 (4.9 MB). An OTA flash overwrites whatever firmware is currently in it; there is no second slot and no A/B rollback (that’s a deliberate design choice — Vol 6 § 3.2.1 explains why M5Launcher trades the rollback slot for FAT + SPIFFS storage instead). The “rollback” you actually rely on is structural: M5Launcher itself lives in app0 (subtype test), outside the OTA mechanism, so a crash-looping OTA firmware is always one Esc-on-boot away from recovery (Vol 6 § 3.6). Some standalone firmwares (e.g. Meshtastic flashed via its own tooling on hardware with a different partition table) do A/B OTA — but on a Cardputer ADV running M5Launcher’s default scheme, it’s one slot.

For tjscientist’s Cardputer ADV (when acquired): expect daily-use OTA path via M5Launcher Catalog (Vol 6 § 3.4). USB cable use becomes rare after initial setup.


7. M5Launcher catalog flashing

Once M5Launcher is installed in app0, its catalog is the day-to-day flashing path:

  1. Boot M5Launcher → OTA.
  2. M5Launcher fetches the online firmware repo over Wi-Fi (the M5Burner-style catalog; bmorcelli also hosts a binary browser at bmorcelli.github.io/Launcher/m5lurner.html).
  3. Browse the available firmwares.
  4. Pick a firmware → pick a version (typically latest).
  5. Confirm flash → M5Launcher downloads the .bin, verifies it, writes it to the single OTA slot (app1/ota_0), reboots into it.

~30 seconds total. The fastest path for “try a new firmware” experimentation.

Catalog rate limit caveat: GitHub anonymous API access is limited to 60 requests / hour per IP. Heavy catalog browsing triggers this. Configuration → “GitHub Token (PAT)” allows a Personal Access Token, bumping the limit to 5000 requests / hour. PAT only needs public_repo scope (read-only). Stored in NVS on the device.


8. Recovery — when device is in crash-loop

If a flashed firmware is crash-looping, broken, or otherwise stuck:

Step 1 — Esc-on-boot recovery (the canonical path):

  1. Power off (toggle side switch).
  2. Hold the Esc key (top-left corner of keyboard).
  3. While holding Esc, slide the side switch ON.
  4. M5Launcher’s early-boot code detects the Esc-held state, ignores otadata, boots directly from factory partition.
  5. From M5Launcher → ToolsReset OTA wipes otadata, returning to known-good state.
  6. Re-OTA-flash a working firmware via Catalog.

Step 2 — If Esc-on-boot doesn’t work (factory itself is broken, or M5Launcher isn’t installed):

  1. Hold G0 button during USB plug-in to force mask-ROM download mode.
  2. Use M5Burner / web flasher / esptool.py to re-flash M5Launcher.
  3. Mask-ROM download mode always works regardless of firmware state — the ESP32-S3 cannot be bricked by firmware alone.

Step 3 — Nuclear option (when something is really wrong):

esptool.py --chip esp32s3 -p /dev/ttyACM0 erase_flash
esptool.py --chip esp32s3 -p /dev/ttyACM0 -b 1500000 \
    write_flash 0x0 stock_backup_YYYYMMDD.bin

Erase entire flash, then restore from your factory backup (§ 5). Worst case: ~5 minutes total.

“My Cardputer is bricked” troubleshooting:

SymptomLikely causeFix
Device doesn’t enumerate on USBSide switch OFF; or charge-only cableToggle switch ON; use data-capable cable
Device enumerates but immediately disconnectsCrash-loopEsc-on-boot to M5Launcher
Device shows logo briefly then black screenApp crashEsc-on-boot; reflash
esptool.py says “no chip detected”ESP32-S3 not in download modeHold G0 during USB plug-in
All of the above failMask-ROM USB neededHold G0 + plug USB; should work always

In ~5 years of Cardputer ADV community history, no one has reported a true firmware-brick that mask-ROM USB couldn’t recover. The recovery story is robust.


9. Bootloader-mode entry walkthrough

Detailed steps for entering ESP32-S3 download mode (needed when firmware isn’t responding):

  1. Power off the Cardputer ADV (side switch OFF).
  2. Press and hold the G0 button on the device (this is the “BOOT” button — on Cardputer ADV, it’s the keyboard’s \ key per the boot-button mapping, or a dedicated tiny button — verify against vendor docs).
  3. Plug in USB-C while holding G0.
  4. Slide the side switch ON (still holding G0).
  5. After ~1 second, release G0.

The ESP32-S3 mask-ROM is now active. esptool.py, M5Burner, web flashers should now see the device as a USB-JTAG / serial-debug device in download mode.

Alternative auto-reset method (works for most operations):

esptool.py, M5Burner, and PlatformIO can use DTR/RTS-based auto-reset to enter download mode without manual button holding. The Arduino USB-CDC interface on the ESP32-S3 exposes DTR/RTS lines that, when toggled, drive the BOOT and EN pins. PlatformIO and friends handle this automatically.

When auto-reset doesn’t work (it occasionally fails on the first attempt), manual G0 hold during USB plug-in is the reliable fallback.


10. Common flash gotchas

SymptomCauseFix
”Cardputer” vs “Cardputer-Adv” firmware mismatchWrong board variant (Vol 1 § 2.2)Reflash with the ADV-specific binary
Device not enumerating on USBCharge-only USB cableUse data-capable cable
Device not chargingSide switch is OFFSlide switch ON
”No chip detected” in esptoolNot in download modeHold G0 during USB plug-in
Web flasher won’t connectWrong browser (Firefox / Safari)Use Chrome / Edge / Brave
Web flasher connects but “device error”Already opened by another processClose other serial monitors / Arduino IDE / PlatformIO
OTA times outSlow SD cardReplace with Class 10 / U1+ card
OTA succeeds but device crash-loopsNew firmware buggyEsc-on-boot recovery
Flash succeeds, device boots, BLACK SCREENWrong TFT pin mapping (custom build)Verify build flags match Vol 3 § 2
Flash succeeds, “Brownout triggered”Inadequate USB power during bootBetter USB cable; check battery; relax brownout threshold (Vol 11 § 5)
Catalog says “GitHub rate limit exceeded”Anonymous API limit (60/h) hitAdd GitHub PAT in Config

11. Resources

Tools

Web flashers

ESP32-S3 download mode docs

Cross-references

  • M5Launcher catalog system in detail: Vol 6 § 3.4
  • Programming environments (which compile to the binaries you flash): Vol 7
  • Build errors (compile-side issues): Vol 10 § 10
  • Recovery story repeat (briefer): Vol 11 § 9

This is Volume 8 of a twelve-volume series. Next: Vol 9 collects end-to-end use-case recipes — pentest workflows, off-grid mesh recipes, hardware modifications, audio recipes, retro setup.