Skip to content

feat: expose MAC, chip revision, and chip features via eFuse reads - #57

Merged
deadprogram merged 1 commit into
tinygo-org:mainfrom
jgangemi:jae/chip-info-efuse
Jul 25, 2026
Merged

feat: expose MAC, chip revision, and chip features via eFuse reads#57
deadprogram merged 1 commit into
tinygo-org:mainfrom
jgangemi:jae/chip-info-efuse

Conversation

@jgangemi

Copy link
Copy Markdown
Contributor

What

Adds three methods to Flasher for reading chip identity from eFuse:

  • MAC() (net.HardwareAddr, error) — factory-programmed base MAC
  • ChipRevision() (ChipRevision, error) — silicon revision (Major/Minor, String()"vX.Y")
  • ChipFeatures() ([]string, error) — human-readable feature list (Wi-Fi/BT, core count, clock, embedded flash/PSRAM, coding scheme, …)

Dispatch is via three optional func-pointer fields on chipDef (ReadMAC/ReadChipRevision/ReadChipFeatures), matching the existing PostConnect/HardResetOTG pattern; per-chip decoders and register constants live in each target_esp32*.go. Chips without a decoder return UnsupportedCommandError.

Supported: ESP32, ESP32-S2, ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-H2, ESP32-P4. ESP8266 is left unsupported (its OTP layout is a different scheme).

Why

These read plain eFuse registers via READ_REG (0x0A), which — unlike GET_SECURITY_INFO — is implemented by both the ROM loader and the stub. So they work whether or not the stub is loaded (including SkipStub / no-reset flows). All decode logic mirrors esptool's per-chip read_mac(), get_major_chip_version() / get_minor_chip_version(), and get_chip_features().

Testing

  • Host unit tests for every chip's MAC / revision / features decoder against known register values (table-driven, covering corners: v0.0, the ESP32-S3 ECO0 block-version workaround, max major/minor, unknown flash/PSRAM cap), plus the nil-dispatch (unsupported-chip) cases. New decoders are at 100% statement coverage.
  • Every register offset/shift/mask and feature string was cross-checked against esptool master source, per chip.
  • Hardware-validated on an ESP32-D0WD-V3 (revision v3.1): MAC, ChipRevision (v3.1), and ChipFeatures all match esptool chip-id output exactly. The remaining chip families are esptool-source-verified and host-tested; on-silicon validation for those is still pending.

Add Flasher.MAC()/ChipRevision()/ChipFeatures(), reading the
factory-programmed base MAC, silicon revision, and feature list
straight from eFuse registers, mirroring esptool's read_mac()/
get_major_chip_version()/get_minor_chip_version()/get_chip_features()
per chip.

- add ReadMAC/ReadChipRevision/ReadChipFeatures func-pointer fields to
  chipDef, with thin nil-checking dispatchers on Flasher
- implement per-chip decoders for ESP32 (classic, lookup-table major
  revision), S2, S3 (including the ECO0 block-version workaround),
  C2, C3, C5, C6, H2, and P4-rev1; ESP8266 leaves all three nil
- ReadRegister has no isStub() gate, so these work pre- and post-stub
  (no_reset/SkipStub included)
- table-driven host tests per chip covering every decoder branch,
  plus dispatcher nil-chip/unsupported-chip cases
@deadprogram

Copy link
Copy Markdown
Member

Thank you very much for the awesome addition @jgangemi now merging!

@deadprogram
deadprogram merged commit f8a6928 into tinygo-org:main Jul 25, 2026
3 checks passed
jgangemi added a commit to dangernoodle-io/pogopin that referenced this pull request Jul 29, 2026
v0.8.0 adds MAC/chip-revision/chip-features readers (upstream tinygo-org/espflasher#57)
plus flash-write reliability fixes. Note: it caps classic-ESP32 UART flash baud at
230400 (FIFO-overflow fix), so flashing an ESP32 over a UART bridge downshifts from
pogopin's 460800 default to 230400 — slower but more reliable. Other chip families
are unaffected.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants