Skip to content

Commit 2f1b12e

Browse files
committed
mimxrt/sdcard: Wait for card programming completion after write.
After a write command completes, the SD card data has been transferred to the card's internal buffer but not yet programmed to flash memory. The card enters programming state during this operation. Add sdcard_cmd_send_status() to poll card status via CMD13. Add sdcard_wait_ready() to poll until READY_FOR_DATA bit is set and card returns to transfer state, with configurable timeout. Update sdcard_write() to call sdcard_wait_ready() with 5s timeout after the transfer completes, ensuring the write is fully complete before returning to the caller. Signed-off-by: Andrew Leech <[email protected]>
1 parent d955ec9 commit 2f1b12e

File tree

1 file changed

+62
-5
lines changed

1 file changed

+62
-5
lines changed

ports/mimxrt/sdcard.c

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ static bool sdcard_cmd_send_csd(mimxrt_sdcard_obj_t *card, csd_t *csd);
242242
static bool sdcard_cmd_select_card(mimxrt_sdcard_obj_t *sdcard);
243243
static bool sdcard_cmd_set_blocklen(mimxrt_sdcard_obj_t *sdcard);
244244
static bool sdcard_cmd_set_bus_width(mimxrt_sdcard_obj_t *sdcard, usdhc_data_bus_width_t bus_width);
245+
static bool sdcard_cmd_send_status(mimxrt_sdcard_obj_t *card);
246+
static bool sdcard_wait_ready(mimxrt_sdcard_obj_t *card, uint32_t timeout_ms);
245247

246248
void sdcard_card_inserted_callback(USDHC_Type *base, void *userData) {
247249
#if defined MICROPY_USDHC1 && USDHC1_AVAIL
@@ -701,6 +703,54 @@ static bool sdcard_cmd_set_bus_width(mimxrt_sdcard_obj_t *card, usdhc_data_bus_w
701703
}
702704
}
703705

706+
static bool sdcard_cmd_send_status(mimxrt_sdcard_obj_t *card) {
707+
status_t status;
708+
usdhc_command_t command = {
709+
.index = SDCARD_CMD_SEND_STATUS,
710+
.argument = (card->rca << 16),
711+
.type = kCARD_CommandTypeNormal,
712+
.responseType = kCARD_ResponseTypeR1,
713+
.responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG,
714+
};
715+
usdhc_transfer_t transfer = {
716+
.data = NULL,
717+
.command = &command,
718+
};
719+
720+
status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 250);
721+
722+
if (status == kStatus_Success) {
723+
card->status = command.response[0];
724+
return true;
725+
} else {
726+
return false;
727+
}
728+
}
729+
730+
static bool sdcard_wait_ready(mimxrt_sdcard_obj_t *card, uint32_t timeout_ms) {
731+
uint32_t start = mp_hal_ticks_ms();
732+
733+
while ((mp_hal_ticks_ms() - start) < timeout_ms) {
734+
if (!sdcard_cmd_send_status(card)) {
735+
return false;
736+
}
737+
738+
// Check if card is ready for data (bit 8) and in transfer state (bits 9-12 == 4)
739+
uint32_t card_state = SDMMC_R1_CURRENT_STATE(card->status);
740+
bool ready_for_data = (card->status & SDMMC_MASK(SDCARD_STATUS_READY_FOR_DATA_SHIFT)) != 0;
741+
742+
if (ready_for_data && (card_state == SDCARD_STATE_TRANSFER)) {
743+
return true;
744+
}
745+
746+
// Allow other MicroPython tasks to run while polling
747+
MICROPY_EVENT_POLL_HOOK;
748+
mp_hal_delay_ms(1); // Wait 1ms between polls
749+
}
750+
751+
return false; // Timeout
752+
}
753+
704754
static bool sdcard_reset(mimxrt_sdcard_obj_t *card) {
705755
card->block_len = SDCARD_DEFAULT_BLOCK_SIZE;
706756
card->rca = 0UL;
@@ -884,12 +934,19 @@ bool sdcard_write(mimxrt_sdcard_obj_t *card, uint8_t *buffer, uint32_t block_num
884934

885935
status_t status = sdcard_transfer_blocking(card->usdhc_inst, &card->handle, &transfer, 3000);
886936

887-
if (status == kStatus_Success) {
888-
card->status = command.response[0];
889-
return true;
890-
} else {
937+
if (status != kStatus_Success) {
891938
return false;
892939
}
940+
941+
card->status = command.response[0];
942+
943+
// Wait for the card to complete programming the data to flash.
944+
// The transfer above only ensures the data has been sent to the card's buffer.
945+
if (!sdcard_wait_ready(card, 5000)) {
946+
return false;
947+
}
948+
949+
return true;
893950
}
894951

895952
bool sdcard_set_active(mimxrt_sdcard_obj_t *card) {
@@ -913,7 +970,7 @@ bool sdcard_probe_bus_voltage(mimxrt_sdcard_obj_t *card) {
913970
/* Get operating voltage*/
914971
valid_voltage = (((card->oper_cond >> 31U) == 1U) ? true : false);
915972
count++;
916-
ticks_delay_us64(1000);
973+
mp_hal_delay_ms(1);
917974
}
918975

919976
if (count >= SDCARD_MAX_VOLT_TRIAL) {

0 commit comments

Comments
 (0)