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
This commit is contained in:
Adam Múdry
2025-07-01 08:59:53 +02:00
11 changed files with 203 additions and 50 deletions

View File

@@ -91,6 +91,11 @@ sd_host_slot_handle_t sdmmc_get_slot_handle(int slot_id)
return slot_id == 0 ? s_slot0 : s_slot1; return slot_id == 0 ? s_slot0 : s_slot1;
} }
static sd_host_slot_handle_t* sdmmc_get_slot_handle_ptr(int slot_id)
{
return slot_id == 0 ? &s_slot0 : &s_slot1;
}
esp_err_t sdmmc_host_is_slot_set_to_uhs1(int slot, bool *is_uhs1) esp_err_t sdmmc_host_is_slot_set_to_uhs1(int slot, bool *is_uhs1)
{ {
SLOT_CHECK(slot); SLOT_CHECK(slot);
@@ -145,8 +150,9 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t *slot_config)
esp_err_t sdmmc_host_deinit_slot(int slot) esp_err_t sdmmc_host_deinit_slot(int slot)
{ {
esp_err_t ret = ESP_FAIL; esp_err_t ret = ESP_FAIL;
sd_host_slot_handle_t hdl = sdmmc_get_slot_handle(slot); sd_host_slot_handle_t* hdl = sdmmc_get_slot_handle_ptr(slot);
ESP_RETURN_ON_ERROR(sd_host_remove_slot(hdl), TAG, "failed to remove slot"); ESP_RETURN_ON_ERROR(sd_host_remove_slot(*hdl), TAG, "failed to remove slot");
*hdl = NULL;
ret = sd_host_del_controller(s_ctlr); ret = sd_host_del_controller(s_ctlr);
//for backward compatibility, return ESP_OK when only slot is removed and host is still there //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)
esp_err_t sdmmc_host_deinit(void) esp_err_t sdmmc_host_deinit(void)
{ {
esp_err_t ret = ESP_FAIL; esp_err_t ret = ESP_FAIL;
sd_host_slot_handle_t hdl[2] = {s_slot0, s_slot1}; sd_host_slot_handle_t* hdl_ptrs[2] = {&s_slot0, &s_slot1};
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (hdl[i]) { sd_host_slot_handle_t hdl = *hdl_ptrs[i];
ret = sd_host_remove_slot(hdl[i]); if (hdl) {
ret = sd_host_remove_slot(hdl);
ESP_RETURN_ON_ERROR(ret, TAG, "failed to remove slot%d", i); ESP_RETURN_ON_ERROR(ret, TAG, "failed to remove slot%d", i);
*hdl_ptrs[i] = NULL;
} }
} }
ESP_RETURN_ON_ERROR(sd_host_del_controller(s_ctlr), TAG, "failed to delete controller"); ESP_RETURN_ON_ERROR(sd_host_del_controller(s_ctlr), TAG, "failed to delete controller");

View File

@@ -37,6 +37,10 @@ menu "SDMMC Test Board Configuration"
bool "ESP32-P4 Function EV Board with SDSPI breakout" bool "ESP32-P4 Function EV Board with SDSPI breakout"
depends on IDF_TARGET_ESP32P4 depends on IDF_TARGET_ESP32P4
config SDMMC_BOARD_ESP32P4_EMMC_TEST
bool "ESP32-P4 eMMC Test Board v1"
depends on IDF_TARGET_ESP32P4
config SDMMC_BOARD_ESP32C5_BREAKOUT config SDMMC_BOARD_ESP32C5_BREAKOUT
bool "ESP32-C5 breakout board" bool "ESP32-C5 breakout board"
depends on IDF_TARGET_ESP32C5 depends on IDF_TARGET_ESP32C5

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -375,6 +375,88 @@ static const sdmmc_test_board_info_t s_board_info = {
}, },
}; };
#elif CONFIG_SDMMC_BOARD_ESP32P4_EMMC_TEST
#define SD_TEST_BOARD_EN_GPIO 23
#define SD_TEST_BOARD_EN_LEVEL 0
// Pin pulled down to discharge VDD_SDIO capacitors. CMD pin used here.
#define SD_TEST_BOARD_DISCHARGE_GPIO 19
#define SD_TEST_BOARD_PWR_RST_DELAY_MS 100
#define SD_TEST_BOARD_PWR_ON_DELAY_MS 100
static void card_power_set_esp32p4_emmc(bool en)
{
if (en) {
/* power off to make sure the card is reset */
gpio_reset_pin(SD_TEST_BOARD_EN_GPIO);
gpio_set_direction(SD_TEST_BOARD_EN_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(SD_TEST_BOARD_EN_GPIO, !SD_TEST_BOARD_EN_LEVEL);
/* discharge capacitors on VDD_SDIO */
gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO);
gpio_set_direction(SD_TEST_BOARD_DISCHARGE_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(SD_TEST_BOARD_DISCHARGE_GPIO, 0);
usleep(SD_TEST_BOARD_PWR_RST_DELAY_MS * 1000);
/* power on */
gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO);
gpio_set_level(SD_TEST_BOARD_EN_GPIO, SD_TEST_BOARD_EN_LEVEL);
usleep(SD_TEST_BOARD_PWR_ON_DELAY_MS * 1000);
} else {
/* power off the card */
gpio_set_level(SD_TEST_BOARD_EN_GPIO, !SD_TEST_BOARD_EN_LEVEL);
gpio_set_direction(SD_TEST_BOARD_EN_GPIO, GPIO_MODE_INPUT);
/* discharge capacitors on VDD_SDIO */
gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO);
gpio_set_direction(SD_TEST_BOARD_DISCHARGE_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(SD_TEST_BOARD_DISCHARGE_GPIO, 0);
usleep(SD_TEST_BOARD_PWR_RST_DELAY_MS * 1000);
/* reset the pin but leaving it floating so that VDD_SDIO won't be charged again */
gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO);
gpio_pullup_dis(SD_TEST_BOARD_DISCHARGE_GPIO);
}
}
static const sdmmc_test_board_info_t s_board_info = {
.name = "ESP32-P4 eMMC test board v1",
.slot = {
{
.slot_exists = true,
.is_emmc = true,
.bus_width = 8,
.clk = 43,
.cmd_mosi = 44,
.d0_miso = 39,
.d1 = 40,
.d2 = 41,
.d3_cs = 42,
.d4 = 45,
.d5 = 46,
.d6 = 47,
.d7 = 48,
.cd = GPIO_NUM_NC,
.wp = GPIO_NUM_NC,
.unused_pin = 54,
},
{
.slot_exists = true,
.bus_width = 4,
.clk = 18,
.cmd_mosi = 19,
.d0_miso = 14,
.d1 = 15,
.d2 = 16,
.d3_cs = 17,
.d4 = GPIO_NUM_NC,
.d5 = GPIO_NUM_NC,
.d6 = GPIO_NUM_NC,
.d7 = GPIO_NUM_NC,
.cd = 22,
.wp = GPIO_NUM_NC,
.unused_pin = 54,
}
},
.card_power_set = card_power_set_esp32p4_emmc
};
#elif CONFIG_SDMMC_BOARD_ESP32C5_BREAKOUT #elif CONFIG_SDMMC_BOARD_ESP32C5_BREAKOUT
static const sdmmc_test_board_info_t s_board_info = { static const sdmmc_test_board_info_t s_board_info = {

View File

@@ -13,8 +13,12 @@ examples/storage/emmc:
- esp_driver_sdmmc - esp_driver_sdmmc
- esp_driver_sdspi - esp_driver_sdspi
enable: enable:
- if: IDF_TARGET == "esp32s3" - if: IDF_TARGET in ["esp32s3", "esp32p4"]
reason: only support on esp32s3 reason: only support on esp32s3 and esp32p4
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runners
examples/storage/partition_api/partition_find: examples/storage/partition_api/partition_find:
depends_components: depends_components:

View File

@@ -1,5 +1,5 @@
| Supported Targets | ESP32-S3 | | Supported Targets | ESP32-P4 | ESP32-S3 |
| ----------------- | -------- | | ----------------- | -------- | -------- |
# eMMC chip example (with SDMMC Host) # eMMC chip example (with SDMMC Host)
@@ -22,34 +22,34 @@ This example supports eMMC chips.
## Hardware ## Hardware
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. 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.
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. 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.
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). 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.
### Pin assignments for ESP32-S3 ### Pin assignments
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: 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:
1. Using menuconfig: Run `idf.py menuconfig` in the project directory and open "eMMC Example Configuration" menu. 1. Using menuconfig: Run `idf.py menuconfig` in the project directory and open "eMMC Example Configuration" menu.
2. In the source code: See the initialization of ``sdmmc_slot_config_t slot_config`` structure in the example code. 2. In the source code: See the initialization of ``sdmmc_slot_config_t slot_config`` structure in the example code.
The table below lists the default pin assignments. The table below lists the default pin assignments.
ESP32-S3 pin | eMMC pin | Notes ESP32-S3 pin | ESP32-P4 pin | eMMC pin | Notes
--------------|-------------|------------ --------------|----------------|-------------|-------
GPIO34 | CLK | 10k pullup GPIO34 | GPIO43 | CLK | 10k pullup
GPIO33 | CMD | 10k pullup GPIO33 | GPIO44 | CMD | 10k pullup
GPIO37 | D0 | 10k pullup GPIO37 | GPIO39 | D0 | 10k pullup
GPIO38 | D1 | not used in 1-line mode; but card's D1 pin must have a 10k pullup GPIO38 | GPIO40 | D1 | not used in 1-line mode; but card's D1 pin must have a 10k pullup
GPIO39 | D2 | not used in 1-line mode; but card's D2 pin must have a 10k pullup GPIO39 | GPIO41 | D2 | not used in 1-line mode; but card's D2 pin must have a 10k pullup
GPIO36 | D3 | not used in 1-line mode, but card's D3 pin must have a 10k pullup GPIO36 | GPIO42 | D3 | not used in 1-line mode, but card's D3 pin must have a 10k pullup
GPIO35 | D4 | not used in 1/4-line mode, but card's D4 pin must have a 10k pullup GPIO35 | GPIO45 | D4 | not used in 1/4-line mode, but card's D4 pin must have a 10k pullup
GPIO40 | D5 | not used in 1/4-line mode, but card's D5 pin must have a 10k pullup GPIO40 | GPIO46 | D5 | not used in 1/4-line mode, but card's D5 pin must have a 10k pullup
GPIO42 | D6 | not used in 1/4-line mode, but card's D6 pin must have a 10k pullup GPIO42 | GPIO47 | D6 | not used in 1/4-line mode, but card's D6 pin must have a 10k pullup
GPIO41 | D7 | not used in 1/4-line mode, but card's D7 pin must have a 10k pullup GPIO41 | GPIO48 | D7 | not used in 1/4-line mode, but card's D7 pin must have a 10k pullup
### Line modes ### Line modes

View File

@@ -28,28 +28,34 @@ menu "eMMC Example Configuration"
config EXAMPLE_PIN_CMD config EXAMPLE_PIN_CMD
int "CMD GPIO number" int "CMD GPIO number"
default 33 if IDF_TARGET_ESP32S3 default 33 if IDF_TARGET_ESP32S3
default 44 if IDF_TARGET_ESP32P4
config EXAMPLE_PIN_CLK config EXAMPLE_PIN_CLK
int "CLK GPIO number" int "CLK GPIO number"
default 34 if IDF_TARGET_ESP32S3 default 34 if IDF_TARGET_ESP32S3
default 43 if IDF_TARGET_ESP32P4
config EXAMPLE_PIN_D0 config EXAMPLE_PIN_D0
int "D0 GPIO number" int "D0 GPIO number"
default 37 if IDF_TARGET_ESP32S3 default 37 if IDF_TARGET_ESP32S3
default 39 if IDF_TARGET_ESP32P4
if EXAMPLE_EMMC_BUS_WIDTH_4 || EXAMPLE_EMMC_BUS_WIDTH_8 if EXAMPLE_EMMC_BUS_WIDTH_4 || EXAMPLE_EMMC_BUS_WIDTH_8
config EXAMPLE_PIN_D1 config EXAMPLE_PIN_D1
int "D1 GPIO number" int "D1 GPIO number"
default 38 if IDF_TARGET_ESP32S3 default 38 if IDF_TARGET_ESP32S3
default 40 if IDF_TARGET_ESP32P4
config EXAMPLE_PIN_D2 config EXAMPLE_PIN_D2
int "D2 GPIO number" int "D2 GPIO number"
default 39 if IDF_TARGET_ESP32S3 default 39 if IDF_TARGET_ESP32S3
default 41 if IDF_TARGET_ESP32P4
config EXAMPLE_PIN_D3 config EXAMPLE_PIN_D3
int "D3 GPIO number" int "D3 GPIO number"
default 36 if IDF_TARGET_ESP32S3 default 36 if IDF_TARGET_ESP32S3
default 42 if IDF_TARGET_ESP32P4
endif # EXAMPLE_EMMC_BUS_WIDTH_4 || EXAMPLE_EMMC_BUS_WIDTH_8 endif # EXAMPLE_EMMC_BUS_WIDTH_4 || EXAMPLE_EMMC_BUS_WIDTH_8
@@ -58,18 +64,26 @@ menu "eMMC Example Configuration"
config EXAMPLE_PIN_D4 config EXAMPLE_PIN_D4
int "D4 GPIO number" int "D4 GPIO number"
default 35 if IDF_TARGET_ESP32S3 default 35 if IDF_TARGET_ESP32S3
default 45 if IDF_TARGET_ESP32P4
default -1
config EXAMPLE_PIN_D5 config EXAMPLE_PIN_D5
int "D5 GPIO number" int "D5 GPIO number"
default 40 if IDF_TARGET_ESP32S3 default 40 if IDF_TARGET_ESP32S3
default 46 if IDF_TARGET_ESP32P4
default -1
config EXAMPLE_PIN_D6 config EXAMPLE_PIN_D6
int "D6 GPIO number" int "D6 GPIO number"
default 42 if IDF_TARGET_ESP32S3 default 42 if IDF_TARGET_ESP32S3
default 47 if IDF_TARGET_ESP32P4
default -1
config EXAMPLE_PIN_D7 config EXAMPLE_PIN_D7
int "D7 GPIO number" int "D7 GPIO number"
default 41 if IDF_TARGET_ESP32S3 default 41 if IDF_TARGET_ESP32S3
default 48 if IDF_TARGET_ESP32P4
default -1
endif # EXAMPLE_EMMC_BUS_WIDTH_8 endif # EXAMPLE_EMMC_BUS_WIDTH_8

View File

@@ -1 +1,2 @@
CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED=y CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED=y
CONFIG_ESP_TASK_WDT_INIT=n

View File

@@ -167,6 +167,10 @@ menu "Performance Benchmark Example Configuration"
Otherwise the card may enter SPI mode, Otherwise the card may enter SPI mode,
the only way to recover from which is to cycle power to the card. the only way to recover from which is to cycle power to the card.
config EXAMPLE_SDMMC_BUS_WIDTH_8
bool "8 lines (D0 - D7)"
depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4
config EXAMPLE_SDMMC_BUS_WIDTH_4 config EXAMPLE_SDMMC_BUS_WIDTH_4
bool "4 lines (D0 - D3)" bool "4 lines (D0 - D3)"
@@ -191,7 +195,7 @@ menu "Performance Benchmark Example Configuration"
default 37 if IDF_TARGET_ESP32S3 default 37 if IDF_TARGET_ESP32S3
default 39 if IDF_TARGET_ESP32P4 default 39 if IDF_TARGET_ESP32P4
if EXAMPLE_SDMMC_BUS_WIDTH_4 if EXAMPLE_SDMMC_BUS_WIDTH_4 || EXAMPLE_SDMMC_BUS_WIDTH_8
config EXAMPLE_PIN_D1 config EXAMPLE_PIN_D1
int "D1 GPIO number" int "D1 GPIO number"
@@ -208,7 +212,31 @@ menu "Performance Benchmark Example Configuration"
default 34 if IDF_TARGET_ESP32S3 default 34 if IDF_TARGET_ESP32S3
default 42 if IDF_TARGET_ESP32P4 default 42 if IDF_TARGET_ESP32P4
endif # EXAMPLE_SDMMC_BUS_WIDTH_4 endif # EXAMPLE_SDMMC_BUS_WIDTH_4 || EXAMPLE_SDMMC_BUS_WIDTH_8
if EXAMPLE_SDMMC_BUS_WIDTH_8
config EXAMPLE_PIN_D4
int "D4 GPIO number"
default 35 if IDF_TARGET_ESP32S3
default 45 if IDF_TARGET_ESP32P4
config EXAMPLE_PIN_D5
int "D5 GPIO number"
default 40 if IDF_TARGET_ESP32S3
default 46 if IDF_TARGET_ESP32P4
config EXAMPLE_PIN_D6
int "D6 GPIO number"
default 42 if IDF_TARGET_ESP32S3
default 47 if IDF_TARGET_ESP32P4
config EXAMPLE_PIN_D7
int "D7 GPIO number"
default 41 if IDF_TARGET_ESP32S3
default 48 if IDF_TARGET_ESP32P4
endif # EXAMPLE_SDMMC_BUS_WIDTH_8
endif # SOC_SDMMC_USE_GPIO_MATRIX endif # SOC_SDMMC_USE_GPIO_MATRIX

View File

@@ -1,3 +1,3 @@
## IDF Component Manager Manifest File ## IDF Component Manager Manifest File
dependencies: dependencies:
joltwallet/littlefs: "~=1.16.0" joltwallet/littlefs: "~=1.20.0"

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
@@ -22,6 +22,9 @@
#include "esp_vfs_fat.h" #include "esp_vfs_fat.h"
#include "esp_spiffs.h" #include "esp_spiffs.h"
#include "wear_levelling.h" #include "wear_levelling.h"
#if SOC_SDMMC_IO_POWER_EXTERNAL
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
#endif
#include "esp_littlefs.h" #include "esp_littlefs.h"
@@ -91,6 +94,16 @@ void app_main(void)
test_sd_littlefs(); test_sd_littlefs();
#endif // CONFIG_EXAMPLE_TEST_SD_CARD_LITTLEFS #endif // CONFIG_EXAMPLE_TEST_SD_CARD_LITTLEFS
// Deinitialize the power control driver if it was used
#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO
esp_err_t ret = sd_pwr_ctrl_del_on_chip_ldo(host_g.pwr_ctrl_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to delete the on-chip LDO power control driver");
ESP_ERROR_CHECK(ret);
}
host_g.pwr_ctrl_handle = NULL;
#endif
#endif // CONFIG_EXAMPLE_TEST_SD_CARD #endif // CONFIG_EXAMPLE_TEST_SD_CARD
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
@@ -31,11 +31,11 @@ sdspi_device_config_t slot_config_g;
#endif // CONFIG_EXAMPLE_USE_SDSPI #endif // CONFIG_EXAMPLE_USE_SDSPI
#ifdef CONFIG_EXAMPLE_USE_SDMMC #ifdef CONFIG_EXAMPLE_USE_SDMMC
void init_sd_config(sdmmc_host_t *out_host, sdmmc_slot_config_t *out_slot_config, int freq_khz) { void init_sd_config(sdmmc_host_t *out_host, sdmmc_slot_config_t *out_slot_config, int freq_khz)
#else // CONFIG_EXAMPLE_USE_SDMMC #else // CONFIG_EXAMPLE_USE_SDMMC
void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_config, int freq_khz) { void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_config, int freq_khz)
#endif // CONFIG_EXAMPLE_USE_SDSPI #endif // CONFIG_EXAMPLE_USE_SDSPI
{
// For SoCs where the SD power can be supplied both via an internal or external (e.g. on-board LDO) power supply. // For SoCs where the SD power can be supplied both via an internal or external (e.g. on-board LDO) power supply.
// When using specific IO pins (which can be used for ultra high-speed SDMMC) to connect to the SD card // When using specific IO pins (which can be used for ultra high-speed SDMMC) to connect to the SD card
// and the internal LDO power supply, we need to initialize the power supply first. // and the internal LDO power supply, we need to initialize the power supply first.
@@ -66,7 +66,9 @@ void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_conf
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
// Set bus width to use: // Set bus width to use:
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 #ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_8
slot_config.width = 8;
#elif CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4
slot_config.width = 4; slot_config.width = 4;
#else #else
slot_config.width = 1; slot_config.width = 1;
@@ -78,11 +80,17 @@ void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_conf
slot_config.clk = CONFIG_EXAMPLE_PIN_CLK; slot_config.clk = CONFIG_EXAMPLE_PIN_CLK;
slot_config.cmd = CONFIG_EXAMPLE_PIN_CMD; slot_config.cmd = CONFIG_EXAMPLE_PIN_CMD;
slot_config.d0 = CONFIG_EXAMPLE_PIN_D0; slot_config.d0 = CONFIG_EXAMPLE_PIN_D0;
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 #if CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 || CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_8
slot_config.d1 = CONFIG_EXAMPLE_PIN_D1; slot_config.d1 = CONFIG_EXAMPLE_PIN_D1;
slot_config.d2 = CONFIG_EXAMPLE_PIN_D2; slot_config.d2 = CONFIG_EXAMPLE_PIN_D2;
slot_config.d3 = CONFIG_EXAMPLE_PIN_D3; slot_config.d3 = CONFIG_EXAMPLE_PIN_D3;
#endif // CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 #endif // CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 || CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_8
#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_8
slot_config.d4 = CONFIG_EXAMPLE_PIN_D4;
slot_config.d5 = CONFIG_EXAMPLE_PIN_D5;
slot_config.d6 = CONFIG_EXAMPLE_PIN_D6;
slot_config.d7 = CONFIG_EXAMPLE_PIN_D7;
#endif // CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_8
#endif // CONFIG_SOC_SDMMC_USE_GPIO_MATRIX #endif // CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
// Enable internal pullups on enabled pins. The internal pullups // Enable internal pullups on enabled pins. The internal pullups
@@ -120,7 +128,8 @@ void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_conf
*out_slot_config = slot_config; *out_slot_config = slot_config;
} }
esp_err_t init_sd_card(sdmmc_card_t **out_card) { esp_err_t init_sd_card(sdmmc_card_t **out_card)
{
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
sdmmc_card_t* card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t)); sdmmc_card_t* card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t));
if (card == NULL) { if (card == NULL) {
@@ -155,7 +164,8 @@ esp_err_t init_sd_card(sdmmc_card_t **out_card) {
return ret; return ret;
} }
void deinit_sd_card(sdmmc_card_t **card) { void deinit_sd_card(sdmmc_card_t **card)
{
// Unmount SD card // Unmount SD card
#ifdef CONFIG_EXAMPLE_USE_SDMMC #ifdef CONFIG_EXAMPLE_USE_SDMMC
sdmmc_host_deinit(); sdmmc_host_deinit();
@@ -163,17 +173,6 @@ void deinit_sd_card(sdmmc_card_t **card) {
sdspi_host_deinit(); sdspi_host_deinit();
#endif // CONFIG_EXAMPLE_USE_SDSPI #endif // CONFIG_EXAMPLE_USE_SDSPI
// Deinitialize the power control driver if it was used
#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO
sd_pwr_ctrl_handle_t pwr_ctrl_handle = (*card)->host.pwr_ctrl_handle;
esp_err_t ret = sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to delete the on-chip LDO power control driver");
ESP_ERROR_CHECK(ret);
}
pwr_ctrl_handle = NULL;
#endif
free(*card); free(*card);
*card = NULL; *card = NULL;
} }