sdio_slave_hal.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  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. /*******************************************************************************
  15. * NOTICE
  16. * The hal is not public api, don't use in application code.
  17. * See readme.md in soc/include/hal/readme.md
  18. ******************************************************************************/
  19. // The HAL layer for SDIO slave (common part)
  20. // SDIO slave HAL usages:
  21. /*
  22. Architecture:
  23. The whole SDIO slave peripheral consists of three parts: the registers (including the interrupt
  24. control and shared registers), a send FIFO, and a receive FIFO. The document
  25. ``esp_slave_protocol.rst`` describes the functionality of the peripheral in detail. An SDIO host
  26. will only ever access one of the three parts at any one time, thus the hardware functionality of
  27. the SDIO slave peripheral are completely independent. Likewise, this HAL is organized in such a
  28. fashion as to correspond to the three independent parts.
  29. The shared registers are quite simple: the slave can directly access them from the internal data
  30. bus, while the host can access them by CMD52/53 with the correct address. As for the interrupts:
  31. when an SDIO host interrupts the SDIO slave peripheral (by writing a command), the corresponding
  32. bit in the interrupt register will be set; when the SDIO slave peripheral needs to interrupt the
  33. host, it write some register to cause the host interrupt bit being set, and the slave hardware
  34. will output the interrupt signal on the DAT1 line.
  35. For the FIFOs, the peripheral provides counters as registers so that the host can always know whether the slave
  36. is ready to send/receive data. The HAL resets the counters during initialization, and the host should somehow
  37. inform the slave to reset the counters again if it should reboot (or lose the counter value for some reasons).
  38. Then the host can read/write the FIFOs by CMD53 commands according to the counters.
  39. In order to avoid copying data to/from the FIFOs or memory buffers each time, the HAL layer
  40. contains a descriptor queue (implemented as linked-list) that allows descriptors of memory
  41. buffers to be queued for transmission/reception. Once a buffer is queued, the HAL takes ownership
  42. of the buffer until some "finish" functions successfully return, indicating the
  43. transmission/reception of that buffer is complete. The ISR is invoked multiple times to iterate
  44. through the queued descriptors, and also to signal to the upper layer if a buffer has been
  45. freed.
  46. The HAL is used as below:
  47. - Receiving part:
  48. 1. Call `sdio_slave_hal_recv_start` to start the receiving DMA.
  49. If there are already buffers loaded, the receiving will start from those buffers first.
  50. 2. Call `sdio_slave_hal_recv_init_desc` with a `sdio_slave_hal_recv_desc_t` and the buffer address to
  51. associate the descriptor with the buffer.
  52. The HAL initialize this descriptors with the determined length and maybe some extra data.
  53. 3. Call `sdio_slave_hal_load_buf` with the initialized descriptor of the buffer to load a
  54. receiving buffer to the HAL.
  55. When the DMA is started, the descriptors is loaded onto the DMA linked-list, and the
  56. counter of receiving buffers is increased so that the host will know this by the
  57. receiving interrupt. The hardware will automatically go through the linked list and write
  58. data into the buffers loaded on the list.
  59. 4. (Optional, mandatory only when interrupt enabled) Call `sdio_slave_hal_recv_done` to check
  60. and clear the receiving interrupt bits.
  61. 5. Call `sdio_slave_hal_recv_has_next_item` to check whether there are finished buffers.
  62. 6. Call `sdio_slave_hal_recv_unload_desc` for the same times as
  63. `sdio_slave_hal_recv_has_next_item` successfully returns.
  64. 7. (Optional) Call `sdio_slave_hal_recv_reset_counter` to reset the counter to current loaded
  65. but not used buffers if you want to reset the counter only. This is available only when
  66. the DMA is stopped.
  67. 8. (Optional) Call `sdio_slave_hal_recv_flush_one_buffer` (recursively) if you want to
  68. discard data of one (or more) buffers and load them again. This is available only when
  69. the DMA is stopped.
  70. 9. (Optional when deinitialization) Call `sdio_slave_hal_recv_unload_desc` recursively to get
  71. all the buffers loaded to the HAL, no matter they are used or not. Don't do this when the
  72. DMA is not stopped.
  73. - Sending part:
  74. The sending driver is slightly different, since we are not using the re-start feature.
  75. (TODO: re-write this part if the stitch mode is released)
  76. 1. Call `sdio_slave_hal_send_start` to start the sending DMA.
  77. If there is already any data queued, it will ne ready to be sent to host now.
  78. 2. Call `sdio_slave_hal_send_queue` to queue the data to send.
  79. If the interrupt is enabled, the ISR will be invoked.
  80. 3. (Required if interrupt enabled) Call `` to clear the interrupt bits used by the SW
  81. invoking logic.
  82. 4. Call `sdio_slave_hal_send_new_packet_if_exist` to check and send new packet (if there is
  83. data queued).
  84. 5. Call `sdio_slave_hal_send_eof_happened` to check whether the previous packet is done.
  85. It will also clear the interrupt status bit for this event.
  86. 6. Call `sdio_slave_hal_send_get_next_finished_arg` recursively to get the arguments for the
  87. finished buffers.
  88. 7. (Optional when deinitialization) Call `sdio_slave_hal_send_flush_next_buffer` recursively
  89. to get all buffers queued, regardless sent or not. Don't do this when the DMA is not stopped.
  90. 8. (Optional) Call `sdio_slave_hal_send_reset_counter` to reset the counter to current loaded
  91. but not sent buffers if you want to reset the counter only. Don't do this when the DMA is not
  92. stopped.
  93. Note a counter should be used when performing step 2 and 6, to make sure that the queue size
  94. is enough.
  95. - Host part:
  96. 1. Call `sdio_slave_hal_hostint_set_ena` and `sdio_slave_hal_hostint_get_ena` to
  97. enable/disable the interrupt sent to master. Note that the host can also modify the same
  98. registers at the same time. Try to avoid using them outside the initialization process.
  99. 2. Call `sdio_slave_hal_hostint_send` and `sdio_slave_hal_hostint_clear` to trigger general
  100. purpose interrupts or cancel all kinds of interrupts send to the host. These interrupts are
  101. set/cleared in a concurrent-safe way, so the slave can call these functions safely.
  102. 3. Call `sdio_slave_hal_slvint_fetch_clear` to fetch the general purpose interrupts sent by
  103. the host to the slave. These interrupts will also be cleared after the calls.
  104. 4. Call `sdio_slave_hal_host_get_reg` and `sdio_slave_hal_host_set_reg` to read/write the
  105. general purpose shared between the host and slave. Note that these registers are also not
  106. concurrent-safe. Try not to write to the same register from two directions at the same time.
  107. */
  108. #pragma once
  109. #include <esp_err.h>
  110. #include "soc/lldesc.h"
  111. #include "hal/sdio_slave_types.h"
  112. #include "hal/sdio_slave_ll.h"
  113. /// Space used for each sending descriptor. Should initialize the sendbuf accoring to this size.
  114. #define SDIO_SLAVE_SEND_DESC_SIZE sizeof(sdio_slave_hal_send_desc_t)
  115. /// Status of the sending part
  116. typedef enum {
  117. STATE_IDLE = 1,
  118. STATE_WAIT_FOR_START = 2,
  119. STATE_SENDING = 3,
  120. STATE_GETTING_RESULT = 4,
  121. STATE_GETTING_UNSENT_DESC = 5,
  122. } send_state_t;
  123. typedef struct {
  124. uint8_t* data; ///< Address of the buffer
  125. size_t size; ///< Size of the buffer, but can only queue (size/SDIO_SLAVE_SEND_DESC_SIZE)-1 descriptors
  126. uint8_t* write_ptr;
  127. uint8_t* read_ptr;
  128. uint8_t* free_ptr;
  129. } sdio_ringbuf_t;
  130. // Append two extra words to be used by the HAL.
  131. // Should Initialize the member `data` of `send_desc_queue` of the HAL context
  132. // with size of this desc * N.
  133. /// DMA descriptor with extra fields
  134. typedef struct sdio_slave_hal_send_desc_s {
  135. lldesc_t dma_desc; ///< Used by Hardware, has pointer linking to next desc
  136. uint32_t pkt_len; ///< Accumulated length till this descriptor
  137. void* arg; ///< Holding arguments indicating this buffer */
  138. } sdio_slave_hal_send_desc_t;
  139. /// Descriptor used by the receiving part, call `sdio_slave_hal_recv_init_desc`
  140. /// to initialize it before use.
  141. typedef lldesc_t sdio_slave_hal_recv_desc_t;
  142. #define sdio_slave_hal_recv_desc_s lldesc_s
  143. typedef STAILQ_HEAD(recv_stailq_head_s, sdio_slave_hal_recv_desc_s) sdio_slave_hal_recv_stailq_t;
  144. /** HAL context structure. Call `sdio_slave_hal_init` to initialize it and
  145. * configure required members before actually use the HAL.
  146. */
  147. typedef struct {
  148. /// Hardware registers for this SDIO slave peripheral, configured by
  149. /// `sdio_slave_hal_init`
  150. struct {
  151. slc_dev_t* slc;
  152. host_dev_t* host;
  153. hinf_dev_t* hinf;
  154. };
  155. sdio_slave_sending_mode_t sending_mode; /**< Sending mode, should be manually configured before using the HAL.
  156. * see `sdio_slave_sending_mode_t`.
  157. */
  158. sdio_slave_timing_t timing; /**< Timing mode (launch edge and latch edge settings). Should be manually
  159. * configured before using the HAL. `SDIO_SLAVE_TIMING_PSEND_PSAMPLE` is
  160. * recommended by default.
  161. */
  162. int send_queue_size; /**< Max buffers that can be queued before sending. Should be manually
  163. * configured before using the HAL.
  164. */
  165. size_t recv_buffer_size; /**< The size of each buffer. The host and slave should share a
  166. * pre-negotiated value. Should be manually configured before using
  167. * the HAL.
  168. */
  169. sdio_ringbuf_t send_desc_queue; /**< The ring buffer used to hold queued descriptors. Should be manually
  170. * initialized before using the HAL.
  171. */
  172. //Internal status, no need to touch.
  173. send_state_t send_state; // Current state of sending part.
  174. uint32_t tail_pkt_len; // The accumulated send length of the tail packet.
  175. sdio_slave_hal_send_desc_t* in_flight_head; // The head of linked list in-flight.
  176. sdio_slave_hal_send_desc_t* in_flight_end; // The end of linked list in-flight.
  177. sdio_slave_hal_send_desc_t* in_flight_next; // The header of linked list to be sent next time.
  178. sdio_slave_hal_send_desc_t* returned_desc; // The last returned descriptor
  179. sdio_slave_hal_recv_stailq_t recv_link_list; // Linked list of buffers ready to hold data and the buffers already hold data.
  180. volatile sdio_slave_hal_recv_desc_t* recv_cur_ret; // Next desc to return, NULL if all loaded descriptors are returned.
  181. } sdio_slave_context_t ;
  182. /**
  183. * Initialize the HAL, should provide buffers to the context and configure the
  184. * members before this funciton is called.
  185. *
  186. * @param hal Context of the HAL layer.
  187. */
  188. void sdio_slave_hal_init(sdio_slave_context_t *hal);
  189. /**
  190. * Initialize the SDIO slave peripheral hardware.
  191. *
  192. * @param hal Context of the HAL layer.
  193. */
  194. void sdio_slave_hal_hw_init(sdio_slave_context_t *hal);
  195. /**
  196. * Set the IO ready for host to read.
  197. *
  198. * @param hal Context of the HAL layer.
  199. * @param ready true to tell the host the slave is ready, otherwise false.
  200. */
  201. void sdio_slave_hal_set_ioready(sdio_slave_context_t *hal, bool ready);
  202. /*---------------------------------------------------------------------------
  203. * Send
  204. *--------------------------------------------------------------------------*/
  205. /**
  206. * The hardware sending DMA starts. If there is existing data, send them.
  207. *
  208. * @param hal Context of the HAL layer.
  209. */
  210. esp_err_t sdio_slave_hal_send_start(sdio_slave_context_t *hal);
  211. /**
  212. * Stops hardware sending DMA.
  213. *
  214. * @note The data in the queue, as well as the counter are not touched.
  215. * @param hal Context of the HAL layer.
  216. */
  217. void sdio_slave_hal_send_stop(sdio_slave_context_t *hal);
  218. /**
  219. * Put some data into the sending queue.
  220. *
  221. * @note The caller should keeps the buffer, until the `arg` is returned by
  222. * `sdio_slave_hal_send_get_next_finished_arg`.
  223. * @note The caller should count to ensure there is enough space in the queue.
  224. * The initial queue size is sizeof(sendbuf.data)/sizeof(sdio_slave_hal_send_desc_t)-1,
  225. * Will decrease by one when this function successfully returns.
  226. * Released only by `sdio_slave_hal_send_get_next_finished_arg` or
  227. * `sdio_slave_hal_send_flush_next_buffer`.
  228. *
  229. * @note The HAL is not thread-safe. The caller should use a spinlock to ensure
  230. * the `sdio_slave_hal_send_queue` and ... are not called at the same time.
  231. *
  232. * @param hal Context of the HAL layer.
  233. * @param addr Address of data in the memory to send.
  234. * @param len Length of data to send.
  235. * @param arg Argument indicating this sending.
  236. * @return Always ESP_OK.
  237. */
  238. esp_err_t sdio_slave_hal_send_queue(sdio_slave_context_t *hal, uint8_t *addr, size_t len, void *arg);
  239. /**
  240. * The ISR should call this, to handle the SW invoking event.
  241. * @param hal Context of the HAL layer.
  242. */
  243. void sdio_slave_hal_send_handle_isr_invoke(sdio_slave_context_t *hal);
  244. /**
  245. * Check whether there is no in-flight transactions, and send new packet if there
  246. * is new packets queued.
  247. *
  248. * @param hal Context of the HAL layer.
  249. * @return
  250. * - ESP_OK: The DMA starts to send a new packet.
  251. * - ESP_ERR_NOT_FOUND: No packet waiting to be sent.
  252. * - ESP_ERR_INVALID_STATE: There is packet in-flight.
  253. */
  254. esp_err_t sdio_slave_hal_send_new_packet_if_exist(sdio_slave_context_t *hal);
  255. /**
  256. * Check whether the sending EOF has happened and clear the interrupt.
  257. *
  258. * Call `sdio_slave_hal_send_get_next_finished_arg` recursively to retrieve arguments of finished
  259. * buffers.
  260. *
  261. * @param hal Context of the HAL layer.
  262. * @return true if happened, otherwise false.
  263. */
  264. bool sdio_slave_hal_send_eof_happened(sdio_slave_context_t *hal);
  265. /**
  266. * Get the arguments of finished packets. Call recursively until all finished
  267. * arguments are all retrieved.
  268. *
  269. * @param hal Context of the HAL layer.
  270. * @param out_arg Output argument of the finished buffer.
  271. * @param out_returned_cnt Released queue size to be queued again.
  272. * @return
  273. * - ESP_OK: if one argument retrieved.
  274. * - ESP_ERR_NOT_FOUND: All the arguments of the finished buffers are retrieved.
  275. */
  276. esp_err_t sdio_slave_hal_send_get_next_finished_arg(sdio_slave_context_t *hal, void **out_arg, uint32_t* out_returned_cnt);
  277. /**
  278. * Flush one buffer in the queue, no matter sent, canceled or not sent yet.
  279. *
  280. * Call recursively to clear the whole queue before deinitialization.
  281. *
  282. * @note Only call when the DMA is stopped!
  283. * @param hal Context of the HAL layer.
  284. * @param out_arg Argument indiciating the buffer to send
  285. * @param out_return_cnt Space in the queue released after this descriptor is flushed.
  286. * @return
  287. * - ESP_ERR_INVALID_STATE: This function call be called only when the DMA is stopped.
  288. * - ESP_ERR_NOT_FOUND: if no buffer in the queue
  289. * - ESP_OK: if a buffer is successfully flushed and returned.
  290. */
  291. esp_err_t sdio_slave_hal_send_flush_next_buffer(sdio_slave_context_t *hal, void **out_arg, uint32_t *out_return_cnt);
  292. /**
  293. * Walk through all the unsent buffers and reset the counter to the accumulated length of them. The data will be kept.
  294. *
  295. * @note Only call when the DMA is stopped!
  296. * @param hal Context of the HAL layer.
  297. * @return
  298. * - ESP_ERR_INVALID_STATE: this function call be called only when the DMA is stopped
  299. * - ESP_OK: if success
  300. */
  301. esp_err_t sdio_slave_hal_send_reset_counter(sdio_slave_context_t *hal);
  302. /*---------------------------------------------------------------------------
  303. * Receive
  304. *--------------------------------------------------------------------------*/
  305. /**
  306. * Start the receiving DMA.
  307. *
  308. * @note If there are already some buffers loaded, will receive from them first.
  309. * @param hal Context of the HAL layer.
  310. */
  311. void sdio_slave_hal_recv_start(sdio_slave_context_t *hal);
  312. /**
  313. * Stop the receiving DMA.
  314. *
  315. * @note Data and the counter will not be touched. You can still call
  316. * `sdio_slave_hal_recv_has_next_item` to get the received buffer.
  317. * And unused buffers loaded to the HAL will still be in the `loaded`
  318. * state in the HAL, until returned by `sdio_slave_hal_recv_unload_desc`.
  319. * @param hal Context of the HAL layer.
  320. */
  321. void sdio_slave_hal_recv_stop(sdio_slave_context_t* hal);
  322. /**
  323. * Associate the buffer to the descriptor given. The descriptor may also be initialized with some
  324. * other data.
  325. *
  326. * @param hal Context of the HAL layer.
  327. * @param desc Descriptor to associate with the buffer
  328. * @param start Start address of the buffer
  329. */
  330. void sdio_slave_hal_recv_init_desc(sdio_slave_context_t *hal, sdio_slave_hal_recv_desc_t *desc, uint8_t *start);
  331. /**
  332. * Load the buffer to the HAL to be used to receive data.
  333. *
  334. * @note Loaded buffers will be returned to the upper layer only when:
  335. * 1. Returned by `sdio_slave_hal_recv_has_next_item` when receiving to that buffer successfully
  336. * done.
  337. * 2. Returned by `sdio_slave_hal_recv_unload_desc` unconditionally.
  338. * @param hal Context of the HAL layer.
  339. * @param desc Descriptor to load to the HAL to receive.
  340. */
  341. void sdio_slave_hal_load_buf(sdio_slave_context_t *hal, sdio_slave_hal_recv_desc_t *desc);
  342. /**
  343. * Check and clear the interrupt indicating a buffer has finished receiving.
  344. *
  345. * @param hal Context of the HAL layer.
  346. * @return true if interrupt triggered, otherwise false.
  347. */
  348. bool sdio_slave_hal_recv_done(sdio_slave_context_t* hal);
  349. /**
  350. * Call this function recursively to check whether there is any buffer that has
  351. * finished receiving.
  352. *
  353. * Will walk through the linked list to find a newer finished buffer. For each successful return,
  354. * it means there is one finished buffer. You can one by `sdio_slave_hal_recv_unload_desc`. You can
  355. * also call `sdio_slave_hal_recv_has_next_item` several times continuously before you call the
  356. * `sdio_slave_hal_recv_unload_desc` for the same times.
  357. *
  358. * @param hal Context of the HAL layer.
  359. * @return true if there is
  360. */
  361. bool sdio_slave_hal_recv_has_next_item(sdio_slave_context_t* hal);
  362. /**
  363. * Unconditionally remove and return the first descriptor loaded to the HAL.
  364. *
  365. * Unless during de-initialization, `sdio_slave_hal_recv_has_next_item` should have succeed for the
  366. * same times as this function is called, to ensure the returned descriptor has finished its
  367. * receiving job.
  368. *
  369. * @param hal Context of the HAL layer.
  370. * @return The removed descriptor, NULL means the linked-list is empty.
  371. */
  372. sdio_slave_hal_recv_desc_t *sdio_slave_hal_recv_unload_desc(sdio_slave_context_t *hal);
  373. /**
  374. * Walk through all the unused buffers and reset the counter to the number of
  375. * them.
  376. *
  377. * @note Only call when the DMA is stopped!
  378. * @param hal Context of the HAL layer.
  379. */
  380. void sdio_slave_hal_recv_reset_counter(sdio_slave_context_t *hal);
  381. /**
  382. * Walk through all the used buffers, clear the finished flag and appended them
  383. * back to the end of the unused list, waiting to receive then.
  384. *
  385. * @note You will lose all the received data in the buffer.
  386. * @note Only call when the DMA is stopped!
  387. * @param hal Context of the HAL layer.
  388. */
  389. void sdio_slave_hal_recv_flush_one_buffer(sdio_slave_context_t *hal);
  390. /*---------------------------------------------------------------------------
  391. * Host
  392. *--------------------------------------------------------------------------*/
  393. /**
  394. * Enable some of the interrupts for the host.
  395. *
  396. * @note May have concurrency issue wit the host or other tasks, suggest only use it during
  397. * initialization.
  398. * @param hal Context of the HAL layer.
  399. * @param mask Bitwise mask for the interrupts to enable.
  400. */
  401. void sdio_slave_hal_hostint_set_ena(sdio_slave_context_t *hal, const sdio_slave_hostint_t *mask);
  402. /**
  403. * Get the enabled interrupts.
  404. *
  405. * @param hal Context of the HAL layer.
  406. * @param out_int_mask Output of the enabled interrupts
  407. */
  408. void sdio_slave_hal_hostint_get_ena(sdio_slave_context_t *hal, sdio_slave_hostint_t *out_int_mask);
  409. /**
  410. * Send general purpose interrupt (slave send to host).
  411. * @param hal Context of the HAL layer.
  412. * @param mask Interrupts to send, only `SDIO_SLAVE_HOSTINT_BIT*` are allowed.
  413. */
  414. void sdio_slave_hal_hostint_send(sdio_slave_context_t *hal, const sdio_slave_hostint_t *mask);
  415. /**
  416. * Cleared the specified interrupts for the host.
  417. *
  418. * @param hal Context of the HAL layer.
  419. * @param mask Interrupts to clear.
  420. */
  421. void sdio_slave_hal_hostint_clear(sdio_slave_context_t *hal, const sdio_slave_hostint_t *mask);
  422. /**
  423. * Fetch the interrupt (host send to slave) status bits and clear all of them.
  424. * @param hal Context of the HAL layer.
  425. * @param out_int_mask Output interrupt status
  426. */
  427. void sdio_slave_hal_slvint_fetch_clear(sdio_slave_context_t *hal, sdio_slave_ll_slvint_t *out_int_mask);
  428. /**
  429. * Get the value of a shared general purpose register.
  430. *
  431. * @param hal Context of the HAL layer.
  432. * @param pos Position of the register, 4 bytes share a word. 0-63 except 24-27.
  433. * @return The register value.
  434. */
  435. uint8_t sdio_slave_hal_host_get_reg(sdio_slave_context_t *hal, int pos);
  436. /**
  437. * Set the value of shared general purpose register.
  438. *
  439. * @param hal Context of the HAL layer.
  440. * @param pos Position of the register, 4 bytes share a word. 0-63 except 24-27.
  441. * @param reg Value to set.
  442. */
  443. void sdio_slave_hal_host_set_reg(sdio_slave_context_t *hal, int pos, uint8_t reg);