Skip to content

Commit 83d3568

Browse files
P-R-O-C-H-Ylucasssvazpre-commit-ci-lite[bot]
authored
feat(sdmmc): Add SDMMC support for P4 + remove BUILTIN LED (#10460)
* feat(sdmmc): Add support for P4 * fix(board): Remove builtin led * Update libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino Add missing note about power pin for P4 Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> * ci(pre-commit): Apply automatic fixes * feat(sdmmc): Option to set power channel * feat(sdmmc): Update pins_arduino.h * feat(sdmmc): remove sdmmc power from periman * fix(sdmmc): use corrent variable * fix(sdmmc): Remove periman * feat(sdmmc): Toggle power pin if defined * feat(sdmmc): setPowerChannel available only when supported * feat(sdmmc): Toggle sd power pin for 200ms * fix(example): Remove p4 pins as they are listed already * feat(sdmmc): Check if power channel is specified * ci(pre-commit): Apply automatic fixes * fix(ci): codespell fix --------- Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 7cfe470 commit 83d3568

File tree

5 files changed

+138
-23
lines changed

5 files changed

+138
-23
lines changed

libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino

+13-7
Original file line numberDiff line numberDiff line change
@@ -14,6 +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 | SLOT 0 (IO_MUX)
1718
* ESP32-S3 DevKit | 21 47 GND 39 3V3 GND 40 41 42 |
1819
* ESP32-S3-USB-OTG | 38 37 GND 36 3V3 GND 35 34 33 |
1920
* ESP32 | 4 2 GND 14 3V3 GND 15 13 12 |
@@ -42,6 +43,7 @@
4243
#include "FS.h"
4344
#include "SD_MMC.h"
4445

46+
#ifdef CONFIG_IDF_TARGET_ESP32S3
4547
// Default pins for ESP-S3
4648
// Warning: ESP32-S3-WROOM-2 is using most of the default GPIOs (33-37) to interface with on-board OPI flash.
4749
// If the SD_MMC is initialized with default pins it will result in rebooting loop - please
@@ -54,6 +56,7 @@ int d0 = 37;
5456
int d1 = 38;
5557
int d2 = 33;
5658
int d3 = 39; // GPIO 34 is not broken-out on ESP32-S3-DevKitC-1 v1.1
59+
#endif
5760

5861
void listDir(fs::FS &fs, const char *dirname, uint8_t levels) {
5962
Serial.printf("Listing directory: %s\n", dirname);
@@ -211,15 +214,16 @@ void testFileIO(fs::FS &fs, const char *path) {
211214
void setup() {
212215
Serial.begin(115200);
213216
/*
214-
// If you want to change the pin assignment on ESP32-S3 uncomment this block and the appropriate
217+
// If you want to change the pin assignment or you get an error that some pins
218+
// are not assigned on ESP32-S3/ESP32-P4 uncomment this block and the appropriate
215219
// line depending if you want to use 1-bit or 4-bit line.
216-
// Please note that ESP32 does not allow pin change and will always fail.
220+
// Please note that ESP32 does not allow pin change and setPins() will always fail.
217221
//if(! SD_MMC.setPins(clk, cmd, d0)){
218222
//if(! SD_MMC.setPins(clk, cmd, d0, d1, d2, d3)){
219-
Serial.println("Pin change failed!");
220-
return;
221-
}
222-
*/
223+
// Serial.println("Pin change failed!");
224+
// return;
225+
//}
226+
*/
223227

224228
if (!SD_MMC.begin()) {
225229
Serial.println("Card Mount Failed");
@@ -262,4 +266,6 @@ void setup() {
262266
Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024));
263267
}
264268

265-
void loop() {}
269+
void loop() {
270+
delay(10);
271+
}

libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +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 | SLOT 0 (IO_MUX)
1718
* ESP32-S3 DevKit | 21 47 GND 39 3V3 GND 40 41 42 |
1819
* ESP32-S3-USB-OTG | 38 37 GND 36 3V3 GND 35 34 33 |
1920
* ESP32 | 4 2 GND 14 3V3 GND 15 13 12 |

libraries/SD_MMC/src/SD_MMC.cpp

+99-7
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@
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+
3539
using namespace fs;
3640

3741
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)
4043
_pin_clk = SDMMC_CLK;
4144
_pin_cmd = SDMMC_CMD;
4245
_pin_d0 = SDMMC_D0;
@@ -45,9 +48,8 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
4548
_pin_d2 = SDMMC_D2;
4649
_pin_d3 = SDMMC_D3;
4750
#endif // BOARD_HAS_1BIT_SDMMC
48-
#endif // !defined(CONFIG_IDF_TARGET_ESP32P4)
4951

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)
5153
_pin_clk = SDMMC_SLOT1_IOMUX_PIN_NUM_CLK;
5254
_pin_cmd = SDMMC_SLOT1_IOMUX_PIN_NUM_CMD;
5355
_pin_d0 = SDMMC_SLOT1_IOMUX_PIN_NUM_D0;
@@ -57,7 +59,9 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
5759
_pin_d3 = SDMMC_SLOT1_IOMUX_PIN_NUM_D3;
5860
#endif // BOARD_HAS_1BIT_SDMMC
5961

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)
6165
_pin_clk = SDMMC_SLOT0_IOMUX_PIN_NUM_CLK;
6266
_pin_cmd = SDMMC_SLOT0_IOMUX_PIN_NUM_CMD;
6367
_pin_d0 = SDMMC_SLOT0_IOMUX_PIN_NUM_D0;
@@ -66,6 +70,19 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) {
6670
_pin_d2 = SDMMC_SLOT0_IOMUX_PIN_NUM_D2;
6771
_pin_d3 = SDMMC_SLOT0_IOMUX_PIN_NUM_D3;
6872
#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;
6986
#endif
7087
}
7188

