From 67829713324942d92c530e6d57e61a381653b2e1 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 25 Jul 2021 17:33:26 +0200 Subject: [PATCH] sdmmc: accept CMD_DONE being is reported together with RTO SDMMC databook specifies that when an error interrupt is generated (such as RTO, DCRC, RCRC), CMD_DONE interrupt is also generated. The code used to break out of the event handling loop to wait for another interrupt event to happen, reporting CMD_DONE. However if interrupt processing was delayed, it is possible that a single event contains both RTO and CMD_DONE. Previously, CMD_DONE would not be handled, and the state machine would be stuck in SDMMC_SENDING_CMD state, until a timeout. This didn't change the outcome (err=0x107), but delayed the handling of response timeout event. Fix by not breaking out of the event handler, optionally processing the CMD_DONE interrupt if it has been reported in the same message. --- components/driver/sdmmc_transaction.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/driver/sdmmc_transaction.c b/components/driver/sdmmc_transaction.c index e406b56f6d..cb1aeae3a6 100644 --- a/components/driver/sdmmc_transaction.c +++ b/components/driver/sdmmc_transaction.c @@ -404,7 +404,9 @@ static esp_err_t process_events(sdmmc_event_t evt, sdmmc_command_t* cmd, case SDMMC_SENDING_CMD: if (mask_check_and_clear(&evt.sdmmc_status, SDMMC_CMD_ERR_MASK)) { process_command_response(orig_evt.sdmmc_status, cmd); - break; // Need to wait for the CMD_DONE interrupt + // In addition to the error interrupt, CMD_DONE will also be + // reported. It may occur immediately (in the same sdmmc_event_t) or + // be delayed until the next interrupt. } if (mask_check_and_clear(&evt.sdmmc_status, SDMMC_INTMASK_CMD_DONE)) { process_command_response(orig_evt.sdmmc_status, cmd);