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