|
|
@@ -51,6 +51,34 @@ void make_hw_cmd(uint32_t opcode, uint32_t arg, int timeout_ms, sdspi_hw_cmd_t *
|
|
|
hw_cmd->timeout_ms = timeout_ms;
|
|
|
}
|
|
|
|
|
|
+static void r1_response_to_err(uint8_t r1, esp_err_t *out_err)
|
|
|
+{
|
|
|
+ if (r1 & SD_SPI_R1_NO_RESPONSE) {
|
|
|
+ ESP_LOGD(TAG, "R1 response not found");
|
|
|
+ *out_err = ESP_ERR_TIMEOUT;
|
|
|
+ } else if (r1 & SD_SPI_R1_CMD_CRC_ERR) {
|
|
|
+ ESP_LOGD(TAG, "R1 response: command CRC error");
|
|
|
+ *out_err = ESP_ERR_INVALID_CRC;
|
|
|
+ } else if (r1 & SD_SPI_R1_ILLEGAL_CMD) {
|
|
|
+ ESP_LOGD(TAG, "R1 response: command not supported");
|
|
|
+ *out_err = ESP_ERR_NOT_SUPPORTED;
|
|
|
+ } else if (r1 & SD_SPI_R1_ADDR_ERR) {
|
|
|
+ ESP_LOGD(TAG, "R1 response: alignment error");
|
|
|
+ *out_err = ESP_ERR_INVALID_ARG;
|
|
|
+ } else if (r1 & SD_SPI_R1_PARAM_ERR) {
|
|
|
+ ESP_LOGD(TAG, "R1 response: size error");
|
|
|
+ *out_err = ESP_ERR_INVALID_SIZE;
|
|
|
+ } else if ((r1 & SD_SPI_R1_ERASE_RST) ||
|
|
|
+ (r1 & SD_SPI_R1_ERASE_SEQ_ERR)) {
|
|
|
+ *out_err = ESP_ERR_INVALID_STATE;
|
|
|
+ } else if (r1 & SD_SPI_R1_IDLE_STATE) {
|
|
|
+ // Idle state is handled at command layer
|
|
|
+ } else if (r1 != 0) {
|
|
|
+ ESP_LOGD(TAG, "R1 response: unexpected value 0x%02x", r1);
|
|
|
+ *out_err = ESP_ERR_INVALID_RESPONSE;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
esp_err_t sdspi_host_do_transaction(int slot, sdmmc_command_t *cmdinfo)
|
|
|
{
|
|
|
_lock_acquire(&s_lock);
|
|
|
@@ -93,21 +121,11 @@ esp_err_t sdspi_host_do_transaction(int slot, sdmmc_command_t *cmdinfo)
|
|
|
// Some errors should be reported using return code
|
|
|
if (flags & SDSPI_CMD_FLAG_RSP_R1) {
|
|
|
cmdinfo->response[0] = hw_cmd.r1;
|
|
|
- if (hw_cmd.r1 == 0xff) {
|
|
|
- // No response received at all
|
|
|
- } else if (hw_cmd.r1 & SD_SPI_R1_CMD_CRC_ERR) {
|
|
|
- ret = ESP_ERR_INVALID_CRC;
|
|
|
- } else if (hw_cmd.r1 & SD_SPI_R1_IDLE_STATE) {
|
|
|
- // Idle state is handled at command layer
|
|
|
- } else if (hw_cmd.r1 != 0) {
|
|
|
- ESP_LOGD(TAG, "Unexpected R1 response: 0x%02x", hw_cmd.r1);
|
|
|
- }
|
|
|
+ r1_response_to_err(hw_cmd.r1, &ret);
|
|
|
} else if (flags & SDSPI_CMD_FLAG_RSP_R2) {
|
|
|
cmdinfo->response[0] = (((uint32_t)hw_cmd.r1) << 8) | (hw_cmd.response[0] >> 24);
|
|
|
} else if (flags & (SDSPI_CMD_FLAG_RSP_R3 | SDSPI_CMD_FLAG_RSP_R7)) {
|
|
|
- // Drop r1 response, only copy the other 4 bytes of data
|
|
|
- // TODO: can we somehow preserve r1 response and keep upper layer
|
|
|
- // same as in SD mode?
|
|
|
+ r1_response_to_err(hw_cmd.r1, &ret);
|
|
|
cmdinfo->response[0] = __builtin_bswap32(hw_cmd.response[0]);
|
|
|
}
|
|
|
}
|