Skip to content

Commit a9c5a2a

Browse files
committed
Merge branch 'feat/perf_benchmark_support_esp32p4' into 'master'
feat(storage): Update emmc and perf_benchmark example to work with ESP32-P4, fix SDMMC slot deinit bug in legacy driver Closes IDF-13394 and IDF-13483 See merge request espressif/esp-idf!39826
2 parents 78faa25 + 20313f8 commit a9c5a2a

File tree

11 files changed

+203
-50
lines changed

11 files changed

+203
-50
lines changed

components/esp_driver_sdmmc/legacy/src/sdmmc_host.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ sd_host_slot_handle_t sdmmc_get_slot_handle(int slot_id)
9191
return slot_id == 0 ? s_slot0 : s_slot1;
9292
}
9393

94+
static sd_host_slot_handle_t* sdmmc_get_slot_handle_ptr(int slot_id)
95+
{
96+
return slot_id == 0 ? &s_slot0 : &s_slot1;
97+
}
98+
9499
esp_err_t sdmmc_host_is_slot_set_to_uhs1(int slot, bool *is_uhs1)
95100
{
96101
SLOT_CHECK(slot);
@@ -145,8 +150,9 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
145150
esp_err_t sdmmc_host_deinit_slot(int slot)
146151
{
147152
esp_err_t ret = ESP_FAIL;
148-
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot);
149-
ESP_RETURN_ON_ERROR(sd_host_remove_slot(hdl), TAG, "failed to remove slot");
153+
sd_host_slot_handle_t* hdl = sdmmc_get_slot_handle_ptr(slot);
154+
ESP_RETURN_ON_ERROR(sd_host_remove_slot(*hdl), TAG, "failed to remove slot");
155+
*hdl = NULL;
150156

151157
ret = sd_host_del_controller(s_ctlr);
152158
//for backward compatibility, return ESP_OK when only slot is removed and host is still there
@@ -160,11 +166,13 @@ esp_err_t sdmmc_host_deinit_slot(int slot)
160166
esp_err_t sdmmc_host_deinit(void)
161167
{
162168
esp_err_t ret = ESP_FAIL;
163-
sd_host_slot_handle_t hdl[2] = {s_slot0, s_slot1};
169+
sd_host_slot_handle_t* hdl_ptrs[2] = {&s_slot0, &s_slot1};
164170
for (int i = 0; i < 2; i++) {
165-
if (hdl[i]) {
166-
ret = sd_host_remove_slot(hdl[i]);
171+
sd_host_slot_handle_t hdl = *hdl_ptrs[i];
172+
if (hdl) {
173+
ret = sd_host_remove_slot(hdl);
167174
ESP_RETURN_ON_ERROR(ret, TAG, "failed to remove slot%d", i);
175+
*hdl_ptrs[i] = NULL;
168176
}
169177
}
170178
ESP_RETURN_ON_ERROR(sd_host_del_controller(s_ctlr), TAG, "failed to delete controller");

components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/Kconfig.projbuild

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ menu "SDMMC Test Board Configuration"
3737
bool "ESP32-P4 Function EV Board with SDSPI breakout"
3838
depends on IDF_TARGET_ESP32P4
3939

40+
config SDMMC_BOARD_ESP32P4_EMMC_TEST
41+
bool "ESP32-P4 eMMC Test Board v1"
42+
depends on IDF_TARGET_ESP32P4
43+
4044
config SDMMC_BOARD_ESP32C5_BREAKOUT
4145
bool "ESP32-C5 breakout board"
4246
depends on IDF_TARGET_ESP32C5

components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/sdmmc_test_board_defs.c

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -375,6 +375,88 @@ static const sdmmc_test_board_info_t s_board_info = {
375375
},
376376
};
377377

378+
#elif CONFIG_SDMMC_BOARD_ESP32P4_EMMC_TEST
379+
380+
#define SD_TEST_BOARD_EN_GPIO 23
381+
#define SD_TEST_BOARD_EN_LEVEL 0
382+
// Pin pulled down to discharge VDD_SDIO capacitors. CMD pin used here.
383+
#define SD_TEST_BOARD_DISCHARGE_GPIO 19
384+
#define SD_TEST_BOARD_PWR_RST_DELAY_MS 100
385+
#define SD_TEST_BOARD_PWR_ON_DELAY_MS 100
386+
387+
static void card_power_set_esp32p4_emmc(bool en)
388+
{
389+
if (en) {
390+
/* power off to make sure the card is reset */
391+
gpio_reset_pin(SD_TEST_BOARD_EN_GPIO);
392+
gpio_set_direction(SD_TEST_BOARD_EN_GPIO, GPIO_MODE_OUTPUT);
393+
gpio_set_level(SD_TEST_BOARD_EN_GPIO, !SD_TEST_BOARD_EN_LEVEL);
394+
/* discharge capacitors on VDD_SDIO */
395+
gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO);
396+
gpio_set_direction(SD_TEST_BOARD_DISCHARGE_GPIO, GPIO_MODE_OUTPUT);
397+
gpio_set_level(SD_TEST_BOARD_DISCHARGE_GPIO, 0);
398+
usleep(SD_TEST_BOARD_PWR_RST_DELAY_MS * 1000);
399+
/* power on */
400+
gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO);
401+
gpio_set_level(SD_TEST_BOARD_EN_GPIO, SD_TEST_BOARD_EN_LEVEL);
402+
usleep(SD_TEST_BOARD_PWR_ON_DELAY_MS * 1000);
403+
} else {
404+
/* power off the card */
405+
gpio_set_level(SD_TEST_BOARD_EN_GPIO, !SD_TEST_BOARD_EN_LEVEL);
406+
gpio_set_direction(SD_TEST_BOARD_EN_GPIO, GPIO_MODE_INPUT);
407+
/* discharge capacitors on VDD_SDIO */
408+
gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO);
409+
gpio_set_direction(SD_TEST_BOARD_DISCHARGE_GPIO, GPIO_MODE_OUTPUT);
410+
gpio_set_level(SD_TEST_BOARD_DISCHARGE_GPIO, 0);
411+
usleep(SD_TEST_BOARD_PWR_RST_DELAY_MS * 1000);
412+
/* reset the pin but leaving it floating so that VDD_SDIO won't be charged again */
413+
gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO);
414+
gpio_pullup_dis(SD_TEST_BOARD_DISCHARGE_GPIO);
415+
}
416+
}
417+
418+
static const sdmmc_test_board_info_t s_board_info = {
419+
.name = "ESP32-P4 eMMC test board v1",
420+
.slot = {
421+
{
422+
.slot_exists = true,
423+
.is_emmc = true,
424+
.bus_width = 8,
425+
.clk = 43,
426+
.cmd_mosi = 44,
427+
.d0_miso = 39,
428+
.d1 = 40,
429+
.d2 = 41,
430+
.d3_cs = 42,
431+
.d4 = 45,
432+
.d5 = 46,
433+
.d6 = 47,
434+
.d7 = 48,
435+
.cd = GPIO_NUM_NC,
436+
.wp = GPIO_NUM_NC,
437+
.unused_pin = 54,
438+
},
439+
{
440+
.slot_exists = true,
441+
.bus_width = 4,
442+
.clk = 18,
443+
.cmd_mosi = 19,
444+
.d0_miso = 14,
445+
.d1 = 15,
446+
.d2 = 16,
447+
.d3_cs = 17,
448+
.d4 = GPIO_NUM_NC,
449+
.d5 = GPIO_NUM_NC,
450+
.d6 = GPIO_NUM_NC,
451+
.d7 = GPIO_NUM_NC,
452+
.cd = 22,
453+
.wp = GPIO_NUM_NC,
454+
.unused_pin = 54,
455+
}
456+
},
457+
.card_power_set = card_power_set_esp32p4_emmc
458+
};
459+
378460
#elif CONFIG_SDMMC_BOARD_ESP32C5_BREAKOUT
379461

