1 /*!
2  * @file        apm32f4xx_dma.h
3  *
4  * @brief       This file contains all the functions prototypes for the DMA firmware library.
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 /* Define to prevent recursive inclusion */
27 #ifndef __APM32F4XX_DMA_H
28 #define __APM32F4XX_DMA_H
29 
30 #ifdef __cplusplus
31   extern "C" {
32 #endif
33 
34 /* Includes */
35 #include "apm32f4xx.h"
36 
37 /** @addtogroup APM32F4xx_StdPeriphDriver
38   @{
39 */
40 
41 /** @addtogroup DMA_Driver
42   @{
43 */
44 
45 /** @defgroup DMA_Enumerations
46   @{
47 */
48 
49 /**
50  * @brief DMA channel
51  */
52 typedef enum
53 {
54     DMA_CHANNEL_0,  /*!< Select DMA channel 0 */
55     DMA_CHANNEL_1,  /*!< Select DMA channel 1 */
56     DMA_CHANNEL_2,  /*!< Select DMA channel 2 */
57     DMA_CHANNEL_3,  /*!< Select DMA channel 3 */
58     DMA_CHANNEL_4,  /*!< Select DMA channel 4 */
59     DMA_CHANNEL_5,  /*!< Select DMA channel 5 */
60     DMA_CHANNEL_6,  /*!< Select DMA channel 6 */
61     DMA_CHANNEL_7   /*!< Select DMA channel 7 */
62 } DMA_CHANNEL_T;
63 
64 /**
65  * @brief DMA Transmission direction
66  */
67 typedef enum
68 {
69     DMA_DIR_PERIPHERALTOMEMORY, /*!< Peripheral to memory */
70     DMA_DIR_MEMORYTOPERIPHERAL, /*!< Memory to peripheral */
71     DMA_DIR_MEMORYTOMEMORY      /*!< Memory to memory */
72 } DMA_DIR_T;
73 
74 /**
75  * @brief DMA Peripheral address increment
76  */
77 typedef enum
78 {
79     DMA_PERIPHERAL_INC_DISABLE, /*!< Disable peripheral increment mode */
80     DMA_PERIPHERAL_INC_ENABLE   /*!< Enable peripheral increment mode */
81 } DMA_PERIPHERAL_INC_T;
82 
83 /**
84  * @brief DMA Memory address increment
85  */
86 typedef enum
87 {
88     DMA_MEMORY_INC_DISABLE, /*!< Disable memory increment mode */
89     DMA_MEMORY_INC_ENABLE   /*!< Enable memory increment mode */
90 } DMA_MEMORY_INC_T;
91 
92 /**
93  * @brief DMA Peripheral Data Size
94  */
95 typedef enum
96 {
97     DMA_PERIPHERAL_DATA_SIZE_BYTE,      /*!< Set peripheral data size to byte */
98     DMA_PERIPHERAL_DATA_SIZE_HALFWORD,  /*!< Set peripheral data size to half-word */
99     DMA_PERIPHERAL_DATA_SIZE_WORD       /*!< Set peripheral data size to word */
100 } DMA_PERIPHERAL_DATA_SIZE_T;
101 
102 /**
103  * @brief DMA Memory Data Size
104  */
105 typedef enum
106 {
107     DMA_MEMORY_DATA_SIZE_BYTE,          /*!< Set memory data size to byte */
108     DMA_MEMORY_DATA_SIZE_HALFWORD,      /*!< Set memory data size to half-word */
109     DMA_MEMORY_DATA_SIZE_WORD           /*!< Set memory data size to word */
110 } DMA_MEMORY_DATA_SIZE_T;
111 
112 /**
113  * @brief DMA Mode
114  */
115 typedef enum
116 {
117     DMA_MODE_NORMAL,    /*!< Disable circular mode */
118     DMA_MODE_CIRCULAR   /*!< Enable circular mode */
119 } DMA_LOOP_MODE_T;
120 
121 /**
122  * @brief DMA priority level
123  */
124 typedef enum
125 {
126     DMA_PRIORITY_LOW,       /*!< Set priority level to low */
127     DMA_PRIORITY_MEDIUM,    /*!< Set priority level to medium */
128     DMA_PRIORITY_HIGH,      /*!< Set priority level to high */
129     DMA_PRIORITY_VERYHIGH   /*!< Set priority level to very high */
130 } DMA_PRIORITY_T;
131 
132 /**
133  * @brief DMA fifo direct mode
134  */
135 typedef enum
136 {
137     DMA_FIFOMODE_DISABLE,   /*!< Enable fifo mode */
138     DMA_FIFOMODE_ENABLE     /*!< Disable fifo mode */
139 } DMA_FIFOMODE_T;
140 
141 /**
142  * @brief DMA fifo threshold select
143  */
144 typedef enum
145 {
146     DMA_FIFOTHRESHOLD_QUARTER,      /*!< Select quarter FIFO threshold */
147     DMA_FIFOTHRESHOLD_HALFFULL,     /*!< Select half-full FIFO threshold */
148     DMA_FIFOTHRESHOLD_3QUARTERS,    /*!< Select three quarters FIFO threshold */
149     DMA_FIFOTHRESHOLD_FULL          /*!< Select full FIFO threshold */
150 } DMA_FIFOTHRESHOLD_T;
151 
152 /**
153  * @brief DMA memory burst
154  */
155 typedef enum
156 {
157     DMA_MEMORYBURST_SINGLE, /*!< Single memory burst transfer */
158     DMA_MEMORYBURST_INC4,   /*!< INC4 memory burst transfer */
159     DMA_MEMORYBURST_INC8,   /*!< INC8 memory burst transfer */
160     DMA_MEMORYBURST_INC16   /*!< INC16 memory burst transfer */
161 } DMA_MEMORYBURST_T;
162 
163 /**
164  * @brief DMA peripheral burst
165  */
166 typedef enum
167 {
168     DMA_PERIPHERALBURST_SINGLE, /*!< Single peripheral burst transfer */
169     DMA_PERIPHERALBURST_INC4,   /*!< INC4 peripheral burst transfer */
170     DMA_PERIPHERALBURST_INC8,   /*!< INC8 peripheral burst transfer */
171     DMA_PERIPHERALBURST_INC16   /*!< INC16 peripheral burst transfer */
172 } DMA_PERIPHERALBURST_T;
173 
174 /**
175  * @brief DMA fifo status level
176  */
177 typedef enum
178 {
179     DMA_FIFOSTATUS_LESS1QUARTER,    /*!< When FIFO is less than 1 quarter-full and not empty */
180     DMA_FIFOSTATUS_1QUARTER,        /*!< If more than 1 quarter-full */
181     DMA_FIFOSTATUS_HalfFull,        /*!< If more than 1 half-full */
182     DMA_FIFOSTATUS_3QUARTERS,       /*!< If more than 3 quarters-full */
183     DMA_FIFOSTATUS_EMPTY,           /*!< When FIFO is empty */
184     DMA_FIFOSTATUS_FULL             /*!< When FIFO is full */
185 } DMA_FIFOSTATUS_T;
186 
187 /**
188  * @brief DMA Flag
189  */
190 typedef enum
191 {
192     DMA_FLAG_FEIFLG0   =  0x10000001,   /*!< Channel0 FIFO error flag */
193     DMA_FLAG_DMEIFLG0  =  0x10000004,   /*!< Channel0 direct mode error flag */
194     DMA_FLAG_TEIFLG0   =  0x10000008,   /*!< Channel0 transfer error flag */
195     DMA_FLAG_HTIFLG0   =  0x10000010,   /*!< Channel0 half transfer complete flag */
196     DMA_FLAG_TCIFLG0   =  0x10000020,   /*!< Channel0 transfer complete flag */
197 
198     DMA_FLAG_FEIFLG1   =  0x10000040,   /*!< Channel1 FIFO error flag */
199     DMA_FLAG_DMEIFLG1  =  0x10000100,   /*!< Channel1 direct mode error flag */
200     DMA_FLAG_TEIFLG1   =  0x10000200,   /*!< Channel1 transfer error flag */
201     DMA_FLAG_HTIFLG1   =  0x10000400,   /*!< Channel1 half transfer complete flag */
202     DMA_FLAG_TCIFLG1   =  0x10000800,   /*!< Channel1 transfer complete flag */
203 
204     DMA_FLAG_FEIFLG2   =  0x10010000,   /*!< Channel2 FIFO error flag */
205     DMA_FLAG_DMEIFLG2  =  0x10040000,   /*!< Channel2 direct mode error flag */
206     DMA_FLAG_TEIFLG2   =  0x10080000,   /*!< Channel2 transfer error flag */
207     DMA_FLAG_HTIFLG2   =  0x10100000,   /*!< Channel2 half transfer complete flag */
208     DMA_FLAG_TCIFLG2   =  0x10200000,   /*!< Channel2 transfer complete flag */
209 
210     DMA_FLAG_FEIFLG3   =  0x10400000,   /*!< Channel3 FIFO error flag */
211     DMA_FLAG_DMEIFLG3  =  0x11000000,   /*!< Channel3 direct mode error flag */
212     DMA_FLAG_TEIFLG3   =  0x12000000,   /*!< Channel3 transfer error flag */
213     DMA_FLAG_HTIFLG3   =  0x14000000,   /*!< Channel3 half transfer complete flag */
214     DMA_FLAG_TCIFLG3   =  0x18000000,   /*!< Channel3 transfer complete flag */
215 
216     DMA_FLAG_FEIFLG4   =  0x20000001,   /*!< Channel4 FIFO error flag */
217     DMA_FLAG_DMEIFLG4  =  0x20000004,   /*!< Channel4 direct mode error flag */
218     DMA_FLAG_TEIFLG4   =  0x20000008,   /*!< Channel4 transfer error flag */
219     DMA_FLAG_HTIFLG4   =  0x20000010,   /*!< Channel4 half transfer complete flag */
220     DMA_FLAG_TCIFLG4   =  0x20000020,   /*!< Channel4 transfer complete flag */
221 
222     DMA_FLAG_FEIFLG5   =  0x20000040,   /*!< Channel5 FIFO error flag */
223     DMA_FLAG_DMEIFLG5  =  0x20000100,   /*!< Channel5 direct mode error flag */
224     DMA_FLAG_TEIFLG5   =  0x20000200,   /*!< Channel5 transfer error flag */
225     DMA_FLAG_HTIFLG5   =  0x20000400,   /*!< Channel5 half transfer complete flag */
226     DMA_FLAG_TCIFLG5   =  0x20000800,   /*!< Channel5 transfer complete flag */
227 
228     DMA_FLAG_FEIFLG6   =  0x20010000,   /*!< Channel6 FIFO error flag */
229     DMA_FLAG_DMEIFLG6  =  0x20040000,   /*!< Channel6 direct mode error flag */
230     DMA_FLAG_TEIFLG6   =  0x20080000,   /*!< Channel6 transfer error flag */
231     DMA_FLAG_HTIFLG6   =  0x20100000,   /*!< Channel6 half transfer complete flag */
232     DMA_FLAG_TCIFLG6   =  0x20200000,   /*!< Channel6 transfer complete flag */
233 
234     DMA_FLAG_FEIFLG7   =  0x20400000,   /*!< Channel7 FIFO error flag */
235     DMA_FLAG_DMEIFLG7  =  0x21000000,   /*!< Channel7 direct mode error flag */
236     DMA_FLAG_TEIFLG7   =  0x22000000,   /*!< Channel7 transfer error flag */
237     DMA_FLAG_HTIFLG7   =  0x24000000,   /*!< Channel7 half transfer complete flag */
238     DMA_FLAG_TCIFLG7   =  0x28000000    /*!< Channel7 transfer complete flag */
239 } DMA_FLAG_T;
240 
241 /**
242  * @brief DMA Interrupt Flag
243  */
244 typedef enum
245 {
246     DMA_INT_FEIFLG  = 0x01, /*!< FIFO error interrupt mask */
247     DMA_INT_DMEIFLG = 0x02, /*!< Direct mode error interrupt mask */
248     DMA_INT_TEIFLG  = 0x04, /*!< Transfer error interrupt mask */
249     DMA_INT_HTIFLG  = 0x08, /*!< Half transfer complete interrupt mask */
250     DMA_INT_TCIFLG  = 0x10  /*!< Transfer complete interrupt mask */
251 } DMA_INT_T;
252 
253 /**
254  * @brief DMA Interrupts Flag
255  */
256 typedef enum
257 {
258     DMA_INT_FEIFLG0   =  0x20000001,    /*!< Stream0 FIFO error flag */
259     DMA_INT_DMEIFLG0  =  0x00001004,    /*!< Stream0 direct mode error flag */
260     DMA_INT_TEIFLG0   =  0x00002008,    /*!< Stream0 transfer error flag */
261     DMA_INT_HTIFLG0   =  0x00004010,    /*!< Stream0 half transfer complete flag */
262     DMA_INT_TCIFLG0   =  0x00008020,    /*!< Stream0 transfer complete flag */
263 
264     DMA_INT_FEIFLG1   =  0x20000040,    /*!< Stream1 FIFO error flag */
265     DMA_INT_DMEIFLG1  =  0x00001100,    /*!< Stream1 direct mode error flag */
266     DMA_INT_TEIFLG1   =  0x00002200,    /*!< Stream1 transfer error flag */
267     DMA_INT_HTIFLG1   =  0x00004400,    /*!< Stream1 half transfer complete flag */
268     DMA_INT_TCIFLG1   =  0x00008800,    /*!< Stream1 transfer complete flag */
269 
270     DMA_INT_FEIFLG2   =  0x20010000,    /*!< Stream2 FIFO error flag */
271     DMA_INT_DMEIFLG2  =  0x00041000,    /*!< Stream2 direct mode error flag */
272     DMA_INT_TEIFLG2   =  0x00082000,    /*!< Stream2 transfer error flag */
273     DMA_INT_HTIFLG2   =  0x00104000,    /*!< Stream2 half transfer complete flag */
274     DMA_INT_TCIFLG2   =  0x00208000,    /*!< Stream2 transfer complete flag */
275 
276     DMA_INT_FEIFLG3   =  0x20400000,    /*!< Stream3 FIFO error flag */
277     DMA_INT_DMEIFLG3  =  0x01001000,    /*!< Stream3 direct mode error flag */
278     DMA_INT_TEIFLG3   =  0x02002000,    /*!< Stream3 transfer error flag */
279     DMA_INT_HTIFLG3   =  0x04004000,    /*!< Stream3 half transfer complete flag */
280     DMA_INT_TCIFLG3   =  0x08008000,    /*!< Stream3 transfer complete flag */
281 
282     DMA_INT_FEIFLG4   =  0x50000001,    /*!< Stream4 FIFO error flag */
283     DMA_INT_DMEIFLG4  =  0x10001004,    /*!< Stream4 direct mode error flag */
284     DMA_INT_TEIFLG4   =  0x10002008,    /*!< Stream4 transfer error flag */
285     DMA_INT_HTIFLG4   =  0x10004010,    /*!< Stream4 half transfer complete flag */
286     DMA_INT_TCIFLG4   =  0x10008020,    /*!< Stream4 transfer complete flag */
287 
288     DMA_INT_FEIFLG5   =  0x50000040,    /*!< Stream5 FIFO error flag */
289     DMA_INT_DMEIFLG5  =  0x10001100,    /*!< Stream5 direct mode error flag */
290     DMA_INT_TEIFLG5   =  0x10002200,    /*!< Stream5 transfer error flag */
291     DMA_INT_HTIFLG5   =  0x10004400,    /*!< Stream5 half transfer complete flag */
292     DMA_INT_TCIFLG5   =  0x10008800,    /*!< Stream5 transfer complete flag */
293 
294     DMA_INT_FEIFLG6   =  0x50010000,    /*!< Stream6 FIFO error flag */
295     DMA_INT_DMEIFLG6  =  0x10041000,    /*!< Stream6 direct mode error flag */
296     DMA_INT_TEIFLG6   =  0x10082000,    /*!< Stream6 transfer error flag */
297     DMA_INT_HTIFLG6   =  0x10104000,    /*!< Stream6 half transfer complete flag */
298     DMA_INT_TCIFLG6   =  0x10208000,    /*!< Stream6 transfer complete flag */
299 
300     DMA_INT_FEIFLG7   =  0x50400000,    /*!< Stream7 FIFO error flag */
301     DMA_INT_DMEIFLG7  =  0x11001000,    /*!< Stream7 direct mode error flag */
302     DMA_INT_TEIFLG7   =  0x12002000,    /*!< Stream7 transfer error flag */
303     DMA_INT_HTIFLG7   =  0x14004000,    /*!< Stream7 half transfer complete flag */
304     DMA_INT_TCIFLG7   =  0x18008000     /*!< Stream7 transfer complete flag */
305 } DMA_INT_FLAG_T;
306 
307 /**
308  * @brief DMA peripheral increment offset
309  */
310 typedef enum
311 {
312     DMA_PERIOSIZE_PSIZE,        /*!< Peripheral address increment is done
313                                     accordingly to PSIZE parameter */
314     DMA_PERIOSIZE_WORDALIGNED   /*!< Peripheral address increment offset is
315                                     fixed to 4 (32-bit aligned addresses). */
316 } DMA_PERIOSIZE_T;
317 
318 /**
319  * @brief DMA flow controller
320  */
321 typedef enum
322 {
323     DMA_FLOWCTRL_MEMORY,        /*!< DMAy_Channelx transactions flow controller is
324                                     the DMA controller */
325     DMA_FLOWCTRL_PERIPHERAL     /*!< DMAy_Channelx transactions flow controller
326                                     is the peripheral */
327 } DMA_FLOWCTRL_T;
328 
329 /**
330  * @brief DMA memory targets
331  */
332 typedef enum
333 {
334     DMA_MEMORY_0,   /*!< Memory 0 Address */
335     DMA_MEMORY_1    /*!< Memory 1 Address */
336 } DMA_MEMORY_T;
337 
338 /**@} end of group DMA_Enumerations*/
339 
340 /** @addtogroup DMA_Structure Data Structure
341   @{
342 */
343 
344 /**
345  * @brief DMA Config struct definition
346  */
347 typedef struct
348 {
349     DMA_CHANNEL_T              channel;             /*!< Channel selection */
350     uint32_t                   peripheralBaseAddr;  /*!< Peripheral base address */
351     uint32_t                   memoryBaseAddr;      /*!< Memory base address */
352     DMA_DIR_T                  dir;                 /*!< Direction */
353     uint32_t                   bufferSize;          /*!< Buffer size */
354     DMA_PERIPHERAL_INC_T       peripheralInc;       /*!< Peripheral increment mode selection */
355     DMA_MEMORY_INC_T           memoryInc;           /*!< Memory increment mode selection */
356     DMA_PERIPHERAL_DATA_SIZE_T peripheralDataSize;  /*!< Peripheral data size */
357     DMA_MEMORY_DATA_SIZE_T     memoryDataSize;      /*!< Memory data size */
358     DMA_LOOP_MODE_T            loopMode;            /*!< Loop mode */
359     DMA_PRIORITY_T             priority;            /*!< DMA priority level */
360     DMA_FIFOMODE_T             fifoMode;            /*!< FIFO mode selection */
361     DMA_FIFOTHRESHOLD_T        fifoThreshold;       /*!< FIFO threshold configuration */
362     DMA_MEMORYBURST_T          memoryBurst;         /*!< Memory burst configuration */
363     DMA_PERIPHERALBURST_T      peripheralBurst;     /*!< Peripheral burst configuration */
364 } DMA_Config_T;
365 
366 /**@} end of group DMA_Structure*/
367 
368 /** @defgroup DMA_Functions
369   @{
370 */
371 
372 /* DMA Reset and Configuration */
373 void DMA_Reset(DMA_Stream_T* stream);
374 void DMA_Config(DMA_Stream_T* stream, DMA_Config_T* dmaConfig);
375 void DMA_ConfigStructInit( DMA_Config_T* dmaConfig);
376 void DMA_Enable(DMA_Stream_T* stream);
377 void DMA_Disable(DMA_Stream_T* stream);
378 
379 /* Stream Configuration  */
380 void DMA_ConfigPeriphIncOffsetSize(DMA_Stream_T* stream, DMA_PERIOSIZE_T perioSize);
381 void DMA_ConfigFlowController(DMA_Stream_T* stream, DMA_FLOWCTRL_T flowController);
382 
383 /* DMA Data Number */
384 void DMA_ConfigDataNumber(DMA_Stream_T* stream, uint16_t dataNumber);
385 uint16_t DMA_ReadDataNumber(DMA_Stream_T* stream);
386 
387 /* DMA Double Buffer mode */
388 void DMA_ConfigBufferMode(DMA_Stream_T* stream, uint32_t memory1BaseAddr, DMA_MEMORY_T currentMemory);
389 void DMA_EnableDoubleBufferMode(DMA_Stream_T* stream);
390 void DMA_DisableDoubleBufferMode(DMA_Stream_T* stream);
391 void DMA_ConfigMemoryTarget(DMA_Stream_T* stream, uint32_t memoryBaseAddr, DMA_MEMORY_T memoryTarget);
392 uint32_t DMA_ReadCurrentMemoryTarget(DMA_Stream_T* stream);
393 
394 /* DMA Interrupts and flags */
395 uint8_t DMA_ReadCmdStatus(DMA_Stream_T* stream);
396 uint32_t DMA_ReadFIFOFlag(DMA_Stream_T* stream);
397 
398 uint8_t DMA_ReadStatusFlag(DMA_Stream_T* stream, DMA_FLAG_T flag);
399 void DMA_ClearStatusFlag(DMA_Stream_T* stream, uint32_t flag);
400 
401 void DMA_EnableInterrupt(DMA_Stream_T* stream, uint32_t interrupt);
402 void DMA_DisableInterrupt(DMA_Stream_T* stream, uint32_t interrupt);
403 uint8_t DMA_ReadIntFlag(DMA_Stream_T* stream, DMA_INT_FLAG_T flag);
404 void DMA_ClearIntFlag(DMA_Stream_T* stream, uint32_t flag);
405 
406 #ifdef __cplusplus
407 }
408 #endif
409 
410 #endif /*__APM32F4XX_DMA_H */
411 
412 /**@} end of group DMA_Enumerations */
413 /**@} end of group DMA_Driver */
414 /**@} end of group APM32F4xx_StdPeriphDriver */
415