Skip to content

Commit 36083dc

Browse files
committed
feat(sdmmc): Option to set power channel
1 parent db6296e commit 36083dc

File tree

3 files changed

+87
-45
lines changed

3 files changed

+87
-45
lines changed

libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino

+8-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Connections for ║ ║ ╔═══╩═║═║═══╗ ║ ║ ║
1515
* full-sized ║ ║ ║ ╔═╝ ║ ║ ║ ║ ║
1616
* SD card ║ ║ ║ ║ ║ ║ ║ ║ ║
17-
* ESP32-P4 Func EV | 40 39 GND 43 3V3 GND 44 43 42 | + POWER (4)
17+
* ESP32-P4 Func EV | 40 39 GND 43 3V3 GND 44 43 42 | SLOT 0 (IO_MUX)
1818
* ESP32-S3 DevKit | 21 47 GND 39 3V3 GND 40 41 42 |
1919
* ESP32-S3-USB-OTG | 38 37 GND 36 3V3 GND 35 34 33 |
2020
* ESP32 | 4 2 GND 14 3V3 GND 15 13 12 |
@@ -55,10 +55,10 @@ int cmd = 35;
5555
int d0 = 37;
5656
int d1 = 38;
5757
int d2 = 33;
58-
int d3 = 39; // GPIO 34 is not broken-out on ESP32-S3-DevKitC-1 v1.1
59-
int power = -1; // SDMMC IO power controlled internally
58+
int d3 = 39; // GPIO 34 is not broken-out on ESP32-S3-DevKitC-1 v1.1
6059

