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