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