1 /*!
2  * @file        apm32s10x_dma.c
3  *
4  * @brief       This file provides all the DMA firmware functions
5  *
6  * @version     V1.0.1
7  *
8  * @date        2022-12-31
9  *
10  * @attention
11  *
12  *  Copyright (C) 2022-2023 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 /* Includes */
27 #include "apm32s10x_dma.h"
28 
29 /** @addtogroup APM32S10x_StdPeriphDriver
30   @{
31 */
32 
33 /** @addtogroup DMA_Driver DMA Driver
34   @{
35 */
36 
37 /** @defgroup DMA_Functions Functions
38   @{
39 */
40 
41 /*!
42  * @brief     Reset specified DMA Channel registers to their default reset
43  *
44  * @param     channel:DMA1_channelx(x can be from 1 to 7).
45  *
46  * @retval    None
47  */
DMA_Reset(DMA_Channel_T * channel)48 void DMA_Reset(DMA_Channel_T* channel)
49 {
50     channel->CHCFG_B.CHEN = BIT_RESET;
51     channel->CHCFG = 0;
52     channel->CHNDATA = 0;
53     channel->CHMADDR = 0;
54     channel->CHPADDR = 0;
55 
56     if (channel == DMA1_Channel1)
57     {
58         DMA1->INTFCLR |= 0xFFFFFFF0;
59     }
60     else if (channel == DMA1_Channel2)
61     {
62         DMA1->INTFCLR |= 0xFFFFFF0F;
63     }
64     else if (channel == DMA1_Channel3)
65     {
66         DMA1->INTFCLR |= 0xFFFFF0FF;
67     }
68     else if (channel == DMA1_Channel4)
69     {
70         DMA1->INTFCLR |= 0xFFFF0FFF;
71     }
72     else if (channel == DMA1_Channel5)
73     {
74         DMA1->INTFCLR |= 0xFFF0FFFF;
75     }
76     else if (channel == DMA1_Channel6)
77     {
78         DMA1->INTFCLR |= 0xFF0FFFFF;
79     }
80     else if (channel == DMA1_Channel7)
81     {
82         DMA1->INTFCLR |= 0xF0FFFFFF;
83     }
84 }
85 
86 /*!
87  * @brief     Configs specified DMA Channel through a structure.
88  *
89  * @param     channel:DMA1_channelx(x can be from 1 to 7)
90  *
91  * @param     dmaConfig: Point to a DMA_Config_T structure
92  *
93  * @retval    None
94  */
DMA_Config(DMA_Channel_T * channel,DMA_Config_T * dmaConfig)95 void DMA_Config(DMA_Channel_T* channel, DMA_Config_T* dmaConfig)
96 {
97     channel->CHCFG_B.DIRCFG = dmaConfig->dir;
98     channel->CHCFG_B.CIRMODE = dmaConfig->loopMode;
99     channel->CHCFG_B.PERIMODE = dmaConfig->peripheralInc;
100     channel->CHCFG_B.MIMODE = dmaConfig->memoryInc;
101     channel->CHCFG_B.PERSIZE = dmaConfig->peripheralDataSize;
102     channel->CHCFG_B.MEMSIZE = dmaConfig->memoryDataSize;
103     channel->CHCFG_B.CHPL = dmaConfig->priority;
104     channel->CHCFG_B.M2MMODE = dmaConfig->M2M;
105 
106     channel->CHNDATA = dmaConfig->bufferSize;
107     channel->CHPADDR = dmaConfig->peripheralBaseAddr;
108     channel->CHMADDR = dmaConfig->memoryBaseAddr;
109 }
110 
111 /*!
112  * @brief     Populate the structure with default values.
113  *
114  * @param     dmaConfig: Point to a DMA_Config_T structure.
115  *
116  * @retval    None
117  */
DMA_ConfigStructInit(DMA_Config_T * dmaConfig)118 void DMA_ConfigStructInit(DMA_Config_T* dmaConfig)
119 {
120     dmaConfig->peripheralBaseAddr = 0;
121     dmaConfig->memoryBaseAddr = 0;
122     dmaConfig->dir = DMA_DIR_PERIPHERAL_SRC;
123     dmaConfig->bufferSize = 0;
124     dmaConfig->peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
125     dmaConfig->memoryInc = DMA_MEMORY_INC_DISABLE;
126     dmaConfig->peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_BYTE;
127     dmaConfig->memoryDataSize = DMA_MEMORY_DATA_SIZE_BYTE;
128     dmaConfig->loopMode = DMA_MODE_NORMAL;
129     dmaConfig->priority = DMA_PRIORITY_LOW;
130     dmaConfig->M2M = DMA_M2MEN_DISABLE;
131 }
132 
133 /*!
134  * @brief     Enable the specified DMA Channel
135  *
136  * @param     channel:DMA1_channelx(x can be from 1 to 7)
137  *
138  * @retval    None
139  */
DMA_Enable(DMA_Channel_T * channel)140 void DMA_Enable(DMA_Channel_T* channel)
141 {
142     channel->CHCFG_B.CHEN = ENABLE;
143 }
144 
145 /*!
146  * @brief     Disable the specified DMA Channel
147  *
148  * @param     channel:DMA1_channelx(x can be from 1 to 7)
149  *
150  * @retval    None
151  */
DMA_Disable(DMA_Channel_T * channel)152 void DMA_Disable(DMA_Channel_T* channel)
153 {
154     channel->CHCFG_B.CHEN = DISABLE;
155 }
156 
157 /*!
158  * @brief     Configs the number of data units in the channel.
159  *
160  * @param     channel:DMA1_channelx(x can be from 1 to 7)
161  *
162  * @param     dataNumber:The number of data units in the current DMA Channel transfer.
163  *
164  * @retval    None
165  */
DMA_ConfigDataNumber(DMA_Channel_T * channel,uint16_t dataNumber)166 void DMA_ConfigDataNumber(DMA_Channel_T* channel, uint16_t dataNumber)
167 {
168     channel->CHNDATA = dataNumber;
169 }
170 
171 /*!
172  * @brief     Read the number of data units in the channel
173  *
174  * @param     channel:DMA1_channelx(x can be from 1 to 7)
175  *
176  * @retval    The number of CHNDATA value
177  */
DMA_ReadDataNumber(DMA_Channel_T * channel)178 uint16_t DMA_ReadDataNumber(DMA_Channel_T* channel)
179 {
180     return channel->CHNDATA;
181 }
182 
183 /*!
184  * @brief     Enables the specified DMA Channel interrupts.
185  *
186  * @param     channel:DMA1_channelx(x can be from 1 to 7)
187  *
188  * @param     interrupt: DMA interrupts sources to selsct
189  *                       This parameter can be any combination of the following values:
190  *                       @arg DMA_INT_TC   : All Transfer Complete Interrupt
191  *                       @arg DMA_INT_HT   : Half Transfer Complete Interrupt
192  *                       @arg DMA_INT_TERR : Transfer Error Occur Interrupt
193  *
194  * @retval    None
195  */
DMA_EnableInterrupt(DMA_Channel_T * channel,uint32_t interrupt)196 void DMA_EnableInterrupt(DMA_Channel_T* channel, uint32_t interrupt)
197 {
198     channel->CHCFG |= interrupt;
199 }
200 
201 /*!
202  * @brief     Disable the specified DMA Channel interrupts.
203  *
204  * @param     channel:DMA1_channelx(x can be from 1 to 7)
205  *
206  * @param     interrupt: DMA interrupts sources to selsct
207  *                       This parameter can be any combination of the following values:
208  *                       @arg DMA_INT_TC   : All Transfer Complete Interrupt
209  *                       @arg DMA_INT_HT   : Half Transfer Complete Interrupt
210  *                       @arg DMA_INT_TERR : Transfer Error Occur Interrupt
211  *
212  * @retval    None
213  */
DMA_DisableInterrupt(DMA_Channel_T * channel,uint32_t interrupt)214 void DMA_DisableInterrupt(DMA_Channel_T* channel, uint32_t interrupt)
215 {
216     channel->CHCFG &= ~interrupt;
217 }
218 
219 /*!
220  * @brief     Read whether the specifie DMA Channel flag is set or not.
221  *
222  * @param     flag: the flag to check.
223  *                  This parameter can be one of the following values:
224  *                    @arg DMA1_FLAG_GINT1: DMA1 Channel 1 global flag.
225  *                    @arg DMA1_FLAG_TC1:   DMA1 Channel 1 transfer complete flag.
226  *                    @arg DMA1_FLAG_HT1:   DMA1 Channel 1 half transfer flag.
227  *                    @arg DMA1_FLAG_TERR1: DMA1 Channel 1 transfer error flag.
228  *                    @arg DMA1_FLAG_GINT2: DMA1 Channel 2 global flag.
229  *                    @arg DMA1_FLAG_TC2:   DMA1 Channel 2 transfer complete flag.
230  *                    @arg DMA1_FLAG_HT2:   DMA1 Channel 2 half transfer flag.
231  *                    @arg DMA1_FLAG_TERR2: DMA1 Channel 2 transfer error flag.
232  *                    @arg DMA1_FLAG_GINT3: DMA1 Channel 3 global flag.
233  *                    @arg DMA1_FLAG_TC3:   DMA1 Channel 3 transfer complete flag.
234  *                    @arg DMA1_FLAG_HT3:   DMA1 Channel 3 half transfer flag.
235  *                    @arg DMA1_FLAG_TERR3: DMA1 Channel 3 transfer error flag.
236  *                    @arg DMA1_FLAG_GINT4: DMA1 Channel 4 global flag.
237  *                    @arg DMA1_FLAG_TC4:   DMA1 Channel 4 transfer complete flag.
238  *                    @arg DMA1_FLAG_HT4:   DMA1 Channel 4 half transfer flag.
239  *                    @arg DMA1_FLAG_TERR4: DMA1 Channel 4 transfer error flag.
240  *                    @arg DMA1_FLAG_GINT5: DMA1 Channel 5 global flag.
241  *                    @arg DMA1_FLAG_TC5:   DMA1 Channel 5 transfer complete flag.
242  *                    @arg DMA1_FLAG_HT5:   DMA1 Channel 5 half transfer flag.
243  *                    @arg DMA1_FLAG_TERR5: DMA1 Channel 5 transfer error flag.
244  *                    @arg DMA1_FLAG_GINT6: DMA1 Channel 6 global flag.
245  *                    @arg DMA1_FLAG_TC6:   DMA1 Channel 6 transfer complete flag.
246  *                    @arg DMA1_FLAG_HT6:   DMA1 Channel 6 half transfer flag.
247  *                    @arg DMA1_FLAG_TERR6: DMA1 Channel 6 transfer error flag.
248  *                    @arg DMA1_FLAG_GINT7: DMA1 Channel 7 global flag.
249  *                    @arg DMA1_FLAG_TC7:   DMA1 Channel 7 transfer complete flag.
250  *                    @arg DMA1_FLAG_HT7:   DMA1 Channel 7 half transfer flag.
251  *                    @arg DMA1_FLAG_TERR7: DMA1 Channel 7 transfer error flag.
252  *
253  * @retval    Flag State
254  */
DMA_ReadStatusFlag(DMA_FLAG_T flag)255 uint8_t DMA_ReadStatusFlag(DMA_FLAG_T flag)
256 {
257     if ((DMA1->INTSTS & flag) != RESET)
258     {
259         return SET ;
260     }
261     else
262     {
263         return RESET ;
264     }
265 }
266 
267 /*!
268  * @brief     Clears the specifie DMA Channel's flags.
269  *
270  * @param     flag:the flag to Clear.
271  *                  This parameter can be any combination of the following values:
272  *                    @arg DMA1_FLAG_GINT1: DMA1 Channel 1 global flag.
273  *                    @arg DMA1_FLAG_TC1:   DMA1 Channel 1 transfer complete flag.
274  *                    @arg DMA1_FLAG_HT1:   DMA1 Channel 1 half transfer flag.
275  *                    @arg DMA1_FLAG_TERR1: DMA1 Channel 1 transfer error flag.
276  *                    @arg DMA1_FLAG_GINT2: DMA1 Channel 2 global flag.
277  *                    @arg DMA1_FLAG_TC2:   DMA1 Channel 2 transfer complete flag.
278  *                    @arg DMA1_FLAG_HT2:   DMA1 Channel 2 half transfer flag.
279  *                    @arg DMA1_FLAG_TERR2: DMA1 Channel 2 transfer error flag.
280  *                    @arg DMA1_FLAG_GINT3: DMA1 Channel 3 global flag.
281  *                    @arg DMA1_FLAG_TC3:   DMA1 Channel 3 transfer complete flag.
282  *                    @arg DMA1_FLAG_HT3:   DMA1 Channel 3 half transfer flag.
283  *                    @arg DMA1_FLAG_TERR3: DMA1 Channel 3 transfer error flag.
284  *                    @arg DMA1_FLAG_GINT4: DMA1 Channel 4 global flag.
285  *                    @arg DMA1_FLAG_TC4:   DMA1 Channel 4 transfer complete flag.
286  *                    @arg DMA1_FLAG_HT4:   DMA1 Channel 4 half transfer flag.
287  *                    @arg DMA1_FLAG_TERR4: DMA1 Channel 4 transfer error flag.
288  *                    @arg DMA1_FLAG_GINT5: DMA1 Channel 5 global flag.
289  *                    @arg DMA1_FLAG_TC5:   DMA1 Channel 5 transfer complete flag.
290  *                    @arg DMA1_FLAG_HT5:   DMA1 Channel 5 half transfer flag.
291  *                    @arg DMA1_FLAG_TERR5: DMA1 Channel 5 transfer error flag.
292  *                    @arg DMA1_FLAG_GINT6: DMA1 Channel 6 global flag.
293  *                    @arg DMA1_FLAG_TC6:   DMA1 Channel 6 transfer complete flag.
294  *                    @arg DMA1_FLAG_HT6:   DMA1 Channel 6 half transfer flag.
295  *                    @arg DMA1_FLAG_TERR6: DMA1 Channel 6 transfer error flag.
296  *                    @arg DMA1_FLAG_GINT7: DMA1 Channel 7 global flag.
297  *                    @arg DMA1_FLAG_TC7:   DMA1 Channel 7 transfer complete flag.
298  *                    @arg DMA1_FLAG_HT7:   DMA1 Channel 7 half transfer flag.
299  *                    @arg DMA1_FLAG_TERR7: DMA1 Channel 7 transfer error flag.
300  *
301  * @retval    None
302  */
DMA_ClearStatusFlag(uint32_t flag)303 void DMA_ClearStatusFlag(uint32_t flag)
304 {
305     DMA1->INTFCLR = flag;
306 }
307 
308 /*!
309  * @brief     Read whether the specified DMA Channel interrupts is set or not.
310  *
311  * @param     interrupt: interrupt source to check.
312  *                  This parameter can be one of the following values:
313  *                    @arg DMA1_INT_FLAG_GINT1 : DMA1 Channel 1 global interrupt.
314  *                    @arg DMA1_INT_FLAG_TC1   : DMA1 Channel 1 transfer complete interrupt.
315  *                    @arg DMA1_INT_FLAG_HT1   : DMA1 Channel 1 half transfer interrupt.
316  *                    @arg DMA1_INT_FLAG_TERR1 : DMA1 Channel 1 transfer error interrupt.
317  *                    @arg DMA1_INT_FLAG_GINT2 : DMA1 Channel 2 global interrupt.
318  *                    @arg DMA1_INT_FLAG_TC2   : DMA1 Channel 2 transfer complete interrupt.
319  *                    @arg DMA1_INT_FLAG_HT2   : DMA1 Channel 2 half transfer interrupt.
320  *                    @arg DMA1_INT_FLAG_TERR2 : DMA1 Channel 2 transfer error interrupt.
321  *                    @arg DMA1_INT_FLAG_GINT3 : DMA1 Channel 3 global interrupt.
322  *                    @arg DMA1_INT_FLAG_TC3   : DMA1 Channel 3 transfer complete interrupt.
323  *                    @arg DMA1_INT_FLAG_HT3   : DMA1 Channel 3 half transfer interrupt.
324  *                    @arg DMA1_INT_FLAG_TERR3 : DMA1 Channel 3 transfer error interrupt.
325  *                    @arg DMA1_INT_FLAG_GINT4 : DMA1 Channel 4 global interrupt.
326  *                    @arg DMA1_INT_FLAG_TC4   : DMA1 Channel 4 transfer complete interrupt.
327  *                    @arg DMA1_INT_FLAG_HT4   : DMA1 Channel 4 half transfer interrupt.
328  *                    @arg DMA1_INT_FLAG_TERR4 : DMA1 Channel 4 transfer error interrupt.
329  *                    @arg DMA1_INT_FLAG_GINT5 : DMA1 Channel 5 global interrupt.
330  *                    @arg DMA1_INT_FLAG_TC5     DMA1 Channel 5 transfer complete interrupt.
331  *                    @arg DMA1_INT_FLAG_HT5     DMA1 Channel 5 half transfer interrupt.
332  *                    @arg DMA1_INT_FLAG_TERR5 : DMA1 Channel 5 transfer error interrupt.
333  *                    @arg DMA1_INT_FLAG_GINT6 : DMA1 Channel 6 global interrupt.
334  *                    @arg DMA1_INT_FLAG_TC6   : DMA1 Channel 6 transfer complete interrupt.
335  *                    @arg DMA1_INT_FLAG_HT6   : DMA1 Channel 6 half transfer interrupt.
336  *                    @arg DMA1_INT_FLAG_TERR6 : DMA1 Channel 6 transfer error interrupt.
337  *                    @arg DMA1_INT_FLAG_GINT7 : DMA1 Channel 7 global interrupt.
338  *                    @arg DMA1_INT_FLAG_TC7   : DMA1 Channel 7 transfer complete interrupt.
339  *                    @arg DMA1_INT_FLAG_HT7   : DMA1 Channel 7 half transfer interrupt.
340  *                    @arg DMA1_INT_FLAG_TERR7 : DMA1 Channel 7 transfer error interrupt.
341  *
342  * @retval    interrupt State
343  */
DMA_ReadIntFlag(DMA_INT_FLAG_T flag)344 uint8_t DMA_ReadIntFlag(DMA_INT_FLAG_T flag)
345 {
346     if ((DMA1->INTSTS & flag) != RESET)
347     {
348         return SET ;
349     }
350     else
351     {
352         return RESET ;
353     }
354 }
355 
356 /*!
357  * @brief     Clears the specified DMA Channel's interrupts.
358  *
359  * @param     flag: the interrupt flag to Clear.
360  *                  This parameter can be any combination of the following values:
361  *                    @arg DMA1_INT_FLAG_GINT1 : DMA1 Channel 1 global interrupt.
362  *                    @arg DMA1_INT_FLAG_TC1   : DMA1 Channel 1 transfer complete interrupt.
363  *                    @arg DMA1_INT_FLAG_HT1   : DMA1 Channel 1 half transfer interrupt.
364  *                    @arg DMA1_INT_FLAG_TERR1 : DMA1 Channel 1 transfer error interrupt.
365  *                    @arg DMA1_INT_FLAG_GINT2 : DMA1 Channel 2 global interrupt.
366  *                    @arg DMA1_INT_FLAG_TC2   : DMA1 Channel 2 transfer complete interrupt.
367  *                    @arg DMA1_INT_FLAG_HT2   : DMA1 Channel 2 half transfer interrupt.
368  *                    @arg DMA1_INT_FLAG_TERR2 : DMA1 Channel 2 transfer error interrupt.
369  *                    @arg DMA1_INT_FLAG_GINT3 : DMA1 Channel 3 global interrupt.
370  *                    @arg DMA1_INT_FLAG_TC3   : DMA1 Channel 3 transfer complete interrupt.
371  *                    @arg DMA1_INT_FLAG_HT3   : DMA1 Channel 3 half transfer interrupt.
372  *                    @arg DMA1_INT_FLAG_TERR3 : DMA1 Channel 3 transfer error interrupt.
373  *                    @arg DMA1_INT_FLAG_GINT4 : DMA1 Channel 4 global interrupt.
374  *                    @arg DMA1_INT_FLAG_TC4   : DMA1 Channel 4 transfer complete interrupt.
375  *                    @arg DMA1_INT_FLAG_HT4   : DMA1 Channel 4 half transfer interrupt.
376  *                    @arg DMA1_INT_FLAG_TERR4 : DMA1 Channel 4 transfer error interrupt.
377  *                    @arg DMA1_INT_FLAG_GINT5 : DMA1 Channel 5 global interrupt.
378  *                    @arg DMA1_INT_FLAG_TC5     DMA1 Channel 5 transfer complete interrupt.
379  *                    @arg DMA1_INT_FLAG_HT5     DMA1 Channel 5 half transfer interrupt.
380  *                    @arg DMA1_INT_FLAG_TERR5 : DMA1 Channel 5 transfer error interrupt.
381  *                    @arg DMA1_INT_FLAG_GINT6 : DMA1 Channel 6 global interrupt.
382  *                    @arg DMA1_INT_FLAG_TC6   : DMA1 Channel 6 transfer complete interrupt.
383  *                    @arg DMA1_INT_FLAG_HT6   : DMA1 Channel 6 half transfer interrupt.
384  *                    @arg DMA1_INT_FLAG_TERR6 : DMA1 Channel 6 transfer error interrupt.
385  *                    @arg DMA1_INT_FLAG_GINT7 : DMA1 Channel 7 global interrupt.
386  *                    @arg DMA1_INT_FLAG_TC7   : DMA1 Channel 7 transfer complete interrupt.
387  *                    @arg DMA1_INT_FLAG_HT7   : DMA1 Channel 7 half transfer interrupt.
388  *                    @arg DMA1_INT_FLAG_TERR7 : DMA1 Channel 7 transfer error interrupt.
389  *
390  * @retval    None
391  */
DMA_ClearIntFlag(uint32_t flag)392 void DMA_ClearIntFlag(uint32_t flag)
393 {
394     DMA1->INTFCLR = flag;
395 }
396 
397 /**@} end of group DMA_Functions */
398 /**@} end of group DMA_Driver */
399 /**@} end of group APM32S10x_StdPeriphDriver */
400