1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_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 "stm32l4xx_ll_dma.h"
22 #include "stm32l4xx_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 STM32L4xx_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 
53 #define IS_LL_DMA_PERIPHINCMODE(__VALUE__)      (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
54                                                  ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
55 
56 #define IS_LL_DMA_MEMORYINCMODE(__VALUE__)      (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
57                                                  ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
58 
59 #define IS_LL_DMA_PERIPHDATASIZE(__VALUE__)     (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE)      || \
60                                                  ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD)  || \
61                                                  ((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
62 
63 #define IS_LL_DMA_MEMORYDATASIZE(__VALUE__)     (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE)      || \
64                                                  ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD)  || \
65                                                  ((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
66 
67 #define IS_LL_DMA_NBDATA(__VALUE__)             ((__VALUE__)  <= 0x0000FFFFU)
68 
69 #if defined(DMAMUX1)
70 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__)      ((__VALUE__) <= 93U)
71 #else
72 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__)      (((__VALUE__) == LL_DMA_REQUEST_0)  || \
73                                                  ((__VALUE__) == LL_DMA_REQUEST_1)  || \
74                                                  ((__VALUE__) == LL_DMA_REQUEST_2)  || \
75                                                  ((__VALUE__) == LL_DMA_REQUEST_3)  || \
76                                                  ((__VALUE__) == LL_DMA_REQUEST_4)  || \
77                                                  ((__VALUE__) == LL_DMA_REQUEST_5)  || \
78                                                  ((__VALUE__) == LL_DMA_REQUEST_6)  || \
79                                                  ((__VALUE__) == LL_DMA_REQUEST_7))
80 #endif /* DMAMUX1 */
81 
82 #define IS_LL_DMA_PRIORITY(__VALUE__)           (((__VALUE__) == LL_DMA_PRIORITY_LOW)    || \
83                                                  ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
84                                                  ((__VALUE__) == LL_DMA_PRIORITY_HIGH)   || \
85                                                  ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
86 
87 #if defined (DMA2)
88 #if defined (DMA2_Channel6) && defined (DMA2_Channel7)
89 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
90                                                          (((CHANNEL) == LL_DMA_CHANNEL_1) || \
91                                                           ((CHANNEL) == LL_DMA_CHANNEL_2) || \
92                                                           ((CHANNEL) == LL_DMA_CHANNEL_3) || \
93                                                           ((CHANNEL) == LL_DMA_CHANNEL_4) || \
94                                                           ((CHANNEL) == LL_DMA_CHANNEL_5) || \
95                                                           ((CHANNEL) == LL_DMA_CHANNEL_6) || \
96                                                           ((CHANNEL) == LL_DMA_CHANNEL_7))) || \
97                                                          (((INSTANCE) == DMA2) && \
98                                                          (((CHANNEL) == LL_DMA_CHANNEL_1) || \
99                                                           ((CHANNEL) == LL_DMA_CHANNEL_2) || \
100                                                           ((CHANNEL) == LL_DMA_CHANNEL_3) || \
101                                                           ((CHANNEL) == LL_DMA_CHANNEL_4) || \
102                                                           ((CHANNEL) == LL_DMA_CHANNEL_5) || \
103                                                           ((CHANNEL) == LL_DMA_CHANNEL_6) || \
104                                                           ((CHANNEL) == LL_DMA_CHANNEL_7))))
105 #else
106 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
107                                                          (((CHANNEL) == LL_DMA_CHANNEL_1) || \
108                                                           ((CHANNEL) == LL_DMA_CHANNEL_2) || \
109                                                           ((CHANNEL) == LL_DMA_CHANNEL_3) || \
110                                                           ((CHANNEL) == LL_DMA_CHANNEL_4) || \
111                                                           ((CHANNEL) == LL_DMA_CHANNEL_5) || \
112                                                           ((CHANNEL) == LL_DMA_CHANNEL_6) || \
113                                                           ((CHANNEL) == LL_DMA_CHANNEL_7))) || \
114                                                          (((INSTANCE) == DMA2) && \
115                                                          (((CHANNEL) == LL_DMA_CHANNEL_1) || \
116                                                           ((CHANNEL) == LL_DMA_CHANNEL_2) || \
117                                                           ((CHANNEL) == LL_DMA_CHANNEL_3) || \
118                                                           ((CHANNEL) == LL_DMA_CHANNEL_4) || \
119                                                           ((CHANNEL) == LL_DMA_CHANNEL_5))))
120 #endif
121 #else
122 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL)  ((((INSTANCE) == DMA1) && \
123                                                             (((CHANNEL) == LL_DMA_CHANNEL_1)|| \
124                                                             ((CHANNEL) == LL_DMA_CHANNEL_2) || \
125                                                             ((CHANNEL) == LL_DMA_CHANNEL_3) || \
126                                                             ((CHANNEL) == LL_DMA_CHANNEL_4) || \
127                                                             ((CHANNEL) == LL_DMA_CHANNEL_5) || \
128                                                             ((CHANNEL) == LL_DMA_CHANNEL_6) || \
129                                                             ((CHANNEL) == LL_DMA_CHANNEL_7))))
130 #endif
131 /**
132   * @}
133   */
134 
135 /* Private function prototypes -----------------------------------------------*/
136 
137 /* Exported functions --------------------------------------------------------*/
138 /** @addtogroup DMA_LL_Exported_Functions
139   * @{
140   */
141 
142 /** @addtogroup DMA_LL_EF_Init
143   * @{
144   */
145 
146 /**
147   * @brief  De-initialize the DMA registers to their default reset values.
148   * @param  DMAx DMAx Instance
149   * @param  Channel This parameter can be one of the following values:
150   *         @arg @ref LL_DMA_CHANNEL_1
151   *         @arg @ref LL_DMA_CHANNEL_2
152   *         @arg @ref LL_DMA_CHANNEL_3
153   *         @arg @ref LL_DMA_CHANNEL_4
154   *         @arg @ref LL_DMA_CHANNEL_5
155   *         @arg @ref LL_DMA_CHANNEL_6
156   *         @arg @ref LL_DMA_CHANNEL_7
157   *         @arg @ref LL_DMA_CHANNEL_ALL
158   * @retval An ErrorStatus enumeration value:
159   *          - SUCCESS: DMA registers are de-initialized
160   *          - ERROR: DMA registers are not de-initialized
161   */
LL_DMA_DeInit(DMA_TypeDef * DMAx,uint32_t Channel)162 ErrorStatus LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
163 {
164   ErrorStatus status = SUCCESS;
165   DMA_Channel_TypeDef *tmp;
166 
167   /* Check the DMA Instance DMAx and Channel parameters*/
168   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel) || (Channel == LL_DMA_CHANNEL_ALL));
169 
170   if (Channel == LL_DMA_CHANNEL_ALL)
171   {
172     if (DMAx == DMA1)
173     {
174       /* Force reset of DMA clock */
175       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
176 
177       /* Release reset of DMA clock */
178       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
179     }
180 #if defined(DMA2)
181     else if (DMAx == DMA2)
182     {
183       /* Force reset of DMA clock */
184       LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2);
185 
186       /* Release reset of DMA clock */
187       LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2);
188     }
189 #endif
190     else
191     {
192       status = ERROR;
193     }
194   }
195   else
196   {
197     tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
198 
199     /* Disable the selected DMAx_Channely */
200     CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
201 
202     /* Reset DMAx_Channely control register */
203     WRITE_REG(tmp->CCR, 0U);
204 
205     /* Reset DMAx_Channely remaining bytes register */
206     WRITE_REG(tmp->CNDTR, 0U);
207 
208     /* Reset DMAx_Channely peripheral address register */
209     WRITE_REG(tmp->CPAR, 0U);
210 
211     /* Reset DMAx_Channely memory 0 address register */
212     WRITE_REG(tmp->CMAR, 0U);
213 
214 #if defined(DMAMUX1)
215     /* Reset Request register field for DMAx Channel */
216     LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMAMUX_REQ_MEM2MEM);
217 #else
218     /* Reset Request register field for DMAx Channel */
219     LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMA_REQUEST_0);
220 #endif /* DMAMUX1 */
221 
222     if (Channel == LL_DMA_CHANNEL_1)
223     {
224       /* Reset interrupt pending bits for DMAx Channel1 */
225       LL_DMA_ClearFlag_GI1(DMAx);
226     }
227     else if (Channel == LL_DMA_CHANNEL_2)
228     {
229       /* Reset interrupt pending bits for DMAx Channel2 */
230       LL_DMA_ClearFlag_GI2(DMAx);
231     }
232     else if (Channel == LL_DMA_CHANNEL_3)
233     {
234       /* Reset interrupt pending bits for DMAx Channel3 */
235       LL_DMA_ClearFlag_GI3(DMAx);
236     }
237     else if (Channel == LL_DMA_CHANNEL_4)
238     {
239       /* Reset interrupt pending bits for DMAx Channel4 */
240       LL_DMA_ClearFlag_GI4(DMAx);
241     }
242     else if (Channel == LL_DMA_CHANNEL_5)
243     {
244       /* Reset interrupt pending bits for DMAx Channel5 */
245       LL_DMA_ClearFlag_GI5(DMAx);
246     }
247 
248     else if (Channel == LL_DMA_CHANNEL_6)
249     {
250       /* Reset interrupt pending bits for DMAx Channel6 */
251       LL_DMA_ClearFlag_GI6(DMAx);
252     }
253     else if (Channel == LL_DMA_CHANNEL_7)
254     {
255       /* Reset interrupt pending bits for DMAx Channel7 */
256       LL_DMA_ClearFlag_GI7(DMAx);
257     }
258     else
259     {
260       status = ERROR;
261     }
262   }
263 
264   return status;
265 }
266 
267 /**
268   * @brief  Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
269   * @note   To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
270   *         @arg @ref __LL_DMA_GET_INSTANCE
271   *         @arg @ref __LL_DMA_GET_CHANNEL
272   * @param  DMAx DMAx Instance
273   * @param  Channel This parameter can be one of the following values:
274   *         @arg @ref LL_DMA_CHANNEL_1
275   *         @arg @ref LL_DMA_CHANNEL_2
276   *         @arg @ref LL_DMA_CHANNEL_3
277   *         @arg @ref LL_DMA_CHANNEL_4
278   *         @arg @ref LL_DMA_CHANNEL_5
279   *         @arg @ref LL_DMA_CHANNEL_6
280   *         @arg @ref LL_DMA_CHANNEL_7
281   * @param  DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
282   * @retval An ErrorStatus enumeration value:
283   *          - SUCCESS: DMA registers are initialized
284   *          - ERROR: Not applicable
285   */
LL_DMA_Init(DMA_TypeDef * DMAx,uint32_t Channel,LL_DMA_InitTypeDef * DMA_InitStruct)286 ErrorStatus LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
287 {
288   /* Check the DMA Instance DMAx and Channel parameters*/
289   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
290 
291   /* Check the DMA parameters from DMA_InitStruct */
292   assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
293   assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
294   assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
295   assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
296   assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
297   assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
298   assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
299   assert_param(IS_LL_DMA_PERIPHREQUEST(DMA_InitStruct->PeriphRequest));
300   assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
301 
302   /*---------------------------- DMAx CCR Configuration ------------------------
303    * Configure DMAx_Channely: data transfer direction, data transfer mode,
304    *                          peripheral and memory increment mode,
305    *                          data size alignment and  priority level with parameters :
306    * - Direction:      DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
307    * - Mode:           DMA_CCR_CIRC bit
308    * - PeriphOrM2MSrcIncMode:  DMA_CCR_PINC bit
309    * - MemoryOrM2MDstIncMode:  DMA_CCR_MINC bit
310    * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
311    * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
312    * - Priority:               DMA_CCR_PL[1:0] bits
313    */
314   LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction              | \
315                         DMA_InitStruct->Mode                   | \
316                         DMA_InitStruct->PeriphOrM2MSrcIncMode  | \
317                         DMA_InitStruct->MemoryOrM2MDstIncMode  | \
318                         DMA_InitStruct->PeriphOrM2MSrcDataSize | \
319                         DMA_InitStruct->MemoryOrM2MDstDataSize | \
320                         DMA_InitStruct->Priority);
321 
322   /*-------------------------- DMAx CMAR Configuration -------------------------
323    * Configure the memory or destination base address with parameter :
324    * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
325    */
326   LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
327 
328   /*-------------------------- DMAx CPAR Configuration -------------------------
329    * Configure the peripheral or source base address with parameter :
330    * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
331    */
332   LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
333 
334   /*--------------------------- DMAx CNDTR Configuration -----------------------
335    * Configure the peripheral base address with parameter :
336    * - NbData: DMA_CNDTR_NDT[15:0] bits
337    */
338   LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
339 
340 #if defined(DMAMUX1)
341   /*--------------------------- DMAMUXx CCR Configuration ----------------------
342    * Configure the DMA request for DMA Channels on DMAMUX Channel x with parameter :
343    * - PeriphRequest: DMA_CxCR[7:0] bits
344    */
345   LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest);
346 #else
347   /*--------------------------- DMAx CSELR Configuration -----------------------
348    * Configure the DMA request for DMA instance on Channel x with parameter :
349    * - PeriphRequest: DMA_CSELR[31:0] bits
350    */
351   LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest);
352 #endif /* DMAMUX1 */
353 
354   return SUCCESS;
355 }
356 
357 /**
358   * @brief  Set each @ref LL_DMA_InitTypeDef field to default value.
359   * @param  DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
360   * @retval None
361   */
LL_DMA_StructInit(LL_DMA_InitTypeDef * DMA_InitStruct)362 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
363 {
364   /* Set DMA_InitStruct fields to default values */
365   DMA_InitStruct->PeriphOrM2MSrcAddress  = 0x00000000U;
366   DMA_InitStruct->MemoryOrM2MDstAddress  = 0x00000000U;
367   DMA_InitStruct->Direction              = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
368   DMA_InitStruct->Mode                   = LL_DMA_MODE_NORMAL;
369   DMA_InitStruct->PeriphOrM2MSrcIncMode  = LL_DMA_PERIPH_NOINCREMENT;
370   DMA_InitStruct->MemoryOrM2MDstIncMode  = LL_DMA_MEMORY_NOINCREMENT;
371   DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
372   DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
373   DMA_InitStruct->NbData                 = 0x00000000U;
374 #if defined(DMAMUX1)
375   DMA_InitStruct->PeriphRequest          = LL_DMAMUX_REQ_MEM2MEM;
376 #else
377   DMA_InitStruct->PeriphRequest          = LL_DMA_REQUEST_0;
378 #endif /* DMAMUX1 */
379   DMA_InitStruct->Priority               = LL_DMA_PRIORITY_LOW;
380 }
381 
382 /**
383   * @}
384   */
385 
386 /**
387   * @}
388   */
389 
390 /**
391   * @}
392   */
393 
394 #endif /* DMA1 || DMA2 */
395 
396 /**
397   * @}
398   */
399 
400 #endif /* USE_FULL_LL_DRIVER */
401