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.
This commit is contained in:
Ivan Grokhotkov 2021-07-25 17:33:26 +02:00
parent 82c78db4df
commit 6782971332

View File

@ -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);