Przeglądaj źródła

test(sdmmc): support power down card on S3 emmc board

Xiao Xufeng 2 lat temu
rodzic
commit
df7e887d18

+ 31 - 9
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);
     }
 }
 

+ 1 - 1
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

+ 4 - 1
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);
 }

+ 22 - 1
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);
 }

+ 1 - 1
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]")

+ 3 - 3
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]")