From 2f10ca582b537ca4b03e693a832f7e25042d897e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Wed, 8 May 2024 11:52:11 +0200 Subject: [PATCH 1/2] fix(storage): Fix SD card examples for SoCs with SOC_SDMMC_IO_POWER_EXTERNAL 1 --- examples/storage/perf_benchmark/README.md | 31 ++++++++++++---- .../perf_benchmark/main/Kconfig.projbuild | 22 +++++++++++ .../main/perf_benchmark_example_sd_utils.c | 37 +++++++++++++++++++ examples/storage/sd_card/sdmmc/README.md | 6 ++- .../sd_card/sdmmc/main/Kconfig.projbuild | 17 +++++---- .../sd_card/sdmmc/main/sd_card_example_main.c | 24 ++++++------ .../sdmmc/pytest_sdmmc_card_example.py | 4 +- examples/storage/sd_card/sdspi/README.md | 34 ++++++++++++++--- .../sd_card/sdspi/main/Kconfig.projbuild | 15 ++++++++ .../sd_card/sdspi/main/sd_card_example_main.c | 32 +++++++++++++++- .../sdspi/pytest_sdspi_card_example.py | 4 +- 11 files changed, 185 insertions(+), 41 deletions(-) diff --git a/examples/storage/perf_benchmark/README.md b/examples/storage/perf_benchmark/README.md index fefb02b31f..d3f4f6b5d1 100644 --- a/examples/storage/perf_benchmark/README.md +++ b/examples/storage/perf_benchmark/README.md @@ -54,14 +54,14 @@ This example doesn't utilize card detect (CD) and write protect (WP) signals fro The table below shows the default pin assignments. -SD card pin | SPI pin | ESP32 pin | ESP32-S2 | ESP32-S3 | ESP32-H2 | ESP32-C3 and other chips | Notes -------------|---------|---------------|----------|----------|----------|--------------------------|------------- - D0 | MISO | GPIO2 | GPIO37 | GPIO37 | GPIO0 | GPIO6 | 10k pullup - D1 | - | GPIO4 | - | GPIO38 | - | - | not used in 1-line SD mode; 10k pullup in 4-line mode - D2 | - | GPIO12 (MTDI) | - | GPIO33 | - | - | not used in 1-line SD mode; 10k pullup in 4-line mode - D3 | CS | GPIO13 (MTCK) | GPIO34 | GPIO34 | GPIO1 | GPIO1 | not used in 1-line SD mode, but card's D3 pin must have a 10k pullup - CLK | SCK | GPIO14 (MTMS) | GPIO36 | GPIO36 | GPIO4 | GPIO5 | 10k pullup - CMD | MOSI | GPIO15 (MTDO) | GPIO35 | GPIO35 | GPIO5 | GPIO4 | 10k pullup +SD card pin | SPI pin | ESP32 pin | ESP32-S2 | ESP32-S3 | ESP32-P4 SDMMC | ESP32-P4 SDSPI | ESP32-H2 | ESP32-C3 and other chips | Notes +------------|---------|---------------|----------|----------|----------------|----------------|----------|--------------------------|------------- + D0 | MISO | GPIO2 | GPIO37 | GPIO37 | GPIO43 | GPIO13 | GPIO0 | GPIO6 | 10k pullup + D1 | - | GPIO4 | - | GPIO38 | GPIO44 | - | - | - | not used in 1-line SD mode; 10k pullup in 4-line mode + D2 | - | GPIO12 (MTDI) | - | GPIO33 | GPIO39 | - | - | - | not used in 1-line SD mode; 10k pullup in 4-line mode + D3 | CS | GPIO13 (MTCK) | GPIO34 | GPIO34 | GPIO40 | GPIO10 | GPIO1 | GPIO1 | not used in 1-line SD mode, but card's D3 pin must have a 10k pullup + CLK | SCK | GPIO14 (MTMS) | GPIO36 | GPIO36 | GPIO41 | GPIO12 | GPIO4 | GPIO5 | 10k pullup + CMD | MOSI | GPIO15 (MTDO) | GPIO35 | GPIO35 | GPIO42 | GPIO11 | GPIO5 | GPIO4 | 10k pullup ### 4-line and 1-line SD modes @@ -97,6 +97,21 @@ This command will burn the `XPD_SDIO_TIEH`, `XPD_SDIO_FORCE`, and `XPD_SDIO_REG` See [the document about pullup requirements](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/sd_pullup_requirements.html) for more details about pullup support and compatibility of modules and development boards. +#### ESP32-P4 related notes + +This only applies when `Test SD card` setting in `Performance Benchmark Example Configuration` is enabled. + +On ESP32-P4, Slot 1 of the 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 `Performance Benchmark Example Configuration` menu. +2. In the source code: See the initialization of `sdmmc_slot_config_t slot_config` structure in the example code. + +If pins selected correspond with default pins used for ESP32-P4 SDMMC (i.e. SD card slot is connected to them), possibly an additional setting up needs to be done. + +These pins are able to connect to an ultra high-speed SD card (UHS-I) which requires 1.8V switching (instead of the regular 3.3V). This means the user has to provide an external LDO power supply to use them, or to enable and configure an internal LDO via `idf.py menuconfig` -> `SD/MMC Example Configuration` -> `SD power supply comes from internal LDO IO`. + +When using different GPIO pins this is not required and `SD power supply comes from internal LDO IO` setting can be disabled. + ### Note about SPIFFS The test for SPIFFS is run only once, because SPIFFS has a problem with deleting files. diff --git a/examples/storage/perf_benchmark/main/Kconfig.projbuild b/examples/storage/perf_benchmark/main/Kconfig.projbuild index e12a3268ab..82debaba8f 100644 --- a/examples/storage/perf_benchmark/main/Kconfig.projbuild +++ b/examples/storage/perf_benchmark/main/Kconfig.projbuild @@ -179,28 +179,34 @@ menu "Performance Benchmark Example Configuration" config EXAMPLE_PIN_CMD int "CMD GPIO number" default 35 if IDF_TARGET_ESP32S3 + default 44 if IDF_TARGET_ESP32P4 config EXAMPLE_PIN_CLK int "CLK GPIO number" default 36 if IDF_TARGET_ESP32S3 + default 43 if IDF_TARGET_ESP32P4 config EXAMPLE_PIN_D0 int "D0 GPIO number" default 37 if IDF_TARGET_ESP32S3 + default 39 if IDF_TARGET_ESP32P4 if EXAMPLE_SDMMC_BUS_WIDTH_4 config EXAMPLE_PIN_D1 int "D1 GPIO number" default 38 if IDF_TARGET_ESP32S3 + default 40 if IDF_TARGET_ESP32P4 config EXAMPLE_PIN_D2 int "D2 GPIO number" default 33 if IDF_TARGET_ESP32S3 + default 41 if IDF_TARGET_ESP32P4 config EXAMPLE_PIN_D3 int "D3 GPIO number" default 34 if IDF_TARGET_ESP32S3 + default 42 if IDF_TARGET_ESP32P4 endif # EXAMPLE_SDMMC_BUS_WIDTH_4 @@ -243,6 +249,22 @@ menu "Performance Benchmark Example Configuration" endif # EXAMPLE_USE_SDSPI + config EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + depends on SOC_SDMMC_IO_POWER_EXTERNAL + bool "SD power supply comes from internal LDO IO (READ HELP!)" + default y + help + Only needed when the SD card is connected to specific IO pins which can be used for high-speed SDMMC. + Please read the schematic first and check if the SD VDD is connected to any internal LDO output. + Unselect this option if the SD card is powered by an external power supply. + + config EXAMPLE_SD_PWR_CTRL_LDO_IO_ID + depends on SOC_SDMMC_IO_POWER_EXTERNAL && EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + int "LDO ID" + default 4 if IDF_TARGET_ESP32P4 + help + Please read the schematic first and input your LDO ID. + endmenu # "SD card test config" endmenu # "Performance Monitor Example Configuration" diff --git a/examples/storage/perf_benchmark/main/perf_benchmark_example_sd_utils.c b/examples/storage/perf_benchmark/main/perf_benchmark_example_sd_utils.c index bfd6477886..9979d6d821 100644 --- a/examples/storage/perf_benchmark/main/perf_benchmark_example_sd_utils.c +++ b/examples/storage/perf_benchmark/main/perf_benchmark_example_sd_utils.c @@ -13,6 +13,10 @@ #if SOC_SDMMC_HOST_SUPPORTED #include "driver/sdmmc_host.h" #endif +#if SOC_SDMMC_IO_POWER_EXTERNAL +#include "sd_pwr_ctrl_by_on_chip_ldo.h" +#endif +#include "esp_err.h" #include "esp_log.h" #ifdef CONFIG_EXAMPLE_TEST_SD_CARD @@ -32,6 +36,22 @@ void init_sd_config(sdmmc_host_t *out_host, sdmmc_slot_config_t *out_slot_config void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_config, int freq_khz) { #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. + // 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. +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID, + }; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + esp_err_t sd_pwr_ctrl_ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); + if (sd_pwr_ctrl_ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create a new an on-chip LDO power control driver"); + ESP_ERROR_CHECK(sd_pwr_ctrl_ret); + } +#endif // CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + // By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz) // For setting a specific frequency, use host.max_freq_khz // (range 400kHz - 40MHz for SDMMC, 400kHz - 20MHz for SDSPI) @@ -91,6 +111,11 @@ void init_sd_config(sdmmc_host_t *out_host, sdspi_device_config_t *out_slot_conf slot_config.gpio_cs = CONFIG_EXAMPLE_PIN_CS; slot_config.host_id = host.slot; #endif // CONFIG_EXAMPLE_USE_SDSPI + +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + host.pwr_ctrl_handle = pwr_ctrl_handle; +#endif // CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + *out_host = host; *out_slot_config = slot_config; } @@ -137,6 +162,18 @@ void deinit_sd_card(sdmmc_card_t **card) { #else // CONFIG_EXAMPLE_USE_SDMMC sdspi_host_deinit(); #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); *card = NULL; } diff --git a/examples/storage/sd_card/sdmmc/README.md b/examples/storage/sd_card/sdmmc/README.md index 3e5006020b..8f665f208e 100644 --- a/examples/storage/sd_card/sdmmc/README.md +++ b/examples/storage/sd_card/sdmmc/README.md @@ -70,7 +70,7 @@ GPIO34 | D3 | not used in 1-line SD mode, but card's D3 pin must On ESP32-P4, Slot 1 of the 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 "SD/MMC Example Configuration" menu. +1. Using menuconfig: Run `idf.py menuconfig` in the project directory and open `SD/MMC Example Configuration` menu. 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. @@ -84,6 +84,10 @@ GPIO40 | D1 | not used in 1-line SD mode; 10k pullup in 4-line m GPIO41 | D2 | not used in 1-line SD mode; 10k pullup in 4-line mode GPIO42 | D3 | not used in 1-line SD mode, but card's D3 pin must have a 10k pullup +Default dedicated pins on ESP32-P4 are able to connect to an ultra high-speed SD card (UHS-I) which requires 1.8V switching (instead of the regular 3.3V). This means the user has to provide an external LDO power supply to use them, or to enable and configure an internal LDO via `idf.py menuconfig` -> `SD/MMC Example Configuration` -> `SD power supply comes from internal LDO IO`. + +When using different GPIO pins this is not required and `SD power supply comes from internal LDO IO` setting can be disabled. + ### 4-line and 1-line SD modes By default, this example uses 4 line SD mode, utilizing 6 pins: CLK, CMD, D0 - D3. It is possible to use 1-line mode (CLK, CMD, D0) by changing "SD/MMC bus width" in the example configuration menu (see `CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_1`). diff --git a/examples/storage/sd_card/sdmmc/main/Kconfig.projbuild b/examples/storage/sd_card/sdmmc/main/Kconfig.projbuild index 3e74dfacf7..70449a8e39 100644 --- a/examples/storage/sd_card/sdmmc/main/Kconfig.projbuild +++ b/examples/storage/sd_card/sdmmc/main/Kconfig.projbuild @@ -152,18 +152,19 @@ menu "SD/MMC Example Configuration" endif # EXAMPLE_SDMMC_BUS_WIDTH_4 - config EXAMPLE_SDMMC_IO_POWER_INTERNAL_LDO + config EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO depends on SOC_SDMMC_IO_POWER_EXTERNAL - bool "SDMMC IO power supply comes from internal LDO (READ HELP!)" + bool "SD power supply comes from internal LDO IO (READ HELP!)" default y help - Please read the schematic first and check if the SDMMC VDD is connected to any internal LDO output. - If the SDMMC is powered by an external supplier, unselect me + Only needed when the SD card is connected to specific IO pins which can be used for high-speed SDMMC. + Please read the schematic first and check if the SD VDD is connected to any internal LDO output. + Unselect this option if the SD card is powered by an external power supply. - config EXAMPLE_SDMMC_IO_LDO_ID - depends on SOC_SDMMC_IO_POWER_EXTERNAL + config EXAMPLE_SD_PWR_CTRL_LDO_IO_ID + depends on SOC_SDMMC_IO_POWER_EXTERNAL && EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO int "LDO ID" - default 4 + default 4 if IDF_TARGET_ESP32P4 help - Please read the schematic first and input your LDO ID + Please read the schematic first and input your LDO ID. endmenu diff --git a/examples/storage/sd_card/sdmmc/main/sd_card_example_main.c b/examples/storage/sd_card/sdmmc/main/sd_card_example_main.c index e752d3a3cb..6821d05fb2 100644 --- a/examples/storage/sd_card/sdmmc/main/sd_card_example_main.c +++ b/examples/storage/sd_card/sdmmc/main/sd_card_example_main.c @@ -15,7 +15,9 @@ #include "sdmmc_cmd.h" #include "driver/sdmmc_host.h" #include "sd_test_io.h" +#if SOC_SDMMC_IO_POWER_EXTERNAL #include "sd_pwr_ctrl_by_on_chip_ldo.h" +#endif #define EXAMPLE_MAX_CHAR_SIZE 64 @@ -127,18 +129,18 @@ void app_main(void) // Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000; sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - /** - * On these chips, the SDMMC IO power is supplied externally - */ -#if CONFIG_EXAMPLE_SDMMC_IO_POWER_INTERNAL_LDO + // 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 + // and the internal LDO power supply, we need to initialize the power supply first. +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO sd_pwr_ctrl_ldo_config_t ldo_config = { - .ldo_chan_id = 4, // `LDO_VO4` is used as the SDMMC IO power + .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID, }; sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to new an on-chip ldo power control driver"); + ESP_LOGE(TAG, "Failed to create a new on-chip LDO power control driver"); return; } host.pwr_ctrl_handle = pwr_ctrl_handle; @@ -237,7 +239,7 @@ void app_main(void) ESP_LOGI(TAG, "file still exists"); return; } else { - ESP_LOGI(TAG, "file doesnt exist, format done"); + ESP_LOGI(TAG, "file doesn't exist, formatting done"); } #endif // CONFIG_EXAMPLE_FORMAT_SD_CARD @@ -257,14 +259,14 @@ void app_main(void) // All done, unmount partition and disable SDMMC peripheral esp_vfs_fat_sdcard_unmount(mount_point, card); + ESP_LOGI(TAG, "Card unmounted"); -#if SOC_SDMMC_IO_POWER_EXTERNAL + // Deinitialize the power control driver if it was used +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO ret = sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle); if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to delete on-chip ldo power control driver"); + ESP_LOGE(TAG, "Failed to delete the on-chip LDO power control driver"); return; } #endif - - ESP_LOGI(TAG, "Card unmounted"); } diff --git a/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py b/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py index 0a1685e873..d6bbb9bb55 100644 --- a/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py +++ b/examples/storage/sd_card/sdmmc/pytest_sdmmc_card_example.py @@ -1,7 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 - - import logging import re @@ -32,7 +30,7 @@ def test_examples_sd_card_sdmmc(dut: Dut) -> None: 'Reading file /sdcard/foo.txt', "Read from file: 'Hello {}!'".format(name)) sd_card_format = re.compile(str.encode('Formatting card, allocation unit size=\\S+')) - message_list2 = ('file doesnt exist, format done', + message_list2 = ("file doesn't exist, formatting done", 'Opening file /sdcard/nihao.txt', 'File written', 'Reading file /sdcard/nihao.txt', diff --git a/examples/storage/sd_card/sdspi/README.md b/examples/storage/sd_card/sdspi/README.md index 4e52527838..1432abf557 100644 --- a/examples/storage/sd_card/sdspi/README.md +++ b/examples/storage/sd_card/sdspi/README.md @@ -41,12 +41,12 @@ This example doesn't utilize card detect (CD) and write protect (WP) signals fro The table below shows the default pin assignments. -SD card pin | SPI pin | ESP32 pin | ESP32-S2, ESP32-S3 | ESP32-H2 | ESP32-C3 and other chips | Notes -------------|---------|---------------|--------------------|----------|---------------------------|------------- - D0 | MISO | GPIO2 | GPIO37 | GPIO0 | GPIO6 | - D3 | CS | GPIO13 (MTCK) | GPIO34 | GPIO1 | GPIO1 | - CLK | SCK | GPIO14 (MTMS) | GPIO36 | GPIO4 | GPIO5 | - CMD | MOSI | GPIO15 (MTDO) | GPIO35 | GPIO5 | GPIO4 | 10k pullup +SD card pin | SPI pin | ESP32 pin | ESP32-S2, ESP32-S3 | ESP32-P4 | ESP32-H2 | ESP32-C3 and other chips | Notes +------------|---------|---------------|--------------------|----------|----------|--------------------------|------------ + D0 | MISO | GPIO2 | GPIO37 | GPIO13 | GPIO0 | GPIO6 | + D3 | CS | GPIO13 (MTCK) | GPIO34 | GPIO10 | GPIO1 | GPIO1 | + CLK | SCK | GPIO14 (MTMS) | GPIO36 | GPIO12 | GPIO4 | GPIO5 | + CMD | MOSI | GPIO15 (MTDO) | GPIO35 | GPIO11 | GPIO5 | GPIO4 | 10k pullup #### ESP32 related notes @@ -63,6 +63,28 @@ With the default pin assignments, this example is compatible ESP32-S2-USB-OTG an For other development boards, adjust the pin assignments as explained above. +#### ESP32-P4 related notes + +On ESP32-P4, Slot 1 of the 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 `SD SPI Example Configuration` menu. +2. In the source code: See the initialization of `sdmmc_slot_config_t slot_config` structure in the example code. + +Default pins for SDSPI are listed in the table above [Pin assignments](#1-pin-assignments) and using them doesn't require any additional settings. + +However on some development boards the SD card slot can be wired to default dedicated pins for SDMMC, which are listed in the table below. + +SD card pin | ESP32-P4 pin +------------|-------------- +D0 (MISO) | GPIO39 +D3 (CS) | GPIO42 +CLK (SCK) | GPIO43 +CMD (MOSI) | GPIO44 + +These pins are able to connect to an ultra high-speed SD card (UHS-I) which requires 1.8V switching (instead of the regular 3.3V). This means the user has to provide an external LDO power supply to use them, or to enable and configure an internal LDO via `idf.py menuconfig` -> `SD/MMC Example Configuration` -> `SD power supply comes from internal LDO IO`. + +When using different GPIO pins this is not required and `SD power supply comes from internal LDO IO` setting can be disabled. + #### Notes for ESP32-C3 and other chips Espressif doesn't offer development boards with an SD card slot for these chips. Please check the pin assignments and adjust them for your board if necessary. The process to change pin assignments is described above. diff --git a/examples/storage/sd_card/sdspi/main/Kconfig.projbuild b/examples/storage/sd_card/sdspi/main/Kconfig.projbuild index 64f1c561e0..77fd451ed7 100644 --- a/examples/storage/sd_card/sdspi/main/Kconfig.projbuild +++ b/examples/storage/sd_card/sdspi/main/Kconfig.projbuild @@ -93,4 +93,19 @@ menu "SD SPI Example Configuration" default 6 if IDF_TARGET_ESP32S3 default 1 + config EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + depends on SOC_SDMMC_IO_POWER_EXTERNAL + bool "SD power supply comes from internal LDO IO (READ HELP!)" + default n + help + Only needed when the SD card is connected to specific IO pins which can be used for high-speed SDMMC. + Please read the schematic first and check if the SD VDD is connected to any internal LDO output. + Unselect this option if the SD card is powered by an external power supply. + + config EXAMPLE_SD_PWR_CTRL_LDO_IO_ID + depends on SOC_SDMMC_IO_POWER_EXTERNAL && EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + int "LDO ID" + default 4 if IDF_TARGET_ESP32P4 + help + Please read the schematic first and input your LDO ID. endmenu diff --git a/examples/storage/sd_card/sdspi/main/sd_card_example_main.c b/examples/storage/sd_card/sdspi/main/sd_card_example_main.c index d5edc7503e..7f3a339e41 100644 --- a/examples/storage/sd_card/sdspi/main/sd_card_example_main.c +++ b/examples/storage/sd_card/sdspi/main/sd_card_example_main.c @@ -14,6 +14,9 @@ #include "esp_vfs_fat.h" #include "sdmmc_cmd.h" #include "sd_test_io.h" +#if SOC_SDMMC_IO_POWER_EXTERNAL +#include "sd_pwr_ctrl_by_on_chip_ldo.h" +#endif #define EXAMPLE_MAX_CHAR_SIZE 64 @@ -120,6 +123,23 @@ void app_main(void) // Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000; sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + // 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 + // and the internal LDO power supply, we need to initialize the power supply first. +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID, + }; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create a new on-chip LDO power control driver"); + return; + } + host.pwr_ctrl_handle = pwr_ctrl_handle; +#endif + spi_bus_config_t bus_cfg = { .mosi_io_num = PIN_NUM_MOSI, .miso_io_num = PIN_NUM_MISO, @@ -128,6 +148,7 @@ void app_main(void) .quadhd_io_num = -1, .max_transfer_sz = 4000, }; + ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize bus."); @@ -205,7 +226,7 @@ void app_main(void) ESP_LOGI(TAG, "file still exists"); return; } else { - ESP_LOGI(TAG, "file doesnt exist, format done"); + ESP_LOGI(TAG, "file doesn't exist, formatting done"); } #endif // CONFIG_EXAMPLE_FORMAT_SD_CARD @@ -229,4 +250,13 @@ void app_main(void) //deinitialize the bus after all devices are removed spi_bus_free(host.slot); + + // Deinitialize the power control driver if it was used +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + 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"); + return; + } +#endif } diff --git a/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py b/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py index 4f2b42bb58..ddec7002bf 100644 --- a/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py +++ b/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py @@ -1,7 +1,5 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 - - import logging import re @@ -33,7 +31,7 @@ def test_examples_sd_card_sdspi(dut: Dut) -> None: 'Reading file /sdcard/foo.txt', "Read from file: 'Hello {}!'".format(name)) sd_card_format = re.compile(str.encode('Formatting card, allocation unit size=\\S+')) - message_list2 = ('file doesnt exist, format done', + message_list2 = ("file doesn't exist, formatting done", 'Opening file /sdcard/nihao.txt', 'File written', 'Reading file /sdcard/nihao.txt', From f3b7e0502a796977af3dadd4c7e49ffe483f70fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Wed, 8 May 2024 11:54:11 +0200 Subject: [PATCH 2/2] ci(examples/storage): Enable perf_benchmark spiflash example and build others --- examples/storage/.build-test-rules.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index 028df4eb16..c943c2cb2e 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -115,16 +115,13 @@ examples/storage/perf_benchmark: - esp_partition - esp_driver_sdmmc disable: - - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"] - temporary: true - reason: SDMMC and SDSPI not supported on P4 yet # TODO: IDF-6502, IDF-7501 - if: IDF_TARGET == "esp32c5" temporary: true reason: not supported yet # TODO: [ESP32C5] IDF-8704 disable_test: - - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["spiflash"] + - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"] temporary: true - reason: SPIFLASH not supported on P4 yet, only build stage enabled # TODO: IDF-7499 + reason: lack of runners, build only # TODO: IDF-8970 examples/storage/sd_card/sdmmc: depends_components: