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