gd32f10x_dma.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /*!
  2. \file gd32f10x_dma.c
  3. \brief DMA driver
  4. \version 2014-12-26, V1.0.0, firmware for GD32F10x
  5. \version 2017-06-20, V2.0.0, firmware for GD32F10x
  6. \version 2018-07-31, V2.1.0, firmware for GD32F10x
  7. \version 2019-10-30, V2.1.1, firmware for GD32F10x
  8. \version 2020-09-30, V2.2.0, firmware for GD32F10x
  9. */
  10. /*
  11. Copyright (c) 2020, GigaDevice Semiconductor Inc.
  12. Redistribution and use in source and binary forms, with or without modification,
  13. are permitted provided that the following conditions are met:
  14. 1. Redistributions of source code must retain the above copyright notice, this
  15. list of conditions and the following disclaimer.
  16. 2. Redistributions in binary form must reproduce the above copyright notice,
  17. this list of conditions and the following disclaimer in the documentation
  18. and/or other materials provided with the distribution.
  19. 3. Neither the name of the copyright holder nor the names of its contributors
  20. may be used to endorse or promote products derived from this software without
  21. specific prior written permission.
  22. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  25. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  26. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  29. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  31. OF SUCH DAMAGE.
  32. */
  33. #include "gd32f10x_dma.h"
  34. #define DMA_WRONG_HANDLE while(1){}
  35. /* check whether peripheral matches channels or not */
  36. static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx);
  37. /*!
  38. \brief deinitialize DMA a channel registers
  39. \param[in] dma_periph: DMAx(x=0,1)
  40. \arg DMAx(x=0,1)
  41. \param[in] channelx: specify which DMA channel is deinitialized
  42. only one parameter can be selected which is shown as below:
  43. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  44. \param[out] none
  45. \retval none
  46. */
  47. void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx)
  48. {
  49. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  50. DMA_WRONG_HANDLE
  51. }
  52. /* disable DMA a channel */
  53. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN;
  54. /* reset DMA channel registers */
  55. DMA_CHCTL(dma_periph, channelx) = DMA_CHCTL_RESET_VALUE;
  56. DMA_CHCNT(dma_periph, channelx) = DMA_CHCNT_RESET_VALUE;
  57. DMA_CHPADDR(dma_periph, channelx) = DMA_CHPADDR_RESET_VALUE;
  58. DMA_CHMADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE;
  59. DMA_INTC(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx);
  60. }
  61. /*!
  62. \brief initialize the parameters of DMA struct with the default values
  63. \param[in] init_struct: the initialization data needed to initialize DMA channel
  64. \param[out] none
  65. \retval none
  66. */
  67. void dma_struct_para_init(dma_parameter_struct* init_struct)
  68. {
  69. /* set the DMA struct with the default values */
  70. init_struct->periph_addr = 0U;
  71. init_struct->periph_width = 0U;
  72. init_struct->periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  73. init_struct->memory_addr = 0U;
  74. init_struct->memory_width = 0U;
  75. init_struct->memory_inc = DMA_MEMORY_INCREASE_DISABLE;
  76. init_struct->number = 0U;
  77. init_struct->direction = DMA_PERIPHERAL_TO_MEMORY;
  78. init_struct->priority = DMA_PRIORITY_LOW;
  79. }
  80. /*!
  81. \brief initialize DMA channel
  82. \param[in] dma_periph: DMAx(x=0,1)
  83. \arg DMAx(x=0,1)
  84. \param[in] channelx: specify which DMA channel is initialized
  85. only one parameter can be selected which is shown as below:
  86. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  87. \param[in] init_struct: the data needed to initialize DMA channel
  88. periph_addr: peripheral base address
  89. periph_width: DMA_PERIPHERAL_WIDTH_8BIT, DMA_PERIPHERAL_WIDTH_16BIT, DMA_PERIPHERAL_WIDTH_32BIT
  90. periph_inc: DMA_PERIPH_INCREASE_ENABLE, DMA_PERIPH_INCREASE_DISABLE
  91. memory_addr: memory base address
  92. memory_width: DMA_MEMORY_WIDTH_8BIT, DMA_MEMORY_WIDTH_16BIT, DMA_MEMORY_WIDTH_32BIT
  93. memory_inc: DMA_MEMORY_INCREASE_ENABLE, DMA_MEMORY_INCREASE_DISABLE
  94. direction: DMA_PERIPHERAL_TO_MEMORY, DMA_MEMORY_TO_PERIPHERAL
  95. number: the number of remaining data to be transferred by the DMA
  96. priority: DMA_PRIORITY_LOW, DMA_PRIORITY_MEDIUM, DMA_PRIORITY_HIGH, DMA_PRIORITY_ULTRA_HIGH
  97. \param[out] none
  98. \retval none
  99. */
  100. void dma_init(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct *init_struct)
  101. {
  102. uint32_t ctl;
  103. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  104. DMA_WRONG_HANDLE
  105. }
  106. /* configure peripheral base address */
  107. DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr;
  108. /* configure memory base address */
  109. DMA_CHMADDR(dma_periph, channelx) = init_struct->memory_addr;
  110. /* configure the number of remaining data to be transferred */
  111. DMA_CHCNT(dma_periph, channelx) = (init_struct->number & DMA_CHANNEL_CNT_MASK);
  112. /* configure peripheral transfer width,memory transfer width, */
  113. ctl = DMA_CHCTL(dma_periph, channelx);
  114. ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO);
  115. ctl |= (init_struct->periph_width | init_struct->memory_width | init_struct->priority);
  116. DMA_CHCTL(dma_periph, channelx) = ctl;
  117. /* configure peripheral increasing mode */
  118. if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc){
  119. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
  120. }else{
  121. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
  122. }
  123. /* configure memory increasing mode */
  124. if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc){
  125. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA;
  126. }else{
  127. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA;
  128. }
  129. /* configure the direction of data transfer */
  130. if(DMA_PERIPHERAL_TO_MEMORY == init_struct->direction){
  131. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR;
  132. }else{
  133. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR;
  134. }
  135. }
  136. /*!
  137. \brief enable DMA circulation mode
  138. \param[in] dma_periph: DMAx(x=0,1)
  139. \arg DMAx(x=0,1)
  140. \param[in] channelx: specify which DMA channel
  141. only one parameter can be selected which is shown as below:
  142. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  143. \param[out] none
  144. \retval none
  145. */
  146. void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx)
  147. {
  148. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  149. DMA_WRONG_HANDLE
  150. }
  151. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN;
  152. }
  153. /*!
  154. \brief disable DMA circulation mode
  155. \param[in] dma_periph: DMAx(x=0,1)
  156. \arg DMAx(x=0,1)
  157. \param[in] channelx: specify which DMA channel
  158. only one parameter can be selected which is shown as below:
  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_circulation_disable(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_CMEN;
  169. }
  170. /*!
  171. \brief enable memory to memory mode
  172. \param[in] dma_periph: DMAx(x=0,1)
  173. \arg DMAx(x=0,1)
  174. \param[in] channelx: specify which DMA channel
  175. only one parameter can be selected which is shown as below:
  176. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  177. \param[out] none
  178. \retval none
  179. */
  180. void dma_memory_to_memory_enable(uint32_t dma_periph, dma_channel_enum channelx)
  181. {
  182. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  183. DMA_WRONG_HANDLE
  184. }
  185. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_M2M;
  186. }
  187. /*!
  188. \brief disable memory to memory mode
  189. \param[in] dma_periph: DMAx(x=0,1)
  190. \arg DMAx(x=0,1)
  191. \param[in] channelx: specify which DMA channel
  192. only one parameter can be selected which is shown as below:
  193. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  194. \param[out] none
  195. \retval none
  196. */
  197. void dma_memory_to_memory_disable(uint32_t dma_periph, dma_channel_enum channelx)
  198. {
  199. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  200. DMA_WRONG_HANDLE
  201. }
  202. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_M2M;
  203. }
  204. /*!
  205. \brief enable DMA channel
  206. \param[in] dma_periph: DMAx(x=0,1)
  207. \arg DMAx(x=0,1)
  208. \param[in] channelx: specify which DMA channel
  209. only one parameter can be selected which is shown as below:
  210. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  211. \param[out] none
  212. \retval none
  213. */
  214. void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx)
  215. {
  216. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  217. DMA_WRONG_HANDLE
  218. }
  219. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CHEN;
  220. }
  221. /*!
  222. \brief disable DMA channel
  223. \param[in] dma_periph: DMAx(x=0,1)
  224. \arg DMAx(x=0,1)
  225. \param[in] channelx: specify which DMA channel
  226. only one parameter can be selected which is shown as below:
  227. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  228. \param[out] none
  229. \retval none
  230. */
  231. void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx)
  232. {
  233. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  234. DMA_WRONG_HANDLE
  235. }
  236. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN;
  237. }
  238. /*!
  239. \brief set DMA peripheral base address
  240. \param[in] dma_periph: DMAx(x=0,1)
  241. \arg DMAx(x=0,1)
  242. \param[in] channelx: specify which DMA channel to set peripheral base address
  243. only one parameter can be selected which is shown as below:
  244. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  245. \param[in] address: peripheral base address
  246. \param[out] none
  247. \retval none
  248. */
  249. void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address)
  250. {
  251. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  252. DMA_WRONG_HANDLE
  253. }
  254. DMA_CHPADDR(dma_periph, channelx) = address;
  255. }
  256. /*!
  257. \brief set DMA memory base address
  258. \param[in] dma_periph: DMAx(x=0,1)
  259. \arg DMAx(x=0,1)
  260. \param[in] channelx: specify which DMA channel to set memory base address
  261. only one parameter can be selected which is shown as below:
  262. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  263. \param[in] address: memory base address
  264. \param[out] none
  265. \retval none
  266. */
  267. void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address)
  268. {
  269. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  270. DMA_WRONG_HANDLE
  271. }
  272. DMA_CHMADDR(dma_periph, channelx) = address;
  273. }
  274. /*!
  275. \brief set the number of remaining data to be transferred by the DMA
  276. \param[in] dma_periph: DMAx(x=0,1)
  277. \arg DMAx(x=0,1)
  278. \param[in] channelx: specify which DMA channel to set number
  279. only one parameter can be selected which is shown as below:
  280. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  281. \param[in] number: the number of remaining data to be transferred by the DMA
  282. \arg 0x0000-0xFFFF
  283. \param[out] none
  284. \retval none
  285. */
  286. void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number)
  287. {
  288. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  289. DMA_WRONG_HANDLE
  290. }
  291. DMA_CHCNT(dma_periph, channelx) = (number & DMA_CHANNEL_CNT_MASK);
  292. }
  293. /*!
  294. \brief get the number of remaining data to be transferred by the DMA
  295. \param[in] dma_periph: DMAx(x=0,1)
  296. \arg DMAx(x=0,1)
  297. \param[in] channelx: specify which DMA channel to set number
  298. only one parameter can be selected which is shown as below:
  299. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  300. \param[out] none
  301. \retval uint32_t: the number of remaining data to be transferred by the DMA
  302. */
  303. uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx)
  304. {
  305. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  306. DMA_WRONG_HANDLE
  307. }
  308. return (uint32_t)DMA_CHCNT(dma_periph, channelx);
  309. }
  310. /*!
  311. \brief configure priority level of DMA channel
  312. \param[in] dma_periph: DMAx(x=0,1)
  313. \arg DMAx(x=0,1)
  314. \param[in] channelx: specify which DMA channel
  315. only one parameter can be selected which is shown as below:
  316. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  317. \param[in] priority: priority Level of this channel
  318. only one parameter can be selected which is shown as below:
  319. \arg DMA_PRIORITY_LOW: low priority
  320. \arg DMA_PRIORITY_MEDIUM: medium priority
  321. \arg DMA_PRIORITY_HIGH: high priority
  322. \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority
  323. \param[out] none
  324. \retval none
  325. */
  326. void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority)
  327. {
  328. uint32_t ctl;
  329. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  330. DMA_WRONG_HANDLE
  331. }
  332. /* acquire DMA_CHxCTL register */
  333. ctl = DMA_CHCTL(dma_periph, channelx);
  334. /* assign regiser */
  335. ctl &= ~DMA_CHXCTL_PRIO;
  336. ctl |= priority;
  337. DMA_CHCTL(dma_periph, channelx) = ctl;
  338. }
  339. /*!
  340. \brief configure transfer data size of memory
  341. \param[in] dma_periph: DMAx(x=0,1)
  342. \arg DMAx(x=0,1)
  343. \param[in] channelx: specify which DMA channel
  344. only one parameter can be selected which is shown as below:
  345. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  346. \param[in] mwidth: transfer data width of memory
  347. only one parameter can be selected which is shown as below:
  348. \arg DMA_MEMORY_WIDTH_8BIT: transfer data width of memory is 8-bit
  349. \arg DMA_MEMORY_WIDTH_16BIT: transfer data width of memory is 16-bit
  350. \arg DMA_MEMORY_WIDTH_32BIT: transfer data width of memory is 32-bit
  351. \param[out] none
  352. \retval none
  353. */
  354. void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mwidth)
  355. {
  356. uint32_t ctl;
  357. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  358. DMA_WRONG_HANDLE
  359. }
  360. /* acquire DMA_CHxCTL register */
  361. ctl = DMA_CHCTL(dma_periph, channelx);
  362. /* assign regiser */
  363. ctl &= ~DMA_CHXCTL_MWIDTH;
  364. ctl |= mwidth;
  365. DMA_CHCTL(dma_periph, channelx) = ctl;
  366. }
  367. /*!
  368. \brief configure transfer data size of peripheral
  369. \param[in] dma_periph: DMAx(x=0,1)
  370. \arg DMAx(x=0,1)
  371. \param[in] channelx: specify which DMA channel
  372. only one parameter can be selected which is shown as below:
  373. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  374. \param[in] pwidth: transfer data width of peripheral
  375. only one parameter can be selected which is shown as below:
  376. \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data width of peripheral is 8-bit
  377. \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data width of peripheral is 16-bit
  378. \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data width of peripheral is 32-bit
  379. \param[out] none
  380. \retval none
  381. */
  382. void dma_periph_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t pwidth)
  383. {
  384. uint32_t ctl;
  385. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  386. DMA_WRONG_HANDLE
  387. }
  388. /* acquire DMA_CHxCTL register */
  389. ctl = DMA_CHCTL(dma_periph, channelx);
  390. /* assign regiser */
  391. ctl &= ~DMA_CHXCTL_PWIDTH;
  392. ctl |= pwidth;
  393. DMA_CHCTL(dma_periph, channelx) = ctl;
  394. }
  395. /*!
  396. \brief enable next address increasement algorithm of memory
  397. \param[in] dma_periph: DMAx(x=0,1)
  398. \arg DMAx(x=0,1)
  399. \param[in] channelx: specify which DMA channel
  400. only one parameter can be selected which is shown as below:
  401. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  402. \param[out] none
  403. \retval none
  404. */
  405. void dma_memory_increase_enable(uint32_t dma_periph, dma_channel_enum channelx)
  406. {
  407. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  408. DMA_WRONG_HANDLE
  409. }
  410. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA;
  411. }
  412. /*!
  413. \brief disable next address increasement algorithm of memory
  414. \param[in] dma_periph: DMAx(x=0,1)
  415. \arg DMAx(x=0,1)
  416. \param[in] channelx: specify which DMA channel
  417. only one parameter can be selected which is shown as below:
  418. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  419. \param[out] none
  420. \retval none
  421. */
  422. void dma_memory_increase_disable(uint32_t dma_periph, dma_channel_enum channelx)
  423. {
  424. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  425. DMA_WRONG_HANDLE
  426. }
  427. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA;
  428. }
  429. /*!
  430. \brief enable next address increasement algorithm of peripheral
  431. \param[in] dma_periph: DMAx(x=0,1)
  432. \arg DMAx(x=0,1)
  433. \param[in] channelx: specify which DMA channel
  434. only one parameter can be selected which is shown as below:
  435. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  436. \param[out] none
  437. \retval none
  438. */
  439. void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx)
  440. {
  441. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  442. DMA_WRONG_HANDLE
  443. }
  444. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
  445. }
  446. /*!
  447. \brief disable next address increasement algorithm of peripheral
  448. \param[in] dma_periph: DMAx(x=0,1)
  449. \arg DMAx(x=0,1)
  450. \param[in] channelx: specify which DMA channel
  451. only one parameter can be selected which is shown as below:
  452. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  453. \param[out] none
  454. \retval none
  455. */
  456. void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx)
  457. {
  458. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  459. DMA_WRONG_HANDLE
  460. }
  461. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
  462. }
  463. /*!
  464. \brief configure the direction of data transfer on the channel
  465. \param[in] dma_periph: DMAx(x=0,1)
  466. \arg DMAx(x=0,1)
  467. \param[in] channelx: specify which DMA channel
  468. only one parameter can be selected which is shown as below:
  469. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  470. \param[in] direction: specify the direction of data transfer
  471. only one parameter can be selected which is shown as below:
  472. \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory
  473. \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral
  474. \param[out] none
  475. \retval none
  476. */
  477. void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t direction)
  478. {
  479. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  480. DMA_WRONG_HANDLE
  481. }
  482. if(DMA_PERIPHERAL_TO_MEMORY == direction){
  483. DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR;
  484. } else {
  485. DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR;
  486. }
  487. }
  488. /*!
  489. \brief check DMA flag is set or not
  490. \param[in] dma_periph: DMAx(x=0,1)
  491. \arg DMAx(x=0,1)
  492. \param[in] channelx: specify which DMA channel to get flag
  493. only one parameter can be selected which is shown as below:
  494. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  495. \param[in] flag: specify get which flag
  496. only one parameter can be selected which is shown as below:
  497. \arg DMA_FLAG_G: global interrupt flag of channel
  498. \arg DMA_FLAG_FTF: full transfer finish flag of channel
  499. \arg DMA_FLAG_HTF: half transfer finish flag of channel
  500. \arg DMA_FLAG_ERR: error flag of channel
  501. \param[out] none
  502. \retval FlagStatus: SET or RESET
  503. */
  504. FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
  505. {
  506. FlagStatus reval;
  507. /* check whether the flag is set or not */
  508. if(RESET != (DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx))){
  509. reval = SET;
  510. }else{
  511. reval = RESET;
  512. }
  513. return reval;
  514. }
  515. /*!
  516. \brief clear the flag of a DMA channel
  517. \param[in] dma_periph: DMAx(x=0,1)
  518. \arg DMAx(x=0,1)
  519. \param[in] channelx: specify which DMA channel to clear flag
  520. only one parameter can be selected which is shown as below:
  521. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  522. \param[in] flag: specify get which flag
  523. only one parameter can be selected which is shown as below:
  524. \arg DMA_FLAG_G: global interrupt flag of channel
  525. \arg DMA_FLAG_FTF: full transfer finish flag of channel
  526. \arg DMA_FLAG_HTF: half transfer finish flag of channel
  527. \arg DMA_FLAG_ERR: error flag of channel
  528. \param[out] none
  529. \retval none
  530. */
  531. void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
  532. {
  533. DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx);
  534. }
  535. /*!
  536. \brief check DMA flag and interrupt enable bit is set or not
  537. \param[in] dma_periph: DMAx(x=0,1)
  538. \arg DMAx(x=0,1)
  539. \param[in] channelx: specify which DMA channel to get flag
  540. only one parameter can be selected which is shown as below:
  541. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  542. \param[in] flag: specify get which flag
  543. only one parameter can be selected which is shown as below:
  544. \arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel
  545. \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel
  546. \arg DMA_INT_FLAG_ERR: error interrupt flag of channel
  547. \param[out] none
  548. \retval FlagStatus: SET or RESET
  549. */
  550. FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
  551. {
  552. uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
  553. switch(flag){
  554. case DMA_INT_FLAG_FTF:
  555. /* check whether the full transfer finish interrupt flag is set and enabled */
  556. interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
  557. interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE;
  558. break;
  559. case DMA_INT_FLAG_HTF:
  560. /* check whether the half transfer finish interrupt flag is set and enabled */
  561. interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
  562. interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE;
  563. break;
  564. case DMA_INT_FLAG_ERR:
  565. /* check whether the error interrupt flag is set and enabled */
  566. interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
  567. interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE;
  568. break;
  569. default:
  570. DMA_WRONG_HANDLE
  571. }
  572. /* when the interrupt flag is set and enabled, return SET */
  573. if(interrupt_flag && interrupt_enable){
  574. return SET;
  575. }else{
  576. return RESET;
  577. }
  578. }
  579. /*!
  580. \brief clear DMA a channel flag
  581. \param[in] dma_periph: DMAx(x=0,1)
  582. \arg DMAx(x=0,1)
  583. \param[in] channelx: specify which DMA channel to clear flag
  584. only one parameter can be selected which is shown as below:
  585. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  586. \param[in] flag: specify get which flag
  587. only one parameter can be selected which is shown as below:
  588. \arg DMA_INT_FLAG_G: global interrupt flag of channel
  589. \arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel
  590. \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel
  591. \arg DMA_INT_FLAG_ERR: error interrupt flag of channel
  592. \param[out] none
  593. \retval none
  594. */
  595. void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
  596. {
  597. DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx);
  598. }
  599. /*!
  600. \brief enable DMA interrupt
  601. \param[in] dma_periph: DMAx(x=0,1)
  602. \arg DMAx(x=0,1)
  603. \param[in] channelx: specify which DMA channel
  604. only one parameter can be selected which is shown as below:
  605. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  606. \param[in] source: specify which interrupt to enbale
  607. one or more parameters can be selected which are shown as below
  608. \arg DMA_INT_FTF: channel full transfer finish interrupt
  609. \arg DMA_INT_HTF: channel half transfer finish interrupt
  610. \arg DMA_INT_ERR: channel error interrupt
  611. \param[out] none
  612. \retval none
  613. */
  614. void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source)
  615. {
  616. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  617. DMA_WRONG_HANDLE
  618. }
  619. DMA_CHCTL(dma_periph, channelx) |= source;
  620. }
  621. /*!
  622. \brief disable DMA interrupt
  623. \param[in] dma_periph: DMAx(x=0,1)
  624. \arg DMAx(x=0,1)
  625. \param[in] channelx: specify which DMA channel
  626. only one parameter can be selected which is shown as below:
  627. \arg DMA0: DMA_CHx(x=0..6), DMA1: DMA_CHx(x=0..4)
  628. \param[in] source: specify which interrupt to disbale
  629. one or more parameters can be selected which are shown as below
  630. \arg DMA_INT_FTF: channel full transfer finish interrupt
  631. \arg DMA_INT_HTF: channel half transfer finish interrupt
  632. \arg DMA_INT_ERR: channel error interrupt
  633. \param[out] none
  634. \retval none
  635. */
  636. void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source)
  637. {
  638. if(ERROR == dma_periph_and_channel_check(dma_periph, channelx)){
  639. DMA_WRONG_HANDLE
  640. }
  641. DMA_CHCTL(dma_periph, channelx) &= ~source;
  642. }
  643. /*!
  644. \brief check whether peripheral and channels match
  645. \param[in] dma_periph: DMAx(x=0,1)
  646. \arg DMAx(x=0,1)
  647. \param[in] channelx: specify which DMA channel
  648. only one parameter can be selected which is shown as below:
  649. \arg DMA_CHx(x=0..6)
  650. \param[out] none
  651. \retval ErrStatus: SUCCESS or ERROR
  652. */
  653. static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx)
  654. {
  655. ErrStatus val = SUCCESS;
  656. if(DMA1 == dma_periph){
  657. /* for DMA1, the channel is from DMA_CH0 to DMA_CH4 */
  658. if(channelx > DMA_CH4){
  659. val = ERROR;
  660. }
  661. }
  662. return val;
  663. }