hpm_dma_drv.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /*
  2. * Copyright (c) 2021-2022 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_DMAV1_DRV_H
  8. #define HPM_DMAV1_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_soc_feature.h"
  11. #include "hpm_dma_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_CHANNEL_PRIORITY_LOW (0U)
  20. #define DMA_CHANNEL_PRIORITY_HIGH (1U)
  21. #define DMA_NUM_TRANSFER_PER_BURST_1T (0U)
  22. #define DMA_NUM_TRANSFER_PER_BURST_2T (1U)
  23. #define DMA_NUM_TRANSFER_PER_BURST_4T (2U)
  24. #define DMA_NUM_TRANSFER_PER_BURST_8T (3U)
  25. #define DMA_NUM_TRANSFER_PER_BURST_16T (4U)
  26. #define DMA_NUM_TRANSFER_PER_BURST_32T (5U)
  27. #define DMA_NUM_TRANSFER_PER_BURST_64T (6U)
  28. #define DMA_NUM_TRANSFER_PER_BURST_128T (7U)
  29. #define DMA_NUM_TRANSFER_PER_BURST_256T (8U)
  30. #define DMA_NUM_TRANSFER_PER_BURST_512T (9U)
  31. #define DMA_NUM_TRANSFER_PER_BURST_1024T (10U)
  32. #define DMA_TRANSFER_WIDTH_BYTE (0U)
  33. #define DMA_TRANSFER_WIDTH_HALF_WORD (1U)
  34. #define DMA_TRANSFER_WIDTH_WORD (2U)
  35. #define DMA_TRANSFER_WIDTH_DOUBLE_WORD (3U)
  36. #define DMA_ALIGN_HALF_WORD(x) (x & ~(1u))
  37. #define DMA_ALIGN_WORD(x) (x & ~(3u))
  38. #define DMA_ALIGN_DOUBLE_WORD(x) (x & ~(7u))
  39. #define DMA_STATUS_ERROR_SHIFT (0U)
  40. #define DMA_STATUS_ABORT_SHIFT (8U)
  41. #define DMA_STATUS_TC_SHIFT (16U)
  42. #define DMA_CHANNEL_STATUS_ONGOING (1U)
  43. #define DMA_CHANNEL_STATUS_ERROR (2U)
  44. #define DMA_CHANNEL_STATUS_ABORT (4U)
  45. #define DMA_CHANNEL_STATUS_TC (8U)
  46. #define DMA_CHANNEL_IRQ_STATUS_ERROR(x) (uint32_t)(1 << (DMA_STATUS_ERROR_SHIFT + x))
  47. #define DMA_CHANNEL_IRQ_STATUS_ABORT(x) (uint32_t)(1 << (DMA_STATUS_ABORT_SHIFT + x))
  48. #define DMA_CHANNEL_IRQ_STATUS_TC(x) (uint32_t)(1 << (DMA_STATUS_TC_SHIFT + x))
  49. #define DMA_CHANNEL_IRQ_STATUS(x) (uint32_t)(DMA_CHANNEL_IRQ_STATUS_TC(x) | \
  50. DMA_CHANNEL_IRQ_STATUS_ABORT(x) | \
  51. DMA_CHANNEL_IRQ_STATUS_ERROR(x))
  52. #define DMA_CHANNEL_IRQ_STATUS_GET_ALL_TC(x) ((x) & (((0x01UL << DMA_SOC_CHANNEL_NUM) - 1) << DMA_STATUS_TC_SHIFT))
  53. #define DMA_CHANNEL_IRQ_STATUS_GET_ALL_ABORT(x) ((x) & (((0x01UL << DMA_SOC_CHANNEL_NUM) - 1) << DMA_STATUS_ABORT_SHIFT))
  54. #define DMA_CHANNEL_IRQ_STATUS_GET_ALL_ERROR(x) ((x) & (((0x01UL << DMA_SOC_CHANNEL_NUM) - 1) << DMA_STATUS_ERROR_SHIFT))
  55. #define DMA_HANDSHAKE_MODE_NORMAL (0U)
  56. #define DMA_HANDSHAKE_MODE_HANDSHAKE (1U)
  57. #define DMA_ADDRESS_CONTROL_INCREMENT (0U)
  58. #define DMA_ADDRESS_CONTROL_DECREMENT (1U)
  59. #define DMA_ADDRESS_CONTROL_FIXED (2U)
  60. #define DMA_INTERRUPT_MASK_NONE (0U)
  61. #define DMA_INTERRUPT_MASK_ERROR DMA_CHCTRL_CTRL_INTERRMASK_MASK
  62. #define DMA_INTERRUPT_MASK_ABORT DMA_CHCTRL_CTRL_INTABTMASK_MASK
  63. #define DMA_INTERRUPT_MASK_TERMINAL_COUNT DMA_CHCTRL_CTRL_INTTCMASK_MASK
  64. #define DMA_INTERRUPT_MASK_ALL \
  65. (uint8_t)(DMA_INTERRUPT_MASK_TERMINAL_COUNT \
  66. | DMA_INTERRUPT_MASK_ABORT \
  67. | DMA_INTERRUPT_MASK_ERROR)
  68. #ifndef DMA_SUPPORT_64BIT_ADDR
  69. #define DMA_SUPPORT_64BIT_ADDR (0)
  70. #endif
  71. /**
  72. * @brief Linked descriptor
  73. *
  74. * It is consumed by DMA controlled directly
  75. */
  76. typedef struct dma_linked_descriptor {
  77. uint32_t ctrl; /**< Control */
  78. uint32_t trans_size; /**< Transfer size in source width */
  79. uint32_t src_addr; /**< Source address */
  80. uint32_t src_addr_high; /**< Source address high 32-bit, only valid when bus width > 32bits */
  81. uint32_t dst_addr; /**< Destination address */
  82. uint32_t dst_addr_high; /**< Destination address high 32-bit, only valid when bus width > 32bits */
  83. uint32_t linked_ptr; /**< Linked descriptor address */
  84. uint32_t linked_ptr_high; /**< Linked descriptor address high 32-bit, , only valid when bus width > 32bits */
  85. } dma_linked_descriptor_t;
  86. /* @brief Channel config */
  87. typedef struct dma_channel_config {
  88. uint8_t priority; /**< Channel priority */
  89. uint8_t src_burst_size; /**< Source burst size */
  90. uint8_t src_mode; /**< Source work mode */
  91. uint8_t dst_mode; /**< Destination work mode */
  92. uint8_t src_width; /**< Source width */
  93. uint8_t dst_width; /**< Destination width */
  94. uint8_t src_addr_ctrl; /**< Source address control */
  95. uint8_t dst_addr_ctrl; /**< Destination address control */
  96. uint16_t interrupt_mask; /**< Interrupt mask */
  97. uint32_t src_addr; /**< Source address */
  98. uint32_t dst_addr; /**< Destination address */
  99. uint32_t linked_ptr; /**< Next linked descriptor */
  100. uint32_t size_in_byte; /**< Total size to be transferred in byte */
  101. #if DMA_SUPPORT_64BIT_ADDR
  102. uint32_t src_addr_high; /**< Source address high 32bits */
  103. uint32_t dst_addr_high; /**< Destination address high 32bits */
  104. uint32_t linked_ptr_high; /**< Linked descriptor high 32bits */
  105. #endif
  106. } dma_channel_config_t;
  107. /* @brief Channel config */
  108. typedef struct dma_handshake_config {
  109. uint32_t dst;
  110. uint32_t src;
  111. uint32_t size_in_byte;
  112. uint8_t data_width; /* data width, value defined by DMA_TRANSFER_WIDTH_xxx */
  113. uint8_t ch_index;
  114. bool dst_fixed;
  115. bool src_fixed;
  116. } dma_handshake_config_t;
  117. /* @brief DMA specific status */
  118. enum {
  119. status_dma_transfer_done = MAKE_STATUS(status_group_dma, 0),
  120. status_dma_transfer_error = MAKE_STATUS(status_group_dma, 1),
  121. status_dma_transfer_abort = MAKE_STATUS(status_group_dma, 2),
  122. status_dma_transfer_ongoing = MAKE_STATUS(status_group_dma, 3),
  123. status_dma_alignment_error = MAKE_STATUS(status_group_dma, 4),
  124. };
  125. #ifdef __cplusplus
  126. extern "C" {
  127. #endif
  128. /**
  129. * @brief Reset DMA
  130. *
  131. * @param[in] ptr DMA base address
  132. */
  133. static inline void dma_reset(DMA_Type *ptr)
  134. {
  135. ptr->DMACTRL |= DMA_DMACTRL_RESET_MASK;
  136. }
  137. /**
  138. * @brief Enable DMA channel
  139. *
  140. * @param[in] ptr DMA base address
  141. * @param[in] ch_index Index of the channel to be enabled
  142. *
  143. * @return status_success if everything's okay
  144. */
  145. static inline hpm_stat_t dma_enable_channel(DMA_Type *ptr, uint32_t ch_index)
  146. {
  147. ptr->CHCTRL[ch_index].CTRL |= DMA_CHCTRL_CTRL_ENABLE_MASK;
  148. if ((ptr->CHEN == 0) || !(ptr->CHEN & 1 << ch_index)) {
  149. return status_fail;
  150. }
  151. return status_success;
  152. }
  153. /**
  154. * @brief Disable DMA channel
  155. *
  156. * @param[in] ptr DMA base address
  157. * @param[in] ch_index Index of the channel to be disabled
  158. *
  159. */
  160. static inline void dma_disable_channel(DMA_Type *ptr, uint32_t ch_index)
  161. {
  162. ptr->CHCTRL[ch_index].CTRL &= ~DMA_CHCTRL_CTRL_ENABLE_MASK;
  163. }
  164. /**
  165. * @brief Check whether DMA channel is enable
  166. *
  167. * @param[in] ptr DMA base address
  168. * @param[in] ch_index Index of the channel
  169. *
  170. * @return true if DMA channel is enable
  171. *
  172. */
  173. static inline bool dma_channel_is_enable(DMA_Type *ptr, uint32_t ch_index)
  174. {
  175. return (ptr->CHCTRL[ch_index].CTRL & DMA_CHCTRL_CTRL_ENABLE_MASK) ? true : false;
  176. }
  177. /**
  178. * @brief Set DMA channel priority
  179. *
  180. * @param[in] ptr DMA base address
  181. * @param[in] ch_index Index of the channel
  182. * @param[in] priority dma priority
  183. * @arg @ref DMA_CHANNEL_PRIORITY_LOW
  184. * @arg @ref DMA_CHANNEL_PRIORITY_HIGH
  185. *
  186. */
  187. static inline void dma_set_priority(DMA_Type *ptr, uint32_t ch_index, uint8_t priority)
  188. {
  189. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_PRIORITY_MASK) | DMA_CHCTRL_CTRL_PRIORITY_SET(priority);
  190. }
  191. /**
  192. * @brief Set DMA channel source work mode
  193. *
  194. * @param[in] ptr DMA base address
  195. * @param[in] ch_index Index of the channel
  196. * @param[in] mode source work mode
  197. * @arg @ref DMA_HANDSHAKE_MODE_NORMAL
  198. * @arg @ref DMA_HANDSHAKE_MODE_HANDSHAKE
  199. *
  200. */
  201. static inline void dma_set_source_work_mode(DMA_Type *ptr, uint32_t ch_index, uint8_t mode)
  202. {
  203. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_SRCMODE_MASK) | DMA_CHCTRL_CTRL_SRCMODE_SET(mode);
  204. }
  205. /**
  206. * @brief Set DMA channel destination work mode
  207. *
  208. * @param[in] ptr DMA base address
  209. * @param[in] ch_index Index of the channel
  210. * @param[in] mode destination work mode
  211. * @arg @ref DMA_HANDSHAKE_MODE_NORMAL
  212. * @arg @ref DMA_HANDSHAKE_MODE_HANDSHAKE
  213. *
  214. */
  215. static inline void dma_set_destination_work_mode(DMA_Type *ptr, uint32_t ch_index, uint8_t mode)
  216. {
  217. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_DSTMODE_MASK) | DMA_CHCTRL_CTRL_DSTMODE_SET(mode);
  218. }
  219. /**
  220. * @brief Set DMA channel source burst size
  221. *
  222. * @param[in] ptr DMA base address
  223. * @param[in] ch_index Index of the channel
  224. * @param[in] burstsize source burst size
  225. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_1T
  226. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_2T
  227. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_4T
  228. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_8T
  229. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_16T
  230. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_32T
  231. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_64T
  232. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_128T
  233. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_256T
  234. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_512T
  235. * @arg @ref DMA_NUM_TRANSFER_PER_BURST_1024T
  236. *
  237. */
  238. static inline void dma_set_source_burst_size(DMA_Type *ptr, uint32_t ch_index, uint8_t burstsize)
  239. {
  240. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_SRCBURSTSIZE_MASK) | DMA_CHCTRL_CTRL_SRCBURSTSIZE_SET(burstsize);
  241. }
  242. /**
  243. * @brief Get DMA channel remaining transfer size
  244. *
  245. * @param[in] ptr DMA base address
  246. * @param[in] ch_index Index of the channel
  247. *
  248. * @return remaining transfer size
  249. *
  250. */
  251. static inline uint32_t dma_get_remaining_transfer_size(DMA_Type *ptr, uint32_t ch_index)
  252. {
  253. return ptr->CHCTRL[ch_index].TRANSIZE;
  254. }
  255. /**
  256. * @brief Set DMA channel transfer size
  257. *
  258. * @param[in] ptr DMA base address
  259. * @param[in] ch_index Index of the channel
  260. * @param[in] size_in_width transfer size of the channel. The width is current dma channel configured source width.
  261. * Transfer total bytes are (size_in_width * source width).
  262. *
  263. */
  264. static inline void dma_set_transfer_size(DMA_Type *ptr, uint32_t ch_index, uint32_t size_in_width)
  265. {
  266. ptr->CHCTRL[ch_index].TRANSIZE = DMA_CHCTRL_TRANSIZE_TRANSIZE_SET(size_in_width);
  267. }
  268. /**
  269. * @brief Set DMA channel source width
  270. *
  271. * @param[in] ptr DMA base address
  272. * @param[in] ch_index Index of the channel
  273. * @param[in] width transfer source width of the channel
  274. * @arg @ref DMA_TRANSFER_WIDTH_BYTE
  275. * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
  276. * @arg @ref DMA_TRANSFER_WIDTH_WORD
  277. * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
  278. */
  279. static inline void dma_set_source_width(DMA_Type *ptr, uint32_t ch_index, uint8_t width)
  280. {
  281. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_SRCWIDTH_MASK) | DMA_CHCTRL_CTRL_SRCWIDTH_SET(width);
  282. }
  283. /**
  284. * @brief Set DMA channel destination width
  285. *
  286. * @param[in] ptr DMA base address
  287. * @param[in] ch_index Index of the channel
  288. * @param[in] width transfer destination width of the channel
  289. * @arg @ref DMA_TRANSFER_WIDTH_BYTE
  290. * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
  291. * @arg @ref DMA_TRANSFER_WIDTH_WORD
  292. * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
  293. */
  294. static inline void dma_set_destination_width(DMA_Type *ptr, uint32_t ch_index, uint8_t width)
  295. {
  296. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_DSTWIDTH_MASK) | DMA_CHCTRL_CTRL_DSTWIDTH_SET(width);
  297. }
  298. /**
  299. * @brief Set DMA channel transfer width and size in byte
  300. *
  301. * @param[in] ptr DMA base address
  302. * @param[in] ch_index Index of the channel
  303. * @param[in] src_width transfer source width of the channel
  304. * @arg @ref DMA_TRANSFER_WIDTH_BYTE
  305. * @arg @ref DMA_TRANSFER_WIDTH_HALF_WORD
  306. * @arg @ref DMA_TRANSFER_WIDTH_WORD
  307. * @arg @ref DMA_TRANSFER_WIDTH_DOUBLE_WORD
  308. * @param[in] size_in_byte transfer size in byte of the channel. The dma transfer size is (size_in_byte >> src_width).
  309. *
  310. */
  311. static inline void dma_set_transfer_src_width_byte_size(DMA_Type *ptr, uint32_t ch_index, uint8_t src_width, uint32_t size_in_byte)
  312. {
  313. assert((src_width == DMA_TRANSFER_WIDTH_BYTE) || (src_width == DMA_TRANSFER_WIDTH_HALF_WORD)
  314. || (src_width == DMA_TRANSFER_WIDTH_WORD) || (src_width == DMA_TRANSFER_WIDTH_DOUBLE_WORD));
  315. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_SRCWIDTH_MASK) | DMA_CHCTRL_CTRL_SRCWIDTH_SET(src_width);
  316. ptr->CHCTRL[ch_index].TRANSIZE = DMA_CHCTRL_TRANSIZE_TRANSIZE_SET(size_in_byte >> src_width);
  317. }
  318. /**
  319. * @brief Set DMA channel source address
  320. *
  321. * @param[in] ptr DMA base address
  322. * @param[in] ch_index Index of the channel
  323. * @param[in] addr source address
  324. *
  325. */
  326. static inline void dma_set_source_address(DMA_Type *ptr, uint32_t ch_index, uint32_t addr)
  327. {
  328. ptr->CHCTRL[ch_index].SRCADDR = addr;
  329. }
  330. /**
  331. * @brief Set DMA channel destination address
  332. *
  333. * @param[in] ptr DMA base address
  334. * @param[in] ch_index Index of the channel
  335. * @param[in] addr destination address
  336. *
  337. */
  338. static inline void dma_set_destination_address(DMA_Type *ptr, uint32_t ch_index, uint32_t addr)
  339. {
  340. ptr->CHCTRL[ch_index].DSTADDR = addr;
  341. }
  342. /**
  343. * @brief Set DMA channel source address control mode
  344. *
  345. * @param[in] ptr DMA base address
  346. * @param[in] ch_index Index of the channel
  347. * @param[in] addr_ctrl source address control mode
  348. * @arg @ref DMA_ADDRESS_CONTROL_INCREMENT
  349. * @arg @ref DMA_ADDRESS_CONTROL_DECREMENT
  350. * @arg @ref DMA_ADDRESS_CONTROL_FIXED
  351. *
  352. */
  353. static inline void dma_set_source_address_ctrl(DMA_Type *ptr, uint32_t ch_index, uint8_t addr_ctrl)
  354. {
  355. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_SRCADDRCTRL_MASK) | DMA_CHCTRL_CTRL_SRCADDRCTRL_SET(addr_ctrl);
  356. }
  357. /**
  358. * @brief Set DMA channel destination address control mode
  359. *
  360. * @param[in] ptr DMA base address
  361. * @param[in] ch_index Index of the channel
  362. * @param[in] addr_ctrl destination address control mode
  363. * @arg @ref DMA_ADDRESS_CONTROL_INCREMENT
  364. * @arg @ref DMA_ADDRESS_CONTROL_DECREMENT
  365. * @arg @ref DMA_ADDRESS_CONTROL_FIXED
  366. *
  367. */
  368. static inline void dma_set_destination_address_ctrl(DMA_Type *ptr, uint32_t ch_index, uint8_t addr_ctrl)
  369. {
  370. ptr->CHCTRL[ch_index].CTRL = (ptr->CHCTRL[ch_index].CTRL & ~DMA_CHCTRL_CTRL_DSTADDRCTRL_MASK) | DMA_CHCTRL_CTRL_DSTADDRCTRL_SET(addr_ctrl);
  371. }
  372. /**
  373. * @brief Abort channel transfer with mask
  374. *
  375. * @param[in] ptr DMA base address
  376. * @param[in] ch_index_mask Mask of channels to be aborted
  377. */
  378. static inline void dma_abort_channel(DMA_Type *ptr, uint32_t ch_index_mask)
  379. {
  380. ptr->CHABORT |= DMA_CHABORT_CHABORT_SET(ch_index_mask);
  381. }
  382. /**
  383. * @brief Check if channels are enabled with mask
  384. *
  385. * @param[in] ptr DMA base address
  386. * @param[in] ch_index_mask Mask of channels to be checked
  387. *
  388. * @return Enabled channel mask
  389. */
  390. static inline uint32_t dma_check_enabled_channel(DMA_Type *ptr,
  391. uint32_t ch_index_mask)
  392. {
  393. return (ch_index_mask & ptr->CHEN);
  394. }
  395. /**
  396. * @brief Check if linked pointer has been configured
  397. *
  398. * @param[in] ptr DMA base address
  399. * @param[in] ch_index Target channel index to be checked
  400. *
  401. * @return true if linked pointer has been configured
  402. */
  403. static inline bool dma_has_linked_pointer_configured(DMA_Type *ptr, uint32_t ch_index)
  404. {
  405. return ptr->CHCTRL[ch_index].LLPOINTER != 0;
  406. }
  407. /**
  408. * @brief Check transfer status
  409. *
  410. * @param[in] ptr DMA base address
  411. * @param[in] ch_index Target channel index to be checked
  412. *
  413. * @retval DMA_CHANNEL_STATUS_ONGOING if transfer is still ongoing
  414. * @retval DMA_CHANNEL_STATUS_ERROR if any error occurred during transferring
  415. * @retval DMA_CHANNEL_STATUS_ABORT if transfer is aborted
  416. * @retval DMA_CHANNEL_STATUS_TC if transfer is finished without error
  417. */
  418. static inline uint32_t dma_check_transfer_status(DMA_Type *ptr, uint8_t ch_index)
  419. {
  420. volatile uint32_t tmp = ptr->INTSTATUS;
  421. volatile uint32_t tmp_channel;
  422. uint32_t dma_status;
  423. dma_status = 0;
  424. tmp_channel = tmp & (1 << (DMA_STATUS_TC_SHIFT + ch_index));
  425. if (tmp_channel) {
  426. dma_status |= DMA_CHANNEL_STATUS_TC;
  427. ptr->INTSTATUS = tmp_channel;
  428. }
  429. tmp_channel = tmp & (1 << (DMA_STATUS_ERROR_SHIFT + ch_index));
  430. if (tmp_channel) {
  431. dma_status |= DMA_CHANNEL_STATUS_ERROR;
  432. ptr->INTSTATUS = tmp_channel;
  433. }
  434. tmp_channel = tmp & (1 << (DMA_STATUS_ABORT_SHIFT + ch_index));
  435. if (tmp_channel) {
  436. dma_status |= DMA_CHANNEL_STATUS_ABORT;
  437. ptr->INTSTATUS = tmp_channel;
  438. }
  439. if (dma_status == 0) {
  440. dma_status = DMA_CHANNEL_STATUS_ONGOING;
  441. }
  442. return dma_status;
  443. }
  444. /**
  445. * @brief Clear transfer status
  446. *
  447. * @param[in] ptr DMA base address
  448. * @param[in] ch_index Target channel index
  449. *
  450. */
  451. static inline void dma_clear_transfer_status(DMA_Type *ptr, uint8_t ch_index)
  452. {
  453. ptr->INTSTATUS = ((1 << (DMA_STATUS_TC_SHIFT + ch_index)) | (1 << (DMA_STATUS_ERROR_SHIFT + ch_index)) | (1 << (DMA_STATUS_ABORT_SHIFT + ch_index)));
  454. }
  455. /**
  456. * @brief Enable DMA Channel interrupt
  457. *
  458. * @param [in] ptr DMA base address
  459. * @param [in] ch_index Target channel index
  460. * @param [in] interrupt_mask Interrupt mask
  461. */
  462. static inline void dma_enable_channel_interrupt(DMA_Type *ptr, uint8_t ch_index, int32_t interrupt_mask)
  463. {
  464. ptr->CHCTRL[ch_index].CTRL &= ~(interrupt_mask & DMA_INTERRUPT_MASK_ALL);
  465. }
  466. /**
  467. * @brief Disable DMA Channel interrupt
  468. *
  469. * @param [in] ptr DMA base address
  470. * @param [in] ch_index Target channel index
  471. * @param [in] interrupt_mask Interrupt mask
  472. */
  473. static inline void dma_disable_channel_interrupt(DMA_Type *ptr, uint8_t ch_index, int32_t interrupt_mask)
  474. {
  475. ptr->CHCTRL[ch_index].CTRL |= (interrupt_mask & DMA_INTERRUPT_MASK_ALL);
  476. }
  477. /**
  478. * @brief Check Channel interrupt master
  479. *
  480. * @param[in] ptr DMA base address
  481. * @param[in] ch_index Target channel index to be checked
  482. * @return uint32_t Interrupt mask
  483. */
  484. static inline uint32_t dma_check_channel_interrupt_mask(DMA_Type *ptr, uint8_t ch_index)
  485. {
  486. return ptr->CHCTRL[ch_index].CTRL & DMA_INTERRUPT_MASK_ALL;
  487. }
  488. /**
  489. * @brief Get clear IRQ status
  490. *
  491. * @param[in] ptr DMA base address
  492. * @param[in] mask irq mask to be cleared
  493. */
  494. static inline void dma_clear_irq_status(DMA_Type *ptr, uint32_t mask)
  495. {
  496. ptr->INTSTATUS = mask; /* Write-1-Clear */
  497. }
  498. /**
  499. * @brief Get IRQ status
  500. *
  501. * @param[in] ptr DMA base address
  502. */
  503. static inline uint32_t dma_get_irq_status(DMA_Type *ptr)
  504. {
  505. return ptr->INTSTATUS;
  506. }
  507. /**
  508. * @brief Get default channel config
  509. *
  510. * @param[in] ptr DMA base address
  511. * @param[in] ch Channel config
  512. */
  513. void dma_default_channel_config(DMA_Type *ptr, dma_channel_config_t *ch);
  514. /**
  515. * @brief Setup DMA channel
  516. *
  517. * @param[in] ptr DMA base address
  518. * @param[in] ch_num Target channel index to be configured
  519. * @param[in] ch Channel config
  520. * @param[in] start_transfer Set true to start transfer
  521. *
  522. * @return status_success if everything is okay
  523. */
  524. hpm_stat_t dma_setup_channel(DMA_Type *ptr, uint8_t ch_num,
  525. dma_channel_config_t *ch, bool start_transfer);
  526. /**
  527. * @brief Config linked descriptor function
  528. *
  529. * @param[in] ptr DMA base address
  530. * @param[in] descriptor Linked descriptor pointer
  531. * @param[in] ch_num Target channel index to be configured
  532. * @param[in] config Descriptor config pointer
  533. *
  534. * @return status_success if everything is okay
  535. */
  536. hpm_stat_t dma_config_linked_descriptor(DMA_Type *ptr, dma_linked_descriptor_t *descriptor, uint8_t ch_num, dma_channel_config_t *config);
  537. /**
  538. * @brief Start DMA copy
  539. *
  540. * @param[in] ptr DMA base address
  541. * @param[in] ch_num Target channel index
  542. * @param[in] dst Destination address
  543. * @param[in] src Source Address
  544. * @param[in] size_in_byte Size in byte
  545. * @param[in] burst_len_in_byte Burst length in byte
  546. *
  547. * @return status_success if everthing is okay
  548. * @note: dst, src, size should be aligned with burst_len_in_byte
  549. */
  550. hpm_stat_t dma_start_memcpy(DMA_Type *ptr, uint8_t ch_num,
  551. uint32_t dst, uint32_t src,
  552. uint32_t size_in_byte, uint32_t burst_len_in_byte);
  553. /**
  554. * @brief Get default handshake config
  555. *
  556. * @param[in] ptr DMA base address
  557. * @param[in] config default config
  558. */
  559. void dma_default_handshake_config(DMA_Type *ptr, dma_handshake_config_t *config);
  560. /**
  561. * @brief config dma handshake function
  562. *
  563. * @param[in] ptr DMA base address
  564. * @param[in] pconfig dma handshake config pointer
  565. * @param[in] start_transfer Set true to start transfer
  566. *
  567. * @return status_success if everything is okay
  568. */
  569. hpm_stat_t dma_setup_handshake(DMA_Type *ptr, dma_handshake_config_t *pconfig, bool start_transfer);
  570. #if defined(DMA_SOC_HAS_IDLE_FLAG) && (DMA_SOC_HAS_IDLE_FLAG == 1)
  571. /**
  572. * @brief Check whether DMA is idle
  573. * @param [in] ptr DMA base address
  574. * @return true DMA is idle
  575. * @return false DMA is busy
  576. */
  577. static inline bool dma_is_idle(DMA_Type *ptr)
  578. {
  579. return ((ptr->IDMISC & DMA_IDMISC_IDLE_FLAG_MASK) != 0U);
  580. }
  581. #endif
  582. #ifdef __cplusplus
  583. }
  584. #endif
  585. /**
  586. * @}
  587. */
  588. #endif /* HPM_DMAV1_DRV_H */