@@ -95,7 +112,7 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) {
95112
d2 = digitalPinToGPIONumber(d2);
96113
d3 = digitalPinToGPIONumber(d3);
97114

98-
#ifdef SOC_SDMMC_USE_GPIO_MATRIX
115+
#if defined(SOC_SDMMC_USE_GPIO_MATRIX) && !defined(CONFIG_IDF_TARGET_ESP32P4)
99116
// SoC supports SDMMC pin configuration via GPIO matrix. Save the pins for later use in SDMMCFS::begin.
100117
_pin_clk = (int8_t)clk;
101118
_pin_cmd = (int8_t)cmd;
@@ -116,11 +133,42 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) {
116133
return false;
117134
}
118135
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
119156
#else
120157
#error SoC not supported
121158
#endif
122159
}
123160

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+
124172
bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed, int sdmmc_frequency, uint8_t maxOpenFiles) {
125173
if (_card) {
126174
return true;
@@ -135,7 +183,9 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
135183
}
136184
//mount
137185
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);
139189
// SoC supports SDMMC pin configuration via GPIO matrix.
140190
// Check that the pins have been set either in the constructor or setPins function.
141191
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_
175225

176226
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
177227
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
178238
host.slot = SDMMC_HOST_SLOT_1;
239+
#endif
179240
host.max_freq_khz = sdmmc_frequency;
180241
#ifdef BOARD_HAS_1BIT_SDMMC
181242
mode1bit = true;
@@ -186,6 +247,34 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_
186247
}
187248
_mode1bit = mode1bit;
188249

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+
189278
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
190279
.format_if_mount_failed = format_if_mount_failed,
191280
.max_files = maxOpenFiles,
@@ -252,6 +341,9 @@ void SDMMCFS::end() {
252341
perimanClearPinBus(_pin_d2);
253342
perimanClearPinBus(_pin_d3);
254343
}
344+
#if defined(BOARD_SDMMC_POWER_PIN)
345+
perimanClearPinBus(BOARD_SDMMC_POWER_PIN);
346+
#endif
255347
}
256348
}
257349

libraries/SD_MMC/src/SD_MMC.h

+6
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,19 @@ class SDMMCFS : public FS {
4444
int8_t _pin_d1 = -1;
4545
int8_t _pin_d2 = -1;
4646
int8_t _pin_d3 = -1;
47+
#ifdef SOC_SDMMC_IO_POWER_EXTERNAL
48+
int8_t _power_channel = -1;
49+
#endif
4750
uint8_t _pdrv = 0xFF;
4851
bool _mode1bit = false;
4952

5053
public:
5154
SDMMCFS(FSImplPtr impl);
5255
bool setPins(int clk, int cmd, int d0);
5356
bool setPins(int clk, int cmd, int d0, int d1, int d2, int d3);
57+
#ifdef SOC_SDMMC_IO_POWER_EXTERNAL
58+
bool setPowerChannel(int power_channel);
59+
#endif
5460
bool begin(
5561
const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false, int sdmmc_frequency = BOARD_MAX_SDMMC_FREQ,
5662
uint8_t maxOpenFiles = 5

variants/esp32p4/pins_arduino.h

+19-9
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,6 @@
44
#include <stdint.h>
55
#include "soc/soc_caps.h"
66

7-
#define PIN_NEOPIXEL 44
8-
// BUILTIN_LED can be used in new Arduino API digitalWrite() like in Blink.ino
9-
static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT + PIN_NEOPIXEL;
10-
#define BUILTIN_LED LED_BUILTIN // backward compatibility
11-
#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN
12-
// RGB_BUILTIN and RGB_BRIGHTNESS can be used in new Arduino API rgbLedWrite()
13-
#define RGB_BUILTIN LED_BUILTIN
14-
#define RGB_BRIGHTNESS 64
15-
167
// BOOT_MODE 35
178
// BOOT_MODE2 36 pullup
189

@@ -58,6 +49,8 @@ static const uint8_t T11 = 13;
5849
static const uint8_t T12 = 14;
5950
static const uint8_t T13 = 15;
6051

52+
/* ESP32-P4 EV Function board specific definitions */
53+
//ETH
6154
#define ETH_PHY_TYPE ETH_PHY_TLK110
6255
#define ETH_PHY_ADDR 1
6356
#define ETH_PHY_MDC 31
@@ -72,4 +65,21 @@ static const uint8_t T13 = 15;
7265
#define ETH_RMII_CLK 50
7366
#define ETH_CLK_MODE EMAC_CLK_EXT_IN
7467

68+
//SDMMC
69+
#define BOARD_HAS_SDMMC
70+
#define BOARD_SDMMC_SLOT 0
71+
#define BOARD_SDMMC_POWER_CHANNEL 4
72+
#define BOARD_SDMMC_POWER_PIN 45
73+
#define BOARD_SDMMC_POWER_ON_LEVEL LOW
74+
75+
//WIFI - ESP32C6
76+
#define BOARD_HAS_SDIO_ESP_HOSTED
77+
#define BOARD_SDIO_ESP_HOSTED_CLK 18
78+
#define BOARD_SDIO_ESP_HOSTED_CMD 19
79+
#define BOARD_SDIO_ESP_HOSTED_D0 14
80+
#define BOARD_SDIO_ESP_HOSTED_D1 15
81+
#define BOARD_SDIO_ESP_HOSTED_D2 16
82+
#define BOARD_SDIO_ESP_HOSTED_D3 17
83+
#define BOARD_SDIO_ESP_HOSTED_RESET 54
84+
7585
#endif /* Pins_Arduino_h */

0 commit comments

Comments
 (0)