380462
static const sdmmc_test_board_info_t s_board_info = {

examples/storage/.build-test-rules.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ examples/storage/emmc:
1313
- esp_driver_sdmmc
1414
- esp_driver_sdspi
1515
enable:
16-
- if: IDF_TARGET == "esp32s3"
17-
reason: only support on esp32s3
16+
- if: IDF_TARGET in ["esp32s3", "esp32p4"]
17+
reason: only support on esp32s3 and esp32p4
18+
disable_test:
19+
- if: IDF_TARGET == "esp32p4"
20+
temporary: true
21+
reason: lack of runners
1822

1923
examples/storage/partition_api/partition_find:
2024
depends_components:

examples/storage/emmc/README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
| Supported Targets | ESP32-S3 |
2-
| ----------------- | -------- |
1+
| Supported Targets | ESP32-P4 | ESP32-S3 |
2+
| ----------------- | -------- | -------- |
33

44
# eMMC chip example (with SDMMC Host)
55

@@ -22,34 +22,34 @@ This example supports eMMC chips.
2222

2323
## Hardware
2424

25-
This example requires an ESP32-S3 development board and an eMMC chip. Default connections can be found in next chapter. The standard ESP32S3 devkits do not have an eMMC integrated. Considering the signal integrity issues, we suggesting you make your custom PCB board with ESP32-S3 module and an eMMC chip. The signal integrity issues will be more important, when the bus is working under higher speeds. This includes but not limited to increasing the frequency, switching to DDR mode. We will talk a bit more about signal integrity issues in a following chapter.
25+
This example requires an ESP32-S3 or ESP32-P4 development board and an eMMC chip. Default connections can be found in next chapter. Standard devkits do not have an eMMC integrated. Considering the signal integrity issues, we suggesting you make your custom PCB board with an ESP module and an eMMC chip. The signal integrity issues will be more important, when the bus is working under higher speeds. This includes but not limited to increasing the frequency, switching to DDR mode. We will talk a bit more about signal integrity issues in a following chapter.
2626

2727
It is possible to connect an eMMC breakout adapter, but note that cable connections will decrease the signal integrity, leading communication timing violations. When in this condition, you may need to use a lower clock frequency, or switch to SDR mode.
2828

29-
Pull-up resistors is needed. As the SD specification and the eMMC datasheet clarify, minimum 10k pull-up resistors are required for the bus IOs to protect the IOs against bus floating issue. Note these pull-up resistors are needed, even if the pin is not used (For example, you use 1-line-mode, the pull-up resistor is still required for the D1 pin).
29+
Pull-up resistors are needed. As specified in the SD specification and the eMMC datasheet, a minimum of 10k pull-up resistors are required on the bus I/Os to protect against bus floating issues. Note that these pull-up resistors are necessary even if a pin is not used. For example, if you are using 1-line mode, a pull-up resistor is still required on the D1 pin.
3030

3131

32-
### Pin assignments for ESP32-S3
32+
### Pin assignments
3333

34-
On ESP32-S3, SDMMC peripheral is connected to GPIO pins using GPIO matrix. This allows arbitrary GPIOs to be used to connect an SD card. In this example, GPIOs can be configured in two ways:
34+
On ESP32-S3 and ESP32-P4, SDMMC peripheral is connected to GPIO pins using GPIO matrix. This allows arbitrary GPIOs to be used to connect an SD card. In this example, GPIOs can be configured in two ways:
3535

3636
1. Using menuconfig: Run `idf.py menuconfig` in the project directory and open "eMMC Example Configuration" menu.
3737
2. In the source code: See the initialization of ``sdmmc_slot_config_t slot_config`` structure in the example code.
3838

3939
The table below lists the default pin assignments.
4040

41-
ESP32-S3 pin | eMMC pin | Notes
42-
--------------|-------------|------------
43-
GPIO34 | CLK | 10k pullup
44-
GPIO33 | CMD | 10k pullup
45-
GPIO37 | D0 | 10k pullup
46-
GPIO38 | D1 | not used in 1-line mode; but card's D1 pin must have a 10k pullup
47-
GPIO39 | D2 | not used in 1-line mode; but card's D2 pin must have a 10k pullup
48-
GPIO36 | D3 | not used in 1-line mode, but card's D3 pin must have a 10k pullup
49-
GPIO35 | D4 | not used in 1/4-line mode, but card's D4 pin must have a 10k pullup
50-
GPIO40 | D5 | not used in 1/4-line mode, but card's D5 pin must have a 10k pullup
51-
GPIO42 | D6 | not used in 1/4-line mode, but card's D6 pin must have a 10k pullup
52-
GPIO41 | D7 | not used in 1/4-line mode, but card's D7 pin must have a 10k pullup
41+
ESP32-S3 pin | ESP32-P4 pin | eMMC pin | Notes
42+
--------------|----------------|-------------|-------
43+
GPIO34 | GPIO43 | CLK | 10k pullup
44+
GPIO33 | GPIO44 | CMD | 10k pullup
45+
GPIO37 | GPIO39 | D0 | 10k pullup
46+
GPIO38 | GPIO40 | D1 | not used in 1-line mode; but card's D1 pin must have a 10k pullup
47+
GPIO39 | GPIO41 | D2 | not used in 1-line mode; but card's D2 pin must have a 10k pullup
48+
GPIO36 | GPIO42 | D3 | not used in 1-line mode, but card's D3 pin must have a 10k pullup
49+
GPIO35 | GPIO45 | D4 | not used in 1/4-line mode, but card's D4 pin must have a 10k pullup
50+
GPIO40 | GPIO46 | D5 | not used in 1/4-line mode, but card's D5 pin must have a 10k pullup
51+
GPIO42 | GPIO47 | D6 | not used in 1/4-line mode, but card's D6 pin must have a 10k pullup
52+
GPIO41 | GPIO48 | D7 | not used in 1/4-line mode, but card's D7 pin must have a 10k pullup
5353

5454

5555
### Line modes

examples/storage/emmc/main/Kconfig.projbuild

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,34 @@ menu "eMMC Example Configuration"
2828
config EXAMPLE_PIN_CMD
2929
int "CMD GPIO number"
3030
default 33 if IDF_TARGET_ESP32S3
31+
default 44 if IDF_TARGET_ESP32P4
3132

3233
config EXAMPLE_PIN_CLK
3334
int "CLK GPIO number"
3435
default 34 if IDF_TARGET_ESP32S3
36+
default 43 if IDF_TARGET_ESP32P4
3537

3638
config EXAMPLE_PIN_D0
3739
int "D0 GPIO number"
3840
default 37 if IDF_TARGET_ESP32S3
41+
default 39 if IDF_TARGET_ESP32P4
3942

4043
if EXAMPLE_EMMC_BUS_WIDTH_4 || EXAMPLE_EMMC_BUS_WIDTH_8
4144

4245
config EXAMPLE_PIN_D1
4346
int "D1 GPIO number"
4447
default 38 if IDF_TARGET_ESP32S3
48+
default 40 if IDF_TARGET_ESP32P4
4549

4650
config EXAMPLE_PIN_D2
4751
int "D2 GPIO number"
4852
default 39 if IDF_TARGET_ESP32S3
53+
default 41 if IDF_TARGET_ESP32P4
4954

5055
config EXAMPLE_PIN_D3
5156
int "D3 GPIO number"
5257
default 36 if IDF_TARGET_ESP32S3
58+
default 42 if IDF_TARGET_ESP32P4
5359

5460
endif # EXAMPLE_EMMC_BUS_WIDTH_4 || EXAMPLE_EMMC_BUS_WIDTH_8
5561

@@ -58,18 +64,26 @@ menu "eMMC Example Configuration"
5864
config EXAMPLE_PIN_D4
5965
int "D4 GPIO number"
6066
default 35 if IDF_TARGET_ESP32S3
67+
default 45 if IDF_TARGET_ESP32P4
68+
default -1
6169

6270
config EXAMPLE_PIN_D5
6371
int "D5 GPIO number"
6472
default 40 if IDF_TARGET_ESP32S3
73+
default 46 if IDF_TARGET_ESP32P4
74+
default -1
6575

6676
config EXAMPLE_PIN_D6
6777
int "D6 GPIO number"
6878
default 42 if IDF_TARGET_ESP32S3
79+
default 47 if IDF_TARGET_ESP32P4
80+
default -1
6981

7082
config EXAMPLE_PIN_D7
7183
int "D7 GPIO number"
7284
default 41 if IDF_TARGET_ESP32S3
85+
default 48 if IDF_TARGET_ESP32P4
86+
default -1
7387

7488
endif # EXAMPLE_EMMC_BUS_WIDTH_8
7589

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED=y
2+
CONFIG_ESP_TASK_WDT_INIT=n

examples/storage/perf_benchmark/main/Kconfig.projbuild

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ menu "Performance Benchmark Example Configuration"
167167
Otherwise the card may enter SPI mode,
168168
the only way to recover from which is to cycle power to the card.
169169

170+
config EXAMPLE_SDMMC_BUS_WIDTH_8
171+
bool "8 lines (D0 - D7)"
172+
depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4
173+
170174
config EXAMPLE_SDMMC_BUS_WIDTH_4
171175
bool "4 lines (D0 - D3)"
172176

@@ -191,7 +195,7 @@ menu "Performance Benchmark Example Configuration"
191195
default 37 if IDF_TARGET_ESP32S3
192196
default 39 if IDF_TARGET_ESP32P4
193197

194-
if EXAMPLE_SDMMC_BUS_WIDTH_4
198+
if EXAMPLE_SDMMC_BUS_WIDTH_4 || EXAMPLE_SDMMC_BUS_WIDTH_8
195199

196200
config EXAMPLE_PIN_D1
197201
int "D1 GPIO number"
@@ -208,7 +212,31 @@ menu "Performance Benchmark Example Configuration"
208212
default 34 if IDF_TARGET_ESP32S3
209213
default 42 if IDF_TARGET_ESP32P4
210214

211-
endif # EXAMPLE_SDMMC_BUS_WIDTH_4
215+
endif # EXAMPLE_SDMMC_BUS_WIDTH_4 || EXAMPLE_SDMMC_BUS_WIDTH_8
216+
217+
if EXAMPLE_SDMMC_BUS_WIDTH_8
218+
219+
config EXAMPLE_PIN_D4
220+
int "D4 GPIO number"
221+
default 35 if IDF_TARGET_ESP32S3
222+
default 45 if IDF_TARGET_ESP32P4
223+
224+
config EXAMPLE_PIN_D5
225+
int "D5 GPIO number"
226+
default 40 if IDF_TARGET_ESP32S3
227+
default 46 if IDF_TARGET_ESP32P4
228+
229+
config EXAMPLE_PIN_D6
230+
int "D6 GPIO number"
231+
default 42 if IDF_TARGET_ESP32S3
232+
default 47 if IDF_TARGET_ESP32P4
233+
234+
config EXAMPLE_PIN_D7
235+
int "D7 GPIO number"
236+
default 41 if IDF_TARGET_ESP32S3
237+
default 48 if IDF_TARGET_ESP32P4
238+
239+
endif # EXAMPLE_SDMMC_BUS_WIDTH_8
212240

213241
endif # SOC_SDMMC_USE_GPIO_MATRIX
214242

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## IDF Component Manager Manifest File
22
dependencies:
3-
joltwallet/littlefs: "~=1.16.0"
3+
joltwallet/littlefs: "~=1.20.0"

examples/storage/perf_benchmark/main/perf_benchmark_example_main.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Unlicense OR CC0-1.0
55
*/
@@ -22,6 +22,9 @@
2222
#include "esp_vfs_fat.h"
2323
#include "esp_spiffs.h"
2424
#include "wear_levelling.h"
25+
#if SOC_SDMMC_IO_POWER_EXTERNAL
26+
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
27+
#endif
2528

2629
#include "esp_littlefs.h"
2730

@@ -91,6 +94,16 @@ void app_main(void)
9194
test_sd_littlefs();
9295
#endif // CONFIG_EXAMPLE_TEST_SD_CARD_LITTLEFS
9396

97+
// Deinitialize the power control driver if it was used
98+
#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO
99+
esp_err_t ret = sd_pwr_ctrl_del_on_chip_ldo(host_g.pwr_ctrl_handle);
100+
if (ret != ESP_OK) {
101+
ESP_LOGE(TAG, "Failed to delete the on-chip LDO power control driver");
102+
ESP_ERROR_CHECK(ret);
103+
}
104+
host_g.pwr_ctrl_handle = NULL;
105+
#endif
106+
94107
#endif // CONFIG_EXAMPLE_TEST_SD_CARD
95108
}
96109

0 commit comments

Comments
 (0)