gd32f30x_dma.c 27 KB

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