essl_sdio.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. // Copyright 2015-2019 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 "essl_sdio.h"
  15. #include "esp_log.h"
  16. #include "freertos/task.h"
  17. #include "essl_internal.h"
  18. #include "soc/soc_caps.h"
  19. #if SOC_SDIO_SLAVE_SUPPORTED
  20. #include "soc/host_reg.h"
  21. static const char TAG[] = "essl_sdio";
  22. #define HOST_SLCHOST_CONF_W_REG(pos) (HOST_SLCHOST_CONF_W0_REG+pos+(pos>23?4:0)+(pos>31?12:0))
  23. #define ESSL_CMD53_END_ADDR 0x1f800
  24. #define TX_BUFFER_MAX 0x1000
  25. #define TX_BUFFER_MASK 0xFFF
  26. #define RX_BYTE_MAX 0x100000
  27. #define RX_BYTE_MASK 0xFFFFF
  28. #define FUNC1_EN_MASK (BIT(1))
  29. /**
  30. * Initialize ``void`` over SDIO by this macro.
  31. */
  32. #define ESSL_SDIO_DEFAULT_CONTEXT() (essl_dev_t){\
  33. .init = essl_sdio_init, \
  34. .wait_for_ready = essl_sdio_wait_for_ready, \
  35. .get_tx_buffer_num = essl_sdio_get_tx_buffer_num,\
  36. .update_tx_buffer_num = essl_sdio_update_tx_buffer_num,\
  37. .get_rx_data_size = essl_sdio_get_rx_data_size,\
  38. .update_rx_data_size = essl_sdio_update_rx_data_size,\
  39. .send_packet = essl_sdio_send_packet,\
  40. .get_packet = essl_sdio_get_packet,\
  41. .write_reg = essl_sdio_write_reg,\
  42. .read_reg = essl_sdio_read_reg,\
  43. .wait_int = essl_sdio_wait_int,\
  44. .send_slave_intr = essl_sdio_send_slave_intr, \
  45. .get_intr = essl_sdio_get_intr, \
  46. .clear_intr = essl_sdio_clear_intr, \
  47. .set_intr_ena = essl_sdio_set_intr_ena, \
  48. .reset_cnt = essl_sdio_reset_cnt, \
  49. }
  50. typedef struct{
  51. //common part
  52. uint16_t buffer_size;
  53. ///< All data that do not fully fill a buffer is still counted as one buffer. E.g. 10 bytes data costs 2 buffers if the size is 8 bytes per buffer.
  54. ///< Buffer size of the slave pre-defined between host and slave before communication.
  55. size_t tx_sent_buffers; ///< Counter holding the amount of buffers already sent to ESP32 slave. Should be set to 0 when initialization.
  56. size_t tx_sent_buffers_latest; ///< The latest reading (from the slave) of counter holding the amount of buffers loaded. Should be set to 0 when initialization.
  57. size_t rx_got_bytes; ///< Counter holding the amount of bytes already received from ESP32 slave. Should be set to 0 when initialization.
  58. size_t rx_got_bytes_latest; ///< The latest reading (from the slave) of counter holding the amount of bytes to send. Should be set to 0 when initialization.
  59. sdmmc_card_t* card; ///< Initialized sdmmc_cmd card
  60. uint16_t block_size;
  61. ///< If this is too large, it takes time to send stuff bits; while if too small, intervals between blocks cost much.
  62. ///< Should be set according to length of data, and larger than ``TRANS_LEN_MAX/511``.
  63. ///< Block size of the SDIO function 1. After the initialization this will hold the value the slave really do. Valid value is 1-2048.
  64. } essl_sdio_context_t;
  65. esp_err_t essl_sdio_update_tx_buffer_num(void *arg, uint32_t wait_ms);
  66. esp_err_t essl_sdio_update_rx_data_size(void *arg, uint32_t wait_ms);
  67. static inline esp_err_t essl_sdio_write_byte(sdmmc_card_t *card, uint32_t addr, uint8_t val, uint8_t *val_o)
  68. {
  69. return sdmmc_io_write_byte(card, 1, addr&0x3FF, val, val_o);
  70. }
  71. static inline esp_err_t essl_sdio_write_bytes(sdmmc_card_t *card, uint32_t addr, uint8_t *val, int len)
  72. {
  73. return sdmmc_io_write_bytes(card, 1, addr&0x3FF, val, len);
  74. }
  75. static inline esp_err_t essl_sdio_read_byte(sdmmc_card_t *card, uint32_t addr, uint8_t *val_o)
  76. {
  77. return sdmmc_io_read_byte(card, 1, addr&0x3FF, val_o);
  78. }
  79. static inline esp_err_t essl_sdio_read_bytes(sdmmc_card_t *card, uint32_t addr, uint8_t *val_o, int len)
  80. {
  81. return sdmmc_io_read_bytes(card, 1, addr&0x3FF, val_o, len);
  82. }
  83. esp_err_t essl_sdio_init_dev(essl_handle_t *out_handle, const essl_sdio_config_t *config)
  84. {
  85. esp_err_t ret = ESP_OK;
  86. essl_sdio_context_t* arg = NULL;
  87. essl_dev_t* dev = NULL;
  88. arg = (essl_sdio_context_t*)heap_caps_malloc(sizeof(essl_sdio_context_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  89. dev = (essl_dev_t*)heap_caps_malloc(sizeof(essl_dev_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  90. if (arg == NULL || dev == NULL) {
  91. ret = ESP_ERR_NO_MEM;
  92. goto cleanup;
  93. }
  94. *dev = ESSL_SDIO_DEFAULT_CONTEXT();
  95. dev->args = arg;
  96. *arg = (essl_sdio_context_t) {
  97. .card = config->card,
  98. .block_size = 0x200,
  99. .buffer_size = config->recv_buffer_size,
  100. .tx_sent_buffers = 0,
  101. .rx_got_bytes = 0,
  102. };
  103. *out_handle = dev;
  104. return ESP_OK;
  105. cleanup:
  106. free(arg);
  107. free(dev);
  108. return ret;
  109. }
  110. esp_err_t essl_sdio_deinit_dev(essl_handle_t handle)
  111. {
  112. if (handle) free (handle->args);
  113. free(handle);
  114. return ESP_OK;
  115. }
  116. esp_err_t essl_sdio_init(void *arg, uint32_t wait_ms)
  117. {
  118. essl_sdio_context_t* ctx = arg;
  119. esp_err_t err;
  120. uint8_t ioe;
  121. sdmmc_card_t* card = ctx->card;
  122. err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_ENABLE, &ioe);
  123. if (err != ESP_OK) return err;
  124. ESP_LOGD(TAG, "IOE: 0x%02x", ioe);
  125. uint8_t ior = 0;
  126. err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
  127. if (err != ESP_OK) return err;
  128. ESP_LOGD(TAG, "IOR: 0x%02x", ior);
  129. // enable function 1
  130. ioe |= FUNC1_EN_MASK;
  131. err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_FN_ENABLE, ioe, &ioe);
  132. if (err != ESP_OK) return err;
  133. ESP_LOGD(TAG, "IOE: 0x%02x", ioe);
  134. // wait for the card to become ready
  135. while ((ior & FUNC1_EN_MASK) == 0) {
  136. err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
  137. if (err != ESP_OK) return err;
  138. ESP_LOGD(TAG, "IOR: 0x%02x", ior);
  139. }
  140. // get interrupt status
  141. uint8_t ie;
  142. err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_INT_ENABLE, &ie);
  143. if (err != ESP_OK) return err;
  144. ESP_LOGD(TAG,"IE: 0x%02x", ie);
  145. // enable interrupts for function 1&2 and master enable
  146. ie |= BIT(0) | FUNC1_EN_MASK;
  147. err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_INT_ENABLE, ie, &ie);
  148. if (err != ESP_OK) return err;
  149. ESP_LOGD(TAG, "IE: 0x%02x", ie);
  150. // get bus width register
  151. uint8_t bus_width;
  152. err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BUS_WIDTH, &bus_width);
  153. if (err != ESP_OK) return err;
  154. ESP_LOGD(TAG,"BUS_WIDTH: 0x%02x", bus_width);
  155. // enable continuous SPI interrupts
  156. bus_width |= CCCR_BUS_WIDTH_ECSI;
  157. err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BUS_WIDTH, bus_width, &bus_width);
  158. if (err != ESP_OK) return err;
  159. ESP_LOGD(TAG, "BUS_WIDTH: 0x%02x", bus_width);
  160. uint16_t bs = 512;
  161. const uint8_t* bs_u8 = (const uint8_t*) &bs;
  162. uint16_t bs_read = 0;
  163. uint8_t* bs_read_u8 = (uint8_t*) &bs_read;
  164. // Set block sizes for functions 0 to 512 bytes
  165. ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
  166. ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
  167. ESP_LOGD(TAG, "Function 0 BS: %04x", (int) bs_read);
  168. ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BLKSIZEL, bs_u8[0], NULL));
  169. ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BLKSIZEH, bs_u8[1], NULL));
  170. ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
  171. ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
  172. ESP_LOGD(TAG, "Function 0 BS: %04x", (int) bs_read);
  173. // Set block sizes for functions 1 to given value (default value = 512).
  174. if (ctx->block_size > 0 || ctx->block_size <= 2048) {
  175. bs = ctx->block_size;
  176. } else {
  177. bs = 512;
  178. }
  179. size_t offset = SD_IO_FBR_START * 1;
  180. ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
  181. ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
  182. ESP_LOGD(TAG, "Function 1 BS: %04x", (int) bs_read);
  183. ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, bs_u8[0], NULL));
  184. ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, bs_u8[1], NULL));
  185. ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
  186. ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
  187. ESP_LOGD(TAG, "Function 1 BS: %04x", (int) bs_read);
  188. if (bs_read != ctx->block_size) {
  189. ESP_LOGW(TAG, "Function1 block size %d different than set value %d", bs_read, ctx->block_size);
  190. ctx->block_size = bs_read;
  191. }
  192. return ESP_OK;
  193. }
  194. esp_err_t essl_sdio_wait_for_ready(void *arg, uint32_t wait_ms)
  195. {
  196. ESP_LOGV(TAG, "wait_for_ioready");
  197. esp_err_t err;
  198. sdmmc_card_t *card = ((essl_sdio_context_t*)arg)->card;
  199. // wait for the card to become ready
  200. uint8_t ior = 0;
  201. while ((ior & FUNC1_EN_MASK) == 0) {
  202. err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
  203. if (err != ESP_OK) return err;
  204. ESP_LOGD(TAG, "IOR: 0x%02x", ior);
  205. }
  206. return ESP_OK;
  207. }
  208. esp_err_t essl_sdio_send_packet(void *arg, const void *start, size_t length, uint32_t wait_ms)
  209. {
  210. essl_sdio_context_t* ctx = arg;
  211. uint16_t buffer_size = ctx->buffer_size;
  212. int buffer_used = (length + buffer_size - 1)/buffer_size;
  213. esp_err_t err;
  214. if (essl_sdio_get_tx_buffer_num(arg) < buffer_used) {
  215. //slave has no enough buffer, try update for once
  216. esp_err_t err = essl_sdio_update_tx_buffer_num(arg, wait_ms);
  217. if (err != ESP_OK) {
  218. return err;
  219. }
  220. if (essl_sdio_get_tx_buffer_num(arg) < buffer_used) {
  221. ESP_LOGV(TAG, "buffer is not enough: %d, %d required.", ctx->tx_sent_buffers_latest, ctx->tx_sent_buffers + buffer_used);
  222. return ESP_ERR_NOT_FOUND;
  223. }
  224. }
  225. ESP_LOGV(TAG, "send_packet: len: %d", length);
  226. uint8_t *start_ptr = (uint8_t*)start;
  227. uint32_t len_remain = length;
  228. do {
  229. const int block_size = 512;
  230. /* Though the driver supports to split packet of unaligned size into
  231. * length of 4x and 1~3, we still send aligned size of data to get
  232. * higher effeciency. The length is determined by the SDIO address, and
  233. * the remainning will be discard by the slave hardware.
  234. */
  235. int block_n = len_remain/block_size;
  236. int len_to_send;
  237. if (block_n) {
  238. len_to_send = block_n * block_size;
  239. err = sdmmc_io_write_blocks(ctx->card, 1, ESSL_CMD53_END_ADDR - len_remain, start_ptr, len_to_send);
  240. } else {
  241. len_to_send = len_remain;
  242. err = sdmmc_io_write_bytes(ctx->card, 1, ESSL_CMD53_END_ADDR - len_remain, start_ptr, (len_to_send + 3) & (~3));
  243. }
  244. if (err != ESP_OK) return err;
  245. start_ptr += len_to_send;
  246. len_remain -= len_to_send;
  247. } while (len_remain);
  248. ctx->tx_sent_buffers += buffer_used;
  249. return ESP_OK;
  250. }
  251. esp_err_t essl_sdio_get_packet(void *arg, void *out_data, size_t size, uint32_t wait_ms)
  252. {
  253. essl_sdio_context_t* ctx = arg;
  254. esp_err_t err;
  255. ESP_LOGV(TAG, "get_packet: read size=%d", size);
  256. if (essl_sdio_get_rx_data_size(arg) < size) {
  257. err = essl_sdio_update_rx_data_size(arg, wait_ms);
  258. if (err != ESP_OK) {
  259. return err;
  260. }
  261. if (essl_sdio_get_rx_data_size(arg) < size) {
  262. return ESP_ERR_NOT_FOUND;
  263. }
  264. }
  265. uint8_t *start = out_data;
  266. uint32_t len_remain = size;
  267. do {
  268. const int block_size = 512; //currently our driver don't support block size other than 512
  269. int len_to_send;
  270. int block_n = len_remain/block_size;
  271. if (block_n != 0) {
  272. len_to_send = block_n * block_size;
  273. err = sdmmc_io_read_blocks(ctx->card, 1, ESSL_CMD53_END_ADDR - len_remain, start, len_to_send);
  274. } else {
  275. len_to_send = len_remain;
  276. /* though the driver supports to split packet of unaligned size into length
  277. * of 4x and 1~3, we still get aligned size of data to get higher
  278. * effeciency. The length is determined by the SDIO address, and the
  279. * remainning will be ignored by the slave hardware.
  280. */
  281. err = sdmmc_io_read_bytes(ctx->card, 1, ESSL_CMD53_END_ADDR - len_remain, start, (len_to_send + 3) & (~3));
  282. }
  283. if (err != ESP_OK) return err;
  284. start += len_to_send;
  285. len_remain -= len_to_send;
  286. ctx->rx_got_bytes += len_to_send;
  287. } while(len_remain!=0);
  288. return err;
  289. }
  290. uint32_t essl_sdio_get_tx_buffer_num(void *arg)
  291. {
  292. essl_sdio_context_t* ctx = arg;
  293. ESP_LOGV(TAG, "tx latest: %d, sent: %d", ctx->tx_sent_buffers_latest, ctx->tx_sent_buffers);
  294. return (ctx->tx_sent_buffers_latest + TX_BUFFER_MAX - ctx->tx_sent_buffers)%TX_BUFFER_MAX;
  295. }
  296. esp_err_t essl_sdio_update_tx_buffer_num(void *arg, uint32_t wait_ms)
  297. {
  298. essl_sdio_context_t* ctx = arg;
  299. uint32_t len;
  300. esp_err_t err;
  301. err = essl_sdio_read_bytes(ctx->card, HOST_SLC0HOST_TOKEN_RDATA_REG, (uint8_t *) &len, 4);
  302. if (err != ESP_OK) return err;
  303. len = (len>>16)&TX_BUFFER_MASK;
  304. ctx->tx_sent_buffers_latest = len;
  305. ESP_LOGV(TAG, "update_tx_buffer_num: %d", len);
  306. return ESP_OK;
  307. }
  308. uint32_t essl_sdio_get_rx_data_size(void *arg)
  309. {
  310. essl_sdio_context_t* ctx = arg;
  311. ESP_LOGV(TAG, "rx latest: %d, read: %d", ctx->rx_got_bytes_latest, ctx->rx_got_bytes);
  312. return (ctx->rx_got_bytes_latest + RX_BYTE_MAX - ctx->rx_got_bytes)%RX_BYTE_MAX;
  313. }
  314. esp_err_t essl_sdio_update_rx_data_size(void *arg, uint32_t wait_ms)
  315. {
  316. essl_sdio_context_t* ctx = arg;
  317. uint32_t len;
  318. esp_err_t err;
  319. ESP_LOGV(TAG, "get_rx_data_size: got_bytes: %d", ctx->rx_got_bytes);
  320. err = essl_sdio_read_bytes(ctx->card, HOST_SLCHOST_PKT_LEN_REG, (uint8_t *) &len, 4);
  321. if (err != ESP_OK) return err;
  322. len &= RX_BYTE_MASK;
  323. ctx->rx_got_bytes_latest = len;
  324. return ESP_OK;
  325. }
  326. esp_err_t essl_sdio_write_reg(void *arg, uint8_t addr, uint8_t value, uint8_t *value_o, uint32_t wait_ms)
  327. {
  328. ESP_LOGV(TAG, "write_reg: %08X", value);
  329. // addrress over range
  330. if (addr >= 60) return ESP_ERR_INVALID_ARG;
  331. //W7 is reserved for interrupts
  332. if (addr >= 28) addr += 4;
  333. return essl_sdio_write_byte(((essl_sdio_context_t*)arg)->card, HOST_SLCHOST_CONF_W_REG(addr), value, value_o);
  334. }
  335. esp_err_t essl_sdio_read_reg(void *arg, uint8_t add, uint8_t *value_o, uint32_t wait_ms)
  336. {
  337. ESP_LOGV(TAG, "read_reg");
  338. // address over range
  339. if (add >= 60) return ESP_ERR_INVALID_ARG;
  340. //W7 is reserved for interrupts
  341. if (add >= 28) add += 4;
  342. esp_err_t ret = essl_sdio_read_byte(((essl_sdio_context_t*)arg)->card, HOST_SLCHOST_CONF_W_REG(add), value_o);
  343. ESP_LOGV(TAG, "reg: %08X", *value_o);
  344. return ret;
  345. }
  346. esp_err_t essl_sdio_clear_intr(void *arg, uint32_t intr_mask, uint32_t wait_ms)
  347. {
  348. ESP_LOGV(TAG, "clear_intr: %08X", intr_mask);
  349. return essl_sdio_write_bytes(((essl_sdio_context_t *) arg)->card, HOST_SLC0HOST_INT_CLR_REG, (uint8_t *) &intr_mask, 4);
  350. }
  351. esp_err_t essl_sdio_get_intr(void *arg, uint32_t *intr_raw, uint32_t *intr_st, uint32_t wait_ms)
  352. {
  353. essl_sdio_context_t* ctx = arg;
  354. esp_err_t r;
  355. ESP_LOGV(TAG, "get_intr");
  356. if (intr_raw == NULL && intr_st == NULL) return ESP_ERR_INVALID_ARG;
  357. if (intr_raw != NULL) {
  358. r= essl_sdio_read_bytes(ctx->card, HOST_SLC0HOST_INT_RAW_REG, (uint8_t *) intr_raw, 4);
  359. if (r != ESP_OK) return r;
  360. }
  361. if (intr_st != NULL) {
  362. r = essl_sdio_read_bytes(ctx->card, HOST_SLC0HOST_INT_ST_REG, (uint8_t *) intr_st, 4);
  363. if (r != ESP_OK) return r;
  364. }
  365. return ESP_OK;
  366. }
  367. esp_err_t essl_sdio_set_intr_ena(void *arg, uint32_t ena_mask, uint32_t wait_ms)
  368. {
  369. ESP_LOGV(TAG, "set_intr_ena: %08X", ena_mask);
  370. return essl_sdio_write_bytes(((essl_sdio_context_t*)arg)->card, HOST_SLC0HOST_FUNC1_INT_ENA_REG,
  371. (uint8_t *) &ena_mask, 4);
  372. }
  373. esp_err_t essl_sdio_get_intr_ena(void *arg, uint32_t *ena_mask_o, uint32_t wait_ms)
  374. {
  375. ESP_LOGV(TAG, "get_intr_ena");
  376. esp_err_t ret = essl_sdio_read_bytes(((essl_sdio_context_t*)arg)->card, HOST_SLC0HOST_FUNC1_INT_ENA_REG,
  377. (uint8_t *) ena_mask_o, 4);
  378. ESP_LOGV(TAG, "ena: %08X", *ena_mask_o);
  379. return ret;
  380. }
  381. esp_err_t essl_sdio_send_slave_intr(void *arg, uint32_t intr_mask, uint32_t wait_ms)
  382. {
  383. ESP_LOGV(TAG, "send_slave_intr: %02x", intr_mask);
  384. return essl_sdio_write_byte(((essl_sdio_context_t*)arg)->card, HOST_SLCHOST_CONF_W7_REG + 0, intr_mask, NULL);
  385. }
  386. esp_err_t essl_sdio_wait_int(void *arg, uint32_t wait_ms)
  387. {
  388. return sdmmc_io_wait_int(((essl_sdio_context_t*)arg)->card, wait_ms);
  389. }
  390. void essl_sdio_reset_cnt(void *arg)
  391. {
  392. essl_sdio_context_t* ctx = arg;
  393. ctx->rx_got_bytes = 0;
  394. ctx->tx_sent_buffers = 0;
  395. }
  396. #endif // #if SOC_SDIO_SLAVE_SUPPORTED