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