32
32
#include " ff.h"
33
33
#include " esp32-hal-periman.h"
34
34
35
+ #if SOC_SDMMC_IO_POWER_EXTERNAL
36
+ #include " sd_pwr_ctrl_by_on_chip_ldo.h"
37
+ #endif
38
+
35
39
using namespace fs ;
36
40
37
41
SDMMCFS::SDMMCFS (FSImplPtr impl) : FS(impl), _card(nullptr ) {
38
- #if !defined(CONFIG_IDF_TARGET_ESP32P4)
39
- #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)
40
43
_pin_clk = SDMMC_CLK;
41
44
_pin_cmd = SDMMC_CMD;
42
45
_pin_d0 = SDMMC_D0;
@@ -45,9 +48,8 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
45
48
_pin_d2 = SDMMC_D2;
46
49
_pin_d3 = SDMMC_D3;
47
50
#endif // BOARD_HAS_1BIT_SDMMC
48
- #endif // !defined(CONFIG_IDF_TARGET_ESP32P4)
49
51
50
- #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)
51
53
_pin_clk = SDMMC_SLOT1_IOMUX_PIN_NUM_CLK;
52
54
_pin_cmd = SDMMC_SLOT1_IOMUX_PIN_NUM_CMD;
53
55
_pin_d0 = SDMMC_SLOT1_IOMUX_PIN_NUM_D0;
@@ -57,7 +59,9 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
57
59
_pin_d3 = SDMMC_SLOT1_IOMUX_PIN_NUM_D3;
58
60
#endif // BOARD_HAS_1BIT_SDMMC
59
61
60
- #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)
61
65
_pin_clk = SDMMC_SLOT0_IOMUX_PIN_NUM_CLK;
62
66
_pin_cmd = SDMMC_SLOT0_IOMUX_PIN_NUM_CMD;
63
67
_pin_d0 = SDMMC_SLOT0_IOMUX_PIN_NUM_D0;
@@ -66,6 +70,19 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
66
70
_pin_d2 = SDMMC_SLOT0_IOMUX_PIN_NUM_D2;
67
71
_pin_d3 = SDMMC_SLOT0_IOMUX_PIN_NUM_D3;
68
72
#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;
69
86
#endif
70
87
}
71
88
@@ -95,7 +112,7 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) {
95
112
d2 = digitalPinToGPIONumber (d2);
96
113
d3 = digitalPinToGPIONumber (d3);
97
114
98
- #ifdef SOC_SDMMC_USE_GPIO_MATRIX
115
+ #if defined( SOC_SDMMC_USE_GPIO_MATRIX) && !defined(CONFIG_IDF_TARGET_ESP32P4)
99
116
// SoC supports SDMMC pin configuration via GPIO matrix. Save the pins for later use in SDMMCFS::begin.
100
117
_pin_clk = (int8_t )clk;
101
118
_pin_cmd = (int8_t )cmd;
@@ -116,11 +133,42 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) {
116
133
return false ;
117
134
}
118
135
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
119
156
#else
120
157
#error SoC not supported
121
158
#endif
122
159
}
123
160
161
+ #ifdef SOC_SDMMC_IO_POWER_EXTERNAL
162
+ bool SDMMCFS::setPowerChannel (int power_channel) {
163
+ if (_card != nullptr ) {
164
+ log_e (" SD_MMC.setPowerChannel must be called before SD_MMC.begin" );
165
+ return false ;
166
+ }
167
+ _power_channel = power_channel;
168
+ return true ;
169
+ }
170
+ #endif
171
+
124
172
bool SDMMCFS::begin (const char *mountpoint, bool mode1bit, bool format_if_mount_failed, int sdmmc_frequency, uint8_t maxOpenFiles) {
125
173
if (_card) {
126
174
return true ;
@@ -135,7 +183,9 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
135
183
}
136
184
// mount
137
185
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT ();
138
- #ifdef SOC_SDMMC_USE_GPIO_MATRIX
186
+ #if (defined(SOC_SDMMC_USE_GPIO_MATRIX) && !defined(CONFIG_IDF_TARGET_ESP32P4)) \
187
+ || (defined (CONFIG_IDF_TARGET_ESP32P4) && ((defined (BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 1 )) || !defined (BOARD_HAS_SDMMC)))
188
+ 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);
139
189
// SoC supports SDMMC pin configuration via GPIO matrix.
140
190
// Check that the pins have been set either in the constructor or setPins function.
141
191
if (_pin_cmd == -1 || _pin_clk == -1 || _pin_d0 == -1 || (!mode1bit && (_pin_d1 == -1 || _pin_d2 == -1 || _pin_d3 == -1 ))) {
@@ -175,7 +225,18 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
175
225
176
226
sdmmc_host_t host = SDMMC_HOST_DEFAULT ();
177
227
host.flags = SDMMC_HOST_FLAG_4BIT;
228
+ #if defined(CONFIG_IDF_TARGET_ESP32P4) && defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 0)
229
+ host.slot = SDMMC_HOST_SLOT_0;
230
+ // reconfigure slot_config to remove all pins in order to use IO_MUX
231
+ slot_config = {
232
+ .cd = SDMMC_SLOT_NO_CD,
233
+ .wp = SDMMC_SLOT_NO_WP,
234
+ .width = 4 ,
235
+ .flags = 0 ,
236
+ };
237
+ #else
178
238
host.slot = SDMMC_HOST_SLOT_1;
239
+ #endif
179
240
host.max_freq_khz = sdmmc_frequency;
180
241
#ifdef BOARD_HAS_1BIT_SDMMC
181
242
mode1bit = true ;
@@ -186,6 +247,34 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
186
247
}
187
248
_mode1bit = mode1bit;
188
249
250
+ #ifdef SOC_SDMMC_IO_POWER_EXTERNAL
251
+ if (_power_channel == -1 ) {
252
+ log_i (" On-chip power channel specified, use external power for SDMMC" );
253
+ } else {
254
+ sd_pwr_ctrl_ldo_config_t ldo_config = {
255
+ .ldo_chan_id = _power_channel,
256
+ };
257
+ sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL ;
258
+
259
+ if (sd_pwr_ctrl_new_on_chip_ldo (&ldo_config, &pwr_ctrl_handle) != ESP_OK) {
260
+ log_e (" Failed to create a new on-chip LDO power control driver" );
261
+ return false ;
262
+ }
263
+ host.pwr_ctrl_handle = pwr_ctrl_handle;
264
+ }
265
+ #endif
266
+
267
+ #if defined(BOARD_SDMMC_POWER_PIN)
268
+ #ifndef BOARD_SDMMC_POWER_ON_LEVEL
269
+ #error "BOARD_SDMMC_POWER_ON_LEVEL not defined, please define it in pins_arduino.h"
270
+ #endif
271
+ pinMode (BOARD_SDMMC_POWER_PIN, OUTPUT);
272
+ digitalWrite (BOARD_SDMMC_POWER_PIN, !BOARD_SDMMC_POWER_ON_LEVEL);
273
+ delay (200 );
274
+ digitalWrite (BOARD_SDMMC_POWER_PIN, BOARD_SDMMC_POWER_ON_LEVEL);
275
+ perimanSetPinBusExtraType (BOARD_SDMMC_POWER_PIN, " SDMMC_POWER" );
276
+ #endif
277
+
189
278
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
190
279
.format_if_mount_failed = format_if_mount_failed,
191
280
.max_files = maxOpenFiles,
@@ -252,6 +341,9 @@ void SDMMCFS::end() {
252
341
perimanClearPinBus (_pin_d2);
253
342
perimanClearPinBus (_pin_d3);
254
343
}
344
+ #if defined(BOARD_SDMMC_POWER_PIN)
345
+ perimanClearPinBus (BOARD_SDMMC_POWER_PIN);
346
+ #endif
255
347
}
256
348
}
257
349
0 commit comments