Uh oh!
There was an error while loading. Please reload this page.
fix: M5Stack Unit C6L boot failure caused by flash_mode=qio - #3098
Merged
Conversation
Board manifest for esp32-c6-devkitm-1 defaults build.flash_mode to qio, which this module's flash chip does not support -- causes a boot crash-loop (repeated USB-Serial-JTAG reconnects) on real hardware. Override with board_build.flash_mode = dio in the common M5Stack_Unit_C6L section so it applies to all envs (ble/usb/repeater/room_server).
ContributorAuthor
Prior art for this fix pattern on the same chip family:
All of these match this PR's root cause: cc @recrof — thanks for all the triage you've done on this thread, it |
recrof
commented
Aug 2, 2026
Member
@liamcottle@ripplebiz I can't reproduce the problem on my board, however I could see how |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the M5Stack Unit C6L boot crash-loop (repeated USB-Serial-JTAG
disconnect/reconnect cycling, no serial output ever reaching the host)
that affects every merged.bin built for this board — including the
official upstream releases.
Supersedes #3088, which misattributed the crash-loop to PI4IO register
init / TCXO voltage / I2C pin routing / TX LED pin. Those four changes
were tested individually and in combination and made no difference
once the actual variable was isolated (see below); this PR reverts none
of them and touches only the flash mode.
Root cause
The
esp32-c6-devkitm-1board manifest(
platforms/espressif32/boards/esp32-c6-devkitm-1.json, all versionschecked: 6.7.0 / 6.10.0 / 6.11.0 / unversioned) sets
build.flash_mode: "qio".merge-bin.pyreads this value directly(
board_config.get("build.flash_mode", "dio")), so every*-merged.binproduced for this board — including the ones in theofficial companion firmware releases — is built with a
QIOheader.This module's actual flash chip does not reliably handle QIO on this
board, and the chip crash-loops on boot (repeated
enumerate/reset of the USB-Serial-JTAG peripheral) whenever the
flash is initialized in QIO mode, regardless of
flash_sizeorflash_freq.How this was isolated
esptoolinvocationpio run -t uploaduses(
-vbuild log) and reproduced it manually, byte-for-byte(same esptool binary/version, same
--baud,--before/--after,--flash_mode,--flash_freq,--flash_size, and all fourflash offsets including
boot_app0.bin, which a naive manualerase_flash+write_flashat0x0had been omitting).erase_flashbetween each test:esptoolv4.8.6 (pio-bundled) vs v5.3.1 (system) — no effect-z(compression) present/absent — no effect (esptool compressesby default regardless)
--flash_size 4MBvsdetect(actual chip is 16MB) — no effect--flash_mode diovsqio— reproduced the crash loop twicewith
qio, resolved twice withdio, on otherwise identicalfirmware and flashing steps
(
read_flash+image_info) after flashing with no--flash_modeoverride at all (i.e. the condition a user gets from flashing a
release
merged.binvia a web flasher or a barewrite_flash 0x0command with no flags): the chip ends up with the file's embedded
QIOheader verbatim, and crash-loops.merged.binfor every C6L env(companion_radio_ble/usb, repeater, room_server) — both in this
fork's
jp-v1.8.1release and in upstream'scompanion-v1.16.0release — has
Flash mode: QIOin its header(
esptool image_info).Fix
One line, in the common
[M5Stack_Unit_C6L]section so it applies toall envs (
companion_radio_ble/usb/repeater/room_server):board_build.flash_mode = dioThis overrides the board manifest's
qiodefault via PlatformIO'sboard_build.*mechanism (not abuild_flags -D, since this needs toreach
merge-bin.py'sboard_config.get("build.flash_mode", ...)lookup, not a preprocessor define).
Test
pio run -e M5Stack_Unit_C6L_companion_radio_usb -t mergebin—confirmed
firmware-merged.binheader now reportsFlash mode: DIO(esptool image_info)erase_flash+write_flash 0x0 firmware-merged.binwith no--flash_modeoverride (matching how a user flashes a released binary) —
boots cleanly, no crash-loop, serial output present
device, to rule out a one-off observation