3232#include " ff.h"
3333#include " esp32-hal-periman.h"
3434
35+ #if SOC_SDMMC_IO_POWER_EXTERNAL
36+ #include " sd_pwr_ctrl_by_on_chip_ldo.h"
37+ #endif
38+
3539using namespace fs ;
3640
3741SDMMCFS::SDMMCFS (FSImplPtr impl) : FS(impl), _card(nullptr ) {
@@ -77,11 +81,11 @@ bool SDMMCFS::sdmmcDetachBus(void *bus_pointer) {
7781 return true ;
7882}
7983
80- bool SDMMCFS::setPins (int clk, int cmd, int d0) {
81- return setPins (clk, cmd, d0, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC);
84+ bool SDMMCFS::setPins (int clk, int cmd, int d0, int power ) {
85+ return setPins (clk, cmd, d0, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC, power );
8286}
8387
84- bool SDMMCFS::setPins (int clk, int cmd, int d0, int d1, int d2, int d3) {
88+ bool SDMMCFS::setPins (int clk, int cmd, int d0, int d1, int d2, int d3, int power ) {
8589 if (_card != nullptr ) {
8690 log_e (" SD_MMC.setPins must be called before SD_MMC.begin" );
8791 return false ;
@@ -94,6 +98,7 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) {
9498 d1 = digitalPinToGPIONumber (d1);
9599 d2 = digitalPinToGPIONumber (d2);
96100 d3 = digitalPinToGPIONumber (d3);
101+ power = digitalPinToGPIONumber (power);
97102
98103#ifdef SOC_SDMMC_USE_GPIO_MATRIX
99104 // SoC supports SDMMC pin configuration via GPIO matrix. Save the pins for later use in SDMMCFS::begin.
@@ -103,6 +108,9 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) {
103108 _pin_d1 = (int8_t )d1;
104109 _pin_d2 = (int8_t )d2;
105110 _pin_d3 = (int8_t )d3;
111+ #ifdef SOC_SDMMC_IO_POWER_EXTERNAL
112+ _pin_power = (int8_t )power;
113+ #endif
106114 return true ;
107115#elif CONFIG_IDF_TARGET_ESP32
108116 // ESP32 doesn't support SDMMC pin configuration via GPIO matrix.
@@ -133,6 +141,9 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
133141 perimanSetBusDeinit (ESP32_BUS_TYPE_SDMMC_D2, SDMMCFS::sdmmcDetachBus);
134142 perimanSetBusDeinit (ESP32_BUS_TYPE_SDMMC_D3, SDMMCFS::sdmmcDetachBus);
135143 }
144+ #ifdef SOC_SDMMC_IO_POWER_EXTERNAL
145+ perimanSetBusDeinit (ESP32_BUS_TYPE_SDMMC_POWER, SDMMCFS::sdmmcDetachBus);
146+ #endif
136147 // mount
137148 sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT ();
138149#ifdef SOC_SDMMC_USE_GPIO_MATRIX
@@ -142,6 +153,12 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
142153 log_e (" SDMMCFS: some SD pins are not set" );
143154 return false ;
144155 }
156+ #ifdef SOC_SDMMC_IO_POWER_EXTERNAL
157+ if (_pin_power == -1 ) {
158+ log_e (" SDMMCFS: power pin is not set" );
159+ return false ;
160+ }
161+ #endif
145162
146163 slot_config.clk = (gpio_num_t )_pin_clk;
147164 slot_config.cmd = (gpio_num_t )_pin_cmd;
@@ -186,6 +203,19 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
186203 }
187204 _mode1bit = mode1bit;
188205
206+ #ifdef SOC_SDMMC_IO_POWER_EXTERNAL
207+ sd_pwr_ctrl_ldo_config_t ldo_config = {
208+ .ldo_chan_id = _pin_power,
209+ };
210+ sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL ;
211+
212+ if (sd_pwr_ctrl_new_on_chip_ldo (&ldo_config, &pwr_ctrl_handle) != ESP_OK) {
213+ log_e (" Failed to create a new on-chip LDO power control driver" );
214+ return false ;
215+ }
216+ host.pwr_ctrl_handle = pwr_ctrl_handle;
217+ #endif
218+
189219 esp_vfs_fat_sdmmc_mount_config_t mount_config = {
190220 .format_if_mount_failed = format_if_mount_failed,
191221 .max_files = maxOpenFiles,
@@ -231,6 +261,11 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
231261 goto err;
232262 }
233263 }
264+ #ifdef SOC_SDMMC_IO_POWER_EXTERNAL
265+ if (!perimanSetPinBus (_pin_power, ESP32_BUS_TYPE_SDMMC_POWER, (void *)(this ), -1 , -1 )) {
266+ goto err;
267+ }
268+ #endif
234269 return true ;
235270
236271err:
0 commit comments