Skip to content

Board detection: open hardware I2C in consumers, and route detection through board_detect::io - #367

Merged
lovyan03 merged 2 commits into
m5stack:developfrom
ainyan03:board_detect_io
Oct 19, 2026
Merged

lovyan03 merged 2 commits into
m5stack:developfrom
ainyan03:board_detect_io

Conversation

@ainyan03

Copy link
Copy Markdown
Contributor

Two changes to the board detection framework before it is released in 0.3.0. The first changes one contract; the second only moves code.

1. Board detection no longer opens a hardware I2C port

All I2C traffic during detection already used a software (bit-banged) port. Only at the end of prepare() was the board's internal hardware I2C port opened and left open for later users. Opening a hardware peripheral is outside what detection should do, and SPI already works the other way: detection reads panel IDs by bit-banging, and Bus_SPI opens the host itself.

Hardware I2C is now opened by its consumers, as touch drivers, Bus_I2C and the other backlight classes already do:

  • The backlights of Core2 (AXP192 / AXP2101), Tough, CoreS3, ToughC5, CoreP4X and Nesso N1 open their port in init(). Panel_Device::init() initializes the light before rst_control(), so the Core2 / CoreS3 reset lines driven through the PMIC / IO expander still find the port open.
  • CoreMatrix opens the port for its TM1680 acknowledgement check and closes it right after, so a failed construction does not leave it open; Bus_I2C::init() owns it afterwards.
  • Tab5: the touch firmware read that selects the panel (ST version 1 → ST7121, 3 → ST7123, GT911 → ILI9881C) moved from display construction to the post-power observation and uses software I2C. Retries (up to 60 × 10 ms), logs and the result are unchanged, also with a fixed board ID and when a power step fails part-way (the old code read it in either case). The DSI ID fallback for ILI9881C stays in construction. The result is passed in board-specific bits of board_result_t::prepared; NVS contents and the public option values are unchanged.
  • The bus journal that released the port on rollback is removed (nothing in detection opens a hardware port any more).

After M5GFX::init() the internal port is still open whenever the board has a touch controller or an I2C backlight, because those open it; M5Unified's In_I2C.begin() opens it in any case.

2. Detection goes through board_detect::io

Detection code called lgfx GPIO / I2C / timing functions and ESP-IDF registers directly from about a dozen files. These now go through one inline layer, src/board_detect/detect_io.hpp (contract) and detect_io_default.inl (the default implementation, which forwards to lgfx and ESP-IDF). The detection files no longer reference lgfx::, esp_* or register macros, apart from the public board_t values and display construction.

  • Pins, time, I2C (returning bool with output arguments, no driver result types), chip information (package, eFuse fields, chip revision, PSRAM state, USB-Serial/JTAG frame number) and the low-level ESP32-S3 dedicated-GPIO and classic ESP32 touch / LED operations.
  • The layer only performs operations and returns raw values; thresholds, decisions, retries and sample aggregation stay in the detectors.
  • Selected at compile time (M5GFX_BOARD_DETECT_IO_HEADER), no virtual calls. Forwarders are always_inline; the LED pulse routine stays in IRAM.
  • The host tests now supply their own implementation of this layer instead of fake SDK headers.

No behavior change is intended in this part. Comparing the disassembly of M5GFX.cpp.o before and after on ESP32, S3, C5, C6, C61 and P4: timing-sensitive functions (bit-banged SPI, held-SDA release, pull measurements, the S3 dedicated-GPIO sampling loop, classic ESP32 touch measurement and LED clear) have the same instruction sequences apart from compact encodings and alignment. The remaining differences are log line numbers and register allocation from the bool / output-argument returns.

Testing

  • Host tests (test/board_detect): all pass; added cases for the Tab5 observation (each touch result, DSI fallback, fixed / detected, power step failure) and the CoreMatrix port release.
  • extras/board_spec: npm test and npm run check pass.
  • Local build matrix of the versions used by this repository's CI: all passed, no new warnings. CI on the fork: passed.
  • On 47 boards (ESP32, S3, C3, C5, C6, H2, P4), the detected board, display configuration and startup time were compared with develop before and after each change: identical (startup times within a few ms on repeated runs). CoreMatrix (C61) detection was checked separately. Backlights on Core2 v1.1 / v1.3 / AWS, Tough, CoreS3 / CoreS3 SE, StackChan and ToughC5, the three Tab5 panels and the CoreMatrix display were checked visually. Nesso N1 and CoreP4X were not available.

Detection communicates over software I2C only; opening hardware peripherals is outside its responsibility. Like SPI, hardware I2C ports are now initialized by their consumers.

Remove preparation handoff and bus journaling. Initialize the affected backlights and CoreMatrix transport in their own setup. Observe Tab5 touch identities with scoped software I2C after power, preserving retries and partial-power-failure observations while keeping public options and NVS unchanged.
Keep driver and platform dependencies in a replaceable implementation so detection can be reused independently. Add compile-time selection for pin, timing, I2C and chip-data operations without exposing driver types.

Leave identification, retry policies and dedicated-GPIO aggregation with the detectors. Preserve timing-sensitive operation sequences and replace SDK host stubs with independent I/O simulation plus a native adapter for construction fixtures.
@lovyan03
lovyan03 merged commit db76adc into m5stack:develop Oct 19, 2026
27 checks passed
@ainyan03
ainyan03 deleted the board_detect_io branch October 19, 2026 11:42
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