From bb11f49c741cf5cf045ef915bd526de9699c863d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 10 Apr 2022 21:23:57 +0200 Subject: [PATCH] sdmmc: check for errors reported by card in sdmmc_write_sectors_dma During write operation (CMD24 or CMD25), the card can report some of the errors in the 1-byte response tokens. Other types of errors are not reported, the host has to get them by issuing CMD13. This commit adds CMD13 request at the end of write operations and reports error to the user if the card status isn't zero. --- components/sdmmc/sdmmc_cmd.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index 9b3c7280b8..6aaf7098f0 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -418,6 +418,7 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, } uint32_t status = 0; size_t count = 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)) { // TODO: add some timeout here err = sdmmc_send_cmd_send_status(card, &status); @@ -428,6 +429,27 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, ESP_LOGV(TAG, "waiting for card to become ready (%d)", count); } } + /* SPI mode: although card busy indication is based on the busy token, + * SD spec recommends that the host checks the results of programming by sending + * SEND_STATUS command. Some of the conditions reported in SEND_STATUS are not + * reported via a data error token. + */ + if (host_is_spi(card)) { + err = sdmmc_send_cmd_send_status(card, &status); + if (err != ESP_OK) { + return err; + } + if (status & SD_SPI_R2_CARD_LOCKED) { + ESP_LOGE(TAG, "%s: write failed, card is locked: r2=0x%04x", + __func__, status); + return ESP_ERR_INVALID_STATE; + } + if (status != 0) { + ESP_LOGE(TAG, "%s: card status indicates an error after write operation: r2=0x%04x", + __func__, status); + return ESP_ERR_INVALID_RESPONSE; + } + } return ESP_OK; }