1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdbool.h>
11 #include <stddef.h>
12 #include <sys/param.h>
13 #include "esp_log.h"
14 #include "esp_heap_caps.h"
15 #include "driver/gpio.h"
16 #include "driver/sdmmc_defs.h"
17 #include "driver/sdspi_host.h"
18 #include "sdspi_private.h"
19 #include "sdspi_crc.h"
20 #include "esp_timer.h"
21 #include "freertos/FreeRTOS.h"
22 #include "freertos/semphr.h"
23 #include "soc/soc_memory_layout.h"
24 
25 
26 /// Max number of transactions in flight (used in start_command_write_blocks)
27 #define SDSPI_TRANSACTION_COUNT 4
28 #define SDSPI_MOSI_IDLE_VAL     0xff    //!< Data value which causes MOSI to stay high
29 #define GPIO_UNUSED 0xff                //!< Flag indicating that CD/WP is unused
30 /// Size of the buffer returned by get_block_buf
31 #define SDSPI_BLOCK_BUF_SIZE    (SDSPI_MAX_DATA_LEN + 4)
32 /// Maximum number of dummy bytes between the request and response (minimum is 1)
33 #define SDSPI_RESPONSE_MAX_DELAY  8
34 
35 /**
36  * @brief Structure containing run time configuration for a single SD slot
37  *
38  * The slot info is referenced to by an sdspi_dev_handle_t (alias int). The handle may be the raw
39  * pointer to the slot info itself (force converted to, new API in IDFv4.2), or the index of the
40  * s_slot array (deprecated API). Returning the raw pointer to the caller instead of storing it
41  * locally can save some static memory.
42  */
43 typedef struct {
44     spi_host_device_t   host_id; //!< SPI host id.
45     spi_device_handle_t spi_handle; //!< SPI device handle, used for transactions
46     uint8_t gpio_cs;            //!< CS GPIO, or GPIO_UNUSED
47     uint8_t gpio_cd;            //!< Card detect GPIO, or GPIO_UNUSED
48     uint8_t gpio_wp;            //!< Write protect GPIO, or GPIO_UNUSED
49     uint8_t gpio_int;            //!< Write protect GPIO, or GPIO_UNUSED
50     /// Set to 1 if the higher layer has asked the card to enable CRC checks
51     uint8_t data_crc_enabled : 1;
52     /// Intermediate buffer used when application buffer is not in DMA memory;
53     /// allocated on demand, SDSPI_BLOCK_BUF_SIZE bytes long. May be zero.
54     uint8_t* block_buf;
55     /// semaphore of gpio interrupt
56     SemaphoreHandle_t   semphr_int;
57 } slot_info_t;
58 
59 // Reserved for old API to be back-compatible
60 static slot_info_t *s_slots[SOC_SPI_PERIPH_NUM] = {};
61 static const char *TAG = "sdspi_host";
62 
63 static const bool use_polling = true;
64 static const bool no_use_polling = true;
65 
66 
67 /// Functions to send out different kinds of commands
68 static esp_err_t start_command_read_blocks(slot_info_t *slot, sdspi_hw_cmd_t *cmd,
69         uint8_t *data, uint32_t rx_length, bool need_stop_command);
70 
71 static esp_err_t start_command_write_blocks(slot_info_t *slot, sdspi_hw_cmd_t *cmd,
72         const uint8_t *data, uint32_t tx_length, bool multi_block, bool stop_trans);
73 
74 static esp_err_t start_command_default(slot_info_t *slot, int flags, sdspi_hw_cmd_t *cmd);
75 
76 static esp_err_t shift_cmd_response(sdspi_hw_cmd_t *cmd, int sent_bytes);
77 
78 static esp_err_t poll_busy(slot_info_t *slot, int timeout_ms, bool polling);
79 
80 /// A few helper functions
81 
82 /// Map handle to pointer of slot information
get_slot_info(sdspi_dev_handle_t handle)83 static slot_info_t* get_slot_info(sdspi_dev_handle_t handle)
84 {
85     if ((uint32_t) handle < SOC_SPI_PERIPH_NUM) {
86         return s_slots[handle];
87     } else {
88         return (slot_info_t *) handle;
89     }
90 }
91 
92 /// Store slot information (if possible) and return corresponding handle
store_slot_info(slot_info_t * slot)93 static sdspi_dev_handle_t store_slot_info(slot_info_t *slot)
94 {
95     /*
96      * To be back-compatible, the first device of each bus will always be stored locally, and
97      * referenced to by the handle `host_id`, otherwise the new API return the raw pointer to the
98      * slot info as the handle, to save some static memory.
99      */
100     if (s_slots[slot->host_id] == NULL) {
101         s_slots[slot->host_id] = slot;
102         return slot->host_id;
103     } else {
104         return (sdspi_dev_handle_t)slot;
105     }
106 }
107 
108 /// Get the slot info for a specific handle, and remove the local reference (if exist).
remove_slot_info(sdspi_dev_handle_t handle)109 static slot_info_t* remove_slot_info(sdspi_dev_handle_t handle)
110 {
111     if ((uint32_t) handle < SOC_SPI_PERIPH_NUM) {
112         slot_info_t* slot = s_slots[handle];
113         s_slots[handle] = NULL;
114         return slot;
115     } else {
116         return (slot_info_t *) handle;
117     }
118 }
119 
120 /// Set CS high for given slot
cs_high(slot_info_t * slot)121 static void cs_high(slot_info_t *slot)
122 {
123     if (slot->gpio_cs != GPIO_UNUSED) {
124         gpio_set_level(slot->gpio_cs, 1);
125     }
126 }
127 
128 /// Set CS low for given slot
cs_low(slot_info_t * slot)129 static void cs_low(slot_info_t *slot)
130 {
131     if (slot->gpio_cs != GPIO_UNUSED) {
132         gpio_set_level(slot->gpio_cs, 0);
133     }
134 }
135 
136 /// Return true if WP pin is configured and is low
card_write_protected(slot_info_t * slot)137 static bool card_write_protected(slot_info_t *slot)
138 {
139     if (slot->gpio_wp == GPIO_UNUSED) {
140         return false;
141     }
142     return gpio_get_level(slot->gpio_wp) == 0;
143 }
144 
145 /// Return true if CD pin is configured and is high
card_missing(slot_info_t * slot)146 static bool card_missing(slot_info_t *slot)
147 {
148     if (slot->gpio_cd == GPIO_UNUSED) {
149         return false;
150     }
151     return gpio_get_level(slot->gpio_cd) == 1;
152 }
153 
154 /// Get pointer to a block of DMA memory, allocate if necessary.
155 /// This is used if the application provided buffer is not in DMA capable memory.
get_block_buf(slot_info_t * slot,uint8_t ** out_buf)156 static esp_err_t get_block_buf(slot_info_t *slot, uint8_t **out_buf)
157 {
158     if (slot->block_buf == NULL) {
159         slot->block_buf = heap_caps_malloc(SDSPI_BLOCK_BUF_SIZE, MALLOC_CAP_DMA);
160         if (slot->block_buf == NULL) {
161             return ESP_ERR_NO_MEM;
162         }
163     }
164     *out_buf = slot->block_buf;
165     return ESP_OK;
166 }
167 
168 /// Clock out one byte (CS has to be high) to make the card release MISO
169 /// (clocking one bit would work as well, but that triggers a bug in SPI DMA)
release_bus(slot_info_t * slot)170 static void release_bus(slot_info_t *slot)
171 {
172     spi_transaction_t t = {
173         .flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
174         .length = 8,
175         .tx_data = {0xff}
176     };
177     spi_device_polling_transmit(slot->spi_handle, &t);
178     // don't care if this failed
179 }
180 
181 /// Clock out 80 cycles (10 bytes) before GO_IDLE command
go_idle_clockout(slot_info_t * slot)182 static void go_idle_clockout(slot_info_t *slot)
183 {
184     //actually we need 10, declare 12 to meet requirement of RXDMA
185     uint8_t data[12];
186     memset(data, 0xff, sizeof(data));
187     spi_transaction_t t = {
188         .length = 10*8,
189         .tx_buffer = data,
190         .rx_buffer = data,
191     };
192     spi_device_polling_transmit(slot->spi_handle, &t);
193     // don't care if this failed
194 }
195 
196 /**
197  * (Re)Configure SPI device. Used to change clock speed.
198  * @param slot Pointer to the slot to be configured
199  * @param clock_speed_hz  clock speed, Hz
200  * @return ESP_OK on success
201  */
configure_spi_dev(slot_info_t * slot,int clock_speed_hz)202 static esp_err_t configure_spi_dev(slot_info_t *slot, int clock_speed_hz)
203 {
204     if (slot->spi_handle) {
205         // Reinitializing
206         spi_bus_remove_device(slot->spi_handle);
207         slot->spi_handle = NULL;
208     }
209     spi_device_interface_config_t devcfg = {
210         .clock_speed_hz = clock_speed_hz,
211         .mode = 0,
212         // For SD cards, CS must stay low during the whole read/write operation,
213         // rather than a single SPI transaction.
214         .spics_io_num = GPIO_NUM_NC,
215         .queue_size = SDSPI_TRANSACTION_COUNT,
216     };
217     return spi_bus_add_device(slot->host_id, &devcfg, &slot->spi_handle);
218 }
219 
sdspi_host_init(void)220 esp_err_t sdspi_host_init(void)
221 {
222     return ESP_OK;
223 }
224 
deinit_slot(slot_info_t * slot)225 static esp_err_t deinit_slot(slot_info_t *slot)
226 {
227     esp_err_t err = ESP_OK;
228     if (slot->spi_handle) {
229         spi_bus_remove_device(slot->spi_handle);
230         slot->spi_handle = NULL;
231         free(slot->block_buf);
232         slot->block_buf = NULL;
233     }
234 
235     uint64_t pin_bit_mask = 0;
236     if (slot->gpio_cs != GPIO_UNUSED) {
237         pin_bit_mask |= BIT64(slot->gpio_cs);
238     }
239     if (slot->gpio_cd != GPIO_UNUSED) {
240         pin_bit_mask |= BIT64(slot->gpio_cd);
241     }
242     if (slot->gpio_wp != GPIO_UNUSED) {
243         pin_bit_mask |= BIT64(slot->gpio_wp);
244     }
245     if (slot->gpio_int != GPIO_UNUSED) {
246         pin_bit_mask |= BIT64(slot->gpio_int);
247         gpio_intr_disable(slot->gpio_int);
248         gpio_isr_handler_remove(slot->gpio_int);
249     }
250     gpio_config_t config = {
251         .pin_bit_mask = pin_bit_mask,
252         .mode = GPIO_MODE_INPUT,
253         .intr_type = GPIO_INTR_DISABLE,
254     };
255     if (pin_bit_mask != 0) {
256         gpio_config(&config);
257     }
258 
259     if (slot->semphr_int) {
260         vSemaphoreDelete(slot->semphr_int);
261         slot->semphr_int = NULL;
262     }
263     free(slot);
264     return err;
265 }
266 
sdspi_host_remove_device(sdspi_dev_handle_t handle)267 esp_err_t sdspi_host_remove_device(sdspi_dev_handle_t handle)
268 {
269     //Get the slot info and remove the reference in the static memory (if used)
270     slot_info_t* slot = remove_slot_info(handle);
271     if (slot == NULL) {
272         return ESP_ERR_INVALID_ARG;
273     }
274 
275    deinit_slot(slot);
276     return ESP_OK;
277 }
278 
279 //only the slots locally stored can be deinit in this function.
sdspi_host_deinit(void)280 esp_err_t sdspi_host_deinit(void)
281 {
282     for (size_t i = 0; i < sizeof(s_slots)/sizeof(s_slots[0]); ++i) {
283         slot_info_t* slot = remove_slot_info(i);
284         //slot isn't used, skip
285         if (slot == NULL) continue;
286 
287         deinit_slot(slot);
288     }
289     return ESP_OK;
290 }
291 
sdspi_host_set_card_clk(sdspi_dev_handle_t handle,uint32_t freq_khz)292 esp_err_t sdspi_host_set_card_clk(sdspi_dev_handle_t handle, uint32_t freq_khz)
293 {
294     slot_info_t *slot = get_slot_info(handle);
295     if (slot == NULL) {
296         return ESP_ERR_INVALID_ARG;
297     }
298     ESP_LOGD(TAG, "Setting card clock to %"PRIu32" kHz", freq_khz);
299     return configure_spi_dev(slot, freq_khz * 1000);
300 }
301 
sdspi_host_get_real_freq(sdspi_dev_handle_t handle,int * real_freq_khz)302 esp_err_t sdspi_host_get_real_freq(sdspi_dev_handle_t handle, int* real_freq_khz)
303 {
304     slot_info_t *slot = get_slot_info(handle);
305     if (slot == NULL) {
306         return ESP_ERR_INVALID_ARG;
307     }
308 
309     return spi_device_get_actual_freq(slot->spi_handle, real_freq_khz);
310 }
311 
gpio_intr(void * arg)312 static void gpio_intr(void* arg)
313 {
314     BaseType_t awoken = pdFALSE;
315     slot_info_t* slot = (slot_info_t*)arg;
316     xSemaphoreGiveFromISR(slot->semphr_int, &awoken);
317     gpio_intr_disable(slot->gpio_int);
318     if (awoken) {
319         portYIELD_FROM_ISR();
320     }
321 }
322 
sdspi_host_init_device(const sdspi_device_config_t * slot_config,sdspi_dev_handle_t * out_handle)323 esp_err_t sdspi_host_init_device(const sdspi_device_config_t* slot_config, sdspi_dev_handle_t* out_handle)
324 {
325     ESP_LOGD(TAG, "%s: SPI%d cs=%d cd=%d wp=%d",
326              __func__, slot_config->host_id + 1, slot_config->gpio_cs,
327              slot_config->gpio_cd, slot_config->gpio_wp);
328 
329     slot_info_t* slot = (slot_info_t*)malloc(sizeof(slot_info_t));
330     if (slot == NULL) {
331         return ESP_ERR_NO_MEM;
332     }
333     *slot = (slot_info_t) {
334         .host_id = slot_config->host_id,
335         .gpio_cs = slot_config->gpio_cs,
336     };
337 
338     // Attach the SD card to the SPI bus
339     esp_err_t ret = configure_spi_dev(slot, SDMMC_FREQ_PROBING * 1000);
340     if (ret != ESP_OK) {
341         ESP_LOGD(TAG, "spi_bus_add_device failed with rc=0x%x", ret);
342         goto cleanup;
343     }
344 
345     // Configure CS pin
346     gpio_config_t io_conf = {
347         .intr_type = GPIO_INTR_DISABLE,
348         .mode = GPIO_MODE_OUTPUT,
349         .pin_bit_mask = 1ULL << slot_config->gpio_cs,
350     };
351     if (slot_config->gpio_cs != SDSPI_SLOT_NO_CS) {
352         slot->gpio_cs = slot_config->gpio_cs;
353     } else {
354         slot->gpio_cs = GPIO_UNUSED;
355     }
356 
357     if (slot->gpio_cs != GPIO_UNUSED) {
358         ret = gpio_config(&io_conf);
359         if (ret != ESP_OK) {
360             ESP_LOGD(TAG, "gpio_config (CS) failed with rc=0x%x", ret);
361             goto cleanup;
362         }
363         cs_high(slot);
364     }
365 
366     // Configure CD and WP pins
367     io_conf = (gpio_config_t) {
368         .intr_type = GPIO_INTR_DISABLE,
369         .mode = GPIO_MODE_INPUT,
370         .pin_bit_mask = 0,
371         .pull_up_en = true
372     };
373     if (slot_config->gpio_cd != SDSPI_SLOT_NO_CD) {
374         io_conf.pin_bit_mask |= (1ULL << slot_config->gpio_cd);
375         slot->gpio_cd = slot_config->gpio_cd;
376     } else {
377         slot->gpio_cd = GPIO_UNUSED;
378     }
379 
380     if (slot_config->gpio_wp != SDSPI_SLOT_NO_WP) {
381         io_conf.pin_bit_mask |= (1ULL << slot_config->gpio_wp);
382         slot->gpio_wp = slot_config->gpio_wp;
383     } else {
384         slot->gpio_wp = GPIO_UNUSED;
385     }
386 
387     if (io_conf.pin_bit_mask != 0) {
388         ret = gpio_config(&io_conf);
389         if (ret != ESP_OK) {
390             ESP_LOGD(TAG, "gpio_config (CD/WP) failed with rc=0x%x", ret);
391             goto cleanup;
392         }
393     }
394 
395     if (slot_config->gpio_int != SDSPI_SLOT_NO_INT) {
396         slot->gpio_int = slot_config->gpio_int;
397         io_conf = (gpio_config_t) {
398             .intr_type = GPIO_INTR_LOW_LEVEL,
399             .mode = GPIO_MODE_INPUT,
400             .pull_up_en = true,
401             .pin_bit_mask = (1ULL << slot_config->gpio_int),
402         };
403         ret = gpio_config(&io_conf);
404         if (ret != ESP_OK) {
405             ESP_LOGE(TAG, "gpio_config (interrupt) failed with rc=0x%x", ret);
406             goto cleanup;
407         }
408 
409         slot->semphr_int = xSemaphoreCreateBinary();
410         if (slot->semphr_int == NULL) {
411             ret = ESP_ERR_NO_MEM;
412             goto cleanup;
413         }
414 
415         gpio_intr_disable(slot->gpio_int);
416         // 1. the interrupt is better to be disabled before the ISR is registered
417         // 2. the semaphore MUST be initialized before the ISR is registered
418         // 3. the gpio_int member should be filled before the ISR is registered
419         ret = gpio_isr_handler_add(slot->gpio_int, &gpio_intr, slot);
420         if (ret != ESP_OK) {
421             ESP_LOGE(TAG, "gpio_isr_handle_add failed with rc=0x%x", ret);
422             goto cleanup;
423         }
424     } else {
425         slot->gpio_int = GPIO_UNUSED;
426     }
427     //Initialization finished, store the store information if possible
428     //Then return corresponding handle
429     *out_handle = store_slot_info(slot);
430     return ESP_OK;
431 cleanup:
432     if (slot->semphr_int) {
433         vSemaphoreDelete(slot->semphr_int);
434         slot->semphr_int = NULL;
435     }
436     if (slot->spi_handle) {
437         spi_bus_remove_device(slot->spi_handle);
438         slot->spi_handle = NULL;
439     }
440     free(slot);
441     return ret;
442 
443 }
444 
sdspi_host_start_command(sdspi_dev_handle_t handle,sdspi_hw_cmd_t * cmd,void * data,uint32_t data_size,int flags)445 esp_err_t sdspi_host_start_command(sdspi_dev_handle_t handle, sdspi_hw_cmd_t *cmd, void *data,
446                                    uint32_t data_size, int flags)
447 {
448     slot_info_t *slot = get_slot_info(handle);
449     if (slot == NULL) {
450         return ESP_ERR_INVALID_ARG;
451     }
452     if (card_missing(slot)) {
453         return ESP_ERR_NOT_FOUND;
454     }
455     // save some parts of cmd, as its contents will be overwritten
456     int cmd_index = cmd->cmd_index;
457     uint32_t cmd_arg;
458     memcpy(&cmd_arg, cmd->arguments, sizeof(cmd_arg));
459     cmd_arg = __builtin_bswap32(cmd_arg);
460     ESP_LOGV(TAG, "%s: slot=%i, CMD%d, arg=0x%08"PRIx32" flags=0x%x, data=%p, data_size=%"PRIu32" crc=0x%02x",
461              __func__, handle, cmd_index, cmd_arg, flags, data, data_size, cmd->crc7);
462 
463     spi_device_acquire_bus(slot->spi_handle, portMAX_DELAY);
464     poll_busy(slot, 40, true);
465 
466     // For CMD0, clock out 80 cycles to help the card enter idle state,
467     // *before* CS is asserted.
468     if (cmd_index == MMC_GO_IDLE_STATE) {
469         go_idle_clockout(slot);
470     }
471     // actual transaction
472     esp_err_t ret = ESP_OK;
473 
474     cs_low(slot);
475     if (flags & SDSPI_CMD_FLAG_DATA) {
476         const bool multi_block = flags & SDSPI_CMD_FLAG_MULTI_BLK;
477         //send stop transmission token only when multi-block write and non-SDIO mode
478         const bool stop_transmission = multi_block && !(flags & SDSPI_CMD_FLAG_RSP_R5);
479         if (flags & SDSPI_CMD_FLAG_WRITE) {
480             ret = start_command_write_blocks(slot, cmd, data, data_size, multi_block, stop_transmission);
481         } else {
482             ret = start_command_read_blocks(slot, cmd, data, data_size, stop_transmission);
483         }
484     } else {
485         ret = start_command_default(slot, flags, cmd);
486     }
487     cs_high(slot);
488 
489     release_bus(slot);
490     spi_device_release_bus(slot->spi_handle);
491 
492     if (ret != ESP_OK) {
493         ESP_LOGD(TAG, "%s: cmd=%d error=0x%x", __func__, cmd_index, ret);
494     } else {
495         // Update internal state when some commands are sent successfully
496         if (cmd_index == SD_CRC_ON_OFF) {
497             slot->data_crc_enabled = (uint8_t) cmd_arg;
498             ESP_LOGD(TAG, "data CRC set=%d", slot->data_crc_enabled);
499         }
500     }
501     return ret;
502 }
503 
start_command_default(slot_info_t * slot,int flags,sdspi_hw_cmd_t * cmd)504 static esp_err_t start_command_default(slot_info_t *slot, int flags, sdspi_hw_cmd_t *cmd)
505 {
506     size_t cmd_size = SDSPI_CMD_R1_SIZE;
507     if ((flags & SDSPI_CMD_FLAG_RSP_R1) ||
508         (flags & SDSPI_CMD_FLAG_NORSP) ||
509         (flags & SDSPI_CMD_FLAG_RSP_R1B )) {
510         cmd_size = SDSPI_CMD_R1_SIZE;
511     } else if (flags & SDSPI_CMD_FLAG_RSP_R2) {
512         cmd_size = SDSPI_CMD_R2_SIZE;
513     } else if (flags & SDSPI_CMD_FLAG_RSP_R3) {
514         cmd_size = SDSPI_CMD_R3_SIZE;
515     } else if (flags & SDSPI_CMD_FLAG_RSP_R4) {
516         cmd_size = SDSPI_CMD_R4_SIZE;
517     } else if (flags & SDSPI_CMD_FLAG_RSP_R5) {
518         cmd_size = SDSPI_CMD_R5_SIZE;
519     } else if (flags & SDSPI_CMD_FLAG_RSP_R7) {
520         cmd_size = SDSPI_CMD_R7_SIZE;
521     }
522     //add extra clocks to avoid polling
523     cmd_size += (SDSPI_NCR_MAX_SIZE-SDSPI_NCR_MIN_SIZE);
524     spi_transaction_t t = {
525         .flags = 0,
526         .length = cmd_size * 8,
527         .tx_buffer = cmd,
528         .rx_buffer = cmd,
529     };
530     esp_err_t ret = spi_device_polling_transmit(slot->spi_handle, &t);
531     if (cmd->cmd_index == MMC_STOP_TRANSMISSION) {
532         /* response is a stuff byte from previous transfer, ignore it */
533         cmd->r1 = 0xff;
534     }
535     if (ret != ESP_OK) {
536         ESP_LOGD(TAG, "%s: spi_device_polling_transmit returned 0x%x", __func__, ret);
537         return ret;
538     }
539     if (flags & SDSPI_CMD_FLAG_NORSP) {
540         /* no (correct) response expected from the card, so skip polling loop */
541         ESP_LOGV(TAG, "%s: ignoring response byte", __func__);
542         cmd->r1 = 0x00;
543     }
544     // we have sent and received bytes with enough length.
545     // now shift the response to match the offset of sdspi_hw_cmd_t
546     ret = shift_cmd_response(cmd, cmd_size);
547     if (ret != ESP_OK) return ESP_ERR_TIMEOUT;
548 
549     if (flags & SDSPI_CMD_FLAG_RSP_R1B) {
550         ret = poll_busy(slot, cmd->timeout_ms, no_use_polling);
551         if (ret != ESP_OK) {
552             return ret;
553         }
554     }
555 
556     return ESP_OK;
557 }
558 
559 // Wait until MISO goes high
poll_busy(slot_info_t * slot,int timeout_ms,bool polling)560 static esp_err_t poll_busy(slot_info_t *slot, int timeout_ms, bool polling)
561 {
562     uint8_t t_rx;
563     spi_transaction_t t = {
564         .tx_buffer = &t_rx,
565         .flags = SPI_TRANS_USE_RXDATA,  //data stored in rx_data
566         .length = 8,
567     };
568     esp_err_t ret;
569 
570     int64_t t_end = esp_timer_get_time() + timeout_ms * 1000;
571     int nonzero_count = 0;
572     do {
573         t_rx = SDSPI_MOSI_IDLE_VAL;
574         t.rx_data[0] = 0;
575         if (polling) {
576             ret = spi_device_polling_transmit(slot->spi_handle, &t);
577         } else {
578             ret = spi_device_transmit(slot->spi_handle, &t);
579         }
580         if (ret != ESP_OK) {
581             return ret;
582         }
583         if (t.rx_data[0] != 0) {
584             if (++nonzero_count == 2) {
585                 return ESP_OK;
586             }
587         }
588     } while(esp_timer_get_time() < t_end);
589     ESP_LOGD(TAG, "%s: timeout", __func__);
590     return ESP_ERR_TIMEOUT;
591 }
592 
593 // Wait for data token, reading 8 bytes at a time.
594 // If the token is found, write all subsequent bytes to extra_ptr,
595 // and store the number of bytes written to extra_size.
poll_data_token(slot_info_t * slot,uint8_t * extra_ptr,size_t * extra_size,int timeout_ms)596 static esp_err_t poll_data_token(slot_info_t *slot, uint8_t *extra_ptr, size_t *extra_size, int timeout_ms)
597 {
598     uint8_t t_rx[8];
599     spi_transaction_t t = {
600         .tx_buffer = &t_rx,
601         .rx_buffer = &t_rx,
602         .length = sizeof(t_rx) * 8,
603     };
604     esp_err_t ret;
605     int64_t t_end = esp_timer_get_time() + timeout_ms * 1000;
606     do {
607         memset(t_rx, SDSPI_MOSI_IDLE_VAL, sizeof(t_rx));
608         ret = spi_device_polling_transmit(slot->spi_handle, &t);
609         if (ret != ESP_OK) {
610             return ret;
611         }
612         bool found = false;
613         for (size_t byte_idx = 0; byte_idx < sizeof(t_rx); byte_idx++) {
614             uint8_t rd_data = t_rx[byte_idx];
615             if (rd_data == TOKEN_BLOCK_START) {
616                 found = true;
617                 memcpy(extra_ptr, t_rx + byte_idx + 1, sizeof(t_rx) - byte_idx - 1);
618                 *extra_size = sizeof(t_rx) - byte_idx - 1;
619                 break;
620             }
621             if (rd_data != 0xff && rd_data != 0) {
622                 ESP_LOGD(TAG, "%s: received 0x%02x while waiting for data",
623                         __func__, rd_data);
624                 return ESP_ERR_INVALID_RESPONSE;
625             }
626         }
627         if (found) {
628             return ESP_OK;
629         }
630     } while (esp_timer_get_time() < t_end);
631     ESP_LOGD(TAG, "%s: timeout", __func__);
632     return ESP_ERR_TIMEOUT;
633 }
634 
635 // the r1 respond could appear 1-8 clocks after the command token is sent
636 // this function search for r1 in the buffer after 1 clocks to max 8 clocks
637 // then shift the data after R1, to match the definition of sdspi_hw_cmd_t.
shift_cmd_response(sdspi_hw_cmd_t * cmd,int sent_bytes)638 static esp_err_t shift_cmd_response(sdspi_hw_cmd_t* cmd, int sent_bytes)
639 {
640     uint8_t* pr1 = &cmd->r1;
641     int ncr_cnt = 1;
642     while(true) {
643         if ((*pr1 & SD_SPI_R1_NO_RESPONSE) == 0) break;
644         pr1++;
645         if (++ncr_cnt > 8) return ESP_ERR_NOT_FOUND;
646     }
647 
648     int copy_bytes = sent_bytes - SDSPI_CMD_SIZE - ncr_cnt;
649     if (copy_bytes > 0) {
650         memcpy(&cmd->r1, pr1, copy_bytes);
651     }
652 
653     return ESP_OK;
654 }
655 
656 
657 /**
658  * Receiving one or more blocks of data happens as follows:
659  * 1. send command + receive r1 response (SDSPI_CMD_R1_SIZE bytes total)
660  * 2. keep receiving bytes until TOKEN_BLOCK_START is encountered (this may
661  *    take a while, depending on card's read speed)
662  * 3. receive up to SDSPI_MAX_DATA_LEN = 512 bytes of actual data
663  * 4. receive 2 bytes of CRC
664  * 5. for multi block transfers, go to step 2
665  *
666  * These steps can be done separately, but that leads to a less than optimal
667  * performance on large transfers because of delays between each step.
668  * For example, if steps 3 and 4 are separate SPI transactions queued one after
669  * another, there will be ~16 microseconds of dead time between end of step 3
670  * and the beginning of step 4. A delay between two blocking SPI transactions
671  * in step 2 is even higher (~60 microseconds).
672  *
673  * To improve read performance the following sequence is adopted:
674  * 1. Do the first transfer: command + r1 response + 8 extra bytes.
675  *    Set pre_scan_data_ptr to point to the 8 extra bytes, and set
676  *    pre_scan_data_size to 8.
677  * 2. Search pre_scan_data_size bytes for TOKEN_BLOCK_START.
678  *    If found, the rest of the bytes contain part of the actual data.
679  *    Store pointer to and size of that extra data as extra_data_{ptr,size}.
680  *    If not found, fall back to polling for TOKEN_BLOCK_START, 8 bytes at a
681  *    time (in poll_data_token function). Deal with extra data in the same way,
682  *    by setting extra_data_{ptr,size}.
683  * 3. Receive the remaining 512 - extra_data_size bytes, plus 4 extra bytes
684  *    (i.e. 516 - extra_data_size). Of the 4 extra bytes, first two will capture
685  *    the CRC value, and the other two will capture 0xff 0xfe sequence
686  *    indicating the start of the next block. Actual scanning is done by
687  *    setting pre_scan_data_ptr to point to these last 2 bytes, and setting
688  *    pre_scan_data_size = 2, then going to step 2 to receive the next block.
689  *    When the final block is being received, the number of extra bytes is 2
690  *    (only for CRC), because we don't need to wait for start token of the
691  *    next block, and some cards are getting confused by these two extra bytes.
692  *
693  * With this approach the delay between blocks of a multi-block transfer is
694  * ~95 microseconds, out of which 35 microseconds are spend doing the CRC check.
695  * Further speedup is possible by pipelining transfers and CRC checks, at an
696  * expense of one extra temporary buffer.
697  */
start_command_read_blocks(slot_info_t * slot,sdspi_hw_cmd_t * cmd,uint8_t * data,uint32_t rx_length,bool need_stop_command)698 static esp_err_t start_command_read_blocks(slot_info_t *slot, sdspi_hw_cmd_t *cmd,
699         uint8_t *data, uint32_t rx_length, bool need_stop_command)
700 {
701     spi_transaction_t t_command = {
702         .length = (SDSPI_CMD_R1_SIZE + SDSPI_RESPONSE_MAX_DELAY) * 8,
703         .tx_buffer = cmd,
704         .rx_buffer = cmd,
705     };
706     esp_err_t ret = spi_device_polling_transmit(slot->spi_handle, &t_command);
707     if (ret != ESP_OK) {
708         return ret;
709     }
710 
711     uint8_t* cmd_u8 = (uint8_t*) cmd;
712     size_t pre_scan_data_size = SDSPI_RESPONSE_MAX_DELAY;
713     uint8_t* pre_scan_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;
714 
715     /* R1 response is delayed by 1-8 bytes from the request.
716      * This loop searches for the response and writes it to cmd->r1.
717      */
718     while ((cmd->r1 & SD_SPI_R1_NO_RESPONSE) != 0 && pre_scan_data_size > 0) {
719         cmd->r1 = *pre_scan_data_ptr;
720         ++pre_scan_data_ptr;
721         --pre_scan_data_size;
722     }
723     if (cmd->r1 & SD_SPI_R1_NO_RESPONSE) {
724         ESP_LOGD(TAG, "no response token found");
725         return ESP_ERR_TIMEOUT;
726     }
727 
728     while (rx_length > 0) {
729         size_t extra_data_size = 0;
730         const uint8_t* extra_data_ptr = NULL;
731         bool need_poll = true;
732 
733         for (size_t i = 0; i < pre_scan_data_size; ++i) {
734             if (pre_scan_data_ptr[i] == TOKEN_BLOCK_START) {
735                 extra_data_size = pre_scan_data_size - i - 1;
736                 extra_data_ptr = pre_scan_data_ptr + i + 1;
737                 need_poll = false;
738                 break;
739             }
740         }
741 
742         if (need_poll) {
743             // Wait for data to be ready
744             ret = poll_data_token(slot, cmd_u8 + SDSPI_CMD_R1_SIZE, &extra_data_size, cmd->timeout_ms);
745             if (ret != ESP_OK) {
746                 return ret;
747             }
748             if (extra_data_size) {
749                 extra_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;
750             }
751         }
752 
753         // Arrange RX buffer
754         size_t will_receive = MIN(rx_length, SDSPI_MAX_DATA_LEN) - extra_data_size;
755         uint8_t* rx_data;
756         ret = get_block_buf(slot, &rx_data);
757         if (ret != ESP_OK) {
758             return ret;
759         }
760 
761         // receive actual data
762         const size_t receive_extra_bytes = (rx_length > SDSPI_MAX_DATA_LEN) ? 4 : 2;
763         memset(rx_data, 0xff, will_receive + receive_extra_bytes);
764         spi_transaction_t t_data = {
765             .length = (will_receive + receive_extra_bytes) * 8,
766             .rx_buffer = rx_data,
767             .tx_buffer = rx_data
768         };
769 
770         ret = spi_device_transmit(slot->spi_handle, &t_data);
771         if (ret != ESP_OK) {
772             return ret;
773         }
774 
775         // CRC bytes need to be received even if CRC is not enabled
776         uint16_t crc = UINT16_MAX;
777         memcpy(&crc, rx_data + will_receive, sizeof(crc));
778 
779         // Bytes to scan for the start token
780         pre_scan_data_size = receive_extra_bytes - sizeof(crc);
781         pre_scan_data_ptr = rx_data + will_receive + sizeof(crc);
782 
783         // Copy data to the destination buffer
784         memcpy(data + extra_data_size, rx_data, will_receive);
785         if (extra_data_size) {
786             memcpy(data, extra_data_ptr, extra_data_size);
787         }
788 
789         // compute CRC of the received data
790         uint16_t crc_of_data = 0;
791         if (slot->data_crc_enabled) {
792             crc_of_data = sdspi_crc16(data, will_receive + extra_data_size);
793             if (crc_of_data != crc) {
794                 ESP_LOGE(TAG, "data CRC failed, got=0x%04x expected=0x%04x", crc_of_data, crc);
795                 esp_log_buffer_hex(TAG, data, 16);
796                 return ESP_ERR_INVALID_CRC;
797             }
798         }
799 
800         data += will_receive + extra_data_size;
801         rx_length -= will_receive + extra_data_size;
802         extra_data_size = 0;
803         extra_data_ptr = NULL;
804     }
805 
806     if (need_stop_command) {
807         // To end multi block transfer, send stop command and wait for the
808         // card to process it
809         sdspi_hw_cmd_t stop_cmd;
810         make_hw_cmd(MMC_STOP_TRANSMISSION, 0, cmd->timeout_ms, &stop_cmd);
811         ret = start_command_default(slot, SDSPI_CMD_FLAG_RSP_R1B, &stop_cmd);
812         if (ret != ESP_OK) {
813             return ret;
814         }
815         if (stop_cmd.r1 != 0) {
816             ESP_LOGD(TAG, "%s: STOP_TRANSMISSION response 0x%02x", __func__, stop_cmd.r1);
817         }
818         ret = poll_busy(slot, cmd->timeout_ms, use_polling);
819         if (ret != ESP_OK) {
820             return ret;
821         }
822     }
823     return ESP_OK;
824 }
825 
826 /* For CMD53, we can send in byte mode, or block mode
827  * The data start token is different, and cannot be determined by the length
828  * That's why we need ``multi_block``.
829  * It's also different that stop transmission token is not needed in the SDIO mode.
830  */
start_command_write_blocks(slot_info_t * slot,sdspi_hw_cmd_t * cmd,const uint8_t * data,uint32_t tx_length,bool multi_block,bool stop_trans)831 static esp_err_t start_command_write_blocks(slot_info_t *slot, sdspi_hw_cmd_t *cmd,
832         const uint8_t *data, uint32_t tx_length, bool multi_block, bool stop_trans)
833 {
834     if (card_write_protected(slot)) {
835         ESP_LOGW(TAG, "%s: card write protected", __func__);
836         return ESP_ERR_INVALID_STATE;
837     }
838     // Send the minimum length that is sure to get the complete response
839     // SD cards always return R1 (1bytes), SDIO returns R5 (2 bytes)
840     const int send_bytes = SDSPI_CMD_R5_SIZE+SDSPI_NCR_MAX_SIZE-SDSPI_NCR_MIN_SIZE;
841 
842     spi_transaction_t t_command = {
843         .length = send_bytes * 8,
844         .tx_buffer = cmd,
845         .rx_buffer = cmd,
846     };
847     esp_err_t ret = spi_device_polling_transmit(slot->spi_handle, &t_command);
848     if (ret != ESP_OK) {
849         return ret;
850     }
851 
852     // check if command response valid
853     ret = shift_cmd_response(cmd, send_bytes);
854     if (ret != ESP_OK) {
855         ESP_LOGD(TAG, "%s: check_cmd_response returned 0x%x", __func__, ret);
856         return ret;
857     }
858 
859     uint8_t start_token = multi_block ?
860              TOKEN_BLOCK_START_WRITE_MULTI : TOKEN_BLOCK_START;
861 
862     while (tx_length > 0) {
863         // Write block start token
864         spi_transaction_t t_start_token = {
865             .length = sizeof(start_token) * 8,
866             .tx_buffer = &start_token
867         };
868         ret = spi_device_polling_transmit(slot->spi_handle, &t_start_token);
869         if (ret != ESP_OK) {
870             return ret;
871         }
872 
873         // Prepare data to be sent
874         size_t will_send = MIN(tx_length, SDSPI_MAX_DATA_LEN);
875         const uint8_t* tx_data = data;
876         if (!esp_ptr_in_dram(tx_data)) {
877             // If the pointer can't be used with DMA, copy data into a new buffer
878             uint8_t* tmp;
879             ret = get_block_buf(slot, &tmp);
880             if (ret != ESP_OK) {
881                 return ret;
882             }
883             memcpy(tmp, tx_data, will_send);
884             tx_data = tmp;
885         }
886 
887         // Write data
888         spi_transaction_t t_data = {
889             .length = will_send * 8,
890             .tx_buffer = tx_data,
891         };
892         ret = spi_device_transmit(slot->spi_handle, &t_data);
893         if (ret != ESP_OK) {
894             return ret;
895         }
896 
897         // Write CRC and get the response in one transaction
898         uint16_t crc = sdspi_crc16(data, will_send);
899         const int size_crc_response = sizeof(crc) + 1;
900 
901         spi_transaction_t t_crc_rsp = {
902             .length = size_crc_response * 8,
903             .flags = SPI_TRANS_USE_TXDATA|SPI_TRANS_USE_RXDATA,
904         };
905         memset(t_crc_rsp.tx_data, 0xff, 4);
906         memcpy(t_crc_rsp.tx_data, &crc, sizeof(crc));
907 
908         ret = spi_device_polling_transmit(slot->spi_handle, &t_crc_rsp);
909         if (ret != ESP_OK) {
910             return ret;
911         }
912 
913         uint8_t data_rsp = t_crc_rsp.rx_data[2];
914         if (!SD_SPI_DATA_RSP_VALID(data_rsp)) return ESP_ERR_INVALID_RESPONSE;
915         switch (SD_SPI_DATA_RSP(data_rsp)) {
916         case SD_SPI_DATA_ACCEPTED:
917             break;
918         case SD_SPI_DATA_CRC_ERROR:
919             return ESP_ERR_INVALID_CRC;
920         case SD_SPI_DATA_WR_ERROR:
921             return ESP_FAIL;
922         default:
923             return ESP_ERR_INVALID_RESPONSE;
924         }
925 
926         // Wait for the card to finish writing data
927         ret = poll_busy(slot, cmd->timeout_ms, no_use_polling);
928         if (ret != ESP_OK) {
929             return ret;
930         }
931 
932         tx_length -= will_send;
933         data += will_send;
934     }
935 
936     if (stop_trans) {
937         uint8_t stop_token[2] = {
938             TOKEN_BLOCK_STOP_WRITE_MULTI,
939             SDSPI_MOSI_IDLE_VAL
940         };
941         spi_transaction_t t_stop_token = {
942             .length = sizeof(stop_token) * 8,
943             .tx_buffer = &stop_token,
944         };
945         ret = spi_device_polling_transmit(slot->spi_handle, &t_stop_token);
946         if (ret != ESP_OK) {
947             return ret;
948         }
949 
950         ret = poll_busy(slot, cmd->timeout_ms, use_polling);
951         if (ret != ESP_OK) {
952             return ret;
953         }
954     }
955 
956     return ESP_OK;
957 }
958 
sdspi_host_io_int_enable(sdspi_dev_handle_t handle)959 esp_err_t sdspi_host_io_int_enable(sdspi_dev_handle_t handle)
960 {
961     //the pin and its interrupt is already initialized, nothing to do here.
962     return ESP_OK;
963 }
964 
965 //the interrupt will give the semaphore and then disable itself
sdspi_host_io_int_wait(sdspi_dev_handle_t handle,TickType_t timeout_ticks)966 esp_err_t sdspi_host_io_int_wait(sdspi_dev_handle_t handle, TickType_t timeout_ticks)
967 {
968     slot_info_t* slot = get_slot_info(handle);
969     //skip the interrupt and semaphore if the gpio is already low.
970     if (gpio_get_level(slot->gpio_int)==0) return ESP_OK;
971 
972     //clear the semaphore before wait
973     xSemaphoreTake(slot->semphr_int, 0);
974     //enable the interrupt and wait for the semaphore
975     gpio_intr_enable(slot->gpio_int);
976     BaseType_t ret = xSemaphoreTake(slot->semphr_int, timeout_ticks);
977     if (ret == pdFALSE) {
978         gpio_intr_disable(slot->gpio_int);
979         return ESP_ERR_TIMEOUT;
980     }
981     return ESP_OK;
982 }
983