From df7e887d18c4ae62bdcf8cbf9b0f8aad3b7ea3ef Mon Sep 17 00:00:00 2001 From: Xiao Xufeng Date: Tue, 18 Jul 2023 19:15:00 +0800 Subject: [PATCH] test(sdmmc): support power down card on S3 emmc board --- .../sdmmc_test_board/sdmmc_test_board_defs.c | 40 ++++++++++++++----- .../sdmmc_tests/sdmmc_test_begin_end.h | 2 +- .../sdmmc_tests/sdmmc_test_begin_end_sd.c | 5 ++- .../sdmmc_tests/sdmmc_test_begin_end_spi.c | 23 ++++++++++- .../sdmmc_tests/sdmmc_test_probe_spi.c | 2 +- .../sdmmc_tests/sdmmc_test_rw_spi.c | 6 +-- 6 files changed, 62 insertions(+), 16 deletions(-) diff --git a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_test_board/sdmmc_test_board_defs.c b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_test_board/sdmmc_test_board_defs.c index 704893fd6d..bb76aed3d0 100644 --- a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_test_board/sdmmc_test_board_defs.c +++ b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_test_board/sdmmc_test_board_defs.c @@ -145,6 +145,8 @@ static const sdmmc_test_board_info_t s_board_info = { #define SD_TEST_BOARD_EN_GPIO 47 #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 4 #define SD_TEST_BOARD_PWR_RST_DELAY_MS 100 #define SD_TEST_BOARD_PWR_ON_DELAY_MS 100 @@ -155,13 +157,27 @@ static void card_power_set_esp32s3_emmc(bool en) 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); } } @@ -239,6 +255,8 @@ static const sdmmc_test_board_info_t s_board_info = { #define SD_BREAKOUT_BOARD_EN_GPIO 10 #define SD_BREAKOUT_BOARD_EN_LEVEL 0 +// Pin pulled down to discharge VDD_SDIO capacitors. CMD pin used here. +#define SD_TEST_BOARD_DISCHARGE_GPIO 4 #define SD_BREAKOUT_BOARD_PWR_RST_DELAY_MS 100 #define SD_BREAKOUT_BOARD_PWR_ON_DELAY_MS 100 @@ -246,26 +264,30 @@ static void card_power_set_esp32c3_breakout(bool en) { if (en) { /* power off to make sure card is reset */ + gpio_reset_pin(SD_BREAKOUT_BOARD_EN_GPIO); gpio_set_direction(SD_BREAKOUT_BOARD_EN_GPIO, GPIO_MODE_OUTPUT); gpio_set_level(SD_BREAKOUT_BOARD_EN_GPIO, !SD_BREAKOUT_BOARD_EN_LEVEL); - /* set CMD low to discharge capacitors on VDD_SDIO */ - gpio_reset_pin(4); - gpio_set_direction(4, GPIO_MODE_OUTPUT); - gpio_set_level(4, 0); + /* 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_BREAKOUT_BOARD_PWR_RST_DELAY_MS * 1000); /* power on */ - gpio_reset_pin(4); + gpio_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO); gpio_set_level(SD_BREAKOUT_BOARD_EN_GPIO, SD_BREAKOUT_BOARD_EN_LEVEL); usleep(SD_BREAKOUT_BOARD_PWR_ON_DELAY_MS * 1000); } else { + /* power off the card */ gpio_set_level(SD_BREAKOUT_BOARD_EN_GPIO, !SD_BREAKOUT_BOARD_EN_LEVEL); gpio_set_direction(SD_BREAKOUT_BOARD_EN_GPIO, GPIO_MODE_INPUT); /* set CMD low to discharge capacitors on VDD_SDIO */ - gpio_reset_pin(4); - gpio_set_direction(4, GPIO_MODE_OUTPUT); - gpio_set_level(4, 0); + 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_BREAKOUT_BOARD_PWR_RST_DELAY_MS * 1000); - gpio_reset_pin(4); + /* 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_reset_pin(SD_TEST_BOARD_DISCHARGE_GPIO); } } diff --git a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end.h b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end.h index 0f7e4ca5ca..da5126b6c3 100644 --- a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end.h +++ b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end.h @@ -65,7 +65,7 @@ void sdmmc_test_spi_begin(int slot, int freq_khz, sdmmc_card_t *out_card); * @brief Helper function to deinitialize the SDMMC host and slot after the test, for SPI mode * @see sdmmc_test_sd_end */ -void sdmmc_test_spi_end(sdmmc_card_t *card); +void sdmmc_test_spi_end(int slot, sdmmc_card_t *card); #ifdef __cplusplus diff --git a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end_sd.c b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end_sd.c index 4f88fe086b..f67be4ead6 100644 --- a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end_sd.c +++ b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end_sd.c @@ -82,7 +82,6 @@ void sdmmc_test_sd_begin(int slot, int width, int freq_khz, int ddr, sdmmc_card_ void sdmmc_test_sd_end(sdmmc_card_t *card) { TEST_ESP_OK(sdmmc_host_deinit()); - sdmmc_test_board_card_power_set(false); // Reset all GPIOs to their default states int slot = card->host.slot; @@ -108,7 +107,11 @@ void sdmmc_test_sd_end(sdmmc_card_t *card) for (int i = 0; i < num_pins; i++) { if (pins[i] >= 0) { gpio_reset_pin(pins[i]); + gpio_pullup_dis(pins[i]); } } esp_log_level_set("gpio", old_level); + + //Need to reset GPIO first, otherrwise cannot discharge VDD of card completely. + sdmmc_test_board_card_power_set(false); } diff --git a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end_spi.c b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end_spi.c index abe215da36..d69dc80565 100644 --- a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end_spi.c +++ b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_begin_end_spi.c @@ -8,6 +8,7 @@ #include "sdkconfig.h" #include "soc/soc_caps.h" #include "unity.h" +#include "esp_log.h" #include "sdmmc_test_board.h" #include "driver/sdspi_host.h" #include "driver/sdmmc_defs.h" @@ -65,9 +66,29 @@ void sdmmc_test_spi_begin(int slot, int freq_khz, sdmmc_card_t *out_card) TEST_ESP_OK(sdmmc_card_init(&config, out_card)); } -void sdmmc_test_spi_end(sdmmc_card_t *card) +void sdmmc_test_spi_end(int slot, sdmmc_card_t *card) { TEST_ESP_OK(sdspi_host_deinit()); TEST_ESP_OK(spi_bus_free(SDSPI_DEFAULT_HOST)); + + const sdmmc_test_board_slot_info_t* slot_info = sdmmc_test_board_get_slot_info(slot); + const int pins[] = { + slot_info->clk, + slot_info->cmd_mosi, + slot_info->d0_miso, + slot_info->d3_cs, + }; + const int num_pins = sizeof(pins) / sizeof(pins[0]); + // Silence logging in gpio_reset_pin, which logs at INFO level + esp_log_level_t old_level = esp_log_level_get("gpio"); + esp_log_level_set("gpio", ESP_LOG_WARN); + for (int i = 0; i < num_pins; i++) { + if (pins[i] >= 0) { + gpio_reset_pin(pins[i]); + gpio_pullup_dis(pins[i]); + } + } + esp_log_level_set("gpio", old_level); + sdmmc_test_board_card_power_set(false); } diff --git a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_probe_spi.c b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_probe_spi.c index 7cd42359bb..d50725f16d 100644 --- a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_probe_spi.c +++ b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_probe_spi.c @@ -16,7 +16,7 @@ static void do_one_sdspi_probe(int slot, int freq_khz) sdmmc_card_print_info(stdout, &card); uint8_t* buffer = heap_caps_calloc(512, 1, MALLOC_CAP_DMA); TEST_ESP_OK(sdmmc_read_sectors(&card, buffer, 0, 1)); - sdmmc_test_spi_end(&card); + sdmmc_test_spi_end(slot, &card); } TEST_CASE("sdspi probe, slot 0", "[sdspi]") diff --git a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_rw_spi.c b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_rw_spi.c index abcf9411b5..3d96bb7179 100644 --- a/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_rw_spi.c +++ b/components/sdmmc/test_apps/sdmmc_console/components/sdmmc_tests/sdmmc_test_rw_spi.c @@ -18,7 +18,7 @@ static void do_one_sdspi_perf_test(int slot, int freq_khz) sdmmc_test_spi_begin(slot, freq_khz, &card); sdmmc_card_print_info(stdout, &card); sdmmc_test_rw_performance(&card, NULL); - sdmmc_test_spi_end(&card); + sdmmc_test_spi_end(slot, &card); } TEST_CASE("sdspi read/write performance, slot 0", "[sdspi]") @@ -40,7 +40,7 @@ static void do_one_sdspi_rw_test_with_offset(int slot, int freq_khz) sdmmc_test_spi_begin(slot, freq_khz, &card); sdmmc_card_print_info(stdout, &card); sdmmc_test_rw_with_offset(&card); - sdmmc_test_spi_end(&card); + sdmmc_test_spi_end(slot, &card); } TEST_CASE("sdspi read/write performance with offset, slot 0", "[sdspi]") @@ -62,7 +62,7 @@ static void do_one_sdspi_rw_test_unaligned_buffer(int slot, int freq_khz) sdmmc_test_spi_begin(slot, freq_khz, &card); sdmmc_card_print_info(stdout, &card); sdmmc_test_rw_unaligned_buffer(&card); - sdmmc_test_spi_end(&card); + sdmmc_test_spi_end(slot, &card); } TEST_CASE("sdspi read/write using unaligned buffer, slot 0", "[sdspi]")