sdspi_host.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  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. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <stdbool.h>
  18. #include <stddef.h>
  19. #include <sys/param.h>
  20. #include "esp_log.h"
  21. #include "esp_heap_caps.h"
  22. #include "driver/gpio.h"
  23. #include "driver/sdmmc_defs.h"
  24. #include "driver/sdspi_host.h"
  25. #include "sdspi_private.h"
  26. #include "sdspi_crc.h"
  27. /// Max number of transactions in flight (used in start_command_write_blocks)
  28. #define SDSPI_TRANSACTION_COUNT 4
  29. #define SDSPI_MOSI_IDLE_VAL 0xff //!< Data value which causes MOSI to stay high
  30. /// FIXME: this has to be replaced with a timeout expressed in ms, rather in retries
  31. #define SDSPI_RETRY_COUNT 1000
  32. #define GPIO_UNUSED 0xff //!< Flag indicating that CD/WP is unused
  33. /// Size of the buffer returned by get_block_buf
  34. #define SDSPI_BLOCK_BUF_SIZE (SDSPI_MAX_DATA_LEN + 4)
  35. /// Structure containing run time configuration for a single SD slot
  36. typedef struct {
  37. spi_device_handle_t handle; //!< SPI device handle, used for transactions
  38. uint8_t gpio_cs; //!< CS GPIO
  39. uint8_t gpio_cd; //!< Card detect GPIO, or GPIO_UNUSED
  40. uint8_t gpio_wp; //!< Write protect GPIO, or GPIO_UNUSED
  41. /// Set to 1 if the higher layer has asked the card to enable CRC checks
  42. uint8_t data_crc_enabled : 1;
  43. /// Number of transactions in 'transactions' array which are in use
  44. uint8_t used_transaction_count: 3;
  45. /// Intermediate buffer used when application buffer is not in DMA memory;
  46. /// allocated on demand, SDSPI_BLOCK_BUF_SIZE bytes long. May be zero.
  47. uint8_t* block_buf;
  48. /// array with SDSPI_TRANSACTION_COUNT transaction structures
  49. spi_transaction_t* transactions;
  50. } slot_info_t;
  51. static slot_info_t s_slots[3];
  52. static const char *TAG = "sdspi_host";
  53. /// Functions to send out different kinds of commands
  54. static esp_err_t start_command_read_blocks(int slot, sdspi_hw_cmd_t *cmd,
  55. uint8_t *data, uint32_t rx_length);
  56. static esp_err_t start_command_write_blocks(int slot, sdspi_hw_cmd_t *cmd,
  57. const uint8_t *data, uint32_t tx_length);
  58. static esp_err_t start_command_default(int slot, int flags, sdspi_hw_cmd_t *cmd);
  59. /// A few helper functions
  60. /// Set CS high for given slot
  61. static void cs_high(int slot)
  62. {
  63. gpio_set_level(s_slots[slot].gpio_cs, 1);
  64. }
  65. /// Set CS low for given slot
  66. static void cs_low(int slot)
  67. {
  68. gpio_set_level(s_slots[slot].gpio_cs, 0);
  69. }
  70. /// Return true if WP pin is configured and is low
  71. static bool card_write_protected(int slot)
  72. {
  73. if (s_slots[slot].gpio_wp == GPIO_UNUSED) {
  74. return false;
  75. }
  76. return gpio_get_level(s_slots[slot].gpio_wp) == 0;
  77. }
  78. /// Return true if CD pin is configured and is high
  79. static bool card_missing(int slot)
  80. {
  81. if (s_slots[slot].gpio_cd == GPIO_UNUSED) {
  82. return false;
  83. }
  84. return gpio_get_level(s_slots[slot].gpio_cd) == 1;
  85. }
  86. /// Check if slot number is within bounds
  87. static bool is_valid_slot(int slot)
  88. {
  89. return slot == VSPI_HOST || slot == HSPI_HOST;
  90. }
  91. static spi_device_handle_t spi_handle(int slot)
  92. {
  93. return s_slots[slot].handle;
  94. }
  95. static bool is_slot_initialized(int slot)
  96. {
  97. return spi_handle(slot) != NULL;
  98. }
  99. static bool data_crc_enabled(int slot)
  100. {
  101. return s_slots[slot].data_crc_enabled;
  102. }
  103. /// Get pointer to a block of DMA memory, allocate if necessary.
  104. /// This is used if the application provided buffer is not in DMA capable memory.
  105. static esp_err_t get_block_buf(int slot, uint8_t** out_buf)
  106. {
  107. if (s_slots[slot].block_buf == NULL) {
  108. s_slots[slot].block_buf = heap_caps_malloc(SDSPI_BLOCK_BUF_SIZE, MALLOC_CAP_DMA);
  109. if (s_slots[slot].block_buf == NULL) {
  110. return ESP_ERR_NO_MEM;
  111. }
  112. }
  113. *out_buf = s_slots[slot].block_buf;
  114. return ESP_OK;
  115. }
  116. static spi_transaction_t* get_transaction(int slot)
  117. {
  118. size_t used_transaction_count = s_slots[slot].used_transaction_count;
  119. assert(used_transaction_count < SDSPI_TRANSACTION_COUNT);
  120. spi_transaction_t* ret = &s_slots[slot].transactions[used_transaction_count];
  121. ++s_slots[slot].used_transaction_count;
  122. return ret;
  123. }
  124. static void release_transaction(int slot)
  125. {
  126. --s_slots[slot].used_transaction_count;
  127. }
  128. static void wait_for_transactions(int slot)
  129. {
  130. size_t used_transaction_count = s_slots[slot].used_transaction_count;
  131. for (size_t i = 0; i < used_transaction_count; ++i) {
  132. spi_transaction_t* t_out;
  133. spi_device_get_trans_result(spi_handle(slot), &t_out, portMAX_DELAY);
  134. release_transaction(slot);
  135. }
  136. }
  137. /// Clock out one byte (CS has to be high) to make the card release MISO
  138. /// (clocking one bit would work as well, but that triggers a bug in SPI DMA)
  139. static void release_bus(int slot)
  140. {
  141. spi_transaction_t t = {
  142. .flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
  143. .length = 8,
  144. .tx_data = {0xff}
  145. };
  146. spi_device_transmit(spi_handle(slot), &t);
  147. // don't care if this failed
  148. }
  149. /// Clock out 80 cycles (10 bytes) before GO_IDLE command
  150. static void go_idle_clockout(int slot)
  151. {
  152. //actually we need 10, declare 12 to meet requirement of RXDMA
  153. uint8_t data[12];
  154. memset(data, 0xff, sizeof(data));
  155. spi_transaction_t t = {
  156. .length = 10*8,
  157. .tx_buffer = data,
  158. .rx_buffer = data,
  159. };
  160. spi_device_transmit(spi_handle(slot), &t);
  161. // don't care if this failed
  162. }
  163. /// Return true if the pointer can be used for DMA
  164. static bool ptr_dma_compatible(const void* ptr)
  165. {
  166. return (uintptr_t) ptr >= 0x3FFAE000 &&
  167. (uintptr_t) ptr < 0x40000000;
  168. }
  169. /**
  170. * Initialize SPI device. Used to change clock speed.
  171. * @param slot SPI host number
  172. * @param clock_speed_hz clock speed, Hz
  173. * @return ESP_OK on success
  174. */
  175. static esp_err_t init_spi_dev(int slot, int clock_speed_hz)
  176. {
  177. if (spi_handle(slot)) {
  178. // Reinitializing
  179. spi_bus_remove_device(spi_handle(slot));
  180. s_slots[slot].handle = NULL;
  181. }
  182. spi_device_interface_config_t devcfg = {
  183. .clock_speed_hz = clock_speed_hz,
  184. .mode = 0,
  185. // For SD cards, CS must stay low during the whole read/write operation,
  186. // rather than a single SPI transaction.
  187. .spics_io_num = -1,
  188. .queue_size = SDSPI_TRANSACTION_COUNT,
  189. };
  190. return spi_bus_add_device((spi_host_device_t) slot, &devcfg, &s_slots[slot].handle);
  191. }
  192. esp_err_t sdspi_host_init()
  193. {
  194. return ESP_OK;
  195. }
  196. esp_err_t sdspi_host_deinit()
  197. {
  198. for (size_t i = 0; i < sizeof(s_slots)/sizeof(s_slots[0]); ++i) {
  199. if (s_slots[i].handle) {
  200. spi_bus_remove_device(s_slots[i].handle);
  201. free(s_slots[i].block_buf);
  202. s_slots[i].block_buf = NULL;
  203. free(s_slots[i].transactions);
  204. s_slots[i].transactions = NULL;
  205. spi_bus_free((spi_host_device_t) i);
  206. s_slots[i].handle = NULL;
  207. }
  208. }
  209. return ESP_OK;
  210. }
  211. esp_err_t sdspi_host_set_card_clk(int slot, uint32_t freq_khz)
  212. {
  213. if (!is_valid_slot(slot)) {
  214. return ESP_ERR_INVALID_ARG;
  215. }
  216. if (!is_slot_initialized(slot)) {
  217. return ESP_ERR_INVALID_STATE;
  218. }
  219. ESP_LOGD(TAG, "Setting card clock to %d kHz", freq_khz);
  220. return init_spi_dev(slot, freq_khz * 1000);
  221. }
  222. esp_err_t sdspi_host_init_slot(int slot, const sdspi_slot_config_t* slot_config)
  223. {
  224. ESP_LOGD(TAG, "%s: SPI%d miso=%d mosi=%d sck=%d cs=%d cd=%d wp=%d, dma_ch=%d",
  225. __func__, slot + 1,
  226. slot_config->gpio_miso, slot_config->gpio_mosi,
  227. slot_config->gpio_sck, slot_config->gpio_cs,
  228. slot_config->gpio_cd, slot_config->gpio_wp,
  229. slot_config->dma_channel);
  230. spi_host_device_t host = (spi_host_device_t) slot;
  231. if (!is_valid_slot(slot)) {
  232. return ESP_ERR_INVALID_ARG;
  233. }
  234. spi_bus_config_t buscfg = {
  235. .miso_io_num = slot_config->gpio_miso,
  236. .mosi_io_num = slot_config->gpio_mosi,
  237. .sclk_io_num = slot_config->gpio_sck,
  238. .quadwp_io_num = -1,
  239. .quadhd_io_num = -1
  240. };
  241. // Initialize SPI bus
  242. esp_err_t ret = spi_bus_initialize((spi_host_device_t)slot, &buscfg,
  243. slot_config->dma_channel);
  244. if (ret != ESP_OK) {
  245. ESP_LOGD(TAG, "spi_bus_initialize failed with rc=0x%x", ret);
  246. return ret;
  247. }
  248. // Attach the SD card to the SPI bus
  249. ret = init_spi_dev(slot, SDMMC_FREQ_PROBING * 1000);
  250. if (ret != ESP_OK) {
  251. ESP_LOGD(TAG, "spi_bus_add_device failed with rc=0x%x", ret);
  252. spi_bus_free(host);
  253. return ret;
  254. }
  255. // Configure CS pin
  256. s_slots[slot].gpio_cs = (uint8_t) slot_config->gpio_cs;
  257. gpio_config_t io_conf = {
  258. .intr_type = GPIO_PIN_INTR_DISABLE,
  259. .mode = GPIO_MODE_OUTPUT,
  260. .pin_bit_mask = 1LL << slot_config->gpio_cs,
  261. };
  262. ret = gpio_config(&io_conf);
  263. if (ret != ESP_OK) {
  264. ESP_LOGD(TAG, "gpio_config (CS) failed with rc=0x%x", ret);
  265. spi_bus_remove_device(spi_handle(slot));
  266. s_slots[slot].handle = NULL;
  267. spi_bus_free(host);
  268. return ret;
  269. }
  270. cs_high(slot);
  271. // Configure CD and WP pins
  272. io_conf = (gpio_config_t) {
  273. .intr_type = GPIO_PIN_INTR_DISABLE,
  274. .mode = GPIO_MODE_OUTPUT,
  275. .pin_bit_mask = 0,
  276. .pull_up_en = true
  277. };
  278. if (slot_config->gpio_cd != SDSPI_SLOT_NO_CD) {
  279. io_conf.pin_bit_mask |= (1 << slot_config->gpio_cd);
  280. s_slots[slot].gpio_wp = slot_config->gpio_wp;
  281. } else {
  282. s_slots[slot].gpio_wp = GPIO_UNUSED;
  283. }
  284. if (slot_config->gpio_wp != SDSPI_SLOT_NO_WP) {
  285. io_conf.pin_bit_mask |= (1 << slot_config->gpio_wp);
  286. s_slots[slot].gpio_cd = slot_config->gpio_cd;
  287. } else {
  288. s_slots[slot].gpio_cd = GPIO_UNUSED;
  289. }
  290. if (io_conf.pin_bit_mask != 0) {
  291. ret = gpio_config(&io_conf);
  292. if (ret != ESP_OK) {
  293. ESP_LOGD(TAG, "gpio_config (CD/WP) failed with rc=0x%x", ret);
  294. spi_bus_remove_device(spi_handle(slot));
  295. s_slots[slot].handle = NULL;
  296. spi_bus_free(host);
  297. return ret;
  298. }
  299. }
  300. s_slots[slot].transactions = calloc(SDSPI_TRANSACTION_COUNT, sizeof(spi_transaction_t));
  301. if (s_slots[slot].transactions == NULL) {
  302. spi_bus_remove_device(spi_handle(slot));
  303. s_slots[slot].handle = NULL;
  304. spi_bus_free(host);
  305. return ESP_ERR_NO_MEM;
  306. }
  307. return ESP_OK;
  308. }
  309. esp_err_t sdspi_host_start_command(int slot, sdspi_hw_cmd_t *cmd, void *data,
  310. uint32_t data_size, int flags)
  311. {
  312. if (!is_valid_slot(slot)) {
  313. return ESP_ERR_INVALID_ARG;
  314. }
  315. if (!is_slot_initialized(slot)) {
  316. return ESP_ERR_INVALID_STATE;
  317. }
  318. if (card_missing(slot)) {
  319. return ESP_ERR_NOT_FOUND;
  320. }
  321. // save some parts of cmd, as its contents will be overwritten
  322. int cmd_index = cmd->cmd_index;
  323. uint32_t cmd_arg;
  324. memcpy(&cmd_arg, cmd->arguments, sizeof(cmd_arg));
  325. cmd_arg = __builtin_bswap32(cmd_arg);
  326. ESP_LOGV(TAG, "%s: slot=%i, CMD%d, arg=0x%08x flags=0x%x, data=%p, data_size=%i crc=0x%02x",
  327. __func__, slot, cmd_index, cmd_arg, flags, data, data_size, cmd->crc7);
  328. // For CMD0, clock out 80 cycles to help the card enter idle state,
  329. // *before* CS is asserted.
  330. if (cmd_index == MMC_GO_IDLE_STATE) {
  331. go_idle_clockout(slot);
  332. }
  333. // actual transaction
  334. esp_err_t ret = ESP_OK;
  335. cs_low(slot);
  336. if (flags & SDSPI_CMD_FLAG_DATA) {
  337. if (flags & SDSPI_CMD_FLAG_WRITE) {
  338. ret = start_command_write_blocks(slot, cmd, data, data_size);
  339. } else {
  340. ret = start_command_read_blocks(slot, cmd, data, data_size);
  341. }
  342. } else {
  343. ret = start_command_default(slot, flags, cmd);
  344. }
  345. cs_high(slot);
  346. release_bus(slot);
  347. if (ret != ESP_OK) {
  348. ESP_LOGE(TAG, "%s: cmd=%d error=0x%x", __func__, cmd_index, ret);
  349. } else {
  350. // Update internal state when some commands are sent successfully
  351. if (cmd_index == SD_CRC_ON_OFF) {
  352. s_slots[slot].data_crc_enabled = (uint8_t) cmd_arg;
  353. ESP_LOGD(TAG, "data CRC set=%d", s_slots[slot].data_crc_enabled);
  354. }
  355. }
  356. return ret;
  357. }
  358. static esp_err_t start_command_default(int slot, int flags, sdspi_hw_cmd_t *cmd)
  359. {
  360. size_t cmd_size = SDSPI_CMD_R1_SIZE;
  361. if (flags & SDSPI_CMD_FLAG_RSP_R1) {
  362. cmd_size = SDSPI_CMD_R1_SIZE;
  363. } else if (flags & SDSPI_CMD_FLAG_RSP_R2) {
  364. cmd_size = SDSPI_CMD_R2_SIZE;
  365. } else if (flags & SDSPI_CMD_FLAG_RSP_R3) {
  366. cmd_size = SDSPI_CMD_R3_SIZE;
  367. } else if (flags & SDSPI_CMD_FLAG_RSP_R7) {
  368. cmd_size = SDSPI_CMD_R7_SIZE;
  369. }
  370. spi_transaction_t t = {
  371. .flags = 0,
  372. .length = cmd_size * 8,
  373. .tx_buffer = cmd,
  374. .rx_buffer = cmd
  375. };
  376. esp_err_t ret = spi_device_transmit(spi_handle(slot), &t);
  377. return ret;
  378. }
  379. // Wait until MISO goes high
  380. static esp_err_t poll_busy(int slot, spi_transaction_t* t)
  381. {
  382. uint8_t t_rx;
  383. *t = (spi_transaction_t) {
  384. .tx_buffer = &t_rx,
  385. .flags = SPI_TRANS_USE_RXDATA, //data stored in rx_data
  386. .length = 8,
  387. };
  388. esp_err_t ret;
  389. for (int i = 0; i < SDSPI_RETRY_COUNT; i++) {
  390. t_rx = SDSPI_MOSI_IDLE_VAL;
  391. t->rx_data[0] = 0;
  392. ret = spi_device_transmit(spi_handle(slot), t);
  393. if (ret != ESP_OK) {
  394. return ret;
  395. }
  396. if (t->rx_data[0] != 0) {
  397. if (i < SDSPI_RETRY_COUNT - 2) {
  398. i = SDSPI_RETRY_COUNT - 2;
  399. }
  400. }
  401. }
  402. return ESP_OK;
  403. }
  404. // Wait for response token
  405. static esp_err_t poll_response_token(int slot, spi_transaction_t* t)
  406. {
  407. uint8_t t_rx;
  408. *t = (spi_transaction_t) {
  409. .tx_buffer = &t_rx,
  410. .flags = SPI_TRANS_USE_RXDATA,
  411. .length = 8,
  412. };
  413. esp_err_t ret;
  414. for (int retry = 0; retry < SDSPI_RETRY_COUNT; retry++) {
  415. t_rx = SDSPI_MOSI_IDLE_VAL;
  416. t->rx_data[0] = 0;
  417. ret = spi_device_transmit(spi_handle(slot), t);
  418. if (ret != ESP_OK) {
  419. return ret;
  420. }
  421. if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_OK) {
  422. break;
  423. }
  424. if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_CRC_ERR) {
  425. return ESP_ERR_INVALID_CRC;
  426. }
  427. if ((t->rx_data[0] & TOKEN_RSP_MASK) == TOKEN_RSP_WRITE_ERR) {
  428. return ESP_ERR_INVALID_RESPONSE;
  429. }
  430. if (retry == SDSPI_RETRY_COUNT - 1) {
  431. return ESP_ERR_TIMEOUT;
  432. }
  433. }
  434. return ESP_OK;
  435. }
  436. // Wait for data token, reading 8 bytes at a time.
  437. // If the token is found, write all subsequent bytes to extra_ptr,
  438. // and store the number of bytes written to extra_size.
  439. static esp_err_t poll_data_token(int slot, spi_transaction_t* t,
  440. uint8_t* extra_ptr, size_t* extra_size)
  441. {
  442. uint8_t t_rx[8];
  443. *t = (spi_transaction_t) {
  444. .tx_buffer = &t_rx,
  445. .rx_buffer = &t_rx,
  446. .length = sizeof(t_rx) * 8,
  447. };
  448. esp_err_t ret;
  449. for (int retry = 0; retry < SDSPI_RETRY_COUNT; retry++) {
  450. memset(t_rx, SDSPI_MOSI_IDLE_VAL, sizeof(t_rx));
  451. ret = spi_device_transmit(spi_handle(slot), t);
  452. if (ret != ESP_OK) {
  453. return ret;
  454. }
  455. bool found = false;
  456. for (int byte_idx = 0; byte_idx < sizeof(t_rx); byte_idx++) {
  457. uint8_t rd_data = t_rx[byte_idx];
  458. if (rd_data == TOKEN_BLOCK_START) {
  459. found = true;
  460. memcpy(extra_ptr, t_rx + byte_idx + 1, sizeof(t_rx) - byte_idx - 1);
  461. *extra_size = sizeof(t_rx) - byte_idx - 1;
  462. break;
  463. }
  464. if (rd_data != 0xff && rd_data != 0) {
  465. ESP_LOGD(TAG, "%s: received 0x%02x while waiting for data",
  466. __func__, rd_data);
  467. return ESP_ERR_INVALID_RESPONSE;
  468. }
  469. }
  470. if (found) {
  471. break;
  472. }
  473. if (retry == SDSPI_RETRY_COUNT - 1) {
  474. return ESP_ERR_TIMEOUT;
  475. }
  476. }
  477. return ESP_OK;
  478. }
  479. /**
  480. * Receiving one or more blocks of data happens as follows:
  481. * 1. send command + receive r1 response (SDSPI_CMD_R1_SIZE bytes total)
  482. * 2. keep receiving bytes until TOKEN_BLOCK_START is encountered (this may
  483. * take a while, depending on card's read speed)
  484. * 3. receive up to SDSPI_MAX_DATA_LEN = 512 bytes of actual data
  485. * 4. receive 2 bytes of CRC
  486. * 5. for multi block transfers, go to step 2
  487. *
  488. * These steps can be done separately, but that leads to a less than optimal
  489. * performance on large transfers because of delays between each step.
  490. * For example, if steps 3 and 4 are separate SPI transactions queued one after
  491. * another, there will be ~16 microseconds of dead time between end of step 3
  492. * and the beginning of step 4. A delay between two blocking SPI transactions
  493. * in step 2 is even higher (~60 microseconds).
  494. *
  495. * To improve read performance the following sequence is adopted:
  496. * 1. Do the first transfer: command + r1 response + 8 extra bytes.
  497. * Set pre_scan_data_ptr to point to the 8 extra bytes, and set
  498. * pre_scan_data_size to 8.
  499. * 2. Search pre_scan_data_size bytes for TOKEN_BLOCK_START.
  500. * If found, the rest of the bytes contain part of the actual data.
  501. * Store pointer to and size of that extra data as extra_data_{ptr,size}.
  502. * If not found, fall back to polling for TOKEN_BLOCK_START, 8 bytes at a
  503. * time (in poll_data_token function). Deal with extra data in the same way,
  504. * by setting extra_data_{ptr,size}.
  505. * 3. Receive the remaining 512 - extra_data_size bytes, plus 4 extra bytes
  506. * (i.e. 516 - extra_data_size). Of the 4 extra bytes, first two will capture
  507. * the CRC value, and the other two will capture 0xff 0xfe sequence
  508. * indicating the start of the next block. Actual scanning is done by
  509. * setting pre_scan_data_ptr to point to these last 2 bytes, and setting
  510. * pre_scan_data_size = 2, then going to step 2 to receive the next block.
  511. *
  512. * With this approach the delay between blocks of a multi-block transfer is
  513. * ~95 microseconds, out of which 35 microseconds are spend doing the CRC check.
  514. * Further speedup is possible by pipelining transfers and CRC checks, at an
  515. * expense of one extra temporary buffer.
  516. */
  517. static esp_err_t start_command_read_blocks(int slot, sdspi_hw_cmd_t *cmd,
  518. uint8_t *data, uint32_t rx_length)
  519. {
  520. bool need_stop_command = rx_length > SDSPI_MAX_DATA_LEN;
  521. spi_transaction_t* t_command = get_transaction(slot);
  522. *t_command = (spi_transaction_t) {
  523. .length = (SDSPI_CMD_R1_SIZE + 8) * 8,
  524. .tx_buffer = cmd,
  525. .rx_buffer = cmd,
  526. };
  527. esp_err_t ret = spi_device_transmit(spi_handle(slot), t_command);
  528. if (ret != ESP_OK) {
  529. return ret;
  530. }
  531. release_transaction(slot);
  532. uint8_t* cmd_u8 = (uint8_t*) cmd;
  533. size_t pre_scan_data_size = 8;
  534. uint8_t* pre_scan_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;
  535. while (rx_length > 0) {
  536. size_t extra_data_size = 0;
  537. const uint8_t* extra_data_ptr = NULL;
  538. bool need_poll = true;
  539. for (int i = 0; i < pre_scan_data_size; ++i) {
  540. if (pre_scan_data_ptr[i] == TOKEN_BLOCK_START) {
  541. extra_data_size = pre_scan_data_size - i - 1;
  542. extra_data_ptr = pre_scan_data_ptr + i + 1;
  543. need_poll = false;
  544. break;
  545. }
  546. }
  547. if (need_poll) {
  548. // Wait for data to be ready
  549. spi_transaction_t* t_poll = get_transaction(slot);
  550. poll_data_token(slot, t_poll, cmd_u8 + SDSPI_CMD_R1_SIZE, &extra_data_size);
  551. if (extra_data_size) {
  552. extra_data_ptr = cmd_u8 + SDSPI_CMD_R1_SIZE;
  553. }
  554. release_transaction(slot);
  555. }
  556. // Arrange RX buffer
  557. size_t will_receive = MIN(rx_length, SDSPI_MAX_DATA_LEN) - extra_data_size;
  558. uint8_t* rx_data;
  559. ret = get_block_buf(slot, &rx_data);
  560. if (ret != ESP_OK) {
  561. return ret;
  562. }
  563. // receive actual data
  564. const size_t receive_extra_bytes = 4;
  565. memset(rx_data, 0xff, will_receive + receive_extra_bytes);
  566. spi_transaction_t* t_data = get_transaction(slot);
  567. *t_data = (spi_transaction_t) {
  568. .length = (will_receive + receive_extra_bytes) * 8,
  569. .rx_buffer = rx_data,
  570. .tx_buffer = rx_data
  571. };
  572. ret = spi_device_transmit(spi_handle(slot), t_data);
  573. if (ret != ESP_OK) {
  574. return ret;
  575. }
  576. release_transaction(slot);
  577. // CRC bytes need to be received even if CRC is not enabled
  578. uint16_t crc = UINT16_MAX;
  579. memcpy(&crc, rx_data + will_receive, sizeof(crc));
  580. // Bytes to scan for the start token
  581. pre_scan_data_size = receive_extra_bytes - sizeof(crc);
  582. pre_scan_data_ptr = rx_data + will_receive + sizeof(crc);
  583. // Copy data to the destination buffer
  584. memcpy(data + extra_data_size, rx_data, will_receive);
  585. if (extra_data_size) {
  586. memcpy(data, extra_data_ptr, extra_data_size);
  587. }
  588. // compute CRC of the received data
  589. uint16_t crc_of_data = 0;
  590. if (data_crc_enabled(slot)) {
  591. crc_of_data = sdspi_crc16(data, will_receive + extra_data_size);
  592. if (crc_of_data != crc) {
  593. ESP_LOGE(TAG, "data CRC failed, got=0x%04x expected=0x%04x", crc_of_data, crc);
  594. esp_log_buffer_hex(TAG, data, 16);
  595. return ESP_ERR_INVALID_CRC;
  596. }
  597. }
  598. data += will_receive + extra_data_size;
  599. rx_length -= will_receive + extra_data_size;
  600. extra_data_size = 0;
  601. extra_data_ptr = NULL;
  602. }
  603. if (need_stop_command) {
  604. // To end multi block transfer, send stop command and wait for the
  605. // card to process it
  606. sdspi_hw_cmd_t stop_cmd;
  607. make_hw_cmd(MMC_STOP_TRANSMISSION, 0, &stop_cmd);
  608. ret = start_command_default(slot, SDSPI_CMD_FLAG_RSP_R1, &stop_cmd);
  609. if (ret != ESP_OK) {
  610. return ret;
  611. }
  612. spi_transaction_t* t_poll = get_transaction(slot);
  613. ret = poll_busy(slot, t_poll);
  614. release_transaction(slot);
  615. }
  616. return ESP_OK;
  617. }
  618. static esp_err_t start_command_write_blocks(int slot, sdspi_hw_cmd_t *cmd,
  619. const uint8_t *data, uint32_t tx_length)
  620. {
  621. if (card_write_protected(slot)) {
  622. ESP_LOGW(TAG, "%s: card write protected", __func__);
  623. return ESP_ERR_INVALID_STATE;
  624. }
  625. spi_transaction_t* t_command = get_transaction(slot);
  626. *t_command = (spi_transaction_t) {
  627. .length = SDSPI_CMD_R1_SIZE * 8,
  628. .tx_buffer = cmd,
  629. .rx_buffer = cmd,
  630. };
  631. esp_err_t ret = spi_device_queue_trans(spi_handle(slot), t_command, 0);
  632. if (ret != ESP_OK) {
  633. return ret;
  634. }
  635. uint8_t start_token = tx_length <= SDSPI_MAX_DATA_LEN ?
  636. TOKEN_BLOCK_START : TOKEN_BLOCK_START_WRITE_MULTI;
  637. wait_for_transactions(slot);
  638. while (tx_length > 0) {
  639. // Write block start token
  640. spi_transaction_t* t_start_token = get_transaction(slot);
  641. *t_start_token = (spi_transaction_t) {
  642. .length = sizeof(start_token) * 8,
  643. .tx_buffer = &start_token
  644. };
  645. esp_err_t ret = spi_device_queue_trans(spi_handle(slot), t_start_token, 0);
  646. if (ret != ESP_OK) {
  647. return ret;
  648. }
  649. // Prepare data to be sent
  650. size_t will_send = MIN(tx_length, SDSPI_MAX_DATA_LEN);
  651. const uint8_t* tx_data = data;
  652. if (!ptr_dma_compatible(tx_data)) {
  653. // If the pointer can't be used with DMA, copy data into a new buffer
  654. uint8_t* tmp;
  655. ret = get_block_buf(slot, &tmp);
  656. if (ret != ESP_OK) {
  657. return ret;
  658. }
  659. memcpy(tmp, tx_data, will_send);
  660. tx_data = tmp;
  661. }
  662. // Write data
  663. spi_transaction_t* t_data = get_transaction(slot);
  664. *t_data = (spi_transaction_t) {
  665. .length = will_send * 8,
  666. .tx_buffer = tx_data,
  667. };
  668. ret = spi_device_queue_trans(spi_handle(slot), t_data, 0);
  669. if (ret != ESP_OK) {
  670. return ret;
  671. }
  672. // Write CRC
  673. uint16_t crc = sdspi_crc16(data, will_send);
  674. spi_transaction_t* t_crc = get_transaction(slot);
  675. *t_crc = (spi_transaction_t) {
  676. .length = sizeof(crc) * 8,
  677. .tx_buffer = (uint8_t*) &crc,
  678. };
  679. ret = spi_device_queue_trans(spi_handle(slot), t_crc, 0);
  680. if (ret != ESP_OK) {
  681. return ret;
  682. }
  683. // Wait for data to be sent
  684. wait_for_transactions(slot);
  685. // Check if R1 response for the command was correct
  686. if (cmd->r1 != 0) {
  687. ESP_LOGD(TAG, "%s: invalid R1 response: 0x%02x", __func__, cmd->r1);
  688. return ESP_ERR_INVALID_RESPONSE;
  689. }
  690. // Poll for response
  691. spi_transaction_t* t_poll = get_transaction(slot);
  692. ret = poll_response_token(slot, t_poll);
  693. release_transaction(slot);
  694. if (ret != ESP_OK) {
  695. return ret;
  696. }
  697. // Wait for the card to finish writing data
  698. t_poll = get_transaction(slot);
  699. ret = poll_busy(slot, t_poll);
  700. release_transaction(slot);
  701. if (ret != ESP_OK) {
  702. return ret;
  703. }
  704. tx_length -= will_send;
  705. data += will_send;
  706. }
  707. if (start_token == TOKEN_BLOCK_START_WRITE_MULTI) {
  708. uint8_t stop_token[2] = {
  709. TOKEN_BLOCK_STOP_WRITE_MULTI,
  710. SDSPI_MOSI_IDLE_VAL
  711. };
  712. spi_transaction_t* t_stop_token = get_transaction(slot);
  713. *t_stop_token = (spi_transaction_t) {
  714. .length = sizeof(stop_token) * 8,
  715. .tx_buffer = &stop_token,
  716. };
  717. ret = spi_device_queue_trans(spi_handle(slot), t_stop_token, 0);
  718. if (ret != ESP_OK) {
  719. return ret;
  720. }
  721. wait_for_transactions(slot);
  722. spi_transaction_t* t_poll = get_transaction(slot);
  723. ret = poll_busy(slot, t_poll);
  724. release_transaction(slot);
  725. if (ret != ESP_OK) {
  726. return ret;
  727. }
  728. }
  729. return ESP_OK;
  730. }