Просмотр исходного кода

driver: sdspi: add support for R1b response

Same as R1 but with busy indication polling
Ivan Grokhotkov 3 лет назад
Родитель
Сommit
3ad98984e9

+ 10 - 2
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;
         }

+ 8 - 7
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
 

+ 3 - 1
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) {