gd32vf103_dma.c 27 KB

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