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