Skip to content

Commit 7b68e74

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 daaaaef commit 7b68e74

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
@@ -704,6 +706,54 @@ static bool sdcard_cmd_set_bus_width(mimxrt_sdcard_obj_t *card, usdhc_data_bus_w
704706
}
705707
}
706708

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

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

890-
if (status == kStatus_Success) {
891-
card->status = command.response[0];
892-
return true;
893-
} else {
940+
if (status != kStatus_Success) {
894941
return false;
895942
}
943+
944+
card->status = command.response[0];
945+
946+
// Wait for the card to complete programming the data to flash.
947+
// The transfer above only ensures the data has been sent to the card's buffer.
948+
if (!sdcard_wait_ready(card, 5000)) {
949+
return false;
950+
}
951+
952+
return true;
896953
}
897954

898955
bool sdcard_set_active(mimxrt_sdcard_obj_t *card) {
@@ -916,7 +973,7 @@ bool sdcard_probe_bus_voltage(mimxrt_sdcard_obj_t *card) {
916973
/* Get operating voltage*/
917974
valid_voltage = (((card->oper_cond >> 31U) == 1U) ? true : false);
918975
count++;
919-
ticks_delay_us64(1000);
976+
mp_hal_delay_ms(1);
920977
}
921978

922979
if (count >= SDCARD_MAX_VOLT_TRIAL) {

0 commit comments

Comments
 (0)