/ Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_ll_dma.c
stm32f4xx_ll_dma.c
  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    */
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    */
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    */
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