1 /*!
2  * @file        apm32f4xx_dma.c
3  *
4  * @brief       This file provides all the DMA firmware functions
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-06-23
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be usefull and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 #include "apm32f4xx_dma.h"
27 #include "apm32f4xx_rcm.h"
28 
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @defgroup DMA_Driver
34   * @brief DMA driver modules
35   @{
36 */
37 
38 /** @defgroup DMA_Functions
39   @{
40 */
41 
42 /*!
43  * @brief     Reset specified DMA Stream registers to their default reset
44  *
45  * @param     stream :DMAy_streamx(y can be 1 or 2 and x can be from 0 to 7)
46  *
47  * @retval    None
48  *
49  * @note      DMA2 channel only for APM32 High density devices.
50  */
DMA_Reset(DMA_Stream_T * stream)51 void DMA_Reset(DMA_Stream_T *stream)
52 {
53     stream->SCFG_B.EN  =  BIT_RESET;
54     stream->SCFG       =  0;
55     stream->NDATA      =  0;
56     stream->PADDR      =  0;
57     stream->M0ADDR     =  0;
58     stream->M1ADDR     =  0;
59     stream->FCTRL      = (uint32_t)0x00000021;
60 
61     if (stream == DMA1_Stream0)
62     {
63         DMA1->LIFCLR |=  0x0000003D;
64     }
65     else if (stream == DMA1_Stream1)
66     {
67         DMA1->LIFCLR |=  0X00000F40;
68     }
69     else if (stream == DMA1_Stream2)
70     {
71         DMA1->LIFCLR |=  0x003D0000;
72     }
73     else if (stream == DMA1_Stream3)
74     {
75         DMA1->LIFCLR |=  0X0F400000;
76     }
77     else if (stream == DMA1_Stream4)
78     {
79         DMA1->HIFCLR |=  0x0000003D;
80     }
81     else if (stream == DMA1_Stream5)
82     {
83         DMA1->HIFCLR |=  0X00000F40;
84     }
85     else if (stream == DMA1_Stream6)
86     {
87         DMA1->HIFCLR |=  0x003D0000;
88     }
89     else if (stream == DMA1_Stream7)
90     {
91         DMA1->HIFCLR |=  0X0F400000;
92     }
93     else if (stream == DMA2_Stream0)
94     {
95         DMA2->LIFCLR |=  0x0000003D;
96     }
97     else if (stream == DMA2_Stream1)
98     {
99         DMA2->LIFCLR |=  0X00000F40;
100     }
101     else if (stream == DMA2_Stream2)
102     {
103         DMA2->LIFCLR |=  0x003D0000;
104     }
105     else if (stream == DMA2_Stream3)
106     {
107         DMA2->LIFCLR |=  0X0F400000;
108     }
109     else if (stream == DMA2_Stream4)
110     {
111         DMA2->HIFCLR |=  0x0000003D;
112     }
113     else if (stream == DMA2_Stream5)
114     {
115         DMA2->HIFCLR |=  0X00000F40;
116     }
117     else if (stream == DMA2_Stream6)
118     {
119         DMA2->HIFCLR |=  0x003D0000;
120     }
121     else if (stream == DMA2_Stream7)
122     {
123         DMA2->HIFCLR |=  0X0F400000;
124     }
125 }
126 
127 /*!
128  * @brief     Configs specified DMA channel through a structure.
129  *
130  * @param     stream:DMA1_channelx(y can be 1 or 2 and x can be from 0 to 7).
131  *
132  * @param     dmaConfig: Point to a DMA_Config_T structure
133  *
134  * @retval    None
135  *
136  * @note      DMA2 channel only for APM32 High density devices.
137  */
DMA_Config(DMA_Stream_T * stream,DMA_Config_T * dmaConfig)138 void DMA_Config(DMA_Stream_T *stream, DMA_Config_T *dmaConfig)
139 {
140     stream->SCFG_B.DIRCFG = dmaConfig->dir;
141     stream->SCFG_B.CIRCMEN = dmaConfig->loopMode;
142     stream->SCFG_B.PERIM = dmaConfig->peripheralInc;
143     stream->SCFG_B.MEMIM = dmaConfig->memoryInc;
144     stream->SCFG_B.PERSIZECFG = dmaConfig->peripheralDataSize;
145     stream->SCFG_B.MEMSIZECFG = dmaConfig->memoryDataSize;
146     stream->SCFG_B.PRILCFG = dmaConfig->priority;
147     stream->SCFG_B.PBCFG = dmaConfig->peripheralBurst;
148     stream->SCFG_B.MBCFG = dmaConfig->memoryBurst;
149     stream->SCFG_B.CHSEL = dmaConfig->channel;
150 
151     stream->NDATA  = dmaConfig->bufferSize;
152     stream->PADDR  = dmaConfig->peripheralBaseAddr;
153     stream->M0ADDR = dmaConfig->memoryBaseAddr;
154 
155     stream->FCTRL_B.DMDEN  = dmaConfig->fifoMode;
156     stream->FCTRL_B.FTHSEL = dmaConfig->fifoThreshold;
157 }
158 
159 /*!
160  * @brief     Populate the structure with default values.
161  *
162  * @param     dmaConfig: Point to a DMA_Config_T structure.
163  *
164  * @retval    None
165  */
DMA_ConfigStructInit(DMA_Config_T * dmaConfig)166 void DMA_ConfigStructInit(DMA_Config_T *dmaConfig)
167 {
168     dmaConfig->channel = DMA_CHANNEL_0;
169     dmaConfig->peripheralBaseAddr = 0;
170     dmaConfig->memoryBaseAddr = 0;
171     dmaConfig->dir = DMA_DIR_PERIPHERALTOMEMORY;
172     dmaConfig->bufferSize = 0;
173     dmaConfig->peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
174     dmaConfig->memoryInc = DMA_MEMORY_INC_DISABLE;
175     dmaConfig->peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_BYTE;
176     dmaConfig->memoryDataSize = DMA_MEMORY_DATA_SIZE_BYTE;
177     dmaConfig->loopMode = DMA_MODE_NORMAL;
178     dmaConfig->priority = DMA_PRIORITY_LOW;
179     dmaConfig->fifoMode = DMA_FIFOMODE_DISABLE;
180     dmaConfig->fifoThreshold = DMA_FIFOTHRESHOLD_QUARTER;
181     dmaConfig->peripheralBurst = DMA_PERIPHERALBURST_SINGLE;
182     dmaConfig->memoryBurst = DMA_MEMORYBURST_SINGLE;
183 }
184 
185 /*!
186  * @brief     Enable the specified DMA channel
187  *
188  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
189  *
190  * @retval    None
191  *
192  * @note      DMA2 channel only for APM32 High density devices.
193  */
DMA_Enable(DMA_Stream_T * stream)194 void DMA_Enable(DMA_Stream_T *stream)
195 {
196     stream->SCFG_B.EN = ENABLE;
197 }
198 
199 /*!
200  * @brief     Disable the specified DMA channel
201  *
202  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
203  *
204  * @retval    None
205  *
206  * @note      DMA2 channel only for APM32 High density devices.
207  */
DMA_Disable(DMA_Stream_T * stream)208 void DMA_Disable(DMA_Stream_T *stream)
209 {
210     stream->SCFG_B.EN = DISABLE;
211 }
212 
213 /*!
214  * @brief     Configures the specified DMA Peripheral increment offset size.
215  *
216  * @param     perioSize: specifies the Peripheral increment offset size.
217  *                       This parameter can be one of the following values:
218  *                        @arg DMA_PERIOSIZE_PSIZE: Peripheral address increment is done
219  *                                                  accordingly to PSIZE parameter.
220  *                        @arg DMA_PERIOSIZE_WORDALIGNED: Peripheral address increment offset is
221  *                                                  fixed to 4 (32-bit aligned addresses).
222  *
223  * @retval    None
224  *
225  * @note      DMA2 Stream only for APM32 High density devices.
226  */
DMA_ConfigPeriphIncOffsetSize(DMA_Stream_T * stream,DMA_PERIOSIZE_T perioSize)227 void DMA_ConfigPeriphIncOffsetSize(DMA_Stream_T *stream, DMA_PERIOSIZE_T perioSize)
228 {
229     stream->SCFG_B.PERIOSIZE = perioSize;
230 }
231 
232 /*!
233  * @brief     Configures the specified DMA flow controller.
234  *
235  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
236  *
237  * @param     flowController: specifies the DMA flow controller.
238  *                             This parameter can be one of the following values:
239  *                             @arg DMA_FLOWCTRL_MEMORY: DMAy_Channelx transactions flow controller is
240  *                                                       the DMA controller.
241  *                             @arg DMA_FLOWCTRL_PERIPHERAL: DMAy_Channelx transactions flow controller
242  *                                                       is the peripheral.
243  *
244  * @retval    None
245  *
246  * @note      DMA2 Stream only for APM32 High density devices.
247  */
DMA_ConfigFlowController(DMA_Stream_T * stream,DMA_FLOWCTRL_T flowController)248 void DMA_ConfigFlowController(DMA_Stream_T *stream, DMA_FLOWCTRL_T flowController)
249 {
250     stream->SCFG_B.PERFC = flowController;
251 }
252 
253 /*!
254  * @brief     Configs the number of data units in the channel.
255  *
256  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
257  *
258  * @param     dataNumber:The number of data units in the current DMA Stream transfer.
259  *
260  * @retval    The number of NDATA value
261  *
262  * @note      DMA2 Stream only for APM32 High density devices.
263  */
DMA_ConfigDataNumber(DMA_Stream_T * stream,uint16_t dataNumber)264 void DMA_ConfigDataNumber(DMA_Stream_T *stream, uint16_t dataNumber)
265 {
266     stream->NDATA = dataNumber;
267 }
268 
269 /*!
270  * @brief     Read the number of data units in the channel
271  *
272  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
273  *
274  * @retval    The number of NDATA value
275  *
276  * @note      DMA2 Stream only for APM32 High density devices.
277  */
DMA_ReadDataNumber(DMA_Stream_T * stream)278 uint16_t DMA_ReadDataNumber(DMA_Stream_T *stream)
279 {
280     return (uint16_t)(stream->NDATA);
281 }
282 
283 /*!
284  * @brief     Configures the double buffer mode and the current memory target.
285  *
286  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
287  *
288  * @param     memory1BaseAddr: the base address of the second buffer (Memory 1)
289  *
290  * @param     currentMemory: specifies which memory will be first buffer for
291  *               the transactions when the Stream will be enabled.
292  *                  This parameter can be one of the following values:
293  *                    @arg DMA_MEMORY_0: Memory 0 is the current buffer.
294  *                    @arg DMA_MEMORY_1: Memory 1 is the current buffer.
295  *
296  * @retval    None
297  */
DMA_ConfigBufferMode(DMA_Stream_T * stream,uint32_t memory1BaseAddr,DMA_MEMORY_T currentMemory)298 void DMA_ConfigBufferMode(DMA_Stream_T *stream, uint32_t memory1BaseAddr, DMA_MEMORY_T currentMemory)
299 {
300     stream->SCFG_B.CTARG = currentMemory;
301     stream->M1ADDR = memory1BaseAddr;
302 }
303 
304 /*!
305  * @brief     Enable the double buffer mode for the selected DMA channel.
306  *
307  * @param     stream: DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
308  *
309  * @retval    None
310  */
DMA_EnableDoubleBufferMode(DMA_Stream_T * stream)311 void DMA_EnableDoubleBufferMode(DMA_Stream_T *stream)
312 {
313     stream->SCFG_B.DBM = BIT_SET;
314 }
315 
316 /*!
317  * @brief     Disable the double buffer mode for the selected DMA channel.
318  *
319  * @param     stream: DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
320  *
321  * @retval    None
322  */
DMA_DisableDoubleBufferMode(DMA_Stream_T * stream)323 void DMA_DisableDoubleBufferMode(DMA_Stream_T *stream)
324 {
325     stream->SCFG_B.DBM = BIT_RESET;
326 }
327 
328 /*!
329  * @brief     Configures the Memory address for the next buffer transfer in double
330  *               buffer mode (for dynamic use).
331  *
332  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
333  *
334  * @param     memoryBaseAddr: The base address of the target memory buffer
335  *
336  * @param     memoryTarget: Next memory target to be used.
337  *               This parameter can be one of the following values:
338  *                  @arg DMA_MEMORY_0: To use the memory address 0
339  *                  @arg DMA_MEMORY_1: To use the memory address 1
340  *
341  * @retval       None
342  */
DMA_ConfigMemoryTarget(DMA_Stream_T * stream,uint32_t memoryBaseAddr,DMA_MEMORY_T memoryTarget)343 void DMA_ConfigMemoryTarget(DMA_Stream_T *stream, uint32_t memoryBaseAddr, DMA_MEMORY_T memoryTarget)
344 {
345     if (memoryTarget != DMA_MEMORY_0)
346     {
347         stream->M1ADDR = memoryBaseAddr;
348     }
349     else
350     {
351         stream->M0ADDR = memoryBaseAddr;
352     }
353 }
354 
355 /*!
356  * @brief     Returns the current memory target used by double buffer transfer.
357  *
358  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
359  *
360  * @retval    The memory target number: 0 for Memory0 or 1 for Memory1.
361  */
DMA_ReadCurrentMemoryTarget(DMA_Stream_T * stream)362 uint32_t DMA_ReadCurrentMemoryTarget(DMA_Stream_T *stream)
363 {
364     return (uint32_t)(stream->SCFG_B.CTARG);
365 }
366 
367 /*!
368  * @brief      Returns the status of EN bit for the specified DMAy channelx.
369  *
370  * @param      stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
371  *
372  * @retval     Return state of the DMAy channelx (ENABLE or DISABLE).
373  */
DMA_ReadCmdStatus(DMA_Stream_T * stream)374 uint8_t DMA_ReadCmdStatus(DMA_Stream_T *stream)
375 {
376     return (uint8_t)(stream->SCFG_B.EN);
377 }
378 
379 /*!
380  * @brief      Returns the current DMAy channelx FIFO filled level.
381  *
382  * @param      stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
383  *
384  * @retval     The FIFO filling state.
385  *                  - DMA_FIFOSTATUS_LESS1QUARTER: when FIFO is less than 1 quarter-full and not empty.
386  *                  - DMA_FIFOSTATUS_1QUARTER: if more than 1 quarter-full.
387  *                  - DMA_FIFOSTATUS_HalfFull: if more than 1 half-full.
388  *                  - DMA_FIFOSTATUS_3QUARTERS: if more than 3 quarters-full.
389  *                  - DMA_FIFOSTATUS_EMPTY: when FIFO is empty
390  *                  - DMA_FIFOSTATUS_FULL: when FIFO is full
391  */
DMA_ReadFIFOFlag(DMA_Stream_T * stream)392 uint32_t DMA_ReadFIFOFlag(DMA_Stream_T *stream)
393 {
394     return (uint32_t)(stream->FCTRL_B.FSTS);
395 }
396 
397 /*!
398  * @brief     Read the specified DMAy channelx flag.
399  *
400  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
401  *
402  * @param     flag: specifies the flag to check.
403  *                This parameter can be one of the following values:
404  *                  @arg DMA_FLAG_TCIFLGx:  channelx transfer complete flag
405  *                  @arg DMA_FLAG_HTIFLGx:  channelx half transfer complete flag
406  *                  @arg DMA_FLAG_TEIFLGx:  channelx transfer error flag
407  *                  @arg DMA_FLAG_DMEIFLGx: channelx direct mode error flag
408  *                  @arg DMA_FLAG_FEIFLGx:  channelx FIFO error flag
409  *               Where x can be 0 to 7 to select the DMA channel.
410  *
411  * @retval    None
412  */
DMA_ReadStatusFlag(DMA_Stream_T * stream,DMA_FLAG_T flag)413 uint8_t DMA_ReadStatusFlag(DMA_Stream_T *stream, DMA_FLAG_T flag)
414 {
415     DMA_T *dma;
416 
417     if (stream < DMA2_Stream0)
418     {
419         dma = DMA1;
420     }
421     else
422     {
423         dma = DMA2;
424     }
425 
426     if ((flag & 0x10000000) != RESET)
427     {
428         if ((dma->LINTSTS & flag) != RESET)
429         {
430             return  SET;
431         }
432         else
433         {
434             return RESET;
435         }
436     }
437     else
438     {
439         if ((dma->HINTSTS & flag) != RESET)
440         {
441             return  SET;
442         }
443         else
444         {
445             return RESET;
446         }
447     }
448 }
449 
450 /*!
451  * @brief     Clears the DMAy channelx's pending flags.
452  *
453  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
454  *
455  * @param     flag: specifies the flag to clear.
456  *                This parameter can be any combination of the following values:
457  *                  @arg DMA_FLAG_TCIFLGx:  channelx transfer complete flag
458  *                  @arg DMA_FLAG_HTIFLGx:  channelx half transfer complete flag
459  *                  @arg DMA_FLAG_TEIFLGx:  channelx transfer error flag
460  *                  @arg DMA_FLAG_DMEIFLGx: channelx direct mode error flag
461  *                  @arg DMA_FLAG_FEIFLGx:  channelx FIFO error flag
462  *               Where x can be 0 to 7 to select the DMA channel.
463  *
464  * @retval    None
465  */
DMA_ClearStatusFlag(DMA_Stream_T * stream,uint32_t flag)466 void DMA_ClearStatusFlag(DMA_Stream_T *stream, uint32_t flag)
467 {
468     DMA_T *dma;
469 
470     if (stream < DMA2_Stream0)
471     {
472         dma = DMA1;
473     }
474     else
475     {
476         dma = DMA2;
477     }
478 
479     if ((flag & 0x10000000) == RESET)
480     {
481         dma->LIFCLR = (flag & 0x0F7D0F7D);
482     }
483     else
484     {
485         dma->HIFCLR = (flag & 0x0F7D0F7D);
486     }
487 }
488 
489 /*!
490  * @brief     Enable the specified DMAy channelx interrupts.
491  *
492  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
493  *
494  * @param     flag: specifies the DMA interrupt sources to be enabled or disabled.
495  *                This parameter can be any combination of the following values:
496  *                  @arg DMA_INT_TCIFLG:  Transfer complete interrupt mask
497  *                  @arg DMA_INT_HTIFLG:  Half transfer complete interrupt mask
498  *                  @arg DMA_INT_TEIFLG:  Transfer error interrupt mask
499  *                  @arg DMA_INT_FEIFLG:  FIFO error interrupt mask
500  *
501  * @retval    None
502  */
DMA_EnableInterrupt(DMA_Stream_T * stream,uint32_t interrupt)503 void DMA_EnableInterrupt(DMA_Stream_T *stream, uint32_t interrupt)
504 {
505     if ((interrupt & DMA_INT_FEIFLG) == DMA_INT_FEIFLG)
506     {
507         stream->FCTRL_B.FEIEN = BIT_SET;;
508     }
509 
510     if (interrupt != DMA_INT_FEIFLG)
511     {
512         stream->SCFG |= (uint32_t)(interrupt & 0x0000001E);
513     }
514 }
515 
516 /*!
517  * @brief     Disable the specified DMAy channelx interrupts.
518  *
519  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
520  *
521  * @param     flag: specifies the DMA interrupt sources to be enabled or disabled.
522  *                This parameter can be any combination of the following values:
523  *                  @arg DMA_INT_TCIFLG:  Transfer complete interrupt mask
524  *                  @arg DMA_INT_DMEIFLG:  Direct mode error interrupt mask
525  *                  @arg DMA_INT_HTIFLG:  Half transfer complete interrupt mask
526  *                  @arg DMA_INT_TEIFLG:  Transfer error interrupt mask
527  *                  @arg DMA_INT_FEIFLG:  FIFO error interrupt mask
528  *
529  * @retval    None
530  */
DMA_DisableInterrupt(DMA_Stream_T * stream,uint32_t interrupt)531 void DMA_DisableInterrupt(DMA_Stream_T *stream, uint32_t interrupt)
532 {
533     if ((interrupt & DMA_INT_FEIFLG) == DMA_INT_FEIFLG)
534     {
535         stream->FCTRL_B.FEIEN = BIT_RESET;;
536     }
537 
538     if (interrupt != DMA_INT_FEIFLG)
539     {
540         stream->SCFG &= ~(uint32_t)(interrupt & 0x0000001E);
541     }
542 }
543 
544 /*!
545  * @brief     Read the specified DMAy channelx interrupt.
546  *
547  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
548  *
549  * @param     flag: specifies the DMA interrupt source to check.
550  *                This parameter can be one of the following values:
551  *                  @arg DMA_INT_TCIFLGx:  streamx transfer complete flag
552  *                  @arg DMA_INT_HTIFLGx:  streamx half transfer complete flag
553  *                  @arg DMA_INT_TEIFLGx:  streamx transfer error flag
554  *                  @arg DMA_INT_DMEIFLGx: streamx direct mode error flag
555  *                  @arg DMA_INT_FEIFLGx:  streamx FIFO error flag
556  *                 Where x can be 0 to 7 to select the DMA channel.
557  *
558  * @retval    None.
559  */
DMA_ReadIntFlag(DMA_Stream_T * stream,DMA_INT_FLAG_T flag)560 uint8_t DMA_ReadIntFlag(DMA_Stream_T *stream, DMA_INT_FLAG_T flag)
561 {
562     uint32_t tmpreg = 0, enablestatus = 0;
563     DMA_T *dma;
564 
565     if (stream < DMA2_Stream0)
566     {
567         dma = DMA1;
568     }
569     else
570     {
571         dma = DMA2;
572     }
573 
574     /** Check if the interrupt enable bit is in the FCTRL or SCFG register */
575     if ((flag & 0x60000000) != RESET)
576     {
577         /** Check the enable bit in FEIEN register */
578         enablestatus = stream->FCTRL_B.FEIEN;
579     }
580     else
581     {
582         /** Get the interrupt enable position mask in SCFG register */
583         tmpreg = ((flag & 0xE000) >> 11) ;
584 
585         /** Check the enable bit in SCFG register */
586         enablestatus = (stream->SCFG & tmpreg);
587     }
588 
589     /* Check if the interrupt pending flag is in LINTSTS or HINTSTS */
590     if ((flag & 0x10000000) == RESET)
591     {
592         tmpreg = dma->LINTSTS;
593     }
594     else
595     {
596         tmpreg = dma->HINTSTS;
597     }
598 
599     tmpreg &= 0x0F7D0F7D;
600 
601     if (((tmpreg & flag) != RESET) && (enablestatus != RESET))
602     {
603         return SET ;
604     }
605     else
606     {
607         return RESET ;
608     }
609 }
610 
611 /*!
612  * @brief     Read the DMAy channelx's interrupt pending bits.
613  *
614  * @param     stream:DMAy_streamx(y can be 1 or 2 and x can be from 1 to 7)
615  *
616  * @param     flag: specifies the DMA interrupt pending bit to clear.
617  *                This parameter can be any combination of the following values:
618  *                  @arg DMA_INT_TCIFLGx:  streamx transfer complete flag
619  *                  @arg DMA_INT_HTIFLGx:  streamx half transfer complete flag
620  *                  @arg DMA_INT_TEIFLGx:  streamx transfer error flag
621  *                  @arg DMA_INT_DMEIFLGx: streamx direct mode error flag
622  *                  @arg DMA_INT_FEIFLGx:  streamx FIFO error flag
623  *               Where x can be 0 to 7 to select the DMA channel.
624  *
625  * @retval    None
626  */
DMA_ClearIntFlag(DMA_Stream_T * stream,uint32_t flag)627 void DMA_ClearIntFlag(DMA_Stream_T *stream, uint32_t flag)
628 {
629     DMA_T *dma;
630 
631     if (stream < DMA2_Stream0)
632     {
633         dma = DMA1;
634     }
635     else
636     {
637         dma = DMA2;
638     }
639 
640     if ((flag & 0x10000000) == RESET)
641     {
642         dma->LIFCLR = (flag & 0x0F7D0F7D);
643     }
644     else
645     {
646         dma->HIFCLR = (flag & 0x0F7D0F7D);
647     }
648 }
649 
650 /**@} end of group DMA_Functions */
651 /**@} end of group DMA_Driver */
652 /**@} end of group APM32F4xx_StdPeriphDriver */
653