diff --git a/pkg/espflasher/flasher.go b/pkg/espflasher/flasher.go index 32ea28a..ce61fe3 100644 --- a/pkg/espflasher/flasher.go +++ b/pkg/espflasher/flasher.go @@ -253,6 +253,16 @@ func (f *Flasher) ChipName() string { return "Unknown" } +// BootloaderFlashOffset returns the flash offset where the bootloader image +// lives for the connected chip. Returns (0, false) if the chip has not been +// detected yet (e.g. connect() has not completed). +func (f *Flasher) BootloaderFlashOffset() (uint32, bool) { + if f.chip == nil { + return 0, false + } + return f.chip.BootloaderFlashOffset, true +} + // connect performs the bootloader connection sequence: // reset → sync → detect chip. func (f *Flasher) connect() error { diff --git a/pkg/espflasher/flasher_test.go b/pkg/espflasher/flasher_test.go index 99b9dd0..705482a 100644 --- a/pkg/espflasher/flasher_test.go +++ b/pkg/espflasher/flasher_test.go @@ -219,6 +219,29 @@ func TestFlasherChipName(t *testing.T) { } } +func TestFlasherBootloaderFlashOffset(t *testing.T) { + // ESP32: 0x1000 + f := &Flasher{chip: defESP32, opts: DefaultOptions()} + off, ok := f.BootloaderFlashOffset() + if !ok || off != 0x1000 { + t.Errorf("ESP32 BootloaderFlashOffset() = (0x%X, %v), want (0x1000, true)", off, ok) + } + + // ESP32-S3: 0x0 + f2 := &Flasher{chip: defESP32S3, opts: DefaultOptions()} + off, ok = f2.BootloaderFlashOffset() + if !ok || off != 0x0 { + t.Errorf("ESP32-S3 BootloaderFlashOffset() = (0x%X, %v), want (0x0, true)", off, ok) + } + + // Chip not detected yet: returns (0, false) + f3 := &Flasher{opts: DefaultOptions()} + off, ok = f3.BootloaderFlashOffset() + if ok || off != 0 { + t.Errorf("undetected BootloaderFlashOffset() = (0x%X, %v), want (0x0, false)", off, ok) + } +} + func TestFlashImagePatchesHeader(t *testing.T) { // Verify that FlashImage calls patchImageHeader by checking that an // invalid flash mode causes an error.