Add support for M5Stack ToughC5 (ESP32-C5) - #296
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The ESP32-C5 fallback board selection can unintentionally fall through to board_unknown unless an external macro is defined, which can break correct pin mapping when auto-detection fails.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
Adds initial board enablement for M5Stack ToughC5 (ESP32-C5) across M5Unified’s board detection, pin mapping, RTC selection, and PMIC integration so the board can boot with the correct peripherals and power controls.
Changes:
- Add ToughC5 pin mappings (I2C internal/external, PortB/PortC, SD) and include it in display/touch-related board groupings.
- Route ToughC5 RTC to RX8130 on ESP32-C5 builds.
- Extend M5PM1_Class with DCDC + LED_EN controls and wire ToughC5 power management into
Power_Class.
File summaries
| File | Description |
|---|---|
| src/utility/RTC_Class.cpp | Select RX8130 RTC instance for board_M5ToughC5 on ESP32-C5. |
| src/utility/power/M5PM1_Class.hpp | Add new PM1 APIs for DCDC output and LED_EN level control. |
| src/utility/power/M5PM1_Class.cpp | Implement DCDC/LED_EN bit controls in PM1 PWR_CFG. |
| src/utility/Power_Class.hpp | Add M5pm1 member for ESP32-C5 builds. |
| src/utility/Power_Class.cpp | Configure PM1 and external power rail control paths for ToughC5; extend PM1-related compile guards to ESP32-C5. |
| src/M5Unified.hpp | Add ESP32-C5/ToughC5 fallback board selection hook. |
| src/M5Unified.cpp | Add ToughC5 pin tables; LP_I2C routing for internal bus when supported; include ToughC5 in display/touch button handling groups. |
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 1
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
| #elif defined (CONFIG_IDF_TARGET_ESP32C5) && defined (ARDUINO_M5STACK_TOUGHC5) | ||
| = board_t::board_M5ToughC5; |
There was a problem hiding this comment.
Changed: the C5 now falls back to the StampC5, matching how the other chips default to their smallest board (StampC3, AtomS3Lite). For context, a real StampC5 never depended on this default — it is identified by its eFuse in _check_boardtype() — and the previous behavior fell back to board_unknown, the same as before this PR. The ToughC5 carries a display and is identified by M5GFX.
PWR_CFG (0x06) bit1 (DCDC_EN) and bit4 (LED_EN) had no accessor; add setDCDCOutput() and setLedEnLevel() alongside the existing LDO / BOOST controls.
Adds the pin tables (I2C, PortB / PortC, SD), the RX8130 RTC, and power management through M5PM1_Class rather than raw register writes: the PMIC gets set up on begin and drives the external 5V rail, the battery readings, the power button and powerOff(). Port A is a level-shifted branch of the internal I2C bus (SDA=G2 / SCL=G3), the way the original M5Stack shares its internal and external I2C. The board carries a display and is identified as such by M5GFX. The C5 also gains a StampC5 fallback for when auto-detection identifies nothing, the way the other chips fall back to their smallest board (StampC3, AtomS3Lite).
The internal bus (SDA=G2 / SCL=G3) sits exactly on the C5's fixed LP_I2C pads, and Port A is a level-shifted branch of the same bus. Running In_I2C and Ex_I2C on the low power port therefore leaves the C5's single high power I2C controller entirely free for user code. The port choice follows the exact condition M5GFX compiles its low power support under; anything older stays on the high power port. Pairs with the M5GFX change that moves the backlight and the touch panel onto the same port.
Adds board support for the M5Stack ToughC5: the pin tables (I2C, PortB / PortC, SD), the RX8130 RTC, and power management through M5PM1_Class (PMIC setup on begin, the external 5V rail, battery readings, the power button and powerOff). M5PM1_Class gains the DCDC / LED_EN controls the board needs. The board carries a display and is identified as such by M5GFX.
Port A is a level-shifted branch of the internal I2C bus (SDA=G2 / SCL=G3), the way the original M5Stack shares its internal and external I2C. Those pins are exactly the C5's fixed LP_I2C pads, so In_I2C and Ex_I2C both run on the low power port, which leaves the C5's single high power I2C controller entirely free for user code. On an SDK without the low power support (pre-5.4 ESP-IDF) everything stays on the high power port.
Pairs with m5stack/M5GFX#238 (backlight / touch on the same port); the two should land together. Verified on the actual board.