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