1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_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
13   * in 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 "stm32h7xx_ll_dma.h"
22 #include "stm32h7xx_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 STM32H7xx_LL_Driver
30   * @{
31   */
32 
33 #if defined (DMA1) || defined (DMA2)
34 
35 /** @addtogroup DMA_LL
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 #if defined(TIM24)
71 #define IS_LL_DMA_REQUEST(REQUEST)                         (((REQUEST)   <= LL_DMAMUX1_REQ_TIM24_TRIG))
72 #elif defined(ADC3)
73 #define IS_LL_DMA_REQUEST(REQUEST)                         (((REQUEST)   <= LL_DMAMUX1_REQ_ADC3))
74 #else
75 #define IS_LL_DMA_REQUEST(REQUEST)                         (((REQUEST)   <= LL_DMAMUX1_REQ_USART10_TX))
76 #endif /* TIM24 */
77 
78 #define IS_LL_DMA_PRIORITY(__VALUE__)                      (((__VALUE__) == LL_DMA_PRIORITY_LOW)    || \
79                                                             ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
80                                                             ((__VALUE__) == LL_DMA_PRIORITY_HIGH)   || \
81                                                             ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
82 
83 #define IS_LL_DMA_DOUBLEBUFFER_MODE(__VALUE__)             (((__VALUE__) == LL_DMA_DOUBLEBUFFER_MODE_DISABLE) || \
84                                                             ((__VALUE__) == LL_DMA_DOUBLEBUFFER_MODE_ENABLE))
85 
86 #define IS_LL_DMA_DOUBLEBUFFER_TARGETMEM(__VALUE__)        (((__VALUE__) == LL_DMA_CURRENTTARGETMEM0)    || \
87                                                             ((__VALUE__) == LL_DMA_CURRENTTARGETMEM1))
88 
89 #define IS_LL_DMA_ALL_STREAM_INSTANCE(INSTANCE, STREAM)   ((((INSTANCE) == DMA1) && \
90                                                            (((STREAM) == LL_DMA_STREAM_0)     || \
91                                                             ((STREAM) == LL_DMA_STREAM_1)     || \
92                                                             ((STREAM) == LL_DMA_STREAM_2)     || \
93                                                             ((STREAM) == LL_DMA_STREAM_3)     || \
94                                                             ((STREAM) == LL_DMA_STREAM_4)     || \
95                                                             ((STREAM) == LL_DMA_STREAM_5)     || \
96                                                             ((STREAM) == LL_DMA_STREAM_6)     || \
97                                                             ((STREAM) == LL_DMA_STREAM_7)     || \
98                                                             ((STREAM) == LL_DMA_STREAM_ALL))) || \
99                                                            (((INSTANCE) == DMA2) && \
100                                                            (((STREAM) == LL_DMA_STREAM_0)     || \
101                                                             ((STREAM) == LL_DMA_STREAM_1)     || \
102                                                             ((STREAM) == LL_DMA_STREAM_2)     || \
103                                                             ((STREAM) == LL_DMA_STREAM_3)     || \
104                                                             ((STREAM) == LL_DMA_STREAM_4)     || \
105                                                             ((STREAM) == LL_DMA_STREAM_5)     || \
106                                                             ((STREAM) == LL_DMA_STREAM_6)     || \
107                                                             ((STREAM) == LL_DMA_STREAM_7)     || \
108                                                             ((STREAM) == LL_DMA_STREAM_ALL))))
109 
110 #define IS_LL_DMA_FIFO_MODE_STATE(STATE)                   (((STATE) == LL_DMA_FIFOMODE_DISABLE ) || \
111                                                             ((STATE) == LL_DMA_FIFOMODE_ENABLE))
112 
113 #define IS_LL_DMA_FIFO_THRESHOLD(THRESHOLD)                (((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_1_4)  || \
114                                                             ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_1_2)  || \
115                                                             ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_3_4)  || \
116                                                             ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_FULL))
117 
118 #define IS_LL_DMA_MEMORY_BURST(BURST)                      (((BURST) == LL_DMA_MBURST_SINGLE) || \
119                                                             ((BURST) == LL_DMA_MBURST_INC4)   || \
120                                                             ((BURST) == LL_DMA_MBURST_INC8)   || \
121                                                             ((BURST) == LL_DMA_MBURST_INC16))
122 
123 #define IS_LL_DMA_PERIPHERAL_BURST(BURST)                  (((BURST) == LL_DMA_PBURST_SINGLE) || \
124                                                             ((BURST) == LL_DMA_PBURST_INC4)   || \
125                                                             ((BURST) == LL_DMA_PBURST_INC8)   || \
126                                                             ((BURST) == LL_DMA_PBURST_INC16))
127 
128 /**
129   * @}
130   */
131 
132 /* Private function prototypes -----------------------------------------------*/
133 
134 /* Exported functions --------------------------------------------------------*/
135 /** @addtogroup DMA_LL_Exported_Functions
136   * @{
137   */
138 
139 /** @addtogroup DMA_LL_EF_Init
140   * @{
141   */
142 
143 /**
144   * @brief  De-initialize the DMA registers to their default reset values.
145   * @param  DMAx DMAx Instance
146   * @param  Stream This parameter can be one of the following values:
147   *         @arg @ref LL_DMA_STREAM_0
148   *         @arg @ref LL_DMA_STREAM_1
149   *         @arg @ref LL_DMA_STREAM_2
150   *         @arg @ref LL_DMA_STREAM_3
151   *         @arg @ref LL_DMA_STREAM_4
152   *         @arg @ref LL_DMA_STREAM_5
153   *         @arg @ref LL_DMA_STREAM_6
154   *         @arg @ref LL_DMA_STREAM_7
155   *         @arg @ref LL_DMA_STREAM_ALL
156   * @retval An ErrorStatus enumeration value:
157   *          - SUCCESS: DMA registers are de-initialized
158   *          - ERROR: DMA registers are not de-initialized
159   */
LL_DMA_DeInit(DMA_TypeDef * DMAx,uint32_t Stream)160 uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Stream)
161 {
162   DMA_Stream_TypeDef *tmp;
163   ErrorStatus status = SUCCESS;
164 
165   /* Check the DMA Instance DMAx and Stream parameters */
166   assert_param(IS_LL_DMA_ALL_STREAM_INSTANCE(DMAx, Stream));
167 
168   if (Stream == LL_DMA_STREAM_ALL)
169   {
170     if (DMAx == DMA1)
171     {
172       /* Force reset of DMA clock */
173       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
174 
175       /* Release reset of DMA clock */
176       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
177     }
178     else if (DMAx == DMA2)
179     {
180       /* Force reset of DMA clock */
181        LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2);
182 
183       /* Release reset of DMA clock */
184       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2);
185     }
186     else
187     {
188       status = ERROR;
189     }
190   }
191   else
192   {
193     /* Disable the selected Stream */
194     LL_DMA_DisableStream(DMAx, Stream);
195 
196     /* Get the DMA Stream Instance */
197     tmp = (DMA_Stream_TypeDef *)(__LL_DMA_GET_STREAM_INSTANCE(DMAx, Stream));
198 
199     /* Reset DMAx_Streamy configuration register */
200     LL_DMA_WriteReg(tmp, CR, 0U);
201 
202     /* Reset DMAx_Streamy remaining bytes register */
203     LL_DMA_WriteReg(tmp, NDTR, 0U);
204 
205     /* Reset DMAx_Streamy peripheral address register */
206     LL_DMA_WriteReg(tmp, PAR, 0U);
207 
208     /* Reset DMAx_Streamy memory address register */
209     LL_DMA_WriteReg(tmp, M0AR, 0U);
210 
211     /* Reset DMAx_Streamy memory address register */
212     LL_DMA_WriteReg(tmp, M1AR, 0U);
213 
214     /* Reset DMAx_Streamy FIFO control register */
215     LL_DMA_WriteReg(tmp, FCR, 0x00000021U);
216 
217     /* Reset Channel register field for DMAx Stream */
218     LL_DMA_SetPeriphRequest(DMAx, Stream, LL_DMAMUX1_REQ_MEM2MEM);
219 
220     if (Stream == LL_DMA_STREAM_0)
221     {
222       /* Reset the Stream0 pending flags */
223       DMAx->LIFCR = 0x0000003FU;
224     }
225     else if (Stream == LL_DMA_STREAM_1)
226     {
227       /* Reset the Stream1 pending flags */
228       DMAx->LIFCR = 0x00000F40U;
229     }
230     else if (Stream == LL_DMA_STREAM_2)
231     {
232       /* Reset the Stream2 pending flags */
233       DMAx->LIFCR = 0x003F0000U;
234     }
235     else if (Stream == LL_DMA_STREAM_3)
236     {
237       /* Reset the Stream3 pending flags */
238       DMAx->LIFCR = 0x0F400000U;
239     }
240     else if (Stream == LL_DMA_STREAM_4)
241     {
242       /* Reset the Stream4 pending flags */
243       DMAx->HIFCR = 0x0000003FU;
244     }
245     else if (Stream == LL_DMA_STREAM_5)
246     {
247       /* Reset the Stream5 pending flags */
248       DMAx->HIFCR = 0x00000F40U;
249     }
250     else if (Stream == LL_DMA_STREAM_6)
251     {
252       /* Reset the Stream6 pending flags */
253       DMAx->HIFCR = 0x003F0000U;
254     }
255     else if (Stream == LL_DMA_STREAM_7)
256     {
257       /* Reset the Stream7 pending flags */
258       DMAx->HIFCR = 0x0F400000U;
259     }
260     else
261     {
262       status = ERROR;
263     }
264   }
265 
266   return (uint32_t)status;
267 }
268 
269 /**
270   * @brief  Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
271   * @note   To convert DMAx_Streamy Instance to DMAx Instance and Streamy, use helper macros :
272   *         @arg @ref __LL_DMA_GET_INSTANCE
273   *         @arg @ref __LL_DMA_GET_STREAM
274   * @param  DMAx DMAx Instance
275   * @param  Stream This parameter can be one of the following values:
276   *         @arg @ref LL_DMA_STREAM_0
277   *         @arg @ref LL_DMA_STREAM_1
278   *         @arg @ref LL_DMA_STREAM_2
279   *         @arg @ref LL_DMA_STREAM_3
280   *         @arg @ref LL_DMA_STREAM_4
281   *         @arg @ref LL_DMA_STREAM_5
282   *         @arg @ref LL_DMA_STREAM_6
283   *         @arg @ref LL_DMA_STREAM_7
284   * @param  DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
285   * @retval An ErrorStatus enumeration value:
286   *          - SUCCESS: DMA registers are initialized
287   *          - ERROR: Not applicable
288   */
LL_DMA_Init(DMA_TypeDef * DMAx,uint32_t Stream,LL_DMA_InitTypeDef * DMA_InitStruct)289 uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Stream, LL_DMA_InitTypeDef *DMA_InitStruct)
290 {
291   /* Check the DMA Instance DMAx and Stream parameters */
292   assert_param(IS_LL_DMA_ALL_STREAM_INSTANCE(DMAx, Stream));
293 
294   /* Check the DMA parameters from DMA_InitStruct */
295   assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
296   assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
297   assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
298   assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
299   assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
300   assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
301   assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
302   assert_param(IS_LL_DMA_REQUEST(DMA_InitStruct->PeriphRequest));
303   assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
304   assert_param(IS_LL_DMA_FIFO_MODE_STATE(DMA_InitStruct->FIFOMode));
305   assert_param(IS_LL_DMA_DOUBLEBUFFER_MODE(DMA_InitStruct->DoubleBufferMode));
306   assert_param(IS_LL_DMA_DOUBLEBUFFER_TARGETMEM(DMA_InitStruct->TargetMemInDoubleBufferMode));
307 
308   /* Check the memory burst, peripheral burst and FIFO threshold parameters only
309      when FIFO mode is enabled */
310   if (DMA_InitStruct->FIFOMode != LL_DMA_FIFOMODE_DISABLE)
311   {
312     assert_param(IS_LL_DMA_FIFO_THRESHOLD(DMA_InitStruct->FIFOThreshold));
313     assert_param(IS_LL_DMA_MEMORY_BURST(DMA_InitStruct->MemBurst));
314     assert_param(IS_LL_DMA_PERIPHERAL_BURST(DMA_InitStruct->PeriphBurst));
315   }
316 
317   /*---------------------------- DMAx SxCR Configuration ------------------------
318    * Configure DMAx_Streamy: data transfer direction, data transfer mode,
319    *                          peripheral and memory increment mode,
320    *                          data size alignment and  priority level with parameters :
321    * - Direction:                   DMA_SxCR_DIR[1:0] bits
322    * - Mode:                        DMA_SxCR_CIRC bit
323    * - PeriphOrM2MSrcIncMode:       DMA_SxCR_PINC bit
324    * - MemoryOrM2MDstIncMode:       DMA_SxCR_MINC bit
325    * - PeriphOrM2MSrcDataSize:      DMA_SxCR_PSIZE[1:0] bits
326    * - MemoryOrM2MDstDataSize:      DMA_SxCR_MSIZE[1:0] bits
327    * - Priority:                    DMA_SxCR_PL[1:0] bits
328    * - DoubleBufferMode:            DMA_SxCR_DBM bit
329    * - TargetMemInDoubleBufferMode: DMA_SxCR_CT bit
330    */
331   LL_DMA_ConfigTransfer(DMAx, Stream,
332                         DMA_InitStruct->Direction               | \
333                         DMA_InitStruct->Mode                    | \
334                         DMA_InitStruct->PeriphOrM2MSrcIncMode   | \
335                         DMA_InitStruct->MemoryOrM2MDstIncMode   | \
336                         DMA_InitStruct->PeriphOrM2MSrcDataSize  | \
337                         DMA_InitStruct->MemoryOrM2MDstDataSize  | \
338                         DMA_InitStruct->Priority                | \
339                         DMA_InitStruct->DoubleBufferMode        | \
340                         DMA_InitStruct->TargetMemInDoubleBufferMode);
341 
342   if (DMA_InitStruct->FIFOMode != LL_DMA_FIFOMODE_DISABLE)
343   {
344     /*---------------------------- DMAx SxFCR Configuration ------------------------
345      * Configure DMAx_Streamy:  fifo mode and fifo threshold with parameters :
346      * - FIFOMode:                DMA_SxFCR_DMDIS bit
347      * - FIFOThreshold:           DMA_SxFCR_FTH[1:0] bits
348      */
349     LL_DMA_ConfigFifo(DMAx, Stream, DMA_InitStruct->FIFOMode, DMA_InitStruct->FIFOThreshold);
350 
351     /*---------------------------- DMAx SxCR Configuration --------------------------
352      * Configure DMAx_Streamy:  memory burst transfer with parameters :
353      * - MemBurst:                DMA_SxCR_MBURST[1:0] bits
354      */
355     LL_DMA_SetMemoryBurstxfer(DMAx, Stream, DMA_InitStruct->MemBurst);
356 
357     /*---------------------------- DMAx SxCR Configuration --------------------------
358      * Configure DMAx_Streamy:  peripheral burst transfer with parameters :
359      * - PeriphBurst:             DMA_SxCR_PBURST[1:0] bits
360      */
361     LL_DMA_SetPeriphBurstxfer(DMAx, Stream, DMA_InitStruct->PeriphBurst);
362   }
363 
364   /*-------------------------- DMAx SxM0AR Configuration --------------------------
365    * Configure the memory or destination base address with parameter :
366    * - MemoryOrM2MDstAddress:     DMA_SxM0AR_M0A[31:0] bits
367    */
368   LL_DMA_SetMemoryAddress(DMAx, Stream, DMA_InitStruct->MemoryOrM2MDstAddress);
369 
370   /*-------------------------- DMAx SxPAR Configuration ---------------------------
371    * Configure the peripheral or source base address with parameter :
372    * - PeriphOrM2MSrcAddress:     DMA_SxPAR_PA[31:0] bits
373    */
374   LL_DMA_SetPeriphAddress(DMAx, Stream, DMA_InitStruct->PeriphOrM2MSrcAddress);
375 
376   /*--------------------------- DMAx SxNDTR Configuration -------------------------
377    * Configure the peripheral base address with parameter :
378    * - NbData:                    DMA_SxNDT[15:0] bits
379    */
380   LL_DMA_SetDataLength(DMAx, Stream, DMA_InitStruct->NbData);
381 
382   /*--------------------------- DMA SxCR_CHSEL Configuration ----------------------
383    * Configure the peripheral base address with parameter :
384    * - PeriphRequest:             DMA_SxCR_CHSEL[3:0] bits
385    */
386   LL_DMA_SetPeriphRequest(DMAx, Stream, DMA_InitStruct->PeriphRequest);
387 
388   return (uint32_t)SUCCESS;
389 }
390 
391 /**
392   * @brief  Set each @ref LL_DMA_InitTypeDef field to default value.
393   * @param  DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
394   * @retval None
395   */
LL_DMA_StructInit(LL_DMA_InitTypeDef * DMA_InitStruct)396 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
397 {
398   /* Set DMA_InitStruct fields to default values */
399   DMA_InitStruct->PeriphOrM2MSrcAddress       = 0x00000000U;
400   DMA_InitStruct->MemoryOrM2MDstAddress       = 0x00000000U;
401   DMA_InitStruct->Direction                   = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
402   DMA_InitStruct->Mode                        = LL_DMA_MODE_NORMAL;
403   DMA_InitStruct->PeriphOrM2MSrcIncMode       = LL_DMA_PERIPH_NOINCREMENT;
404   DMA_InitStruct->MemoryOrM2MDstIncMode       = LL_DMA_MEMORY_NOINCREMENT;
405   DMA_InitStruct->PeriphOrM2MSrcDataSize      = LL_DMA_PDATAALIGN_BYTE;
406   DMA_InitStruct->MemoryOrM2MDstDataSize      = LL_DMA_MDATAALIGN_BYTE;
407   DMA_InitStruct->NbData                      = 0x00000000U;
408   DMA_InitStruct->PeriphRequest               = LL_DMAMUX1_REQ_MEM2MEM;
409   DMA_InitStruct->Priority                    = LL_DMA_PRIORITY_LOW;
410   DMA_InitStruct->FIFOMode                    = LL_DMA_FIFOMODE_DISABLE;
411   DMA_InitStruct->FIFOThreshold               = LL_DMA_FIFOTHRESHOLD_1_4;
412   DMA_InitStruct->MemBurst                    = LL_DMA_MBURST_SINGLE;
413   DMA_InitStruct->PeriphBurst                 = LL_DMA_PBURST_SINGLE;
414   DMA_InitStruct->DoubleBufferMode            = LL_DMA_DOUBLEBUFFER_MODE_DISABLE;
415   DMA_InitStruct->TargetMemInDoubleBufferMode = LL_DMA_CURRENTTARGETMEM0;
416 }
417 
418 /**
419   * @}
420   */
421 
422 /**
423   * @}
424   */
425 
426 /**
427   * @}
428   */
429 
430 #endif /* DMA1 || DMA2 */
431 
432 /**
433   * @}
434   */
435 
436 #endif /* USE_FULL_LL_DRIVER */
437 
438