From e0f1524c86c1a130f2121e192744a8fa1296e3cf Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 23 Apr 2018 14:47:00 +0800 Subject: [PATCH] sdmmc: add tests for CD and WP pins for SD and SPI mode --- components/sdmmc/test/test_sd.c | 115 ++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/components/sdmmc/test/test_sd.c b/components/sdmmc/test/test_sd.c index 0fbe6c5aee..33b3890ccd 100644 --- a/components/sdmmc/test/test_sd.c +++ b/components/sdmmc/test/test_sd.c @@ -20,11 +20,13 @@ #include "driver/sdmmc_host.h" #include "driver/sdspi_host.h" #include "driver/sdmmc_defs.h" +#include "soc/gpio_reg.h" #include "sdmmc_cmd.h" #include "esp_log.h" #include "esp_heap_caps.h" #include #include +#include TEST_CASE("MMC_RSP_BITS", "[sd]") { @@ -239,3 +241,116 @@ TEST_CASE("reads and writes with an unaligned buffer", "[sd][test_env=UT_T1_SDMO free(card); TEST_ESP_OK(sdmmc_host_deinit()); } + +static void test_cd_input(int gpio_cd_num, const sdmmc_host_t* config) +{ + sdmmc_card_t* card = malloc(sizeof(sdmmc_card_t)); + TEST_ASSERT_NOT_NULL(card); + + // SDMMC host should have configured CD as input. + // Enable output as well (not using the driver, to avoid touching input + // enable bits). + gpio_matrix_out(gpio_cd_num, SIG_GPIO_OUT_IDX, false, false); + REG_WRITE(GPIO_ENABLE_W1TS_REG, BIT(gpio_cd_num)); + + // Check that card initialization fails if CD is high + REG_WRITE(GPIO_OUT_W1TS_REG, BIT(gpio_cd_num)); + usleep(100); + TEST_ESP_ERR(ESP_ERR_NOT_FOUND, sdmmc_card_init(config, card)); + + // Check that card initialization succeeds if CD is low + REG_WRITE(GPIO_OUT_W1TC_REG, BIT(gpio_cd_num)); + usleep(100); + TEST_ESP_OK(sdmmc_card_init(config, card)); + + free(card); +} + +TEST_CASE("CD input works in SD mode", "[sd][test_env=UT_T1_SDMODE]") +{ + sdmmc_host_t config = SDMMC_HOST_DEFAULT(); + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + const int gpio_cd_num = 5; + slot_config.gpio_cd = gpio_cd_num; + TEST_ESP_OK(sdmmc_host_init()); + TEST_ESP_OK(sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config)); + + test_cd_input(gpio_cd_num, &config); + + TEST_ESP_OK(sdmmc_host_deinit()); +} + +TEST_CASE("CD input works in SPI mode", "[sd][test_env=UT_T1_SPIMODE]") +{ + sdmmc_host_t config = SDSPI_HOST_DEFAULT(); + sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT(); + const int gpio_cd_num = 5; + slot_config.gpio_cd = gpio_cd_num; + TEST_ESP_OK(sdspi_host_init()); + TEST_ESP_OK(sdspi_host_init_slot(config.slot, &slot_config)); + + test_cd_input(gpio_cd_num, &config); + + TEST_ESP_OK(sdspi_host_deinit()); +} + +static void test_wp_input(int gpio_wp_num, const sdmmc_host_t* config) +{ + sdmmc_card_t* card = malloc(sizeof(sdmmc_card_t)); + TEST_ASSERT_NOT_NULL(card); + + // SDMMC host should have configured WP as input. + // Enable output as well (not using the driver, to avoid touching input + // enable bits). + gpio_matrix_out(gpio_wp_num, SIG_GPIO_OUT_IDX, false, false); + REG_WRITE(GPIO_ENABLE_W1TS_REG, BIT(gpio_wp_num)); + + // Check that the card can be initialized with WP low + REG_WRITE(GPIO_OUT_W1TC_REG, BIT(gpio_wp_num)); + TEST_ESP_OK(sdmmc_card_init(config, card)); + + uint32_t* data = heap_caps_calloc(1, 512, MALLOC_CAP_DMA); + + // Check that card write succeeds if WP is high + REG_WRITE(GPIO_OUT_W1TS_REG, BIT(gpio_wp_num)); + usleep(100); + TEST_ESP_OK(sdmmc_write_sectors(card, &data, 0, 1)); + + // Check that write fails if WP is low + REG_WRITE(GPIO_OUT_W1TC_REG, BIT(gpio_wp_num)); + usleep(100); + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, sdmmc_write_sectors(card, &data, 0, 1)); + // ...but reads still work + TEST_ESP_OK(sdmmc_read_sectors(card, &data, 0, 1)); + + free(data); + free(card); +} + +TEST_CASE("WP input works in SD mode", "[sd][test_env=UT_T1_SDMODE]") +{ + sdmmc_host_t config = SDMMC_HOST_DEFAULT(); + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + const int gpio_wp_num = 5; + slot_config.gpio_wp = gpio_wp_num; + TEST_ESP_OK(sdmmc_host_init()); + TEST_ESP_OK(sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config)); + + test_wp_input(gpio_wp_num, &config); + + TEST_ESP_OK(sdmmc_host_deinit()); +} + +TEST_CASE("WP input works in SPI mode", "[sd][test_env=UT_T1_SPIMODE]") +{ + sdmmc_host_t config = SDSPI_HOST_DEFAULT(); + sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT(); + const int gpio_wp_num = 5; + slot_config.gpio_wp = gpio_wp_num; + TEST_ESP_OK(sdspi_host_init()); + TEST_ESP_OK(sdspi_host_init_slot(config.slot, &slot_config)); + + test_wp_input(gpio_wp_num, &config); + + TEST_ESP_OK(sdspi_host_deinit()); +}