From a44a659b0fbd12e5ee182f8be652fe4827befc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Tue, 15 Oct 2024 22:28:26 +0200 Subject: [PATCH] fix(sdmmc): Improve SD card state checking after write/read command --- components/driver/sdmmc/include/driver/sdmmc_defs.h | 3 ++- components/sdmmc/sdmmc_cmd.c | 9 +++++++-- components/sdmmc/sdmmc_mmc.c | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/components/driver/sdmmc/include/driver/sdmmc_defs.h b/components/driver/sdmmc/include/driver/sdmmc_defs.h index 56cff2407e..ee396efb0c 100644 --- a/components/driver/sdmmc/include/driver/sdmmc_defs.h +++ b/components/driver/sdmmc/include/driver/sdmmc_defs.h @@ -109,6 +109,7 @@ extern "C" { #define MMC_R1_CURRENT_STATE_POS (9) #define MMC_R1_CURRENT_STATE_MASK (0x1E00)/* card current state */ #define MMC_R1_CURRENT_STATE_TRAN (4) +#define MMC_R1_CURRENT_STATE_STATUS(status) ((status & MMC_R1_CURRENT_STATE_MASK) >> MMC_R1_CURRENT_STATE_POS) /* SPI mode R1 response type bits */ #define SD_SPI_R1_IDLE_STATE (1<<0) @@ -425,7 +426,7 @@ extern "C" { * * 67 45 23 01 ef cd ab 89 * - * MMC_RSP_BITS will extact bits as follows: + * MMC_RSP_BITS will extract bits as follows: * * start=0 len=4 -> result=0x00000007 * start=0 len=12 -> result=0x00000567 diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index a4d1b33884..7e555da1ea 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -445,6 +445,11 @@ esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src, return err; } +static bool mmc_ready_for_data(uint32_t status) +{ + return (status & MMC_R1_READY_FOR_DATA) && (MMC_R1_CURRENT_STATE_STATUS(status) == MMC_R1_CURRENT_STATE_TRAN); +} + esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, size_t start_block, size_t block_count, size_t buffer_len) { @@ -481,7 +486,7 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, int64_t t0 = esp_timer_get_time(); int64_t t1 = 0; /* SD mode: wait for the card to become idle based on R1 status */ - while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) { + while (!host_is_spi(card) && !mmc_ready_for_data(status)) { t1 = esp_timer_get_time(); if (t1 - t0 > SDMMC_READY_FOR_DATA_TIMEOUT_US) { ESP_LOGE(TAG, "write sectors dma - timeout"); @@ -597,7 +602,7 @@ esp_err_t sdmmc_read_sectors_dma(sdmmc_card_t* card, void* dst, int64_t t0 = esp_timer_get_time(); int64_t t1 = 0; /* SD mode: wait for the card to become idle based on R1 status */ - while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) { + while (!host_is_spi(card) && !mmc_ready_for_data(status)) { t1 = esp_timer_get_time(); if (t1 - t0 > SDMMC_READY_FOR_DATA_TIMEOUT_US) { ESP_LOGE(TAG, "read sectors dma - timeout"); diff --git a/components/sdmmc/sdmmc_mmc.c b/components/sdmmc/sdmmc_mmc.c index 4d0c756f0d..54e609f54d 100644 --- a/components/sdmmc/sdmmc_mmc.c +++ b/components/sdmmc/sdmmc_mmc.c @@ -268,8 +268,8 @@ esp_err_t sdmmc_init_mmc_check_ext_csd(sdmmc_card_t* card) ESP_LOGE(TAG, "%s: send_status returned 0x%x", __func__, err); goto out; } - status = ((status & MMC_R1_CURRENT_STATE_MASK) >> MMC_R1_CURRENT_STATE_POS); - if (status != MMC_R1_CURRENT_STATE_TRAN) { + + if (MMC_R1_CURRENT_STATE_STATUS(status) != MMC_R1_CURRENT_STATE_TRAN) { ESP_LOGE(TAG, "%s: card not in transfer state", __func__); err = ESP_ERR_INVALID_STATE; goto out;