summaryrefslogtreecommitdiff
path: root/components/drivers
diff options
context:
space:
mode:
authorDamon <[email protected]>2026-02-01 14:02:10 +0800
committerGitHub <[email protected]>2026-02-01 14:02:10 +0800
commit88c1e6c88a99a74ad85eb08652d4e31e960c1f19 (patch)
tree72fdfc16401a443cde1c5b563aaaa3844b0914c6 /components/drivers
parent743b614875fc33257be47ab53b6c5e040ec27893 (diff)
sdio: fix missing card status polling after CMD6 in eMMC DDR mode switch
Diffstat (limited to 'components/drivers')
-rw-r--r--components/drivers/include/drivers/dev_mmcsd_core.h2
-rw-r--r--components/drivers/sdio/dev_mmc.c70
2 files changed, 70 insertions, 2 deletions
diff --git a/components/drivers/include/drivers/dev_mmcsd_core.h b/components/drivers/include/drivers/dev_mmcsd_core.h
index a541bc2e2d..0e170a6695 100644
--- a/components/drivers/include/drivers/dev_mmcsd_core.h
+++ b/components/drivers/include/drivers/dev_mmcsd_core.h
@@ -142,6 +142,8 @@ struct rt_mmcsd_req
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
+/*the programing is state*/
+#define R1_STATE_PRG 0x07
#define R1_SPI_IDLE (1 << 0)
#define R1_SPI_ERASE_RESET (1 << 1)
diff --git a/components/drivers/sdio/dev_mmc.c b/components/drivers/sdio/dev_mmc.c
index 2012d9e529..8a09aa937d 100644
--- a/components/drivers/sdio/dev_mmc.c
+++ b/components/drivers/sdio/dev_mmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2024, RT-Thread Development Team
+ * Copyright (c) 2006-2026, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -270,6 +270,64 @@ static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
return 0;
}
+/*
+ * Send Status.
+ */
+static int mmc_send_status(struct rt_mmcsd_card *card, rt_uint32_t *status, unsigned retries)
+{
+ int err;
+ struct rt_mmcsd_cmd cmd = (struct rt_mmcsd_cmd){ 0 };
+
+ cmd.busy_timeout = 0;
+ cmd.cmd_code = SEND_STATUS;
+ cmd.arg = card->rca << 16;
+ cmd.flags = RESP_R1 | CMD_AC;
+ err = mmcsd_send_cmd(card->host, &cmd, retries);
+ if (err)
+ return err;
+
+ if (status)
+ *status = cmd.resp[0];
+
+ return 0;
+}
+
+/*
+ * Poll Busy.
+ */
+static int mmc_poll_for_busy(struct rt_mmcsd_card *card, rt_uint32_t timeout_ms, unsigned retries)
+{
+ int timeout = rt_tick_from_millisecond(timeout_ms);
+ int err = 0;
+ rt_uint32_t status;
+ rt_tick_t start;
+
+ start = rt_tick_get();
+ do
+ {
+ rt_bool_t out = (int)(rt_tick_get() - start) >= timeout;
+
+ if (out)
+ {
+ LOG_E("wait card busy timeout");
+ return -RT_ETIMEOUT;
+ }
+
+ rt_thread_mdelay(1);
+
+ err = mmc_send_status(card, &status, retries);
+ if (R1_STATUS(err))
+ {
+ LOG_E("error %d requesting status", err);
+ return err;
+ }
+ }
+ while (!(status & R1_READY_FOR_DATA) ||
+ (R1_CURRENT_STATE(status) == R1_STATE_PRG));
+
+ return err;
+}
+
/**
* mmc_switch - modify EXT_CSD register
* @card: the MMC card associated with the data transfer
@@ -295,6 +353,13 @@ static int mmc_switch(struct rt_mmcsd_card *card, rt_uint8_t set,
if (err)
return err;
+ /*
+ * Poll the card status using CMD13 with a timeout of 500ms and a polling interval of 1ms.
+ */
+ err = mmc_poll_for_busy(card, 500, 3);
+ if (err)
+ return err;
+
return 0;
}
@@ -490,7 +555,7 @@ rt_err_t mmc_send_op_cond(struct rt_mmcsd_host *host,
err = -RT_ETIMEOUT;
- rt_thread_mdelay(10); //delay 10ms
+ rt_thread_mdelay(10); /* delay 10ms */
}
if (rocr && !controller_is_spi(host))
@@ -815,3 +880,4 @@ err:
return err;
}
+