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