gd32f30x_dma.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /*!
  2. \file gd32f30x_dma.c
  3. \brief DMA driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-02-10, V1.0.1, firmware for GD32F30x
  8. */
  9. #include "gd32f30x_dma.h"
  10. #define DMA_WRONG_HANDLE while(1){}
  11. static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx);
  12. /*!
  13. \brief deinitialize DMA a channel registers
  14. \param[in] dma_periph: DMAx(x=0,1)
  15. \arg DMAx(x=0,1)
  16. \param[in] channelx: specify which DMA channel is deinitialized
  17. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  18. \param[out] none
  19. \retval none
  20. */
  21. void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx)
  22. {
  23. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  24. DMA_WRONG_HANDLE
  25. }
  26. /* disable DMA a channel */
  27. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN;
  28. /* reset DMA channel registers */
  29. DMA_CHCTL(dma_periph, channelx) = DMA_CHCTL_RESET_VALUE;
  30. DMA_CHCNT(dma_periph, channelx) = DMA_CHCNT_RESET_VALUE;
  31. DMA_CHPADDR(dma_periph, channelx) = DMA_CHPADDR_RESET_VALUE;
  32. DMA_CHMADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE;
  33. DMA_INTC(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx);
  34. }
  35. /*!
  36. \brief initialize DMA channel
  37. \param[in] dma_periph: DMAx(x=0,1)
  38. \arg DMAx(x=0,1)
  39. \param[in] channelx: specify which DMA channel is initialized
  40. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  41. \param[in] init_struct: the data needed to initialize DMA channel
  42. periph_addr: peripheral base address
  43. periph_width: DMA_PERIPHERAL_WIDTH_8BIT, DMA_PERIPHERAL_WIDTH_16BIT, DMA_PERIPHERAL_WIDTH_32BIT
  44. periph_inc: DMA_PERIPH_INCREASE_ENABLE, DMA_PERIPH_INCREASE_DISABLE
  45. memory_addr: memory base address
  46. memory_width: DMA_MEMORY_WIDTH_8BIT, DMA_MEMORY_WIDTH_16BIT, DMA_MEMORY_WIDTH_32BIT
  47. memory_inc: DMA_MEMORY_INCREASE_ENABLE, DMA_MEMORY_INCREASE_DISABLE
  48. direction: DMA_PERIPHERAL_TO_MEMORY, DMA_MEMORY_TO_PERIPHERAL
  49. number: the number of remaining data to be transferred by the DMA
  50. priority: DMA_PRIORITY_LOW, DMA_PRIORITY_MEDIUM, DMA_PRIORITY_HIGH, DMA_PRIORITY_ULTRA_HIGH
  51. \param[out] none
  52. \retval none
  53. */
  54. void dma_init(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct init_struct)
  55. {
  56. uint32_t ctl;
  57. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  58. DMA_WRONG_HANDLE
  59. }
  60. /* configure peripheral base address */
  61. DMA_CHPADDR(dma_periph, channelx) = init_struct.periph_addr;
  62. /* configure memory base address */
  63. DMA_CHMADDR(dma_periph, channelx) = init_struct.memory_addr;
  64. /* configure the number of remaining data to be transferred */
  65. DMA_CHCNT(dma_periph, channelx) = (init_struct.number & DMA_CHANNEL_CNT_MASK);
  66. /* configure peripheral transfer width,memory transfer width, */
  67. ctl = DMA_CHCTL(dma_periph, channelx);
  68. ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO);
  69. ctl |= (init_struct.periph_width | init_struct.memory_width | init_struct.priority);
  70. DMA_CHCTL(dma_periph, channelx) = ctl;
  71. /* configure peripheral increasing mode */
  72. if(DMA_PERIPH_INCREASE_ENABLE == init_struct.periph_inc){
  73. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
  74. }else{
  75. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
  76. }
  77. /* configure memory increasing mode */
  78. if(DMA_MEMORY_INCREASE_ENABLE == init_struct.memory_inc){
  79. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA;
  80. }else{
  81. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA;
  82. }
  83. /* configure the direction of data transfer */
  84. if(DMA_PERIPHERAL_TO_MEMORY == init_struct.direction){
  85. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR;
  86. }else{
  87. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR;
  88. }
  89. }
  90. /*!
  91. \brief enable DMA circulation mode
  92. \param[in] dma_periph: DMAx(x=0,1)
  93. \arg DMAx(x=0,1)
  94. \param[in] channelx: specify which DMA channel
  95. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  96. \param[out] none
  97. \retval none
  98. */
  99. void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx)
  100. {
  101. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  102. DMA_WRONG_HANDLE
  103. }
  104. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN;
  105. }
  106. /*!
  107. \brief disable DMA circulation mode
  108. \param[in] dma_periph: DMAx(x=0,1)
  109. \arg DMAx(x=0,1)
  110. \param[in] channelx: specify which DMA channel
  111. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  112. \param[out] none
  113. \retval none
  114. */
  115. void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx)
  116. {
  117. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  118. DMA_WRONG_HANDLE
  119. }
  120. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN;
  121. }
  122. /*!
  123. \brief enable memory to memory mode
  124. \param[in] dma_periph: DMAx(x=0,1)
  125. \arg DMAx(x=0,1)
  126. \param[in] channelx: specify which DMA channel
  127. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  128. \param[out] none
  129. \retval none
  130. */
  131. void dma_memory_to_memory_enable(uint32_t dma_periph, dma_channel_enum channelx)
  132. {
  133. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  134. DMA_WRONG_HANDLE
  135. }
  136. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_M2M;
  137. }
  138. /*!
  139. \brief disable memory to memory mode
  140. \param[in] dma_periph: DMAx(x=0,1)
  141. \arg DMAx(x=0,1)
  142. \param[in] channelx: specify which DMA channel
  143. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  144. \param[out] none
  145. \retval none
  146. */
  147. void dma_memory_to_memory_disable(uint32_t dma_periph, dma_channel_enum channelx)
  148. {
  149. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  150. DMA_WRONG_HANDLE
  151. }
  152. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_M2M;
  153. }
  154. /*!
  155. \brief enable DMA channel
  156. \param[in] dma_periph: DMAx(x=0,1)
  157. \arg DMAx(x=0,1)
  158. \param[in] channelx: specify which DMA channel
  159. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  160. \param[out] none
  161. \retval none
  162. */
  163. void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx)
  164. {
  165. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  166. DMA_WRONG_HANDLE
  167. }
  168. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CHEN;
  169. }
  170. /*!
  171. \brief disable DMA channel
  172. \param[in] dma_periph: DMAx(x=0,1)
  173. \arg DMAx(x=0,1)
  174. \param[in] channelx: specify which DMA channel
  175. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  176. \param[out] none
  177. \retval none
  178. */
  179. void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx)
  180. {
  181. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  182. DMA_WRONG_HANDLE
  183. }
  184. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN;
  185. }
  186. /*!
  187. \brief set DMA peripheral base address
  188. \param[in] dma_periph: DMAx(x=0,1)
  189. \arg DMAx(x=0,1)
  190. \param[in] channelx: specify which DMA channel to set peripheral base address
  191. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  192. \param[in] address: peripheral base address
  193. \param[out] none
  194. \retval none
  195. */
  196. void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address)
  197. {
  198. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  199. DMA_WRONG_HANDLE
  200. }
  201. DMA_CHPADDR(dma_periph, channelx) = address;
  202. }
  203. /*!
  204. \brief set DMA memory base address
  205. \param[in] dma_periph: DMAx(x=0,1)
  206. \arg DMAx(x=0,1)
  207. \param[in] channelx: specify which DMA channel to set memory base address
  208. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  209. \param[in] address: memory base address
  210. \param[out] none
  211. \retval none
  212. */
  213. void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address)
  214. {
  215. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  216. DMA_WRONG_HANDLE
  217. }
  218. DMA_CHMADDR(dma_periph, channelx) = address;
  219. }
  220. /*!
  221. \brief set the number of remaining data to be transferred by the DMA
  222. \param[in] dma_periph: DMAx(x=0,1)
  223. \arg DMAx(x=0,1)
  224. \param[in] channelx: specify which DMA channel to set number
  225. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  226. \param[in] number: the number of remaining data to be transferred by the DMA
  227. \param[out] none
  228. \retval none
  229. */
  230. void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number)
  231. {
  232. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  233. DMA_WRONG_HANDLE
  234. }
  235. DMA_CHCNT(dma_periph, channelx) = (number & DMA_CHANNEL_CNT_MASK);
  236. }
  237. /*!
  238. \brief get the number of remaining data to be transferred by the DMA
  239. \param[in] dma_periph: DMAx(x=0,1)
  240. \arg DMAx(x=0,1)
  241. \param[in] channelx: specify which DMA channel to set number
  242. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  243. \param[out] none
  244. \retval uint32_t: the number of remaining data to be transferred by the DMA
  245. */
  246. uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx)
  247. {
  248. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  249. DMA_WRONG_HANDLE
  250. }
  251. return (uint32_t)DMA_CHCNT(dma_periph, channelx);
  252. }
  253. /*!
  254. \brief configure priority level of DMA channel
  255. \param[in] dma_periph: DMAx(x=0,1)
  256. \arg DMAx(x=0,1)
  257. \param[in] channelx: specify which DMA channel
  258. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  259. \param[in] priority: priority Level of this channel
  260. \arg DMA_PRIORITY_LOW: low priority
  261. \arg DMA_PRIORITY_MEDIUM: medium priority
  262. \arg DMA_PRIORITY_HIGH: high priority
  263. \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority
  264. \param[out] none
  265. \retval none
  266. */
  267. void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority)
  268. {
  269. uint32_t ctl;
  270. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  271. DMA_WRONG_HANDLE
  272. }
  273. /* acquire DMA_CHxCTL register */
  274. ctl = DMA_CHCTL(dma_periph, channelx);
  275. /* assign regiser */
  276. ctl &= ~DMA_CHXCTL_PRIO;
  277. ctl |= priority;
  278. DMA_CHCTL(dma_periph, channelx) = ctl;
  279. }
  280. /*!
  281. \brief configure transfer data size of memory
  282. \param[in] dma_periph: DMAx(x=0,1)
  283. \arg DMAx(x=0,1)
  284. \param[in] channelx: specify which DMA channel
  285. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  286. \param[in] mwidth: transfer data width of memory
  287. \arg DMA_MEMORY_WIDTH_8BIT: transfer data width of memory is 8-bit
  288. \arg DMA_MEMORY_WIDTH_16BIT: transfer data width of memory is 16-bit
  289. \arg DMA_MEMORY_WIDTH_32BIT: transfer data width of memory is 32-bit
  290. \param[out] none
  291. \retval none
  292. */
  293. void dma_memory_width_config (uint32_t dma_periph, dma_channel_enum channelx, uint32_t mwidth)
  294. {
  295. uint32_t ctl;
  296. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  297. DMA_WRONG_HANDLE
  298. }
  299. /* acquire DMA_CHxCTL register */
  300. ctl = DMA_CHCTL(dma_periph, channelx);
  301. /* assign regiser */
  302. ctl &= ~DMA_CHXCTL_MWIDTH;
  303. ctl |= mwidth;
  304. DMA_CHCTL(dma_periph, channelx) = ctl;
  305. }
  306. /*!
  307. \brief configure transfer data size of peripheral
  308. \param[in] dma_periph: DMAx(x=0,1)
  309. \arg DMAx(x=0,1)
  310. \param[in] channelx: specify which DMA channel
  311. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  312. \param[in] pwidth: transfer data width of peripheral
  313. \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data width of peripheral is 8-bit
  314. \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data width of peripheral is 16-bit
  315. \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data width of peripheral is 32-bit
  316. \param[out] none
  317. \retval none
  318. */
  319. void dma_periph_width_config (uint32_t dma_periph, dma_channel_enum channelx, uint32_t pwidth)
  320. {
  321. uint32_t ctl;
  322. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  323. DMA_WRONG_HANDLE
  324. }
  325. /* acquire DMA_CHxCTL register */
  326. ctl = DMA_CHCTL(dma_periph, channelx);
  327. /* assign regiser */
  328. ctl &= ~DMA_CHXCTL_PWIDTH;
  329. ctl |= pwidth;
  330. DMA_CHCTL(dma_periph, channelx) = ctl;
  331. }
  332. /*!
  333. \brief enable next address increasement algorithm of memory
  334. \param[in] dma_periph: DMAx(x=0,1)
  335. \arg DMAx(x=0,1)
  336. \param[in] channelx: specify which DMA channel
  337. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  338. \param[out] none
  339. \retval none
  340. */
  341. void dma_memory_increase_enable(uint32_t dma_periph, dma_channel_enum channelx)
  342. {
  343. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  344. DMA_WRONG_HANDLE
  345. }
  346. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA;
  347. }
  348. /*!
  349. \brief disable next address increasement algorithm of memory
  350. \param[in] dma_periph: DMAx(x=0,1)
  351. \arg DMAx(x=0,1)
  352. \param[in] channelx: specify which DMA channel
  353. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  354. \param[out] none
  355. \retval none
  356. */
  357. void dma_memory_increase_disable(uint32_t dma_periph, dma_channel_enum channelx)
  358. {
  359. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  360. DMA_WRONG_HANDLE
  361. }
  362. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA;
  363. }
  364. /*!
  365. \brief enable next address increasement algorithm of peripheral
  366. \param[in] dma_periph: DMAx(x=0,1)
  367. \arg DMAx(x=0,1)
  368. \param[in] channelx: specify which DMA channel
  369. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  370. \param[out] none
  371. \retval none
  372. */
  373. void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx)
  374. {
  375. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  376. DMA_WRONG_HANDLE
  377. }
  378. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
  379. }
  380. /*!
  381. \brief disable next address increasement algorithm of peripheral
  382. \param[in] dma_periph: DMAx(x=0,1)
  383. \arg DMAx(x=0,1)
  384. \param[in] channelx: specify which DMA channel
  385. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  386. \param[out] none
  387. \retval none
  388. */
  389. void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx)
  390. {
  391. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  392. DMA_WRONG_HANDLE
  393. }
  394. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
  395. }
  396. /*!
  397. \brief configure the direction of data transfer on the channel
  398. \param[in] dma_periph: DMAx(x=0,1)
  399. \arg DMAx(x=0,1)
  400. \param[in] channelx: specify which DMA channel
  401. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  402. \param[in] direction: specify the direction of data transfer
  403. \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory
  404. \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral
  405. \param[out] none
  406. \retval none
  407. */
  408. void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t direction)
  409. {
  410. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  411. DMA_WRONG_HANDLE
  412. }
  413. if(DMA_PERIPHERAL_TO_MEMORY == direction){
  414. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR;
  415. } else {
  416. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR;
  417. }
  418. }
  419. /*!
  420. \brief check DMA flag is set or not
  421. \param[in] dma_periph: DMAx(x=0,1)
  422. \arg DMAx(x=0,1)
  423. \param[in] channelx: specify which DMA channel to get flag
  424. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  425. \param[in] flag: specify get which flag
  426. only one parameter can be selected which is shown as below:
  427. \arg DMA_FLAG_G: global interrupt flag of channel
  428. \arg DMA_FLAG_FTF: full transfer finish flag of channel
  429. \arg DMA_FLAG_HTF: half transfer finish flag of channel
  430. \arg DMA_FLAG_ERR: error flag of channel
  431. \param[out] none
  432. \retval FlagStatus: SET or RESET
  433. */
  434. FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
  435. {
  436. FlagStatus reval;
  437. if(RESET != (DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx))){
  438. reval = SET;
  439. }else{
  440. reval = RESET;
  441. }
  442. return reval;
  443. }
  444. /*!
  445. \brief clear DMA a channel flag
  446. \param[in] dma_periph: DMAx(x=0,1)
  447. \arg DMAx(x=0,1)
  448. \param[in] channelx: specify which DMA channel to clear flag
  449. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  450. \param[in] flag: specify get which flag
  451. only one parameter can be selected which is shown as below:
  452. \arg DMA_FLAG_G: global interrupt flag of channel
  453. \arg DMA_FLAG_FTF: full transfer finish flag of channel
  454. \arg DMA_FLAG_HTF: half transfer finish flag of channel
  455. \arg DMA_FLAG_ERR: error flag of channel
  456. \param[out] none
  457. \retval none
  458. */
  459. void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
  460. {
  461. DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx);
  462. }
  463. /*!
  464. \brief check DMA flag and interrupt enable bit is set or not
  465. \param[in] dma_periph: DMAx(x=0,1)
  466. \arg DMAx(x=0,1)
  467. \param[in] channelx: specify which DMA channel to get flag
  468. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  469. \param[in] flag: specify get which flag
  470. only one parameter can be selected which is shown as below:
  471. \arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel
  472. \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel
  473. \arg DMA_INT_FLAG_ERR: error interrupt flag of channel
  474. \param[out] none
  475. \retval FlagStatus: SET or RESET
  476. */
  477. FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
  478. {
  479. uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
  480. switch(flag){
  481. case DMA_INT_FLAG_FTF:
  482. interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
  483. interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE;
  484. break;
  485. case DMA_INT_FLAG_HTF:
  486. interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
  487. interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE;
  488. break;
  489. case DMA_INT_FLAG_ERR:
  490. interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
  491. interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE;
  492. break;
  493. default:
  494. DMA_WRONG_HANDLE
  495. }
  496. if(interrupt_flag && interrupt_enable){
  497. return SET;
  498. }else{
  499. return RESET;
  500. }
  501. }
  502. /*!
  503. \brief clear DMA a channel flag
  504. \param[in] dma_periph: DMAx(x=0,1)
  505. \arg DMAx(x=0,1)
  506. \param[in] channelx: specify which DMA channel to clear flag
  507. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  508. \param[in] flag: specify get which flag
  509. only one parameter can be selected which is shown as below:
  510. \arg DMA_INT_FLAG_G: global interrupt flag of channel
  511. \arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel
  512. \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel
  513. \arg DMA_INT_FLAG_ERR: error interrupt flag of channel
  514. \param[out] none
  515. \retval none
  516. */
  517. void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
  518. {
  519. DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx);
  520. }
  521. /*!
  522. \brief enable DMA interrupt
  523. \param[in] dma_periph: DMAx(x=0,1)
  524. \arg DMAx(x=0,1)
  525. \param[in] channelx: specify which DMA channel
  526. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  527. \param[in] source: specify which interrupt to enbale
  528. one or more parameters can be selected which are shown as below
  529. \arg DMA_INT_FTF: channel full transfer finish interrupt
  530. \arg DMA_INT_HTF: channel half transfer finish interrupt
  531. \arg DMA_INT_ERR: channel error interrupt
  532. \param[out] none
  533. \retval none
  534. */
  535. void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source)
  536. {
  537. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  538. DMA_WRONG_HANDLE
  539. }
  540. DMA_CHCTL(dma_periph, channelx) |= source;
  541. }
  542. /*!
  543. \brief disable DMA interrupt
  544. \param[in] dma_periph: DMAx(x=0,1)
  545. \arg DMAx(x=0,1)
  546. \param[in] channelx: specify which DMA channel
  547. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  548. \param[in] source: specify which interrupt to disbale
  549. one or more parameters can be selected which are shown as below
  550. \arg DMA_INT_FTF: channel full transfer finish interrupt
  551. \arg DMA_INT_HTF: channel half transfer finish interrupt
  552. \arg DMA_INT_ERR: channel error interrupt
  553. \param[out] none
  554. \retval none
  555. */
  556. void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source)
  557. {
  558. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  559. DMA_WRONG_HANDLE
  560. }
  561. DMA_CHCTL(dma_periph, channelx) &= ~source;
  562. }
  563. /*!
  564. \brief check whether peripheral and channels match
  565. \param[in] dma_periph: DMAx(x=0,1)
  566. \arg DMAx(x=0,1)
  567. \param[in] channelx: specify which DMA channel
  568. \arg DMA_CHx(x=0..6)
  569. \param[out] none
  570. \retval none
  571. */
  572. static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx)
  573. {
  574. ErrStatus val = SUCCESS;
  575. if(DMA1 == dma_periph){
  576. if(channelx > DMA_CH4){
  577. val = ERROR;
  578. }
  579. }
  580. return val;
  581. }