Merge branch 'fix/sdmmc_write_sectors_dma_always_send_cmd13_v5.0' into 'release/v5.0'

fix(sdmmc): sdmmc_write_sectors_dma always check card status after write (v5.0)

See merge request espressif/esp-idf!34344
This commit is contained in:
Jiang Jiang Jian
2025-04-14 15:04:17 +08:00
3 changed files with 31 additions and 9 deletions

View File

@@ -109,6 +109,7 @@ extern "C" {
#define MMC_R1_CURRENT_STATE_POS (9) #define MMC_R1_CURRENT_STATE_POS (9)
#define MMC_R1_CURRENT_STATE_MASK (0x1E00)/* card current state */ #define MMC_R1_CURRENT_STATE_MASK (0x1E00)/* card current state */
#define MMC_R1_CURRENT_STATE_TRAN (4) #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 */ /* SPI mode R1 response type bits */
#define SD_SPI_R1_IDLE_STATE (1<<0) #define SD_SPI_R1_IDLE_STATE (1<<0)
@@ -425,7 +426,7 @@ extern "C" {
* *
* 67 45 23 01 ef cd ab 89 * 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=4 -> result=0x00000007
* start=0 len=12 -> result=0x00000567 * start=0 len=12 -> result=0x00000567

View File

@@ -431,6 +431,11 @@ esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src,
return err; return err;
} }
static bool sdmmc_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, esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src,
size_t start_block, size_t block_count) size_t start_block, size_t block_count)
{ {
@@ -455,15 +460,23 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src,
} else { } else {
cmd.arg = start_block * block_size; cmd.arg = start_block * block_size;
} }
uint32_t status = 0;
esp_err_t err = sdmmc_send_cmd(card, &cmd); esp_err_t err = sdmmc_send_cmd(card, &cmd);
esp_err_t err_cmd13 = sdmmc_send_cmd_send_status(card, &status);
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err); if (err_cmd13 == ESP_OK) {
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, status 0x%" PRIx32, __func__, err, status);
} else {
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, failed to get status (0x%x)", __func__, err, err_cmd13);
}
return err; return err;
} }
uint32_t status = 0;
size_t count = 0; size_t count = 0;
/* SD mode: wait for the card to become idle based on R1 status */ /* 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) && !sdmmc_ready_for_data(status)) {
// TODO: add some timeout here // TODO: add some timeout here
err = sdmmc_send_cmd_send_status(card, &status); err = sdmmc_send_cmd_send_status(card, &status);
if (err != ESP_OK) { if (err != ESP_OK) {
@@ -551,14 +564,22 @@ esp_err_t sdmmc_read_sectors_dma(sdmmc_card_t* card, void* dst,
} else { } else {
cmd.arg = start_block * block_size; cmd.arg = start_block * block_size;
} }
uint32_t status = 0;
esp_err_t err = sdmmc_send_cmd(card, &cmd); esp_err_t err = sdmmc_send_cmd(card, &cmd);
esp_err_t err_cmd13 = sdmmc_send_cmd_send_status(card, &status);
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err); if (err_cmd13 == ESP_OK) {
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, status 0x%" PRIx32, __func__, err, status);
} else {
ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, failed to get status (0x%x)", __func__, err, err_cmd13);
}
return err; return err;
} }
uint32_t status = 0;
size_t count = 0; size_t count = 0;
while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) { while (!host_is_spi(card) && !sdmmc_ready_for_data(status)) {
// TODO: add some timeout here // TODO: add some timeout here
err = sdmmc_send_cmd_send_status(card, &status); err = sdmmc_send_cmd_send_status(card, &status);
if (err != ESP_OK) { if (err != ESP_OK) {

View File

@@ -263,8 +263,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); ESP_LOGE(TAG, "%s: send_status returned 0x%x", __func__, err);
goto out; 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__); ESP_LOGE(TAG, "%s: card not in transfer state", __func__);
err = ESP_ERR_INVALID_STATE; err = ESP_ERR_INVALID_STATE;
goto out; goto out;