]> granicus.if.org Git - esp-idf/commitdiff
sdmmc: enable host auto_stop only for certain commands
authorIvan Grokhotkov <ivan@espressif.com>
Thu, 5 Jul 2018 08:50:16 +0000 (16:50 +0800)
committerbot <bot@espressif.com>
Fri, 13 Jul 2018 03:28:10 +0000 (03:28 +0000)
Perviously host send_auto_stop flag would be set for every data
transfer over 1 block long. This caused stop commands to be sent
after CMD53, which shouldn't be done. Fix by adding an explicit list
of commands for which send_auto_stop should be set.

components/driver/include/driver/sdmmc_defs.h
components/driver/sdmmc_transaction.c

index b9b13680dd15d6786621f1695f24496a1f58b3a3..c3a63bd8d63d2497565e45ecec9cb19543b18715 100644 (file)
 #define MMC_SEND_EXT_CSD                8       /* R1 */
 #define MMC_SEND_CSD                    9       /* R2 */
 #define MMC_SEND_CID                    10      /* R1 */
+#define MMC_READ_DAT_UNTIL_STOP         11      /* R1 */
 #define MMC_STOP_TRANSMISSION           12      /* R1B */
 #define MMC_SEND_STATUS                 13      /* R1 */
 #define MMC_SET_BLOCKLEN                16      /* R1 */
 #define MMC_READ_BLOCK_SINGLE           17      /* R1 */
 #define MMC_READ_BLOCK_MULTIPLE         18      /* R1 */
+#define MMC_WRITE_DAT_UNTIL_STOP        20      /* R1 */
 #define MMC_SET_BLOCK_COUNT             23      /* R1 */
 #define MMC_WRITE_BLOCK_SINGLE          24      /* R1 */
 #define MMC_WRITE_BLOCK_MULTIPLE        25      /* R1 */
index 495d3d4a158488be061dcee8d01f2bd03a3012a4..43f74c086360a23ff6aa15332d071cb3e6e5b32e 100644 (file)
@@ -271,6 +271,16 @@ static esp_err_t handle_event(sdmmc_command_t* cmd, sdmmc_req_state_t* state,
     return ESP_OK;
 }
 
+static bool cmd_needs_auto_stop(const sdmmc_command_t* cmd)
+{
+    /* SDMMC host needs an "auto stop" flag for the following commands: */
+    return cmd->datalen > 0 &&
+           (cmd->opcode == MMC_WRITE_BLOCK_MULTIPLE ||
+            cmd->opcode == MMC_READ_BLOCK_MULTIPLE ||
+            cmd->opcode == MMC_WRITE_DAT_UNTIL_STOP ||
+            cmd->opcode == MMC_READ_DAT_UNTIL_STOP);
+}
+
 static sdmmc_hw_cmd_t make_hw_cmd(sdmmc_command_t* cmd)
 {
     sdmmc_hw_cmd_t res = { 0 };
@@ -302,12 +312,11 @@ static sdmmc_hw_cmd_t make_hw_cmd(sdmmc_command_t* cmd)
             res.rw = 1;
         }
         assert(cmd->datalen % cmd->blklen == 0);
-        if ((cmd->datalen / cmd->blklen) > 1) {
-            res.send_auto_stop = 1;
-        }
+        res.send_auto_stop = cmd_needs_auto_stop(cmd) ? 1 : 0;
     }
-    ESP_LOGV(TAG, "%s: opcode=%d, rexp=%d, crc=%d", __func__,
-            res.cmd_index, res.response_expect, res.check_response_crc);
+    ESP_LOGV(TAG, "%s: opcode=%d, rexp=%d, crc=%d, auto_stop=%d", __func__,
+            res.cmd_index, res.response_expect, res.check_response_crc,
+            res.send_auto_stop);
     return res;
 }