1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_ll_dma.c
4   * @author  MCD Application Team
5   * @brief   DMA LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2017 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file in
13   * the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   */
18 #if defined(USE_FULL_LL_DRIVER)
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32f4xx_ll_dma.h"
22 #include "stm32f4xx_ll_bus.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif
28 
29 /** @addtogroup STM32F4xx_LL_Driver
30   * @{
31   */
32 
33 #if defined (DMA1) || defined (DMA2)
34 
35 /** @defgroup DMA_LL DMA
36   * @{
37   */
38 
39 /* Private types -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private constants ---------------------------------------------------------*/
42 /* Private macros ------------------------------------------------------------*/
43 /** @addtogroup DMA_LL_Private_Macros
44   * @{
45   */
46 #define IS_LL_DMA_DIRECTION(__VALUE__)          (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
47                                                  ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \
48                                                  ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY))
49 
50 #define IS_LL_DMA_MODE(__VALUE__)               (((__VALUE__) == LL_DMA_MODE_NORMAL)    || \
51                                                  ((__VALUE__) == LL_DMA_MODE_CIRCULAR)  || \
52                                                  ((__VALUE__) == LL_DMA_MODE_PFCTRL))
53 
54 #define IS_LL_DMA_PERIPHINCMODE(__VALUE__)      (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
55                                                  ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
56 
57 #define IS_LL_DMA_MEMORYINCMODE(__VALUE__)      (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
58                                                  ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
59 
60 #define IS_LL_DMA_PERIPHDATASIZE(__VALUE__)     (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE)      || \
61                                                  ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD)  || \
62                                                  ((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
63 
64 #define IS_LL_DMA_MEMORYDATASIZE(__VALUE__)     (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE)      || \
65                                                  ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD)  || \
66                                                  ((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
67 
68 #define IS_LL_DMA_NBDATA(__VALUE__)             ((__VALUE__)  <= 0x0000FFFFU)
69 
70 #define IS_LL_DMA_CHANNEL(__VALUE__)            (((__VALUE__) == LL_DMA_CHANNEL_0)  || \
71                                                  ((__VALUE__) == LL_DMA_CHANNEL_1)  || \
72                                                  ((__VALUE__) == LL_DMA_CHANNEL_2)  || \
73                                                  ((__VALUE__) == LL_DMA_CHANNEL_3)  || \
74                                                  ((__VALUE__) == LL_DMA_CHANNEL_4)  || \
75                                                  ((__VALUE__) == LL_DMA_CHANNEL_5)  || \
76                                                  ((__VALUE__) == LL_DMA_CHANNEL_6)  || \
77                                                  ((__VALUE__) == LL_DMA_CHANNEL_7))
78 
79 #define IS_LL_DMA_PRIORITY(__VALUE__)           (((__VALUE__) == LL_DMA_PRIORITY_LOW)    || \
80                                                  ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
81                                                  ((__VALUE__) == LL_DMA_PRIORITY_HIGH)   || \
82                                                  ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
83 
84 #define IS_LL_DMA_ALL_STREAM_INSTANCE(INSTANCE, STREAM)   ((((INSTANCE) == DMA1) && \
85                                                            (((STREAM) == LL_DMA_STREAM_0) || \
86                                                             ((STREAM) == LL_DMA_STREAM_1) || \
87                                                             ((STREAM) == LL_DMA_STREAM_2) || \
88                                                             ((STREAM) == LL_DMA_STREAM_3) || \
89                                                             ((STREAM) == LL_DMA_STREAM_4) || \
90                                                             ((STREAM) == LL_DMA_STREAM_5) || \
91                                                             ((STREAM) == LL_DMA_STREAM_6) || \
92                                                             ((STREAM) == LL_DMA_STREAM_7) || \
93                                                             ((STREAM) == LL_DMA_STREAM_ALL))) ||\
94                                                             (((INSTANCE) == DMA2) && \
95                                                           (((STREAM) == LL_DMA_STREAM_0) || \
96                                                            ((STREAM) == LL_DMA_STREAM_1) || \
97                                                            ((STREAM) == LL_DMA_STREAM_2) || \
98                                                            ((STREAM) == LL_DMA_STREAM_3) || \
99                                                            ((STREAM) == LL_DMA_STREAM_4) || \
100                                                            ((STREAM) == LL_DMA_STREAM_5) || \
101                                                            ((STREAM) == LL_DMA_STREAM_6) || \
102                                                            ((STREAM) == LL_DMA_STREAM_7) || \
103                                                            ((STREAM) == LL_DMA_STREAM_ALL))))
104 
105 #define IS_LL_DMA_FIFO_MODE_STATE(STATE) (((STATE) == LL_DMA_FIFOMODE_DISABLE ) || \
106                                           ((STATE) == LL_DMA_FIFOMODE_ENABLE))
107 
108 #define IS_LL_DMA_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_1_4) || \
109                                              ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_1_2)  || \
110                                              ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_3_4)  || \
111                                              ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_FULL))
112 
113 #define IS_LL_DMA_MEMORY_BURST(BURST) (((BURST) == LL_DMA_MBURST_SINGLE) || \
114                                        ((BURST) == LL_DMA_MBURST_INC4)   || \
115                                        ((BURST) == LL_DMA_MBURST_INC8)   || \
116                                        ((BURST) == LL_DMA_MBURST_INC16))
117 
118 #define IS_LL_DMA_PERIPHERAL_BURST(BURST) (((BURST) == LL_DMA_PBURST_SINGLE) || \
119                                            ((BURST) == LL_DMA_PBURST_INC4)   || \
120                                            ((BURST) == LL_DMA_PBURST_INC8)   || \
121                                            ((BURST) == LL_DMA_PBURST_INC16))
122 
123 /**
124   * @}
125   */
126 
127 /* Private function prototypes -----------------------------------------------*/
128 
129 /* Exported functions --------------------------------------------------------*/
130 /** @addtogroup DMA_LL_Exported_Functions
131   * @{
132   */
133 
134 /** @addtogroup DMA_LL_EF_Init
135   * @{
136   */
137 
138 /**
139   * @brief  De-initialize the DMA registers to their default reset values.
140   * @param  DMAx DMAx Instance
141   * @param  Stream This parameter can be one of the following values:
142   *         @arg @ref LL_DMA_STREAM_0
143   *         @arg @ref LL_DMA_STREAM_1
144   *         @arg @ref LL_DMA_STREAM_2
145   *         @arg @ref LL_DMA_STREAM_3
146   *         @arg @ref LL_DMA_STREAM_4
147   *         @arg @ref LL_DMA_STREAM_5
148   *         @arg @ref LL_DMA_STREAM_6
149   *         @arg @ref LL_DMA_STREAM_7
150   *         @arg @ref LL_DMA_STREAM_ALL
151   * @retval An ErrorStatus enumeration value:
152   *          - SUCCESS: DMA registers are de-initialized
153   *          - ERROR: DMA registers are not de-initialized
154   */
LL_DMA_DeInit(DMA_TypeDef * DMAx,uint32_t Stream)155 uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Stream)
156 {
157   DMA_Stream_TypeDef *tmp = (DMA_Stream_TypeDef *)DMA1_Stream0;
158   ErrorStatus status = SUCCESS;
159 
160   /* Check the DMA Instance DMAx and Stream parameters*/
161   assert_param(IS_LL_DMA_ALL_STREAM_INSTANCE(DMAx, Stream));
162 
163   if (Stream == LL_DMA_STREAM_ALL)
164   {
165     if (DMAx == DMA1)
166     {
167       /* Force reset of DMA clock */
168       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
169 
170       /* Release reset of DMA clock */
171       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
172     }
173     else if (DMAx == DMA2)
174     {
175       /* Force reset of DMA clock */
176       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2);
177 
178       /* Release reset of DMA clock */
179       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2);
180     }
181     else
182     {
183       status = ERROR;
184     }
185   }
186   else
187   {
188     /* Disable the selected Stream */
189     LL_DMA_DisableStream(DMAx,Stream);
190 
191     /* Get the DMA Stream Instance */
192     tmp = (DMA_Stream_TypeDef *)(__LL_DMA_GET_STREAM_INSTANCE(DMAx, Stream));
193 
194     /* Reset DMAx_Streamy configuration register */
195     LL_DMA_WriteReg(tmp, CR, 0U);
196 
197     /* Reset DMAx_Streamy remaining bytes register */
198     LL_DMA_WriteReg(tmp, NDTR, 0U);
199 
200     /* Reset DMAx_Streamy peripheral address register */
201     LL_DMA_WriteReg(tmp, PAR, 0U);
202 
203     /* Reset DMAx_Streamy memory address register */
204     LL_DMA_WriteReg(tmp, M0AR, 0U);
205 
206     /* Reset DMAx_Streamy memory address register */
207     LL_DMA_WriteReg(tmp, M1AR, 0U);
208 
209     /* Reset DMAx_Streamy FIFO control register */
210     LL_DMA_WriteReg(tmp, FCR, 0x00000021U);
211 
212     /* Reset Channel register field for DMAx Stream*/
213     LL_DMA_SetChannelSelection(DMAx, Stream, LL_DMA_CHANNEL_0);
214 
215     if(Stream == LL_DMA_STREAM_0)
216     {
217        /* Reset the Stream0 pending flags */
218        DMAx->LIFCR = 0x0000003FU;
219     }
220     else if(Stream == LL_DMA_STREAM_1)
221     {
222        /* Reset the Stream1 pending flags */
223        DMAx->LIFCR = 0x00000F40U;
224     }
225     else if(Stream == LL_DMA_STREAM_2)
226     {
227        /* Reset the Stream2 pending flags */
228        DMAx->LIFCR = 0x003F0000U;
229     }
230     else if(Stream == LL_DMA_STREAM_3)
231     {
232        /* Reset the Stream3 pending flags */
233        DMAx->LIFCR = 0x0F400000U;
234     }
235     else if(Stream == LL_DMA_STREAM_4)
236     {
237        /* Reset the Stream4 pending flags */
238        DMAx->HIFCR = 0x0000003FU;
239     }
240     else if(Stream == LL_DMA_STREAM_5)
241     {
242        /* Reset the Stream5 pending flags */
243        DMAx->HIFCR = 0x00000F40U;
244     }
245     else if(Stream == LL_DMA_STREAM_6)
246     {
247        /* Reset the Stream6 pending flags */
248        DMAx->HIFCR = 0x003F0000U;
249     }
250     else if(Stream == LL_DMA_STREAM_7)
251     {
252        /* Reset the Stream7 pending flags */
253        DMAx->HIFCR = 0x0F400000U;
254     }
255     else
256     {
257       status = ERROR;
258     }
259   }
260 
261   return status;
262 }
263 
264 /**
265   * @brief  Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
266   * @note   To convert DMAx_Streamy Instance to DMAx Instance and Streamy, use helper macros :
267   *         @arg @ref __LL_DMA_GET_INSTANCE
268   *         @arg @ref __LL_DMA_GET_STREAM
269   * @param  DMAx DMAx Instance
270   * @param  Stream This parameter can be one of the following values:
271   *         @arg @ref LL_DMA_STREAM_0
272   *         @arg @ref LL_DMA_STREAM_1
273   *         @arg @ref LL_DMA_STREAM_2
274   *         @arg @ref LL_DMA_STREAM_3
275   *         @arg @ref LL_DMA_STREAM_4
276   *         @arg @ref LL_DMA_STREAM_5
277   *         @arg @ref LL_DMA_STREAM_6
278   *         @arg @ref LL_DMA_STREAM_7
279   * @param  DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
280   * @retval An ErrorStatus enumeration value:
281   *          - SUCCESS: DMA registers are initialized
282   *          - ERROR: Not applicable
283   */
LL_DMA_Init(DMA_TypeDef * DMAx,uint32_t Stream,LL_DMA_InitTypeDef * DMA_InitStruct)284 uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Stream, LL_DMA_InitTypeDef *DMA_InitStruct)
285 {
286   /* Check the DMA Instance DMAx and Stream parameters*/
287   assert_param(IS_LL_DMA_ALL_STREAM_INSTANCE(DMAx, Stream));
288 
289   /* Check the DMA parameters from DMA_InitStruct */
290   assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
291   assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
292   assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
293   assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
294   assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
295   assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
296   assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
297   assert_param(IS_LL_DMA_CHANNEL(DMA_InitStruct->Channel));
298   assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
299   assert_param(IS_LL_DMA_FIFO_MODE_STATE(DMA_InitStruct->FIFOMode));
300   /* Check the memory burst, peripheral burst and FIFO threshold parameters only
301      when FIFO mode is enabled */
302   if(DMA_InitStruct->FIFOMode != LL_DMA_FIFOMODE_DISABLE)
303   {
304     assert_param(IS_LL_DMA_FIFO_THRESHOLD(DMA_InitStruct->FIFOThreshold));
305     assert_param(IS_LL_DMA_MEMORY_BURST(DMA_InitStruct->MemBurst));
306     assert_param(IS_LL_DMA_PERIPHERAL_BURST(DMA_InitStruct->PeriphBurst));
307   }
308 
309   /*---------------------------- DMAx SxCR Configuration ------------------------
310    * Configure DMAx_Streamy: data transfer direction, data transfer mode,
311    *                          peripheral and memory increment mode,
312    *                          data size alignment and  priority level with parameters :
313    * - Direction:      DMA_SxCR_DIR[1:0] bits
314    * - Mode:           DMA_SxCR_CIRC bit
315    * - PeriphOrM2MSrcIncMode:  DMA_SxCR_PINC bit
316    * - MemoryOrM2MDstIncMode:  DMA_SxCR_MINC bit
317    * - PeriphOrM2MSrcDataSize: DMA_SxCR_PSIZE[1:0] bits
318    * - MemoryOrM2MDstDataSize: DMA_SxCR_MSIZE[1:0] bits
319    * - Priority:               DMA_SxCR_PL[1:0] bits
320    */
321   LL_DMA_ConfigTransfer(DMAx, Stream, DMA_InitStruct->Direction | \
322                         DMA_InitStruct->Mode                    | \
323                         DMA_InitStruct->PeriphOrM2MSrcIncMode   | \
324                         DMA_InitStruct->MemoryOrM2MDstIncMode   | \
325                         DMA_InitStruct->PeriphOrM2MSrcDataSize  | \
326                         DMA_InitStruct->MemoryOrM2MDstDataSize  | \
327                         DMA_InitStruct->Priority
328                         );
329 
330   if(DMA_InitStruct->FIFOMode != LL_DMA_FIFOMODE_DISABLE)
331   {
332     /*---------------------------- DMAx SxFCR Configuration ------------------------
333      * Configure DMAx_Streamy:  fifo mode and fifo threshold with parameters :
334      * - FIFOMode:                DMA_SxFCR_DMDIS bit
335      * - FIFOThreshold:           DMA_SxFCR_FTH[1:0] bits
336      */
337     LL_DMA_ConfigFifo(DMAx, Stream, DMA_InitStruct->FIFOMode, DMA_InitStruct->FIFOThreshold);
338 
339     /*---------------------------- DMAx SxCR Configuration --------------------------
340      * Configure DMAx_Streamy:  memory burst transfer with parameters :
341      * - MemBurst:                DMA_SxCR_MBURST[1:0] bits
342      */
343     LL_DMA_SetMemoryBurstxfer(DMAx,Stream,DMA_InitStruct->MemBurst);
344 
345     /*---------------------------- DMAx SxCR Configuration --------------------------
346      * Configure DMAx_Streamy:  peripheral burst transfer with parameters :
347      * - PeriphBurst:             DMA_SxCR_PBURST[1:0] bits
348      */
349     LL_DMA_SetPeriphBurstxfer(DMAx,Stream,DMA_InitStruct->PeriphBurst);
350   }
351 
352   /*-------------------------- DMAx SxM0AR Configuration --------------------------
353    * Configure the memory or destination base address with parameter :
354    * - MemoryOrM2MDstAddress:     DMA_SxM0AR_M0A[31:0] bits
355    */
356   LL_DMA_SetMemoryAddress(DMAx, Stream, DMA_InitStruct->MemoryOrM2MDstAddress);
357 
358   /*-------------------------- DMAx SxPAR Configuration ---------------------------
359    * Configure the peripheral or source base address with parameter :
360    * - PeriphOrM2MSrcAddress:     DMA_SxPAR_PA[31:0] bits
361    */
362   LL_DMA_SetPeriphAddress(DMAx, Stream, DMA_InitStruct->PeriphOrM2MSrcAddress);
363 
364   /*--------------------------- DMAx SxNDTR Configuration -------------------------
365    * Configure the peripheral base address with parameter :
366    * - NbData:                    DMA_SxNDT[15:0] bits
367    */
368   LL_DMA_SetDataLength(DMAx, Stream, DMA_InitStruct->NbData);
369 
370   /*--------------------------- DMA SxCR_CHSEL Configuration ----------------------
371    * Configure the peripheral base address with parameter :
372    * - PeriphRequest:             DMA_SxCR_CHSEL[2:0] bits
373    */
374   LL_DMA_SetChannelSelection(DMAx, Stream, DMA_InitStruct->Channel);
375 
376   return SUCCESS;
377 }
378 
379 /**
380   * @brief  Set each @ref LL_DMA_InitTypeDef field to default value.
381   * @param  DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
382   * @retval None
383   */
LL_DMA_StructInit(LL_DMA_InitTypeDef * DMA_InitStruct)384 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
385 {
386   /* Set DMA_InitStruct fields to default values */
387   DMA_InitStruct->PeriphOrM2MSrcAddress  = 0x00000000U;
388   DMA_InitStruct->MemoryOrM2MDstAddress  = 0x00000000U;
389   DMA_InitStruct->Direction              = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
390   DMA_InitStruct->Mode                   = LL_DMA_MODE_NORMAL;
391   DMA_InitStruct->PeriphOrM2MSrcIncMode  = LL_DMA_PERIPH_NOINCREMENT;
392   DMA_InitStruct->MemoryOrM2MDstIncMode  = LL_DMA_MEMORY_NOINCREMENT;
393   DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
394   DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
395   DMA_InitStruct->NbData                 = 0x00000000U;
396   DMA_InitStruct->Channel                = LL_DMA_CHANNEL_0;
397   DMA_InitStruct->Priority               = LL_DMA_PRIORITY_LOW;
398   DMA_InitStruct->FIFOMode               = LL_DMA_FIFOMODE_DISABLE;
399   DMA_InitStruct->FIFOThreshold          = LL_DMA_FIFOTHRESHOLD_1_4;
400   DMA_InitStruct->MemBurst               = LL_DMA_MBURST_SINGLE;
401   DMA_InitStruct->PeriphBurst            = LL_DMA_PBURST_SINGLE;
402 }
403 
404 /**
405   * @}
406   */
407 
408 /**
409   * @}
410   */
411 
412 /**
413   * @}
414   */
415 
416 #endif /* DMA1 || DMA2 */
417 
418 /**
419   * @}
420   */
421 
422 #endif /* USE_FULL_LL_DRIVER */
423 
424