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_ALL_STREAM_INSTANCE(INSTANCE, STREAM)   ((((INSTANCE) == DMA1) && \
84                                                            (((STREAM) == LL_DMA_STREAM_0)     || \
85                                                             ((STREAM) == LL_DMA_STREAM_1)     || \
86                                                             ((STREAM) == LL_DMA_STREAM_2)     || \
87                                                             ((STREAM) == LL_DMA_STREAM_3)     || \
88                                                             ((STREAM) == LL_DMA_STREAM_4)     || \
89                                                             ((STREAM) == LL_DMA_STREAM_5)     || \
90                                                             ((STREAM) == LL_DMA_STREAM_6)     || \
91                                                             ((STREAM) == LL_DMA_STREAM_7)     || \
92                                                             ((STREAM) == LL_DMA_STREAM_ALL))) || \
93                                                            (((INSTANCE) == DMA2) && \
94                                                            (((STREAM) == LL_DMA_STREAM_0)     || \
95                                                             ((STREAM) == LL_DMA_STREAM_1)     || \
96                                                             ((STREAM) == LL_DMA_STREAM_2)     || \
97                                                             ((STREAM) == LL_DMA_STREAM_3)     || \
98                                                             ((STREAM) == LL_DMA_STREAM_4)     || \
99                                                             ((STREAM) == LL_DMA_STREAM_5)     || \
100                                                             ((STREAM) == LL_DMA_STREAM_6)     || \
101                                                             ((STREAM) == LL_DMA_STREAM_7)     || \
102                                                             ((STREAM) == LL_DMA_STREAM_ALL))))
103 
104 #define IS_LL_DMA_FIFO_MODE_STATE(STATE)    (((STATE) == LL_DMA_FIFOMODE_DISABLE ) || \
105                                              ((STATE) == LL_DMA_FIFOMODE_ENABLE))
106 
107 #define IS_LL_DMA_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_1_4)  || \
108                                              ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_1_2)  || \
109                                              ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_3_4)  || \
110                                              ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_FULL))
111 
112 #define IS_LL_DMA_MEMORY_BURST(BURST)       (((BURST) == LL_DMA_MBURST_SINGLE) || \
113                                              ((BURST) == LL_DMA_MBURST_INC4)   || \
114                                              ((BURST) == LL_DMA_MBURST_INC8)   || \
115                                              ((BURST) == LL_DMA_MBURST_INC16))
116 
117 #define IS_LL_DMA_PERIPHERAL_BURST(BURST)  (((BURST) == LL_DMA_PBURST_SINGLE) || \
118                                             ((BURST) == LL_DMA_PBURST_INC4)   || \
119                                             ((BURST) == LL_DMA_PBURST_INC8)   || \
120                                             ((BURST) == LL_DMA_PBURST_INC16))
121 
122 /**
123   * @}
124   */
125 
126 /* Private function prototypes -----------------------------------------------*/
127 
128 /* Exported functions --------------------------------------------------------*/
129 /** @addtogroup DMA_LL_Exported_Functions
130   * @{
131   */
132 
133 /** @addtogroup DMA_LL_EF_Init
134   * @{
135   */
136 
137 /**
138   * @brief  De-initialize the DMA registers to their default reset values.
139   * @param  DMAx DMAx Instance
140   * @param  Stream This parameter can be one of the following values:
141   *         @arg @ref LL_DMA_STREAM_0
142   *         @arg @ref LL_DMA_STREAM_1
143   *         @arg @ref LL_DMA_STREAM_2
144   *         @arg @ref LL_DMA_STREAM_3
145   *         @arg @ref LL_DMA_STREAM_4
146   *         @arg @ref LL_DMA_STREAM_5
147   *         @arg @ref LL_DMA_STREAM_6
148   *         @arg @ref LL_DMA_STREAM_7
149   *         @arg @ref LL_DMA_STREAM_ALL
150   * @retval An ErrorStatus enumeration value:
151   *          - SUCCESS: DMA registers are de-initialized
152   *          - ERROR: DMA registers are not de-initialized
153   */
LL_DMA_DeInit(DMA_TypeDef * DMAx,uint32_t Stream)154 uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Stream)
155 {
156   DMA_Stream_TypeDef *tmp;
157   ErrorStatus status = SUCCESS;
158 
159   /* Check the DMA Instance DMAx and Stream parameters */
160   assert_param(IS_LL_DMA_ALL_STREAM_INSTANCE(DMAx, Stream));
161 
162   if (Stream == LL_DMA_STREAM_ALL)
163   {
164     if (DMAx == DMA1)
165     {
166       /* Force reset of DMA clock */
167       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
168 
169       /* Release reset of DMA clock */
170       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
171     }
172     else if (DMAx == DMA2)
173     {
174       /* Force reset of DMA clock */
175        LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2);
176 
177       /* Release reset of DMA clock */
178       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2);
179     }
180     else
181     {
182       status = ERROR;
183     }
184   }
185   else
186   {
187     /* Disable the selected Stream */
188     LL_DMA_DisableStream(DMAx, Stream);
189 
190     /* Get the DMA Stream Instance */
191     tmp = (DMA_Stream_TypeDef *)(__LL_DMA_GET_STREAM_INSTANCE(DMAx, Stream));
192 
193     /* Reset DMAx_Streamy configuration register */
194     LL_DMA_WriteReg(tmp, CR, 0U);
195 
196     /* Reset DMAx_Streamy remaining bytes register */
197     LL_DMA_WriteReg(tmp, NDTR, 0U);
198 
199     /* Reset DMAx_Streamy peripheral address register */
200     LL_DMA_WriteReg(tmp, PAR, 0U);
201 
202     /* Reset DMAx_Streamy memory address register */
203     LL_DMA_WriteReg(tmp, M0AR, 0U);
204 
205     /* Reset DMAx_Streamy memory address register */
206     LL_DMA_WriteReg(tmp, M1AR, 0U);
207 
208     /* Reset DMAx_Streamy FIFO control register */
209     LL_DMA_WriteReg(tmp, FCR, 0x00000021U);
210 
211     /* Reset Channel register field for DMAx Stream */
212     LL_DMA_SetPeriphRequest(DMAx, Stream, LL_DMAMUX1_REQ_MEM2MEM);
213 
214     if (Stream == LL_DMA_STREAM_0)
215     {
216       /* Reset the Stream0 pending flags */
217       DMAx->LIFCR = 0x0000003FU;
218     }
219     else if (Stream == LL_DMA_STREAM_1)
220     {
221       /* Reset the Stream1 pending flags */
222       DMAx->LIFCR = 0x00000F40U;
223     }
224     else if (Stream == LL_DMA_STREAM_2)
225     {
226       /* Reset the Stream2 pending flags */
227       DMAx->LIFCR = 0x003F0000U;
228     }
229     else if (Stream == LL_DMA_STREAM_3)
230     {
231       /* Reset the Stream3 pending flags */
232       DMAx->LIFCR = 0x0F400000U;
233     }
234     else if (Stream == LL_DMA_STREAM_4)
235     {
236       /* Reset the Stream4 pending flags */
237       DMAx->HIFCR = 0x0000003FU;
238     }
239     else if (Stream == LL_DMA_STREAM_5)
240     {
241       /* Reset the Stream5 pending flags */
242       DMAx->HIFCR = 0x00000F40U;
243     }
244     else if (Stream == LL_DMA_STREAM_6)
245     {
246       /* Reset the Stream6 pending flags */
247       DMAx->HIFCR = 0x003F0000U;
248     }
249     else if (Stream == LL_DMA_STREAM_7)
250     {
251       /* Reset the Stream7 pending flags */
252       DMAx->HIFCR = 0x0F400000U;
253     }
254     else
255     {
256       status = ERROR;
257     }
258   }
259 
260   return (uint32_t)status;
261 }
262 
263 /**
264   * @brief  Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
265   * @note   To convert DMAx_Streamy Instance to DMAx Instance and Streamy, use helper macros :
266   *         @arg @ref __LL_DMA_GET_INSTANCE
267   *         @arg @ref __LL_DMA_GET_STREAM
268   * @param  DMAx DMAx Instance
269   * @param  Stream This parameter can be one of the following values:
270   *         @arg @ref LL_DMA_STREAM_0
271   *         @arg @ref LL_DMA_STREAM_1
272   *         @arg @ref LL_DMA_STREAM_2
273   *         @arg @ref LL_DMA_STREAM_3
274   *         @arg @ref LL_DMA_STREAM_4
275   *         @arg @ref LL_DMA_STREAM_5
276   *         @arg @ref LL_DMA_STREAM_6
277   *         @arg @ref LL_DMA_STREAM_7
278   * @param  DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
279   * @retval An ErrorStatus enumeration value:
280   *          - SUCCESS: DMA registers are initialized
281   *          - ERROR: Not applicable
282   */
LL_DMA_Init(DMA_TypeDef * DMAx,uint32_t Stream,LL_DMA_InitTypeDef * DMA_InitStruct)283 uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Stream, LL_DMA_InitTypeDef *DMA_InitStruct)
284 {
285   /* Check the DMA Instance DMAx and Stream parameters */
286   assert_param(IS_LL_DMA_ALL_STREAM_INSTANCE(DMAx, Stream));
287 
288   /* Check the DMA parameters from DMA_InitStruct */
289   assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
290   assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
291   assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
292   assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
293   assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
294   assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
295   assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
296   assert_param(IS_LL_DMA_REQUEST(DMA_InitStruct->PeriphRequest));
297   assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
298   assert_param(IS_LL_DMA_FIFO_MODE_STATE(DMA_InitStruct->FIFOMode));
299 
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[3:0] bits
373    */
374   LL_DMA_SetPeriphRequest(DMAx, Stream, DMA_InitStruct->PeriphRequest);
375 
376   return (uint32_t)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->PeriphRequest          = LL_DMAMUX1_REQ_MEM2MEM;
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