Skip to content

Commit bbbdec2

Browse files
committed
sdspi: handle error flags for R3/R7 responses
Previously error flags were only handled for R1 responses. This change moves error handling into a separate function and calls it for R1/R3/R7.
1 parent e6d6dee commit bbbdec2

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

components/driver/include/driver/sdmmc_defs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,13 @@
8686

8787
/* SPI mode R1 response type bits */
8888
#define SD_SPI_R1_IDLE_STATE (1<<0)
89+
#define SD_SPI_R1_ERASE_RST (1<<1)
90+
#define SD_SPI_R1_ILLEGAL_CMD (1<<2)
8991
#define SD_SPI_R1_CMD_CRC_ERR (1<<3)
92+
#define SD_SPI_R1_ERASE_SEQ_ERR (1<<4)
93+
#define SD_SPI_R1_ADDR_ERR (1<<5)
94+
#define SD_SPI_R1_PARAM_ERR (1<<6)
95+
#define SD_SPI_R1_NO_RESPONSE (1<<7)
9096

9197
/* 48-bit response decoding (32 bits w/o CRC) */
9298
#define MMC_R1(resp) ((resp)[0])

components/driver/sdspi_transaction.c

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,34 @@ void make_hw_cmd(uint32_t opcode, uint32_t arg, int timeout_ms, sdspi_hw_cmd_t *
5151
hw_cmd->timeout_ms = timeout_ms;
5252
}
5353

54+
static void r1_response_to_err(uint8_t r1, esp_err_t *out_err)
55+
{
56+
if (r1 & SD_SPI_R1_NO_RESPONSE) {
57+
ESP_LOGD(TAG, "R1 response not found");
58+
*out_err = ESP_ERR_TIMEOUT;
59+
} else if (r1 & SD_SPI_R1_CMD_CRC_ERR) {
60+
ESP_LOGD(TAG, "R1 response: command CRC error");
61+
*out_err = ESP_ERR_INVALID_CRC;
62+
} else if (r1 & SD_SPI_R1_ILLEGAL_CMD) {
63+
ESP_LOGD(TAG, "R1 response: command not supported");
64+
*out_err = ESP_ERR_NOT_SUPPORTED;
65+
} else if (r1 & SD_SPI_R1_ADDR_ERR) {
66+
ESP_LOGD(TAG, "R1 response: alignment error");
67+
*out_err = ESP_ERR_INVALID_ARG;
68+
} else if (r1 & SD_SPI_R1_PARAM_ERR) {
69+
ESP_LOGD(TAG, "R1 response: size error");
70+
*out_err = ESP_ERR_INVALID_SIZE;
71+
} else if ((r1 & SD_SPI_R1_ERASE_RST) ||
72+
(r1 & SD_SPI_R1_ERASE_SEQ_ERR)) {
73+
*out_err = ESP_ERR_INVALID_STATE;
74+
} else if (r1 & SD_SPI_R1_IDLE_STATE) {
75+
// Idle state is handled at command layer
76+
} else if (r1 != 0) {
77+
ESP_LOGD(TAG, "R1 response: unexpected value 0x%02x", r1);
78+
*out_err = ESP_ERR_INVALID_RESPONSE;
79+
}
80+
}
81+
5482
esp_err_t sdspi_host_do_transaction(int slot, sdmmc_command_t *cmdinfo)
5583
{
5684
_lock_acquire(&s_lock);
@@ -93,21 +121,11 @@ esp_err_t sdspi_host_do_transaction(int slot, sdmmc_command_t *cmdinfo)
93121
// Some errors should be reported using return code
94122
if (flags & SDSPI_CMD_FLAG_RSP_R1) {
95123
cmdinfo->response[0] = hw_cmd.r1;
96-
if (hw_cmd.r1 == 0xff) {
97-
// No response received at all
98-
} else if (hw_cmd.r1 & SD_SPI_R1_CMD_CRC_ERR) {
99-
ret = ESP_ERR_INVALID_CRC;
100-
} else if (hw_cmd.r1 & SD_SPI_R1_IDLE_STATE) {
101-
// Idle state is handled at command layer
102-
} else if (hw_cmd.r1 != 0) {
103-
ESP_LOGD(TAG, "Unexpected R1 response: 0x%02x", hw_cmd.r1);
104-
}
124+
r1_response_to_err(hw_cmd.r1, &ret);
105125
} else if (flags & SDSPI_CMD_FLAG_RSP_R2) {
106126
cmdinfo->response[0] = (((uint32_t)hw_cmd.r1) << 8) | (hw_cmd.response[0] >> 24);
107127
} else if (flags & (SDSPI_CMD_FLAG_RSP_R3 | SDSPI_CMD_FLAG_RSP_R7)) {
108-
// Drop r1 response, only copy the other 4 bytes of data
109-
// TODO: can we somehow preserve r1 response and keep upper layer
110-
// same as in SD mode?
128+
r1_response_to_err(hw_cmd.r1, &ret);
111129
cmdinfo->response[0] = __builtin_bswap32(hw_cmd.response[0]);
112130
}
113131
}

components/sdmmc/sdmmc_cmd.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)
112112
ESP_LOGD(TAG, "SDHC/SDXC card");
113113
host_ocr |= SD_OCR_SDHC_CAP;
114114
} else if (err == ESP_ERR_TIMEOUT) {
115-
ESP_LOGD(TAG, "CMD8 timeout; not an SDHC/SDXC card");
115+
ESP_LOGD(TAG, "CMD8 timeout; not an SD v2.00 card");
116+
} else if (is_spi && err == ESP_ERR_NOT_SUPPORTED) {
117+
ESP_LOGD(TAG, "CMD8 rejected; not an SD v2.00 card");
116118
} else {
117119
ESP_LOGE(TAG, "%s: send_if_cond (1) returned 0x%x", __func__, err);
118120
return err;

0 commit comments

Comments
 (0)