From 3ad98984e9580c32da30e6525ff6e00a196c0a5f Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 10 Apr 2022 21:45:01 +0200 Subject: [PATCH] driver: sdspi: add support for R1b response Same as R1 but with busy indication polling --- components/driver/sdspi_host.c | 12 ++++++++++-- components/driver/sdspi_private.h | 15 ++++++++------- components/driver/sdspi_transaction.c | 4 +++- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/components/driver/sdspi_host.c b/components/driver/sdspi_host.c index 5a4424b0bd..fd9749a33d 100644 --- a/components/driver/sdspi_host.c +++ b/components/driver/sdspi_host.c @@ -482,7 +482,8 @@ static esp_err_t start_command_default(slot_info_t *slot, int flags, sdspi_hw_cm { size_t cmd_size = SDSPI_CMD_R1_SIZE; if ((flags & SDSPI_CMD_FLAG_RSP_R1) || - (flags & SDSPI_CMD_FLAG_NORSP)) { + (flags & SDSPI_CMD_FLAG_NORSP) || + (flags & SDSPI_CMD_FLAG_RSP_R1B )) { cmd_size = SDSPI_CMD_R1_SIZE; } else if (flags & SDSPI_CMD_FLAG_RSP_R2) { cmd_size = SDSPI_CMD_R2_SIZE; @@ -522,6 +523,13 @@ static esp_err_t start_command_default(slot_info_t *slot, int flags, sdspi_hw_cm ret = shift_cmd_response(cmd, cmd_size); if (ret != ESP_OK) return ESP_ERR_TIMEOUT; + if (flags & SDSPI_CMD_FLAG_RSP_R1B) { + ret = poll_busy(slot, cmd->timeout_ms, no_use_polling); + if (ret != ESP_OK) { + return ret; + } + } + return ESP_OK; } @@ -777,7 +785,7 @@ static esp_err_t start_command_read_blocks(slot_info_t *slot, sdspi_hw_cmd_t *cm // card to process it sdspi_hw_cmd_t stop_cmd; make_hw_cmd(MMC_STOP_TRANSMISSION, 0, cmd->timeout_ms, &stop_cmd); - ret = start_command_default(slot, SDSPI_CMD_FLAG_RSP_R1, &stop_cmd); + ret = start_command_default(slot, SDSPI_CMD_FLAG_RSP_R1B, &stop_cmd); if (ret != ESP_OK) { return ret; } diff --git a/components/driver/sdspi_private.h b/components/driver/sdspi_private.h index 2acf853bd1..e78756b4c2 100644 --- a/components/driver/sdspi_private.h +++ b/components/driver/sdspi_private.h @@ -85,13 +85,14 @@ typedef struct { #define SDSPI_CMD_FLAG_DATA BIT(0) //!< Command has data transfer #define SDSPI_CMD_FLAG_WRITE BIT(1) //!< Data is written to the card #define SDSPI_CMD_FLAG_RSP_R1 BIT(2) //!< Response format R1 (1 byte) -#define SDSPI_CMD_FLAG_RSP_R2 BIT(3) //!< Response format R2 (2 bytes) -#define SDSPI_CMD_FLAG_RSP_R3 BIT(4) //!< Response format R3 (5 bytes) -#define SDSPI_CMD_FLAG_RSP_R4 BIT(5) //!< Response format R4 (5 bytes) -#define SDSPI_CMD_FLAG_RSP_R5 BIT(6) //!< Response format R5 (2 bytes) -#define SDSPI_CMD_FLAG_RSP_R7 BIT(7) //!< Response format R7 (5 bytes) -#define SDSPI_CMD_FLAG_NORSP BIT(8) //!< Don't expect response (used when sending CMD0 first time). -#define SDSPI_CMD_FLAG_MULTI_BLK BIT(9) //!< For the write multiblock commands, the start token should be different +#define SDSPI_CMD_FLAG_RSP_R1B BIT(3) //!< Response format R1 (1 byte), with busy polling +#define SDSPI_CMD_FLAG_RSP_R2 BIT(4) //!< Response format R2 (2 bytes) +#define SDSPI_CMD_FLAG_RSP_R3 BIT(5) //!< Response format R3 (5 bytes) +#define SDSPI_CMD_FLAG_RSP_R4 BIT(6) //!< Response format R4 (5 bytes) +#define SDSPI_CMD_FLAG_RSP_R5 BIT(7) //!< Response format R5 (2 bytes) +#define SDSPI_CMD_FLAG_RSP_R7 BIT(8) //!< Response format R7 (5 bytes) +#define SDSPI_CMD_FLAG_NORSP BIT(9) //!< Don't expect response (used when sending CMD0 first time). +#define SDSPI_CMD_FLAG_MULTI_BLK BIT(10) //!< For the write multiblock commands, the start token should be different #define SDSPI_MAX_DATA_LEN 512 //!< Max size of single block transfer diff --git a/components/driver/sdspi_transaction.c b/components/driver/sdspi_transaction.c index 3fdeb73a4e..583c6cfc35 100644 --- a/components/driver/sdspi_transaction.c +++ b/components/driver/sdspi_transaction.c @@ -140,6 +140,8 @@ esp_err_t sdspi_host_do_transaction(int slot, sdmmc_command_t *cmdinfo) if (cmdinfo->arg & SD_ARG_CMD53_WRITE) flags |= SDSPI_CMD_FLAG_WRITE; // The CMD53 can assign block mode in the arg when the length is exactly 512 bytes if (cmdinfo->arg & SD_ARG_CMD53_BLOCK_MODE) flags |= SDSPI_CMD_FLAG_MULTI_BLK; + } else if (!s_app_cmd && (cmdinfo->opcode == MMC_ERASE || cmdinfo->opcode == MMC_STOP_TRANSMISSION)) { + flags |= SDSPI_CMD_FLAG_RSP_R1B; } else { flags |= SDSPI_CMD_FLAG_RSP_R1; } @@ -152,7 +154,7 @@ esp_err_t sdspi_host_do_transaction(int slot, sdmmc_command_t *cmdinfo) if (ret == ESP_OK) { ESP_LOGV(TAG, "r1 = 0x%02x hw_cmd.r[0]=0x%08x", hw_cmd.r1, hw_cmd.response[0]); // Some errors should be reported using return code - if (flags & SDSPI_CMD_FLAG_RSP_R1) { + if (flags & (SDSPI_CMD_FLAG_RSP_R1 | SDSPI_CMD_FLAG_RSP_R1B)) { cmdinfo->response[0] = hw_cmd.r1; r1_response_to_err(hw_cmd.r1, cmdinfo->opcode, &ret); } else if (flags & SDSPI_CMD_FLAG_RSP_R2) {