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