#define GPIO_UNUSED 0xff //!< Flag indicating that CD/WP is unused\r
/// Size of the buffer returned by get_block_buf\r
#define SDSPI_BLOCK_BUF_SIZE (SDSPI_MAX_DATA_LEN + 4)\r
+/// Maximum number of dummy bytes between the request and response (minimum is 1)\r
+#define SDSPI_RESPONSE_MAX_DELAY 8\r
\r
\r
/// Structure containing run time configuration for a single SD slot\r
.rx_buffer = cmd\r
};\r
esp_err_t ret = spi_device_transmit(spi_handle(slot), &t);\r
+ if (cmd->cmd_index == MMC_STOP_TRANSMISSION) {\r
+ /* response is a stuff byte from previous transfer, ignore it */\r
+ cmd->r1 = 0xff;\r
+ }\r
+ int response_delay_bytes = SDSPI_RESPONSE_MAX_DELAY;\r
+ while ((cmd->r1 & SD_SPI_R1_NO_RESPONSE) != 0 && response_delay_bytes-- > 0) {\r
+ spi_transaction_t* t = get_transaction(slot);\r
+ *t = (spi_transaction_t) {\r
+ .flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,\r
+ .length = 8,\r
+ };\r
+ t->tx_data[0] = 0xff;\r
+ ret = spi_device_transmit(spi_handle(slot), t);\r
+ uint8_t r1 = t->rx_data[0];\r
+ release_transaction(slot);\r
+ if (ret != ESP_OK) {\r
+ return ret;\r
+ }\r
+ cmd->r1 = r1;\r
+ }\r
+ if (cmd->r1 & SD_SPI_R1_NO_RESPONSE) {\r
+ ESP_LOGD(TAG, "%s: no response token found", __func__);\r
+ return ESP_ERR_TIMEOUT;\r
+ }\r
return ret;\r
}\r
\r
* indicating the start of the next block. Actual scanning is done by\r
* setting pre_scan_data_ptr to point to these last 2 bytes, and setting\r
* pre_scan_data_size = 2, then going to step 2 to receive the next block.\r
+ * When the final block is being received, the number of extra bytes is 2\r
+ * (only for CRC), because we don't need to wait for start token of the\r
+ * next block, and some cards are getting confused by these two extra bytes.\r
*\r
* With this approach the delay between blocks of a multi-block transfer is\r
* ~95 microseconds, out of which 35 microseconds are spend doing the CRC check.\r
{\r
bool need_stop_command = rx_length > SDSPI_MAX_DATA_LEN;\r
spi_transaction_t* t_command = get_transaction(slot);\r
- const int cmd_extra_bytes = 8;\r
*t_command = (spi_transaction_t) {\r
- .length = (SDSPI_CMD_R1_SIZE + cmd_extra_bytes) * 8,\r
+ .length = (SDSPI_CMD_R1_SIZE + SDSPI_RESPONSE_MAX_DELAY) * 8,\r
.tx_buffer = cmd,\r
.rx_buffer = cmd,\r
};\r
release_transaction(slot);\r
\r
uint8_t* cmd_u8 = (uint8_t*) cmd;\r
- size_t pre_scan_data_size = cmd_extra_bytes;\r
+ size_t pre_scan_data_size = SDSPI_RESPONSE_MAX_DELAY;\r
uint8_t* pre_scan_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;\r
\r
/* R1 response is delayed by 1-8 bytes from the request.\r
}\r
\r
// receive actual data\r
- const size_t receive_extra_bytes = 4;\r
+ const size_t receive_extra_bytes = (rx_length > SDSPI_MAX_DATA_LEN) ? 4 : 2;\r
memset(rx_data, 0xff, will_receive + receive_extra_bytes);\r
spi_transaction_t* t_data = get_transaction(slot);\r
*t_data = (spi_transaction_t) {\r
if (ret != ESP_OK) {\r
return ret;\r
}\r
+ if (stop_cmd.r1 != 0) {\r
+ ESP_LOGD(TAG, "%s: STOP_TRANSMISSION response 0x%02x", __func__, stop_cmd.r1);\r
+ }\r
spi_transaction_t* t_poll = get_transaction(slot);\r
ret = poll_busy(slot, t_poll, cmd->timeout_ms);\r
release_transaction(slot);\r