Skip to content

Commit 12398c0

Browse files
committed
Merge branch 'fix/sdmmc_write_sectors_dma_always_send_cmd13' into 'master'
fix(sdmmc): sdmmc_write_sectors_dma always check card status after write Closes IDF-9632 See merge request espressif/esp-idf!34132
2 parents 9a3427f + 9c7609a commit 12398c0

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

components/sdmmc/include/sd_protocol_defs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ extern "C" {
108108
#define MMC_R1_CURRENT_STATE_POS (9)
109109
#define MMC_R1_CURRENT_STATE_MASK (0x1E00)/* card current state */
110110
#define MMC_R1_CURRENT_STATE_TRAN (4)
111+
#define MMC_R1_CURRENT_STATE_STATUS(status) (((status) & MMC_R1_CURRENT_STATE_MASK) >> MMC_R1_CURRENT_STATE_POS)
111112

112113
/* SPI mode R1 response type bits */
113114
#define SD_SPI_R1_IDLE_STATE (1<<0)
@@ -424,7 +425,7 @@ extern "C" {
424425
*
425426
* 67 45 23 01 ef cd ab 89
426427
*
427-
* MMC_RSP_BITS will extact bits as follows:
428+
* MMC_RSP_BITS will extract bits as follows:
428429
*
429430
* start=0 len=4 -> result=0x00000007
430431
* start=0 len=12 -> result=0x00000567

components/sdmmc/sdmmc_cmd.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,11 @@ esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src,
459459
return err;
460460
}
461461

462+
static bool sdmmc_ready_for_data(uint32_t status)
463+
{
464+
return (status & MMC_R1_READY_FOR_DATA) && (MMC_R1_CURRENT_STATE_STATUS(status) == MMC_R1_CURRENT_STATE_TRAN);
465+
}
466+
462467
esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src,
463468
size_t start_block, size_t block_count, size_t buffer_len)
464469
{
@@ -484,18 +489,26 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src,
484489
} else {
485490
cmd.arg = start_block * block_size;
486491
}
492+
493+
uint32_t status = 0;
487494
esp_err_t err = sdmmc_send_cmd(card, &cmd);
495+
esp_err_t err_cmd13 = sdmmc_send_cmd_send_status(card, &status);
496+
488497
if (err != ESP_OK) {
489-
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err);
498+
if (err_cmd13 == ESP_OK) {
499+
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, status 0x%" PRIx32, __func__, err, status);
500+
} else {
501+
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, failed to get status (0x%x)", __func__, err, err_cmd13);
502+
}
490503
return err;
491504
}
492-
uint32_t status = 0;
505+
493506
size_t count = 0;
494507
int64_t yield_delay_us = 100 * 1000; // initially 100ms
495508
int64_t t0 = esp_timer_get_time();
496509
int64_t t1 = 0;
497510
/* SD mode: wait for the card to become idle based on R1 status */
498-
while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) {
511+
while (!host_is_spi(card) && !sdmmc_ready_for_data(status)) {
499512
t1 = esp_timer_get_time();
500513
if (t1 - t0 > SDMMC_READY_FOR_DATA_TIMEOUT_US) {
501514
ESP_LOGE(TAG, "write sectors dma - timeout");
@@ -606,18 +619,26 @@ esp_err_t sdmmc_read_sectors_dma(sdmmc_card_t* card, void* dst,
606619
} else {
607620
cmd.arg = start_block * block_size;
608621
}
622+
623+
uint32_t status = 0;
609624
esp_err_t err = sdmmc_send_cmd(card, &cmd);
625+
esp_err_t err_cmd13 = sdmmc_send_cmd_send_status(card, &status);
626+
610627
if (err != ESP_OK) {
611-
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err);
628+
if (err_cmd13 == ESP_OK) {
629+
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, status 0x%" PRIx32, __func__, err, status);
630+
} else {
631+
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, failed to get status (0x%x)", __func__, err, err_cmd13);
632+
}
612633
return err;
613634
}
614-
uint32_t status = 0;
635+
615636
size_t count = 0;
616637
int64_t yield_delay_us = 100 * 1000; // initially 100ms
617638
int64_t t0 = esp_timer_get_time();
618639
int64_t t1 = 0;
619640
/* SD mode: wait for the card to become idle based on R1 status */
620-
while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) {
641+
while (!host_is_spi(card) && !sdmmc_ready_for_data(status)) {
621642
t1 = esp_timer_get_time();
622643
if (t1 - t0 > SDMMC_READY_FOR_DATA_TIMEOUT_US) {
623644
ESP_LOGE(TAG, "read sectors dma - timeout");

components/sdmmc/sdmmc_mmc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ esp_err_t sdmmc_init_mmc_check_ext_csd(sdmmc_card_t* card)
272272
ESP_LOGE(TAG, "%s: send_status returned 0x%x", __func__, err);
273273
goto out;
274274
}
275-
status = ((status & MMC_R1_CURRENT_STATE_MASK) >> MMC_R1_CURRENT_STATE_POS);
276-
if (status != MMC_R1_CURRENT_STATE_TRAN) {
275+
276+
if (MMC_R1_CURRENT_STATE_STATUS(status) != MMC_R1_CURRENT_STATE_TRAN) {
277277
ESP_LOGE(TAG, "%s: card not in transfer state", __func__);
278278
err = ESP_ERR_INVALID_STATE;
279279
goto out;

0 commit comments

Comments
 (0)