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

This commit is contained in:
Xiao Xufeng
2023-07-18 19:15:00 +08:00
parent c7d8b06fd2
commit df7e887d18
6 changed files with 62 additions and 16 deletions

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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]")

View File

@@ -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]")