61-
#elif CONFIG_IDF_TARGET_ESP32P4
60+
#elif defined(CONFIG_IDF_TARGET_ESP32P4) && !defined(BOARD_HAS_SDMMC)
61+
// define BOARD_HAS_SDMMC for ESP32-P4 Function EV board V1.4, as it uses SLOT 0 (IO_MUX)
6262
// Pin definition for ESP32-P4 Function EV board V1.4
6363
int clk = 43;
6464
int cmd = 44;
@@ -225,12 +225,12 @@ void testFileIO(fs::FS &fs, const char *path) {
225225
void setup() {
226226
Serial.begin(115200);
227227
/*
228-
// If you want to change the pin assignment or you get an error that some pins or power pin
229-
// is not assigned on ESP32-S3/ESP32-P4 uncomment this block and the appropriate
228+
// If you want to change the pin assignment or you get an error that some pins
229+
// are not assigned on ESP32-S3/ESP32-P4 uncomment this block and the appropriate
230230
// line depending if you want to use 1-bit or 4-bit line.
231231
// Please note that ESP32 does not allow pin change and setPins() will always fail.
232-
//if(! SD_MMC.setPins(clk, cmd, d0, power)){
233-
//if(! SD_MMC.setPins(clk, cmd, d0, d1, d2, d3, power)){
232+
//if(! SD_MMC.setPins(clk, cmd, d0)){
233+
//if(! SD_MMC.setPins(clk, cmd, d0, d1, d2, d3)){
234234
// Serial.println("Pin change failed!");
235235
// return;
236236
//}

libraries/SD_MMC/src/SD_MMC.cpp

+75-34
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@
3939
using namespace fs;
4040

4141
SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
42-
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
43-
#if defined(SOC_SDMMC_USE_GPIO_MATRIX) && defined(BOARD_HAS_SDMMC)
42+
#if defined(SOC_SDMMC_USE_GPIO_MATRIX) && defined(BOARD_HAS_SDMMC) && !defined(CONFIG_IDF_TARGET_ESP32P4)
4443
_pin_clk = SDMMC_CLK;
4544
_pin_cmd = SDMMC_CMD;
4645
_pin_d0 = SDMMC_D0;
@@ -49,9 +48,8 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
4948
_pin_d2 = SDMMC_D2;
5049
_pin_d3 = SDMMC_D3;
5150
#endif // BOARD_HAS_1BIT_SDMMC
52-
#endif // !defined(CONFIG_IDF_TARGET_ESP32P4)
5351

54-
#elif SOC_SDMMC_USE_IOMUX && defined(BOARD_HAS_SDMMC) && defined(CONFIG_IDF_TARGET_ESP32)
52+
#elif defined(SOC_SDMMC_USE_IOMUX) && defined(BOARD_HAS_SDMMC) && defined(CONFIG_IDF_TARGET_ESP32)
5553
_pin_clk = SDMMC_SLOT1_IOMUX_PIN_NUM_CLK;
5654
_pin_cmd = SDMMC_SLOT1_IOMUX_PIN_NUM_CMD;
5755
_pin_d0 = SDMMC_SLOT1_IOMUX_PIN_NUM_D0;
@@ -61,7 +59,9 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
6159
_pin_d3 = SDMMC_SLOT1_IOMUX_PIN_NUM_D3;
6260
#endif // BOARD_HAS_1BIT_SDMMC
6361

64-
#elif SOC_SDMMC_USE_IOMUX && defined(BOARD_HAS_SDMMC) && defined(CONFIG_IDF_TARGET_ESP32P4)
62+
// ESP32-P4 can use either IOMUX or GPIO matrix
63+
#elif defined(BOARD_HAS_SDMMC) && defined(CONFIG_IDF_TARGET_ESP32P4)
64+
#if defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 0)
6565
_pin_clk = SDMMC_SLOT0_IOMUX_PIN_NUM_CLK;
6666
_pin_cmd = SDMMC_SLOT0_IOMUX_PIN_NUM_CMD;
6767
_pin_d0 = SDMMC_SLOT0_IOMUX_PIN_NUM_D0;
@@ -70,6 +70,19 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
7070
_pin_d2 = SDMMC_SLOT0_IOMUX_PIN_NUM_D2;
7171
_pin_d3 = SDMMC_SLOT0_IOMUX_PIN_NUM_D3;
7272
#endif // BOARD_HAS_1BIT_SDMMC
73+
#else
74+
_pin_clk = SDMMC_CLK;
75+
_pin_cmd = SDMMC_CMD;
76+
_pin_d0 = SDMMC_D0;
77+
#ifndef BOARD_HAS_1BIT_SDMMC
78+
_pin_d1 = SDMMC_D1;
79+
_pin_d2 = SDMMC_D2;
80+
_pin_d3 = SDMMC_D3;
81+
#endif // BOARD_HAS_1BIT_SDMMC
82+
#endif // BOARD_SDMMC_SLOT_NO
83+
#endif
84+
#if defined(SOC_SDMMC_IO_POWER_EXTERNAL) && defined(BOARD_SDMMC_POWER_CHANNEL)
85+
_power_channel = BOARD_SDMMC_POWER_CHANNEL;
7386
#endif
7487
}
7588

@@ -81,11 +94,11 @@ bool SDMMCFS::sdmmcDetachBus(void *bus_pointer) {
8194
return true;
8295
}
8396

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);
97+
bool SDMMCFS::setPins(int clk, int cmd, int d0) {
98+
return setPins(clk, cmd, d0, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC);
8699
}
87100

88-
bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3, int power) {
101+
bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) {
89102
if (_card != nullptr) {
90103
log_e("SD_MMC.setPins must be called before SD_MMC.begin");
91104
return false;
@@ -98,19 +111,15 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3, int powe
98111
d1 = digitalPinToGPIONumber(d1);
99112
d2 = digitalPinToGPIONumber(d2);
100113
d3 = digitalPinToGPIONumber(d3);
101-
power = digitalPinToGPIONumber(power);
102114

103-
#ifdef SOC_SDMMC_USE_GPIO_MATRIX
115+
#if defined(SOC_SDMMC_USE_GPIO_MATRIX) && !defined(CONFIG_IDF_TARGET_ESP32P4)
104116
// SoC supports SDMMC pin configuration via GPIO matrix. Save the pins for later use in SDMMCFS::begin.
105117
_pin_clk = (int8_t)clk;
106118
_pin_cmd = (int8_t)cmd;
107119
_pin_d0 = (int8_t)d0;
108120
_pin_d1 = (int8_t)d1;
109121
_pin_d2 = (int8_t)d2;
110122
_pin_d3 = (int8_t)d3;
111-
#ifdef SOC_SDMMC_IO_POWER_EXTERNAL
112-
_pin_power = (int8_t)power;
113-
#endif
114123
return true;
115124
#elif CONFIG_IDF_TARGET_ESP32
116125
// ESP32 doesn't support SDMMC pin configuration via GPIO matrix.
@@ -124,11 +133,40 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3, int powe
124133
return false;
125134
}
126135
return true;
136+
#elif defined(CONFIG_IDF_TARGET_ESP32P4)
137+
#if defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 0)
138+
// ESP32-P4 can use either IOMUX or GPIO matrix
139+
bool pins_ok =
140+
(clk == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_CLK) && (cmd == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_CMD) && (d0 == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_D0)
141+
&& (((d1 == -1) && (d2 == -1) && (d3 == -1)) || ((d1 == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_D1) && (d2 == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_D2) && (d3 == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_D3)));
142+
if (!pins_ok) {
143+
log_e("SDMMCFS: specified pins are not supported when using IOMUX (SDMMC SLOT 0).");
144+
return false;
145+
}
146+
return true;
147+
#else
148+
_pin_clk = (int8_t)clk;
149+
_pin_cmd = (int8_t)cmd;
150+
_pin_d0 = (int8_t)d0;
151+
_pin_d1 = (int8_t)d1;
152+
_pin_d2 = (int8_t)d2;
153+
_pin_d3 = (int8_t)d3;
154+
return true;
155+
#endif
127156
#else
128157
#error SoC not supported
129158
#endif
130159
}
131160

161+
bool SDMMCFS::setPowerChannel(int power_channel) {
162+
if (_card != nullptr) {
163+
log_e("SD_MMC.setPowerChannel must be called before SD_MMC.begin");
164+
return false;
165+
}
166+
_power_channel = power_channel;
167+
return true;
168+
}
169+
132170
bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed, int sdmmc_frequency, uint8_t maxOpenFiles) {
133171
if (_card) {
134172
return true;
@@ -141,24 +179,16 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
141179
perimanSetBusDeinit(ESP32_BUS_TYPE_SDMMC_D2, SDMMCFS::sdmmcDetachBus);
142180
perimanSetBusDeinit(ESP32_BUS_TYPE_SDMMC_D3, SDMMCFS::sdmmcDetachBus);
143181
}
144-
#ifdef SOC_SDMMC_IO_POWER_EXTERNAL
145-
perimanSetBusDeinit(ESP32_BUS_TYPE_SDMMC_POWER, SDMMCFS::sdmmcDetachBus);
146-
#endif
147182
//mount
148183
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
149-
#ifdef SOC_SDMMC_USE_GPIO_MATRIX
184+
#if (defined(SOC_SDMMC_USE_GPIO_MATRIX) && !defined(CONFIG_IDF_TARGET_ESP32P4)) || (defined(CONFIG_IDF_TARGET_ESP32P4) && ((defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 1)) || !defined(BOARD_HAS_SDMMC)))
185+
log_d("pin_cmd: %d, pin_clk: %d, pin_d0: %d, pin_d1: %d, pin_d2: %d, pin_d3: %d", _pin_cmd, _pin_clk, _pin_d0, _pin_d1, _pin_d2, _pin_d3);
150186
// SoC supports SDMMC pin configuration via GPIO matrix.
151187
// Check that the pins have been set either in the constructor or setPins function.
152188
if (_pin_cmd == -1 || _pin_clk == -1 || _pin_d0 == -1 || (!mode1bit && (_pin_d1 == -1 || _pin_d2 == -1 || _pin_d3 == -1))) {
153189
log_e("SDMMCFS: some SD pins are not set");
154190
return false;
155191
}
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
162192

163193
slot_config.clk = (gpio_num_t)_pin_clk;
164194
slot_config.cmd = (gpio_num_t)_pin_cmd;
@@ -192,7 +222,18 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
192222

193223
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
194224
host.flags = SDMMC_HOST_FLAG_4BIT;
225+
#if defined(CONFIG_IDF_TARGET_ESP32P4) && defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 0)
226+
host.slot = SDMMC_HOST_SLOT_0;
227+
// reconfigure slot_config to remove all pins in order to use IO_MUX
228+
slot_config = {
229+
.cd = SDMMC_SLOT_NO_CD,
230+
.wp = SDMMC_SLOT_NO_WP,
231+
.width = 4,
232+
.flags = 0,
233+
};
234+
#else
195235
host.slot = SDMMC_HOST_SLOT_1;
236+
#endif
196237
host.max_freq_khz = sdmmc_frequency;
197238
#ifdef BOARD_HAS_1BIT_SDMMC
198239
mode1bit = true;
@@ -204,16 +245,16 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
204245
_mode1bit = mode1bit;
205246

206247
#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;
248+
sd_pwr_ctrl_ldo_config_t ldo_config = {
249+
.ldo_chan_id = _pin_power,
250+
};
251+
sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
252+
253+
if(sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle) != ESP_OK) {
254+
log_e("Failed to create a new on-chip LDO power control driver");
255+
return false;
256+
}
257+
host.pwr_ctrl_handle = pwr_ctrl_handle;
217258
#endif
218259

219260
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
@@ -263,7 +304,7 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
263304
}
264305
#ifdef SOC_SDMMC_IO_POWER_EXTERNAL
265306
if (!perimanSetPinBus(_pin_power, ESP32_BUS_TYPE_SDMMC_POWER, (void *)(this), -1, -1)) {
266-
goto err;
307+
goto err;
267308
}
268309
#endif
269310
return true;

libraries/SD_MMC/src/SD_MMC.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,16 @@ class SDMMCFS : public FS {
4545
int8_t _pin_d2 = -1;
4646
int8_t _pin_d3 = -1;
4747
#ifdef SOC_SDMMC_IO_POWER_EXTERNAL
48-
int8_t _pin_power = -1;
48+
int8_t _power_channel = -1;
4949
#endif
5050
uint8_t _pdrv = 0xFF;
5151
bool _mode1bit = false;
5252

5353
public:
5454
SDMMCFS(FSImplPtr impl);
55-
bool setPins(int clk, int cmd, int d0, int power = -1);
56-
bool setPins(int clk, int cmd, int d0, int d1, int d2, int d3, int power = -1);
55+
bool setPins(int clk, int cmd, int d0);
56+
bool setPins(int clk, int cmd, int d0, int d1, int d2, int d3);
57+
bool setPowerChannel(int power_channel);
5758
bool begin(
5859
const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false, int sdmmc_frequency = BOARD_MAX_SDMMC_FREQ,
5960
uint8_t maxOpenFiles = 5

0 commit comments

Comments
 (0)