diff --git a/components/m5stack-tab5/include/m5stack-tab5.hpp b/components/m5stack-tab5/include/m5stack-tab5.hpp index 669ecffb30..c2acfca4a7 100644 --- a/components/m5stack-tab5/include/m5stack-tab5.hpp +++ b/components/m5stack-tab5/include/m5stack-tab5.hpp @@ -746,6 +746,9 @@ class M5StackTab5 : public BaseComponent { static constexpr gpio_num_t sd_dat3_io = GPIO_NUM_42; // CS/DAT3 static constexpr gpio_num_t sd_clk_io = GPIO_NUM_43; // SCK/CLK static constexpr gpio_num_t sd_cmd_io = GPIO_NUM_44; // MOSI/CMD + // The SD card's IO pads (GPIO39-44) are powered by the ESP32-P4's internal + // LDO channel 4 (LDO_VO4), which the SDMMC host has to switch on. + static constexpr int sd_ldo_channel = 4; // RS-485 static constexpr gpio_num_t rs485_rx_io = GPIO_NUM_21; // RX @@ -927,6 +930,7 @@ class M5StackTab5 : public BaseComponent { // uSD Card sdmmc_card_t *sdcard_{nullptr}; + void *sd_pwr_ctrl_handle_{nullptr}; // sd_pwr_ctrl_handle_t (on-chip LDO) // RTC std::atomic rtc_initialized_{false}; diff --git a/components/m5stack-tab5/src/sdcard.cpp b/components/m5stack-tab5/src/sdcard.cpp index 19fd74715c..aaa23c22a7 100644 --- a/components/m5stack-tab5/src/sdcard.cpp +++ b/components/m5stack-tab5/src/sdcard.cpp @@ -1,6 +1,7 @@ #include "m5stack-tab5.hpp" #include +#include #include namespace espp { @@ -37,6 +38,24 @@ bool M5StackTab5::initialize_sdcard(const M5StackTab5::SdCardConfig &config) { // For setting a specific frequency, use host.max_freq_khz (range 400kHz - 20MHz for SDSPI) sdmmc_host_t host = SDMMC_HOST_DEFAULT(); host.max_freq_khz = SDMMC_FREQ_HIGHSPEED; // 40MHz + host.slot = SDMMC_HOST_SLOT_0; + + // The ESP32-P4 powers the SD card's IO pads from its internal LDO (LDO_VO4). + // Without a power control handle that rail stays off, the bus floats and + // card init fails (timeouts, or errors on the first data transfer). Same as + // M5Stack's own Tab5 BSP. + if (sd_pwr_ctrl_handle_ == nullptr) { + sd_pwr_ctrl_ldo_config_t ldo_config{}; + ldo_config.ldo_chan_id = sd_ldo_channel; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = nullptr; + ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); + if (ret != ESP_OK) { + logger_.error("Failed to create the SD power control driver: {}", esp_err_to_name(ret)); + return false; + } + sd_pwr_ctrl_handle_ = pwr_ctrl_handle; + } + host.pwr_ctrl_handle = static_cast(sd_pwr_ctrl_handle_); // This initializes the slot without card detect (CD) and write protect (WP) signals. // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. @@ -47,6 +66,7 @@ bool M5StackTab5::initialize_sdcard(const M5StackTab5::SdCardConfig &config) { slot_config.d1 = sd_dat1_io; slot_config.d2 = sd_dat2_io; slot_config.d3 = sd_dat3_io; + slot_config.width = 4; logger_.debug("Mounting filesystem"); ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &sdcard_); @@ -59,6 +79,8 @@ bool M5StackTab5::initialize_sdcard(const M5StackTab5::SdCardConfig &config) { "Make sure SD card is present and lines have pull-up resistors in place.", esp_err_to_name(ret)); } + sd_pwr_ctrl_del_on_chip_ldo(static_cast(sd_pwr_ctrl_handle_)); + sd_pwr_ctrl_handle_ = nullptr; return false; }