From 5dbe8688455021c95466e70e4397181901fdef95 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 27 Feb 2026 14:37:51 +0100 Subject: [PATCH] fix: use proper bootloader commands for ESP8266 The ESP8266 ROM bootloader doesn't support two commands that were being used: CHANGE_BAUD (0x0F) - baud rate switching is ESP32+ only. Now skipped for ESP8266, so flashing runs at the default 115200 baud. Compressed flash commands (0x10-0x12) - FLASH_DEFL_BEGIN/DATA/END are ESP32+ ROM commands. Now falls back to uncompressed FLASH_BEGIN/DATA/END (0x02-0x04) for ESP8266. Both features are gated by new ROMHasChangeBaud and ROMHasCompressedFlash flags in chipDef. All ESP32 variants have them set to true and ESP8266 defaults to false. Signed-off-by: deadprogram --- chip.go | 9 +++++++++ flasher.go | 24 ++++++++++++++++++------ target_esp32.go | 3 +++ target_esp32c2.go | 2 ++ target_esp32c3.go | 2 ++ target_esp32c6.go | 2 ++ target_esp32h2.go | 2 ++ target_esp32s2.go | 2 ++ target_esp32s3.go | 2 ++ 9 files changed, 42 insertions(+), 6 deletions(-) diff --git a/chip.go b/chip.go index 4778e51..6cfc63d 100644 --- a/chip.go +++ b/chip.go @@ -90,6 +90,15 @@ type chipDef struct { // ESP8266 and original ESP32 do not. SupportsEncryptedFlash bool + // ROMHasCompressedFlash indicates the ROM bootloader supports the + // compressed flash commands (FLASH_DEFL_BEGIN/DATA/END, 0x10-0x12). + // ESP32 and newer ROMs support this; ESP8266 ROM does not. + ROMHasCompressedFlash bool + + // ROMHasChangeBaud indicates the ROM bootloader supports the + // CHANGE_BAUD command (0x0F). ESP32+ ROMs support this; ESP8266 does not. + ROMHasChangeBaud bool + // FlashFrequency maps frequency strings to register values. FlashFrequency map[string]byte diff --git a/flasher.go b/flasher.go index 5334e5f..c06dcf9 100644 --- a/flasher.go +++ b/flasher.go @@ -309,15 +309,18 @@ func (f *Flasher) FlashImage(data []byte, offset uint32, progress ProgressFunc) return fmt.Errorf("attach flash: %w", err) } - // Optionally switch to higher baud rate - if f.opts.FlashBaudRate > 0 && f.opts.FlashBaudRate != f.opts.BaudRate { + // Optionally switch to higher baud rate (not supported by ESP8266 ROM) + canChangeBaud := f.chip == nil || f.chip.ROMHasChangeBaud || f.conn.isStub + if canChangeBaud && f.opts.FlashBaudRate > 0 && f.opts.FlashBaudRate != f.opts.BaudRate { if err := f.changeBaud(f.opts.FlashBaudRate); err != nil { f.logf("Warning: could not change baud rate to %d: %v", f.opts.FlashBaudRate, err) // Continue at original baud rate } } - if f.opts.Compress { + // Use compressed flash only if supported (ESP8266 ROM doesn't support it) + canCompress := f.chip == nil || f.chip.ROMHasCompressedFlash || f.conn.isStub + if f.opts.Compress && canCompress { return f.flashCompressed(data, offset, progress) } return f.flashUncompressed(data, offset, progress) @@ -342,13 +345,17 @@ func (f *Flasher) FlashImages(images []ImagePart, progress ProgressFunc) error { return fmt.Errorf("attach flash: %w", err) } - // Optionally switch to higher baud rate - if f.opts.FlashBaudRate > 0 && f.opts.FlashBaudRate != f.opts.BaudRate { + // Optionally switch to higher baud rate (not supported by ESP8266 ROM) + canChangeBaud := f.chip == nil || f.chip.ROMHasChangeBaud || f.conn.isStub + if canChangeBaud && f.opts.FlashBaudRate > 0 && f.opts.FlashBaudRate != f.opts.BaudRate { if err := f.changeBaud(f.opts.FlashBaudRate); err != nil { f.logf("Warning: could not change baud rate to %d: %v", f.opts.FlashBaudRate, err) } } + // Determine if compressed flash is available + canCompress := f.chip == nil || f.chip.ROMHasCompressedFlash || f.conn.isStub + totalSize := 0 for _, img := range images { totalSize += len(img.Data) @@ -380,7 +387,7 @@ func (f *Flasher) FlashImages(images []ImagePart, progress ProgressFunc) error { } } - if f.opts.Compress { + if f.opts.Compress && canCompress { err = f.flashCompressed(data, img.Offset, partProgress) } else { err = f.flashUncompressed(data, img.Offset, partProgress) @@ -610,7 +617,12 @@ func (f *Flasher) Reset() { } // attachFlash attaches the SPI flash and configures parameters. +// ESP8266 does not need (or support) SPI attach; its ROM handles flash directly. func (f *Flasher) attachFlash() error { + if f.chip != nil && f.chip.ChipType == ChipESP8266 { + return nil // ESP8266 ROM handles flash internally + } + f.logf("Attaching SPI flash...") if err := f.conn.spiAttach(0); err != nil { diff --git a/target_esp32.go b/target_esp32.go index f85dced..6bbdec4 100644 --- a/target_esp32.go +++ b/target_esp32.go @@ -26,6 +26,9 @@ var defESP32 = &chipDef{ BootloaderFlashOffset: 0x1000, + ROMHasCompressedFlash: true, + ROMHasChangeBaud: true, + FlashFrequency: map[string]byte{ "80m": 0xF, "40m": 0x0, diff --git a/target_esp32c2.go b/target_esp32c2.go index 760611b..7edb830 100644 --- a/target_esp32c2.go +++ b/target_esp32c2.go @@ -26,6 +26,8 @@ var defESP32C2 = &chipDef{ BootloaderFlashOffset: 0x0, SupportsEncryptedFlash: true, + ROMHasCompressedFlash: true, + ROMHasChangeBaud: true, FlashFrequency: map[string]byte{ "60m": 0xF, diff --git a/target_esp32c3.go b/target_esp32c3.go index e0f27a8..799f452 100644 --- a/target_esp32c3.go +++ b/target_esp32c3.go @@ -26,6 +26,8 @@ var defESP32C3 = &chipDef{ BootloaderFlashOffset: 0x0, SupportsEncryptedFlash: true, + ROMHasCompressedFlash: true, + ROMHasChangeBaud: true, FlashFrequency: map[string]byte{ "80m": 0xF, diff --git a/target_esp32c6.go b/target_esp32c6.go index 6d96435..24e67cb 100644 --- a/target_esp32c6.go +++ b/target_esp32c6.go @@ -26,6 +26,8 @@ var defESP32C6 = &chipDef{ BootloaderFlashOffset: 0x0, SupportsEncryptedFlash: true, + ROMHasCompressedFlash: true, + ROMHasChangeBaud: true, FlashFrequency: map[string]byte{ "80m": 0x0, // workaround for wrong mspi HS div value in ROM diff --git a/target_esp32h2.go b/target_esp32h2.go index 4df0517..776bc92 100644 --- a/target_esp32h2.go +++ b/target_esp32h2.go @@ -26,6 +26,8 @@ var defESP32H2 = &chipDef{ BootloaderFlashOffset: 0x0, SupportsEncryptedFlash: true, + ROMHasCompressedFlash: true, + ROMHasChangeBaud: true, FlashFrequency: map[string]byte{ "48m": 0xF, diff --git a/target_esp32s2.go b/target_esp32s2.go index 460aabc..884fe57 100644 --- a/target_esp32s2.go +++ b/target_esp32s2.go @@ -27,6 +27,8 @@ var defESP32S2 = &chipDef{ BootloaderFlashOffset: 0x1000, SupportsEncryptedFlash: true, + ROMHasCompressedFlash: true, + ROMHasChangeBaud: true, FlashFrequency: map[string]byte{ "80m": 0xF, diff --git a/target_esp32s3.go b/target_esp32s3.go index 68ad900..ffecae8 100644 --- a/target_esp32s3.go +++ b/target_esp32s3.go @@ -26,6 +26,8 @@ var defESP32S3 = &chipDef{ BootloaderFlashOffset: 0x0, SupportsEncryptedFlash: true, + ROMHasCompressedFlash: true, + ROMHasChangeBaud: true, FlashFrequency: map[string]byte{ "80m": 0xF,