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