diff --git a/README.md b/README.md index 3d1b1c0..68e66a8 100644 --- a/README.md +++ b/README.md @@ -452,3 +452,19 @@ has another name, or `M5UNIFIED_ARDUINO_COMPONENT=OFF` to disable this. |Current
Voltage
Monitor| --- | --- | --- | --- | --- | --- | --- | --- |`INA3221`
40h/41h
(opt)|Current
Voltage
Monitor| + + +### Fixed-board firmware + +Defining a positive `BOARD_ID` when building an application using M5Unified fixes +its device identity to that `board_t` value. An undefined, explicitly empty, or zero value +keeps automatic detection. Fixed startup reads only variants needed by the +selected board and does not use NVS or probe other board families. +An accepted fixed identity takes precedence over `config_t::fallback_board`, +including when display startup fails. Call `M5.begin()` before initializing +`M5.Display` for this configuration to take effect. + +A positive `BOARD_ID` unsupported by the chip also stops automatic detection; +it does not fall back to probing another board. `BOARD_ID` has no effect if +`M5.Display.init()` runs before `M5.begin()`. A valueless compiler option +`-DBOARD_ID` defines the value as 1 (M5Stack), rather than an empty value. diff --git a/src/M5Unified.hpp b/src/M5Unified.hpp index 59410e9..14ca00a 100644 --- a/src/M5Unified.hpp +++ b/src/M5Unified.hpp @@ -348,7 +348,13 @@ namespace m5 // Skipped when the application already ran Display.init(): GPIO46 may then carry the display // bus (StopWatch QSPI io2), which this output would overwrite. The hold is applied below, // once the pin map is known, only on boards that use GPIO46 as their power hold. +#if defined (BOARD_ID) && ((BOARD_ID + 0) > 0) + // A fixed board can use GPIO46 for its display rather than power hold. + const bool gpio46_hold = Display.getBoard() == board_t::board_unknown + && _get_power_hold_pin(static_cast(BOARD_ID)) == GPIO_NUM_46; +#else const bool gpio46_hold = (Display.getBoard() == m5gfx::board_t::board_unknown); +#endif m5gfx::gpio::pin_backup_t gpio46_backup(GPIO_NUM_46); if (gpio46_hold) { @@ -357,6 +363,13 @@ namespace m5 } #endif + m5gfx::detect_config_t detect_config; + detect_config.fallback_board = cfg.fallback_board; + // A positive BOARD_ID fixes the device to its board_t value in M5Unified. +#if defined (BOARD_ID) && ((BOARD_ID + 0) > 0) + detect_config.fixed_board = static_cast(BOARD_ID); +#endif + Display.setDetectConfig(detect_config); auto brightness = Display.getBrightness(); Display.setBrightness(0); bool res = false; @@ -365,20 +378,21 @@ namespace m5 } else { res = Display.init_without_reset(false); } - auto board = Display.getBoard(); - // printf("auto detect board:%d\n",board); + const auto fixed_board = Display.getFixedBoard(); + auto board = fixed_board != board_t::board_unknown ? fixed_board : Display.getBoard(); bool board_detected = (board != board_t::board_unknown); - if (!board_detected) + if (fixed_board != board_t::board_unknown) + { + // Accepted firmware identity survives display startup failure. + if (cfg.fallback_board != board_t::board_unknown && cfg.fallback_board != fixed_board) + { + Log(ESP_LOG_WARN, "fallback board:%u ignored for fixed board:%u", + static_cast(cfg.fallback_board), static_cast(fixed_board)); + } + } + else if (!board_detected) { board = cfg.fallback_board; - // UIFlow selects board-specific firmware with BOARD_ID and M5GFX_BOARD. -#if defined (CONFIG_IDF_TARGET_ESP32P4) && defined (BOARD_ID) -#if BOARD_ID == 31 - if (board == board_t::board_unknown) { board = board_t::board_M5CoreP4X; } -#elif BOARD_ID == 35 - if (board == board_t::board_unknown) { board = board_t::board_M5Tab5X; } -#endif -#endif if (board == board_t::board_unknown) { board = Display.getBoardCandidate(); } if (board == board_t::board_unknown) { board = _default_fallback_board(); } } @@ -798,6 +812,7 @@ namespace m5 bool _probe_i2c_addr(uint8_t sda, uint8_t scl, uint8_t addr); static void _setup_pinmap(board_t); + static int8_t _get_power_hold_pin(board_t); static bool _speaker_enabled_cb_core2(void* args, bool enabled); static bool _speaker_enabled_cb_cores3(void* args, bool enabled); static bool _speaker_enabled_cb_sticks3(void* args, bool enabled); diff --git a/src/M5Unified.inl b/src/M5Unified.inl index 0de5e30..0e8cdf3 100644 --- a/src/M5Unified.inl +++ b/src/M5Unified.inl @@ -86,6 +86,8 @@ namespace m5 int8_t M5Unified::_get_pin_table[pin_name_max]; #if defined (M5UNIFIED_PC_BUILD) + int8_t M5Unified::_get_power_hold_pin(board_t) { return -1; } + void M5Unified::_setup_pinmap(board_t) { std::fill(_get_pin_table, _get_pin_table + pin_name_max, 255); @@ -475,6 +477,13 @@ static constexpr const uint8_t _pin_table_mbus[][31] = { { board_t::board_unknown , 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, }; + int8_t M5Unified::_get_power_hold_pin(board_t id) + { + for (const auto& row : _pin_table_other1) + { if (row[0] == id) { return static_cast(row[1]); } } + return -1; + } + void M5Unified::_setup_pinmap(board_t id) { if (id == board_t::board_M5Tab5X) { @@ -1650,30 +1659,20 @@ static constexpr const uint8_t _pin_table_mbus[][31] = { const auto pkg = m5gfx::get_pkg_ver(); if (pkg == 6) { return board_t::board_M5AtomPsram; } // PICO-V3 if (pkg == 5) { return board_t::board_M5StampPico; } // PICO-D4 - // The legacy detector defaulted D0WDQ6 to TimerCam after other probes failed. - if (pkg == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6) { return board_t::board_M5TimerCam; } - return board_t::board_M5AtomLite; + // StampPico and AtomPsram have no positive detector and remain defaults. + // All D0WDQ6 members have detectors; other packages have no M5 boards. + // Do not assume a rejected member. Unknown retains the generic I2C map. + return board_t::board_unknown; #elif defined (CONFIG_IDF_TARGET_ESP32S3) -#if defined (BOARD_ID) && BOARD_ID == 147 - return board_t::board_M5DualKey; -#endif // ESP32-S3 package 0 is QFN56 and package 1 is LGA56. if (m5gfx::get_pkg_ver() == 1) { return board_t::board_M5StampS3Mini; } return board_t::board_M5StampS3; #elif defined (CONFIG_IDF_TARGET_ESP32C3) return board_t::board_M5StampC3U; -#elif defined (CONFIG_IDF_TARGET_ESP32C6) - // Preserve legacy package/flash defaults when no detector confirms a board. - if (m5gfx::get_pkg_ver() == 1) - { - return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_4_REG, EFUSE_FLASH_CAP) == 2 - ? board_t::board_M5StampC6 : board_t::board_M5NanoC6; - } +#elif defined (CONFIG_IDF_TARGET_ESP32C6) || defined (CONFIG_IDF_TARGET_ESP32H2) || defined (CONFIG_IDF_TARGET_ESP32C5) + // Package-only Stamp suggestions arrive as detector candidates. Do not + // assume a Nano or Stamp after its positive detector rejects the board. return board_t::board_unknown; -#elif defined (CONFIG_IDF_TARGET_ESP32H2) - return board_t::board_M5NanoH2; -#elif defined (CONFIG_IDF_TARGET_ESP32C5) - return board_t::board_M5StampC5; #elif defined (CONFIG_IDF_TARGET_ESP32P4) // Unidentified P4 modules have no display or board-specific power contract. esp_chip_info_t info;