gdma.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. // DO NOT USE THESE APIS IN ANY APPLICATIONS
  7. // GDMA driver is not public for end users, but for ESP-IDF developpers.
  8. #pragma once
  9. #include <stdbool.h>
  10. #include "soc/gdma_channel.h"
  11. #include "esp_err.h"
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. /**
  16. * @brief Type of GDMA channel handle
  17. *
  18. */
  19. typedef struct gdma_channel_t *gdma_channel_handle_t;
  20. /**
  21. * @brief Enumeration of peripherals which have the DMA capability
  22. * @note Some peripheral might not be available on certain chip, please refer to `soc_caps.h` for detail.
  23. *
  24. */
  25. typedef enum {
  26. GDMA_TRIG_PERIPH_M2M, /*!< GDMA trigger peripheral: M2M */
  27. GDMA_TRIG_PERIPH_UART, /*!< GDMA trigger peripheral: UART */
  28. GDMA_TRIG_PERIPH_SPI, /*!< GDMA trigger peripheral: SPI */
  29. GDMA_TRIG_PERIPH_I2S, /*!< GDMA trigger peripheral: I2S */
  30. GDMA_TRIG_PERIPH_AES, /*!< GDMA trigger peripheral: AES */
  31. GDMA_TRIG_PERIPH_SHA, /*!< GDMA trigger peripheral: SHA */
  32. GDMA_TRIG_PERIPH_ADC, /*!< GDMA trigger peripheral: ADC */
  33. GDMA_TRIG_PERIPH_DAC, /*!< GDMA trigger peripheral: DAC */
  34. GDMA_TRIG_PERIPH_LCD, /*!< GDMA trigger peripheral: LCD */
  35. GDMA_TRIG_PERIPH_CAM, /*!< GDMA trigger peripheral: CAM */
  36. GDMA_TRIG_PERIPH_RMT, /*!< GDMA trigger peripheral: RMT */
  37. } gdma_trigger_peripheral_t;
  38. /**
  39. * @brief Enumeration of GDMA channel direction
  40. *
  41. */
  42. typedef enum {
  43. GDMA_CHANNEL_DIRECTION_TX, /*!< GDMA channel direction: TX */
  44. GDMA_CHANNEL_DIRECTION_RX, /*!< GDMA channel direction: RX */
  45. } gdma_channel_direction_t;
  46. /**
  47. * @brief Collection of configuration items that used for allocating GDMA channel
  48. *
  49. */
  50. typedef struct {
  51. gdma_channel_handle_t sibling_chan; /*!< DMA sibling channel handle (NULL means having sibling is not necessary) */
  52. gdma_channel_direction_t direction; /*!< DMA channel direction */
  53. struct {
  54. int reserve_sibling: 1; /*!< If set, DMA channel allocator would prefer to allocate new channel in a new pair, and reserve sibling channel for future use */
  55. } flags;
  56. } gdma_channel_alloc_config_t;
  57. /**
  58. * @brief GDMA transfer ability
  59. *
  60. * @note The alignment set in this structure is **not** a guarantee that gdma driver will take care of the nonalignment cases.
  61. * Actually the GDMA driver has no knowledge about the DMA buffer (address and size) used by upper layer.
  62. * So it's the responsibility of the **upper layer** to take care of the buffer address and size.
  63. *
  64. */
  65. typedef struct {
  66. size_t sram_trans_align; /*!< DMA transfer alignment for memory in SRAM, in bytes. The driver enables/disables burst mode based on this value. 0 means no alignment is required */
  67. size_t psram_trans_align; /*!< DMA transfer alignment for memory in PSRAM, in bytes. The driver sets proper burst block size based on the alignment value. 0 means no alignment is required */
  68. } gdma_transfer_ability_t;
  69. /**
  70. * @brief Type of GDMA event data
  71. *
  72. */
  73. typedef struct {
  74. union {
  75. intptr_t rx_eof_desc_addr; /*!< EOF descriptor address of RX channel */
  76. intptr_t tx_eof_desc_addr; /*!< EOF descriptor address of TX channel */
  77. };
  78. } gdma_event_data_t;
  79. /**
  80. * @brief Type of GDMA event callback
  81. * @param dma_chan GDMA channel handle, created from `gdma_new_channel`
  82. * @param event_data GDMA event data
  83. * @param user_data User registered data from `gdma_register_tx_event_callbacks` or `gdma_register_rx_event_callbacks`
  84. *
  85. * @return Whether a task switch is needed after the callback function returns,
  86. * this is usually due to the callback wakes up some high priority task.
  87. *
  88. */
  89. typedef bool (*gdma_event_callback_t)(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data);
  90. /**
  91. * @brief Group of supported GDMA TX callbacks
  92. * @note The callbacks are all running under ISR environment
  93. *
  94. */
  95. typedef struct {
  96. gdma_event_callback_t on_trans_eof; /*!< Invoked when TX engine meets EOF descriptor */
  97. } gdma_tx_event_callbacks_t;
  98. /**
  99. * @brief Group of supported GDMA RX callbacks
  100. * @note The callbacks are all running under ISR environment
  101. *
  102. */
  103. typedef struct {
  104. gdma_event_callback_t on_recv_eof; /*!< Invoked when RX engine meets EOF descriptor */
  105. } gdma_rx_event_callbacks_t;
  106. /**
  107. * @brief Type of GDMA engine trigger
  108. * @note It's recommended to initialize this structure with `GDMA_MAKE_TRIGGER`.
  109. *
  110. */
  111. typedef struct {
  112. gdma_trigger_peripheral_t periph; /*!< Target peripheral which will trigger DMA operations */
  113. int instance_id; /*!< Peripheral instance ID. Supported IDs are listed in `soc/gdma_channel.h`, e.g. SOC_GDMA_TRIG_PERIPH_UART0 */
  114. } gdma_trigger_t;
  115. /**
  116. * @brief Helper macro to initialize GDMA trigger
  117. * @note value of `peri` must be selected from `gdma_trigger_peripheral_t` enum.
  118. * e.g. GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UART,0)
  119. *
  120. */
  121. #define GDMA_MAKE_TRIGGER(peri, id) \
  122. (gdma_trigger_t) { .periph = peri, .instance_id = SOC_##peri##id }
  123. /**
  124. * @brief A collection of strategy item that each GDMA channel could apply
  125. *
  126. */
  127. typedef struct {
  128. bool owner_check; /*!< If set / clear, DMA channel enables / disables checking owner validity */
  129. bool auto_update_desc; /*!< If set / clear, DMA channel enables / disables hardware to update descriptor automatically (TX channel only) */
  130. } gdma_strategy_config_t;
  131. /**
  132. * @brief Create GDMA channel
  133. * @note This API won't install interrupt service for the allocated channel.
  134. * If interrupt service is needed, user has to register GDMA event callback by `gdma_register_tx_event_callbacks` or `gdma_register_rx_event_callbacks`.
  135. *
  136. * @param[in] config Pointer to a collection of configurations for allocating GDMA channel
  137. * @param[out] ret_chan Returnned channel handle
  138. * @return
  139. * - ESP_OK: Create DMA channel successfully
  140. * - ESP_ERR_INVALID_ARG: Create DMA channel failed because of invalid argument
  141. * - ESP_ERR_NO_MEM: Create DMA channel failed because out of memory
  142. * - ESP_FAIL: Create DMA channel failed because of other error
  143. */
  144. esp_err_t gdma_new_channel(const gdma_channel_alloc_config_t *config, gdma_channel_handle_t *ret_chan);
  145. /**
  146. * @brief Connect GDMA channel to trigger peripheral
  147. *
  148. * @note Suggest to use helper macro `GDMA_MAKE_TRIGGER` to construct parameter `trig_periph`. e.g. GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SHA,0)
  149. * @note Connecting to a peripheral will also reset the DMA FIFO and FSM automatically
  150. *
  151. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  152. * @param[in] trig_periph GDMA trigger peripheral
  153. * @return
  154. * - ESP_OK: Connect GDMA channel successfully
  155. * - ESP_ERR_INVALID_ARG: Connect GDMA channel failed because of invalid argument
  156. * - ESP_ERR_INVALID_STATE: Connect GDMA channel failed because DMA channel is working with another peripheral
  157. * - ESP_FAIL: Connect GDMA channel failed because of other error
  158. */
  159. esp_err_t gdma_connect(gdma_channel_handle_t dma_chan, gdma_trigger_t trig_periph);
  160. /**
  161. * @brief Disconnect GMA channel from peripheral
  162. *
  163. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  164. * @return
  165. * - ESP_OK: Disconnect GDMA channel successfully
  166. * - ESP_ERR_INVALID_ARG: Disconnect GDMA channel failed because of invalid argument
  167. * - ESP_ERR_INVALID_STATE: Disconnect GDMA channel failed because DMA channel is not connected to any peripheral
  168. * - ESP_FAIL: Disconnect DMA channel failed because of other error
  169. */
  170. esp_err_t gdma_disconnect(gdma_channel_handle_t dma_chan);
  171. /**
  172. * @brief Set DMA channel transfer ability
  173. *
  174. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  175. * @param[in] ability Transfer ability, e.g. alignment
  176. * @return
  177. * - ESP_OK: Set DMA channel transfer ability successfully
  178. * - ESP_ERR_INVALID_ARG: Set DMA channel transfer ability failed because of invalid argument
  179. * - ESP_FAIL: Set DMA channel transfer ability failed because of other error
  180. */
  181. esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability);
  182. /**
  183. * @brief Apply channel strategy for GDMA channel
  184. *
  185. * @param dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  186. * @param config Configuration of GDMA channel strategy
  187. * - ESP_OK: Apply channel strategy successfully
  188. * - ESP_ERR_INVALID_ARG: Apply channel strategy failed because of invalid argument
  189. * - ESP_FAIL: Apply channel strategy failed because of other error
  190. */
  191. esp_err_t gdma_apply_strategy(gdma_channel_handle_t dma_chan, const gdma_strategy_config_t *config);
  192. /**
  193. * @brief Delete GDMA channel
  194. * @note If you call `gdma_new_channel` several times for a same peripheral, make sure you call this API the same times.
  195. *
  196. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  197. * @return
  198. * - ESP_OK: Delete GDMA channel successfully
  199. * - ESP_ERR_INVALID_ARG: Delete GDMA channel failed because of invalid argument
  200. * - ESP_FAIL: Delete GDMA channel failed because of other error
  201. */
  202. esp_err_t gdma_del_channel(gdma_channel_handle_t dma_chan);
  203. /**
  204. * @brief Get the channel ID
  205. *
  206. * @note This API breaks the encapsulation of GDMA Channel Object.
  207. * With the returned channel ID, you can even bypass all other GDMA driver API and access Low Level API directly.
  208. *
  209. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  210. * @param[out] channel_id Returned channel ID
  211. * @return
  212. * - ESP_OK: Get GDMA channel ID successfully
  213. * - ESP_ERR_INVALID_ARG: Get GDMA channel ID failed because of invalid argument
  214. * - ESP_FAIL: Get GDMA channel ID failed because of other error
  215. */
  216. esp_err_t gdma_get_channel_id(gdma_channel_handle_t dma_chan, int *channel_id);
  217. /**
  218. * @brief Set GDMA event callbacks for TX channel
  219. * @note This API will install GDMA interrupt service for the channel internally
  220. *
  221. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  222. * @param[in] cbs Group of callback functions
  223. * @param[in] user_data User data, which will be passed to callback functions directly
  224. * @return
  225. * - ESP_OK: Set event callbacks successfully
  226. * - ESP_ERR_INVALID_ARG: Set event callbacks failed because of invalid argument
  227. * - ESP_FAIL: Set event callbacks failed because of other error
  228. */
  229. esp_err_t gdma_register_tx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_tx_event_callbacks_t *cbs, void *user_data);
  230. /**
  231. * @brief Set GDMA event callbacks for RX channel
  232. * @note This API will install GDMA interrupt service for the channel internally
  233. *
  234. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  235. * @param[in] cbs Group of callback functions
  236. * @param[in] user_data User data, which will be passed to callback functions directly
  237. * @return
  238. * - ESP_OK: Set event callbacks successfully
  239. * - ESP_ERR_INVALID_ARG: Set event callbacks failed because of invalid argument
  240. * - ESP_FAIL: Set event callbacks failed because of other error
  241. */
  242. esp_err_t gdma_register_rx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_rx_event_callbacks_t *cbs, void *user_data);
  243. /**
  244. * @brief Set DMA descriptor address and start engine
  245. *
  246. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  247. * @param[in] desc_base_addr Base address of descriptors (usually the descriptors are chained into a link or ring)
  248. * @return
  249. * - ESP_OK: Start DMA engine successfully
  250. * - ESP_ERR_INVALID_ARG: Start DMA engine failed because of invalid argument
  251. * - ESP_FAIL: Start DMA engine failed because of other error
  252. */
  253. esp_err_t gdma_start(gdma_channel_handle_t dma_chan, intptr_t desc_base_addr);
  254. /**
  255. * @brief Stop DMA engine
  256. *
  257. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  258. * @return
  259. * - ESP_OK: Stop DMA engine successfully
  260. * - ESP_ERR_INVALID_ARG: Stop DMA engine failed because of invalid argument
  261. * - ESP_FAIL: Stop DMA engine failed because of other error
  262. */
  263. esp_err_t gdma_stop(gdma_channel_handle_t dma_chan);
  264. /**
  265. * @brief Make the appended descriptors be aware to the DMA engine
  266. * @note This API could also resume a paused DMA engine, make sure new descriptors have been appended to the descriptor chain before calling it.
  267. *
  268. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  269. * @return
  270. * - ESP_OK: Send append command to DMA engine successfully
  271. * - ESP_ERR_INVALID_ARG: Send append command to DMA engine failed because of invalid argument
  272. * - ESP_FAIL: Send append command to DMA engine failed because of other error
  273. */
  274. esp_err_t gdma_append(gdma_channel_handle_t dma_chan);
  275. /**
  276. * @brief Reset DMA channel FIFO and internal finite state machine
  277. * @note Resetting a DMA channel won't break the connection with the target peripheral
  278. *
  279. * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
  280. * @return
  281. * - ESP_OK: DMA channel reset successfully
  282. * - ESP_ERR_INVALID_ARG: DMA channel reset failed due to invalid arguments
  283. * - ESP_FAIL: DMA channel reset failed due to other errors
  284. */
  285. esp_err_t gdma_reset(gdma_channel_handle_t dma_chan);
  286. #ifdef __cplusplus
  287. }
  288. #endif