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