hpm_dmav2_drv.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. /*
  2. * Copyright (c) 2021-2022 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_DMAV2_DRV_H
  8. #define HPM_DMAV2_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_soc_feature.h"
  11. #include "hpm_dmav2_regs.h"
  12. /**
  13. *
  14. * @brief DMA driver APIs
  15. * @defgroup dma_interface DMA driver APIs
  16. * @ingroup io_interfaces
  17. * @{
  18. */
  19. #define DMA_Type DMAV2_Type
  20. #define DMA_CHANNEL_PRIORITY_LOW (0U)
  21. #define DMA_CHANNEL_PRIORITY_HIGH (1U)
  22. #define DMA_NUM_TRANSFER_PER_BURST_1T (0U)
  23. #define DMA_NUM_TRANSFER_PER_BURST_2T (1U)
  24. #define DMA_NUM_TRANSFER_PER_BURST_4T (2U)
  25. #define DMA_NUM_TRANSFER_PER_BURST_8T (3U)
  26. #define DMA_NUM_TRANSFER_PER_BURST_16T (4U)
  27. #define DMA_NUM_TRANSFER_PER_BURST_32T (5U)
  28. #define DMA_NUM_TRANSFER_PER_BURST_64T (6U)
  29. #define DMA_NUM_TRANSFER_PER_BURST_128T (7U)
  30. #define DMA_NUM_TRANSFER_PER_BURST_256T (8U)
  31. #define DMA_NUM_TRANSFER_PER_BURST_512T (9U)
  32. #define DMA_NUM_TRANSFER_PER_BURST_1024T (10U)
  33. #define DMA_TRANSFER_WIDTH_BYTE (0U)
  34. #define DMA_TRANSFER_WIDTH_HALF_WORD (1U)
  35. #define DMA_TRANSFER_WIDTH_WORD (2U)
  36. #define DMA_TRANSFER_WIDTH_DOUBLE_WORD (3U)
  37. #define DMA_ALIGN_HALF_WORD(x) (x & ~(1u))
  38. #define DMA_ALIGN_WORD(x) (x & ~(3u))
  39. #define DMA_ALIGN_DOUBLE_WORD(x) (x & ~(7u))
  40. #define DMA_CHANNEL_STATUS_ONGOING (1U)
  41. #define DMA_CHANNEL_STATUS_ERROR (2U)
  42. #define DMA_CHANNEL_STATUS_ABORT (4U)
  43. #define DMA_CHANNEL_STATUS_TC (8U)
  44. #define DMA_CHANNEL_STATUS_HALF_TC (16U)
  45. #define DMA_CHANNEL_IRQ_STATUS_ERROR(x) (uint32_t)(1 << x)
  46. #define DMA_CHANNEL_IRQ_STATUS_ABORT(x) (uint32_t)(1 << x)
  47. #define DMA_CHANNEL_IRQ_STATUS_TC(x) (uint32_t)(1 << x)
  48. #define DMA_CHANNEL_IRQ_STATUS_HALF_TC(x) (uint32_t)(1 << x)
  49. #define DMA_HANDSHAKE_MODE_NORMAL (0U)
  50. #define DMA_HANDSHAKE_MODE_HANDSHAKE (1U)
  51. #define DMA_ADDRESS_CONTROL_INCREMENT (0U)
  52. #define DMA_ADDRESS_CONTROL_DECREMENT (1U)
  53. #define DMA_ADDRESS_CONTROL_FIXED (2U)
  54. #define DMA_SRC_BURST_OPT_STANDAND_SIZE (0U)
  55. #define DMA_SRC_BURST_OPT_CUSTOM_SIZE (1U)
  56. #define DMA_HANDSHAKE_OPT_ONE_BURST (0U)
  57. #define DMA_HANDSHAKE_OPT_ALL_TRANSIZE (1U)
  58. #define DMA_SWAP_MODE_TABLE (0U)
  59. #define DMA_SWAP_MODE_BYTE (1U)
  60. #define DMA_SWAP_MODE_HALF_WORD (2U)
  61. #define DMA_SWAP_MODE_WORD (3U)
  62. #define DMA_INTERRUPT_MASK_NONE (0U)
  63. #define DMA_INTERRUPT_MASK_ERROR DMAV2_CHCTRL_CTRL_INTERRMASK_MASK
  64. #define DMA_INTERRUPT_MASK_ABORT DMAV2_CHCTRL_CTRL_INTABTMASK_MASK
  65. #define DMA_INTERRUPT_MASK_TERMINAL_COUNT DMAV2_CHCTRL_CTRL_INTTCMASK_MASK
  66. #define DMA_INTERRUPT_MASK_HALF_TC DMAV2_CHCTRL_CTRL_INTHALFCNTMASK_MASK
  67. #define DMA_INTERRUPT_MASK_ALL \
  68. (uint8_t)(DMA_INTERRUPT_MASK_TERMINAL_COUNT \
  69. | DMA_INTERRUPT_MASK_ABORT \
  70. | DMA_INTERRUPT_MASK_ERROR \
  71. | DMA_INTERRUPT_MASK_HALF_TC)
  72. #define DMA_SUPPORT_64BIT_ADDR (0)
  73. enum {
  74. dmav2_state_idle = 0,
  75. dmav2_state_read,
  76. dmav2_state_read_ack,
  77. dmav2_state_write,
  78. dmav2_state_write_ack,
  79. dmav2_state_ll,
  80. dmav2_state_end,
  81. dmav2_state_end_wait,
  82. };
  83. /**
  84. * @brief Linked descriptor
  85. *
  86. * It is consumed by DMA controlled directly
  87. */
  88. typedef struct dma_linked_descriptor {
  89. uint32_t ctrl; /**< Control */
  90. uint32_t trans_size; /**< Transfer size in source width */
  91. uint32_t src_addr; /**< Source address */
  92. uint32_t req_ctrl; /**< Request select */
  93. uint32_t dst_addr; /**< Destination address */
  94. uint32_t swap_table; /**< Swap table */
  95. uint32_t linked_ptr; /**< Linked descriptor address */
  96. uint32_t reserved0; /**< not used on dmav2 */
  97. } dma_linked_descriptor_t;
  98. /* @brief Channel config */
  99. typedef struct dma_channel_config {
  100. uint8_t priority; /**< Channel priority */
  101. uint8_t src_burst_size; /**< Source burst size */
  102. uint8_t src_mode; /**< Source work mode */
  103. uint8_t dst_mode; /**< Destination work mode */
  104. uint8_t src_width; /**< Source width */
  105. uint8_t dst_width; /**< Destination width */
  106. uint8_t src_addr_ctrl; /**< Source address control */
  107. uint8_t dst_addr_ctrl; /**< Destination address control */
  108. uint16_t interrupt_mask; /**< Interrupt mask */
  109. uint32_t src_addr; /**< Source address */
  110. uint32_t dst_addr; /**< Destination address */
  111. uint32_t linked_ptr; /**< Next linked descriptor */
  112. uint32_t size_in_byte; /**< Total size to be transferred in byte */
  113. bool en_infiniteloop; /**< Infinite loop transfer enable. Attention: only DMAV2 support */
  114. uint8_t handshake_opt; /**< Handshake transfer option. Attention: only DMAV2 support */
  115. uint8_t burst_opt; /**< Burst size option. Attention: only DMAV2 support */
  116. #if defined(HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS) && (HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS == 1)
  117. bool en_src_burst_in_fixed_trans; /**< Source burst in fix transfer size enable, discard src_addr_ctrl setting. Attention: only DMAV2 support */
  118. bool en_dst_burst_in_fixed_trans; /**< Destination burst in fix transfer size enable, discard dst_addr_ctrl setting. Attention: only DMAV2 support */
  119. #endif
  120. #if defined(HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP) && (HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP == 1)
  121. uint8_t swap_mode; /**< Swap Mode. Attention: only DMAV2 support */
  122. uint32_t swap_table; /**< Swap Table. Attention: only DMAV2 support */
  123. #endif
  124. } dma_channel_config_t;
  125. /* @brief Channel config */
  126. typedef struct dma_handshake_config {
  127. uint32_t dst;
  128. uint32_t src;
  129. uint32_t size_in_byte;
  130. uint8_t data_width; /* data width, value defined by DMA_TRANSFER_WIDTH_xxx */
  131. uint8_t ch_index;
  132. bool dst_fixed;
  133. bool src_fixed;
  134. bool en_infiniteloop;
  135. uint16_t interrupt_mask;
  136. } dma_handshake_config_t;
  137. /* @brief DMA specific status */
  138. enum {
  139. status_dma_transfer_done = MAKE_STATUS(status_group_dma, 0),
  140. status_dma_transfer_error = MAKE_STATUS(status_group_dma, 1),
  141. status_dma_transfer_abort = MAKE_STATUS(status_group_dma, 2),
  142. status_dma_transfer_ongoing = MAKE_STATUS(status_group_dma, 3),
  143. status_dma_alignment_error = MAKE_STATUS(status_group_dma, 4),
  144. status_dma_transfer_half_done = MAKE_STATUS(status_group_dma, 5),
  145. };
  146. #ifdef __cplusplus
  147. extern "C" {
  148. #endif
  149. /**
  150. * @brief Reset DMA
  151. *
  152. * @param[in] ptr DMA base address
  153. */
  154. static inline void dma_reset(DMAV2_Type *ptr)
  155. {
  156. ptr->DMACTRL |= DMAV2_DMACTRL_RESET_MASK;
  157. }
  158. /**
  159. * @brief Enable DMA channel
  160. *
  161. * @param[in] ptr DMA base address
  162. * @param[in] ch_index Index of the channel to be enabled
  163. *
  164. * @return status_success if everything's okay
  165. */
  166. static inline hpm_stat_t dma_enable_channel(DMAV2_Type *ptr, uint32_t ch_index)
  167. {
  168. ptr->CHCTRL[ch_index].CTRL |= DMAV2_CHCTRL_CTRL_ENABLE_MASK;
  169. if ((ptr->CHEN == 0) || !(ptr->CHEN & 1 << ch_index)) {
  170. return status_fail;
  171. }
  172. return status_success;
  173. }
  174. /**
  175. * @brief Disable DMA channel
  176. *
  177. * @param[in] ptr DMA base address
  178. * @param[in] ch_index Index of the channel to be disabled
  179. *
  180. */
  181. static inline void dma_disable_channel(DMAV2_Type *ptr, uint32_t ch_index)
  182. {
  183. ptr->CHCTRL[ch_index].CTRL &= ~DMAV2_CHCTRL_CTRL_ENABLE_MASK;
  184. }
  185. /**
  186. * @brief Check whether DMA channel is enable
  187. *
  188. * @param[in] ptr DMA base address
  189. * @param[in] ch_index Index of the channel
  190. *
  191. * @return true if DMA channel is enable
  192. *
  193. */
  194. static inline bool dma_channel_is_enable(DMAV2_Type *ptr, uint32_t ch_index)
  195. {
  196. return (ptr->CHCTRL[ch_index].CTRL & DMAV2_CHCTRL_CTRL_ENABLE_MASK) ? true : false;
  197. }
  198. /**
  199. * @brief Set DMA channel priority
  200. *
  201. * @param[in] ptr DMA base address
  202. * @param[in] ch_index Index of the channel
  203. * @param[in] priority dma priority
  204. * @arg @ref DMA_CHANNEL_PRIORITY_LOW
  205. * @arg @ref DMA_CHANNEL_PRIORITY_HIGH
  206. *
  207. */
  208. static inline void dma_set_priority(DMAV2_Type *ptr, uint32_t ch_index, uint8_t priority)
  209. {
  210. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_PRIORITY_MASK) | DMAV2_CHCTRL_CTRL_PRIORITY_SET(priority);
  211. }
  212. /**
  213. * @brief Set DMA channel source work mode
  214. *
  215. * @param[in] ptr DMA base address
  216. * @param[in] ch_index Index of the channel
  217. * @param[in] mode source work mode
  218. * @arg @ref DMA_HANDSHAKE_MODE_NORMAL
  219. * @arg @ref DMA_HANDSHAKE_MODE_HANDSHAKE
  220. *
  221. */
  222. static inline void dma_set_source_work_mode(DMAV2_Type *ptr, uint32_t ch_index, uint8_t mode)
  223. {
  224. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCMODE_MASK) | DMAV2_CHCTRL_CTRL_SRCMODE_SET(mode);
  225. }
  226. /**
  227. * @brief Set DMA channel destination work mode
  228. *
  229. * @param[in] ptr DMA base address
  230. * @param[in] ch_index Index of the channel
  231. * @param[in] mode destination work mode
  232. * @arg @ref DMA_HANDSHAKE_MODE_NORMAL
  233. * @arg @ref DMA_HANDSHAKE_MODE_HANDSHAKE
  234. *
  235. */
  236. static inline void dma_set_destination_work_mode(DMAV2_Type *ptr, uint32_t ch_index, uint8_t mode)
  237. {
  238. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DSTMODE_MASK) | DMAV2_CHCTRL_CTRL_DSTMODE_SET(mode);
  239. }
  240. /**
  241. * @brief Set DMA channel source burst size
  242. *
  243. * @param[in] ptr DMA base address
  244. * @param[in] ch_index Index of the channel
  245. * @param[in] burstsize source burst size
  246. * when BURSTOPT is 0, please reference follows:
  247. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_1T
  248. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_2T
  249. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_4T
  250. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_8T
  251. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_16T
  252. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_32T
  253. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_64T
  254. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_128T
  255. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_256T
  256. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_512T
  257. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_1024T
  258. * when BURSTOPT is 1, burst size is (burstsize + 1).
  259. *
  260. */
  261. static inline void dma_set_source_burst_size(DMAV2_Type *ptr, uint32_t ch_index, uint8_t burstsize)
  262. {
  263. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCBURSTSIZE_MASK) | DMAV2_CHCTRL_CTRL_SRCBURSTSIZE_SET(burstsize);
  264. }
  265. /**
  266. * @brief Get DMA channel remaining transfer size
  267. *
  268. * @param[in] ptr DMA base address
  269. * @param[in] ch_index Index of the channel
  270. *
  271. * @return remaining transfer size
  272. *
  273. */
  274. static inline uint32_t dma_get_remaining_transfer_size(DMAV2_Type *ptr, uint32_t ch_index)
  275. {
  276. return ptr->CHCTRL[ch_index].TRANSIZE;
  277. }
  278. /**
  279. * @brief Set DMA channel transfer size
  280. *
  281. * @param[in] ptr DMA base address
  282. * @param[in] ch_index Index of the channel
  283. * @param[in] size_in_width transfer size of the channel. The width is current dma channel configured source width.
  284. * Transfer total bytes are (size_in_width * source width).
  285. *
  286. */
  287. static inline void dma_set_transfer_size(DMAV2_Type *ptr, uint32_t ch_index, uint32_t size_in_width)
  288. {
  289. ptr->CHCTRL[ch_index].TRANSIZE = DMAV2_CHCTRL_TRANSIZE_TRANSIZE_SET(size_in_width);
  290. }
  291. /**
  292. * @brief Set DMA channel source width
  293. *
  294. * @param[in] ptr DMA base address
  295. * @param[in] ch_index Index of the channel
  296. * @param[in] width transfer source width of the channel
  297. * @arg @ref DMA_TRANSFER_WIDTH_BYTE
  298. * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
  299. * @arg @ref DMA_TRANSFER_WIDTH_WORD
  300. * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
  301. */
  302. static inline void dma_set_source_width(DMAV2_Type *ptr, uint32_t ch_index, uint8_t width)
  303. {
  304. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCWIDTH_MASK) | DMAV2_CHCTRL_CTRL_SRCWIDTH_SET(width);
  305. }
  306. /**
  307. * @brief Set DMA channel destination width
  308. *
  309. * @param[in] ptr DMA base address
  310. * @param[in] ch_index Index of the channel
  311. * @param[in] width transfer destination width of the channel
  312. * @arg @ref DMA_TRANSFER_WIDTH_BYTE
  313. * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
  314. * @arg @ref DMA_TRANSFER_WIDTH_WORD
  315. * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
  316. */
  317. static inline void dma_set_destination_width(DMAV2_Type *ptr, uint32_t ch_index, uint8_t width)
  318. {
  319. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DSTWIDTH_MASK) | DMAV2_CHCTRL_CTRL_DSTWIDTH_SET(width);
  320. }
  321. /**
  322. * @brief Set DMA channel transfer width and size in byte
  323. *
  324. * @param[in] ptr DMA base address
  325. * @param[in] ch_index Index of the channel
  326. * @param[in] src_width transfer source width of the channel
  327. * @arg @ref DMA_TRANSFER_WIDTH_BYTE
  328. * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
  329. * @arg @ref DMA_TRANSFER_WIDTH_WORD
  330. * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
  331. * @param[in] size_in_byte transfer size in byte of the channel. The dma transfer size is (size_in_byte >> src_width).
  332. *
  333. */
  334. static inline void dma_set_transfer_src_width_byte_size(DMAV2_Type *ptr, uint32_t ch_index, uint8_t src_width, uint32_t size_in_byte)
  335. {
  336. assert((src_width == DMA_TRANSFER_WIDTH_BYTE) || (src_width == DMA_TRANSFER_WIDTH_HALF_WORD)
  337. || (src_width == DMA_TRANSFER_WIDTH_WORD) || (src_width == DMA_TRANSFER_WIDTH_DOUBLE_WORD));
  338. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCWIDTH_MASK) | DMAV2_CHCTRL_CTRL_SRCWIDTH_SET(src_width);
  339. ptr->CHCTRL[ch_index].TRANSIZE = DMAV2_CHCTRL_TRANSIZE_TRANSIZE_SET(size_in_byte >> src_width);
  340. }
  341. /**
  342. * @brief Set DMA channel source address
  343. *
  344. * @param[in] ptr DMA base address
  345. * @param[in] ch_index Index of the channel
  346. * @param[in] addr source address
  347. *
  348. */
  349. static inline void dma_set_source_address(DMAV2_Type *ptr, uint32_t ch_index, uint32_t addr)
  350. {
  351. ptr->CHCTRL[ch_index].SRCADDR = addr;
  352. }
  353. /**
  354. * @brief Set DMA channel destination address
  355. *
  356. * @param[in] ptr DMA base address
  357. * @param[in] ch_index Index of the channel
  358. * @param[in] addr destination address
  359. *
  360. */
  361. static inline void dma_set_destination_address(DMAV2_Type *ptr, uint32_t ch_index, uint32_t addr)
  362. {
  363. ptr->CHCTRL[ch_index].DSTADDR = addr;
  364. }
  365. /**
  366. * @brief Set DMA channel source address control mode
  367. *
  368. * @param[in] ptr DMA base address
  369. * @param[in] ch_index Index of the channel
  370. * @param[in] addr_ctrl source address control mode
  371. * @arg @ref DMA_ADDRESS_CONTROL_INCREMENT
  372. * @arg @ref DMA_ADDRESS_CONTROL_DECREMENT
  373. * @arg @ref DMA_ADDRESS_CONTROL_FIXED
  374. *
  375. */
  376. static inline void dma_set_source_address_ctrl(DMAV2_Type *ptr, uint32_t ch_index, uint8_t addr_ctrl)
  377. {
  378. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRCADDRCTRL_MASK) | DMAV2_CHCTRL_CTRL_SRCADDRCTRL_SET(addr_ctrl);
  379. }
  380. /**
  381. * @brief Set DMA channel destination address control mode
  382. *
  383. * @param[in] ptr DMA base address
  384. * @param[in] ch_index Index of the channel
  385. * @param[in] addr_ctrl destination address control mode
  386. * @arg @ref DMA_ADDRESS_CONTROL_INCREMENT
  387. * @arg @ref DMA_ADDRESS_CONTROL_DECREMENT
  388. * @arg @ref DMA_ADDRESS_CONTROL_FIXED
  389. *
  390. */
  391. static inline void dma_set_destination_address_ctrl(DMAV2_Type *ptr, uint32_t ch_index, uint8_t addr_ctrl)
  392. {
  393. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DSTADDRCTRL_MASK) | DMAV2_CHCTRL_CTRL_DSTADDRCTRL_SET(addr_ctrl);
  394. }
  395. /**
  396. * @brief Set DMA channel infinite loop mode
  397. *
  398. * @param[in] ptr DMA base address
  399. * @param[in] ch_index Index of the channel
  400. * @param[in] infinite_loop false - normal mode(single times mode); true - infinite loop mode(cycle mode)
  401. *
  402. */
  403. static inline void dma_set_infinite_loop_mode(DMAV2_Type *ptr, uint32_t ch_index, bool infinite_loop)
  404. {
  405. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_INFINITELOOP_MASK) | DMAV2_CHCTRL_CTRL_INFINITELOOP_SET(infinite_loop);
  406. }
  407. /**
  408. * @brief Set DMA channel source burst option
  409. *
  410. * @param[in] ptr DMA base address
  411. * @param[in] ch_index Index of the channel
  412. * @param[in] burst_opt burst option
  413. * @arg @ref DMA_SRC_BURST_OPT_STANDAND_SIZE
  414. * @arg @ref DMA_SRC_BURST_OPT_CUSTOM_SIZE
  415. *
  416. */
  417. static inline void dma_set_src_busrt_option(DMAV2_Type *ptr, uint32_t ch_index, uint8_t burst_opt)
  418. {
  419. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_BURSTOPT_MASK) | DMAV2_CHCTRL_CTRL_BURSTOPT_SET(burst_opt);
  420. }
  421. /**
  422. * @brief Set DMA channel handshake option
  423. *
  424. * @param[in] ptr DMA base address
  425. * @param[in] ch_index Index of the channel
  426. * @param[in] handshake_opt handshake option
  427. * @arg @ref DMA_HANDSHAKE_OPT_ONE_BURST
  428. * @arg @ref DMA_HANDSHAKE_OPT_ALL_TRANSIZE
  429. *
  430. */
  431. static inline void dma_set_handshake_option(DMAV2_Type *ptr, uint32_t ch_index, uint8_t handshake_opt)
  432. {
  433. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_HANDSHAKEOPT_MASK) | DMAV2_CHCTRL_CTRL_HANDSHAKEOPT_SET(handshake_opt);
  434. }
  435. #if defined(HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS) && (HPM_IP_FEATURE_DMAV2_BURST_IN_FIXED_TRANS == 1)
  436. /**
  437. * @brief Set DMA channel source burst in fixed transfer size enable or disable
  438. *
  439. * @param[in] ptr DMA base address
  440. * @param[in] ch_index Index of the channel
  441. * @param[in] enable false - disable; true - enable
  442. *
  443. */
  444. static inline void dma_set_source_burst_in_fixed_transize_enable(DMAV2_Type *ptr, uint32_t ch_index, bool enable)
  445. {
  446. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SRC_FIXBURST_MASK) | DMAV2_CHCTRL_CTRL_SRC_FIXBURST_SET(enable);
  447. }
  448. /**
  449. * @brief Set DMA channel destination burst in fixed transfer size enable or disable
  450. *
  451. * @param[in] ptr DMA base address
  452. * @param[in] ch_index Index of the channel
  453. * @param[in] enable false - disable; true - enable
  454. *
  455. */
  456. static inline void dma_set_destination_burst_in_fixed_transize_enable(DMAV2_Type *ptr, uint32_t ch_index, bool enable)
  457. {
  458. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_DST_FIXBURST_MASK) | DMAV2_CHCTRL_CTRL_DST_FIXBURST_SET(enable);
  459. }
  460. #endif
  461. #if defined(HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP) && (HPM_IP_FEATURE_DMAV2_BYTE_ORDER_SWAP == 1)
  462. /**
  463. * @brief Set DMA channel swap mode
  464. *
  465. * @param[in] ptr DMA base address
  466. * @param[in] ch_index Index of the channel
  467. * @param[in] swap_mode swap mode
  468. * @arg @ref DMA_SWAP_MODE_TABLE
  469. * @arg @ref DMA_SWAP_MODE_BYTE
  470. * @arg @ref DMA_SWAP_MODE_HALF_WORD
  471. * @arg @ref DMA_SWAP_MODE_WORD
  472. *
  473. */
  474. static inline void dma_set_swap_mode(DMAV2_Type *ptr, uint32_t ch_index, uint8_t swap_mode)
  475. {
  476. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMAV2_CHCTRL_CTRL_SWAP_CTL_MASK) | DMAV2_CHCTRL_CTRL_SWAP_CTL_SET(swap_mode);
  477. }
  478. /**
  479. * @brief Set DMA channel swap table
  480. *
  481. * @param[in] ptr DMA base address
  482. * @param[in] ch_index Index of the channel
  483. * @param[in] swap_table swap table
  484. *
  485. */
  486. static inline void dma_set_swap_table(DMAV2_Type *ptr, uint32_t ch_index, uint32_t swap_table)
  487. {
  488. ptr->CHCTRL[ch_index].SWAPTABLE = swap_table;
  489. }
  490. #endif
  491. /**
  492. * @brief Abort channel transfer with mask
  493. *
  494. * @param[in] ptr DMA base address
  495. * @param[in] ch_index_mask Mask of channels to be aborted
  496. */
  497. static inline void dma_abort_channel(DMAV2_Type *ptr, uint32_t ch_index_mask)
  498. {
  499. ptr->CHABORT |= DMAV2_CHABORT_CHABORT_SET(ch_index_mask);
  500. }
  501. /**
  502. * @brief Check if channels are enabled with mask
  503. *
  504. * @param[in] ptr DMA base address
  505. * @param[in] ch_index_mask Mask of channels to be checked
  506. *
  507. * @return Enabled channel mask
  508. */
  509. static inline uint32_t dma_check_enabled_channel(DMAV2_Type *ptr,
  510. uint32_t ch_index_mask)
  511. {
  512. return (ch_index_mask & ptr->CHEN);
  513. }
  514. /**
  515. * @brief Check if linked pointer has been configured
  516. *
  517. * @param[in] ptr DMA base address
  518. * @param[in] ch_index Target channel index to be checked
  519. *
  520. * @return true if linked pointer has been configured
  521. */
  522. static inline bool dma_has_linked_pointer_configured(DMAV2_Type *ptr, uint32_t ch_index)
  523. {
  524. return ptr->CHCTRL[ch_index].LLPOINTER != 0;
  525. }
  526. /**
  527. * @brief Check transfer status
  528. *
  529. * @param[in] ptr DMA base address
  530. * @param[in] ch_index Target channel index to be checked
  531. *
  532. * @retval DMA_CHANNEL_STATUS_ONGOING if transfer is still ongoing
  533. * @retval DMA_CHANNEL_STATUS_ERROR if any error occurred during transferring
  534. * @retval DMA_CHANNEL_STATUS_ABORT if transfer is aborted
  535. * @retval DMA_CHANNEL_STATUS_TC if transfer is finished without error
  536. * @retval DMA_CHANNEL_STATUS_HALF_TC if half transfer complete without error
  537. */
  538. static inline uint32_t dma_check_transfer_status(DMAV2_Type *ptr, uint8_t ch_index)
  539. {
  540. uint32_t dma_status = 0;
  541. if (ptr->INTTCSTS & (1 << ch_index)) {
  542. dma_status |= DMA_CHANNEL_STATUS_TC;
  543. ptr->INTTCSTS = (1 << ch_index); /* W1C clear status*/
  544. }
  545. if (ptr->INTHALFSTS & (1 << ch_index)) {
  546. dma_status |= DMA_CHANNEL_STATUS_HALF_TC;
  547. ptr->INTHALFSTS = (1 << ch_index); /* W1C clear status*/
  548. }
  549. if (ptr->INTERRSTS & (1 << ch_index)) {
  550. dma_status |= DMA_CHANNEL_STATUS_ERROR;
  551. ptr->INTERRSTS = (1 << ch_index); /* W1C clear status*/
  552. }
  553. if (ptr->INTABORTSTS & (1 << ch_index)) {
  554. dma_status |= DMA_CHANNEL_STATUS_ABORT;
  555. ptr->INTABORTSTS = (1 << ch_index); /* W1C clear status*/
  556. }
  557. if (dma_status == 0) {
  558. dma_status = DMA_CHANNEL_STATUS_ONGOING;
  559. }
  560. return dma_status;
  561. }
  562. /**
  563. * @brief Clear transfer status
  564. *
  565. * @param[in] ptr DMA base address
  566. * @param[in] ch_index Target channel index
  567. *
  568. */
  569. static inline void dma_clear_transfer_status(DMAV2_Type *ptr, uint8_t ch_index)
  570. {
  571. /* W1C */
  572. ptr->INTHALFSTS = (1 << ch_index);
  573. ptr->INTTCSTS = (1 << ch_index);
  574. ptr->INTABORTSTS = (1 << ch_index);
  575. ptr->INTERRSTS = (1 << ch_index);
  576. }
  577. /**
  578. * @brief Enable DMA Channel interrupt
  579. *
  580. * @param [in] ptr DMA base address
  581. * @param [in] ch_index Target channel index
  582. * @param [in] interrupt_mask Interrupt mask
  583. */
  584. static inline void dma_enable_channel_interrupt(DMAV2_Type *ptr, uint8_t ch_index, int32_t interrupt_mask)
  585. {
  586. ptr->CHCTRL[ch_index].CTRL &= ~(interrupt_mask & DMA_INTERRUPT_MASK_ALL);
  587. }
  588. /**
  589. * @brief Disable DMA Channel interrupt
  590. *
  591. * @param [in] ptr DMA base address
  592. * @param [in] ch_index Target channel index
  593. * @param [in] interrupt_mask Interrupt mask
  594. */
  595. static inline void dma_disable_channel_interrupt(DMAV2_Type *ptr, uint8_t ch_index, int32_t interrupt_mask)
  596. {
  597. ptr->CHCTRL[ch_index].CTRL |= (interrupt_mask & DMA_INTERRUPT_MASK_ALL);
  598. }
  599. /**
  600. * @brief Check Channel interrupt master
  601. *
  602. * @param[in] ptr DMA base address
  603. * @param[in] ch_index Target channel index to be checked
  604. * @return uint32_t Interrupt mask
  605. */
  606. static inline uint32_t dma_check_channel_interrupt_mask(DMAV2_Type *ptr, uint8_t ch_index)
  607. {
  608. return ptr->CHCTRL[ch_index].CTRL & DMA_INTERRUPT_MASK_ALL;
  609. }
  610. /**
  611. * @brief Get default channel config
  612. *
  613. * @param[in] ptr DMA base address
  614. * @param[in] ch Channel config
  615. */
  616. void dma_default_channel_config(DMAV2_Type *ptr, dma_channel_config_t *ch);
  617. /**
  618. * @brief Setup DMA channel
  619. *
  620. * @param[in] ptr DMA base address
  621. * @param[in] ch_num Target channel index to be configured
  622. * @param[in] ch Channel config
  623. * @param[in] start_transfer Set true to start transfer
  624. *
  625. * @return status_success if everything is okay
  626. */
  627. hpm_stat_t dma_setup_channel(DMAV2_Type *ptr, uint8_t ch_num,
  628. dma_channel_config_t *ch, bool start_transfer);
  629. /**
  630. * @brief Config linked descriptor function
  631. *
  632. * @param[in] ptr DMA base address
  633. * @param[in] descriptor Linked descriptor pointer
  634. * @param[in] ch_num Target channel index to be configured
  635. * @param[in] config Descriptor config pointer
  636. *
  637. * @return status_success if everything is okay
  638. */
  639. hpm_stat_t dma_config_linked_descriptor(DMAV2_Type *ptr, dma_linked_descriptor_t *descriptor, uint8_t ch_num, dma_channel_config_t *config);
  640. /**
  641. * @brief Start DMA copy
  642. *
  643. * @param[in] ptr DMA base address
  644. * @param[in] ch_num Target channel index
  645. * @param[in] dst Destination address
  646. * @param[in] src Source Address
  647. * @param[in] size_in_byte Size in byte
  648. * @param[in] burst_len_in_byte Burst length in byte
  649. *
  650. * @return status_success if everthing is okay
  651. * @note: dst, src, size should be aligned with burst_len_in_byte
  652. */
  653. hpm_stat_t dma_start_memcpy(DMAV2_Type *ptr, uint8_t ch_num,
  654. uint32_t dst, uint32_t src,
  655. uint32_t size_in_byte, uint32_t burst_len_in_byte);
  656. /**
  657. * @brief Get default handshake config
  658. *
  659. * @param[in] ptr DMA base address
  660. * @param[in] config default config
  661. */
  662. void dma_default_handshake_config(DMAV2_Type *ptr, dma_handshake_config_t *config);
  663. /**
  664. * @brief config dma handshake function
  665. *
  666. * @param[in] ptr DMA base address
  667. * @param[in] pconfig dma handshake config pointer
  668. * @param[in] start_transfer Set true to start transfer
  669. *
  670. * @return status_success if everything is okay
  671. */
  672. hpm_stat_t dma_setup_handshake(DMAV2_Type *ptr, dma_handshake_config_t *pconfig, bool start_transfer);
  673. /**
  674. * @brief Check whether DMA is idle
  675. * @param [in] ptr DMA base address
  676. * @return true DMA is idle
  677. * @return false DMA is busy
  678. */
  679. static inline bool dma_is_idle(DMAV2_Type *ptr)
  680. {
  681. return (DMAV2_IDMISC_DMASTATE_GET(ptr->IDMISC) == dmav2_state_idle) ? true : false;
  682. }
  683. #ifdef __cplusplus
  684. }
  685. #endif
  686. /**
  687. * @}
  688. */
  689. #endif /* HPM_DMAV2_DRV_H */