1 /**
2 ******************************************************************************
3 * @file stm32wlxx_hal_dma.c
4 * @author MCD Application Team
5 * @brief DMA HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Direct Memory Access (DMA) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral State and errors functions
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2020 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 @verbatim
23 ==============================================================================
24 ##### How to use this driver #####
25 ==============================================================================
26 [..]
27 (#) Enable and configure the peripheral to be connected to the DMA Channel
28 (except for internal SRAM / FLASH memories: no initialization is
29 necessary). Please refer to the Reference manual for connection between peripherals
30 and DMA requests.
31
32 (#) For a given Channel, program the required configuration through the following parameters:
33 Channel request, Transfer Direction, Source and Destination data formats,
34 Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
35 using HAL_DMA_Init() function.
36
37 Prior to HAL_DMA_Init the peripheral clock shall be enabled for both DMA & DMAMUX
38 thanks to:
39 (##) DMA1 or DMA2: __HAL_RCC_DMA1_CLK_ENABLE() or __HAL_RCC_DMA2_CLK_ENABLE();
40 (##) DMAMUX1: __HAL_RCC_DMAMUX1_CLK_ENABLE();
41
42 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
43 detection.
44
45 (#) Use HAL_DMA_Abort() function to abort the current transfer
46
47 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
48
49 *** Polling mode IO operation ***
50 =================================
51 [..]
52 (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
53 address and destination address and the Length of data to be transferred
54 (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
55 case a fixed Timeout can be configured by User depending from his application.
56
57 *** Interrupt mode IO operation ***
58 ===================================
59 [..]
60 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
61 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
62 (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
63 Source address and destination address and the Length of data to be transferred.
64 In this case the DMA interrupt is configured
65 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
66 (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
67 add his own function to register callbacks with HAL_DMA_RegisterCallback().
68
69 *** DMA HAL driver macros list ***
70 =============================================
71 [..]
72 Below the list of macros in DMA HAL driver.
73
74 (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
75 (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
76 (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
77 (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
78 (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
79 (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
80 (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt is enabled or not.
81
82 [..]
83 (@) You can refer to the DMA HAL driver header file for more useful macros
84
85 @endverbatim
86 ******************************************************************************
87 */
88
89 /* Includes ------------------------------------------------------------------*/
90 #include "stm32wlxx_hal.h"
91
92 /** @addtogroup STM32WLxx_HAL_Driver
93 * @{
94 */
95
96 /** @defgroup DMA DMA
97 * @brief DMA HAL module driver
98 * @{
99 */
100
101 #ifdef HAL_DMA_MODULE_ENABLED
102
103 /* Private typedef -----------------------------------------------------------*/
104 /* Private define ------------------------------------------------------------*/
105 /* Private macro -------------------------------------------------------------*/
106 /* Private variables ---------------------------------------------------------*/
107 /* Private function prototypes -----------------------------------------------*/
108
109 /** @defgroup DMA_Private_Functions DMA Private Functions
110 * @{
111 */
112 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
113 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma);
114 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma);
115
116 /**
117 * @}
118 */
119
120 /* Exported functions ---------------------------------------------------------*/
121
122 /** @defgroup DMA_Exported_Functions DMA Exported Functions
123 * @{
124 */
125
126 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
127 * @brief Initialization and de-initialization functions
128 *
129 @verbatim
130 ===============================================================================
131 ##### Initialization and de-initialization functions #####
132 ===============================================================================
133 [..]
134 This section provides functions allowing to initialize the DMA Channel source
135 and destination addresses, incrementation and data sizes, transfer direction,
136 circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
137 [..]
138 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
139 reference manual.
140
141 @endverbatim
142 * @{
143 */
144
145 /**
146 * @brief Initialize the DMA according to the specified
147 * parameters in the DMA_InitTypeDef and initialize the associated handle.
148 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
149 * the configuration information for the specified DMA Channel.
150 * @retval HAL status
151 */
HAL_DMA_Init(DMA_HandleTypeDef * hdma)152 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
153 {
154 /* Check the DMA handle allocation */
155 if (hdma == NULL)
156 {
157 return HAL_ERROR;
158 }
159
160 /* Check the parameters */
161 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
162 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
163 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
164 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
165 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
166 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
167 assert_param(IS_DMA_MODE(hdma->Init.Mode));
168 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
169
170 assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));
171
172 /* Compute the channel index */
173 if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
174 {
175 /* DMA1 */
176 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
177 hdma->DmaBaseAddress = DMA1;
178 }
179 else
180 {
181 /* DMA2 */
182 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
183 hdma->DmaBaseAddress = DMA2;
184 }
185
186 /* Change DMA peripheral state */
187 hdma->State = HAL_DMA_STATE_BUSY;
188
189 /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR and MEM2MEM bits */
190 CLEAR_BIT(hdma->Instance->CCR, (DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
191 DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
192 DMA_CCR_DIR | DMA_CCR_MEM2MEM));
193
194 /* Set the DMA Channel configuration */
195 SET_BIT(hdma->Instance->CCR, (hdma->Init.Direction | \
196 hdma->Init.PeriphInc | hdma->Init.MemInc | \
197 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment | \
198 hdma->Init.Mode | hdma->Init.Priority));
199
200 /* Initialize parameters for DMAMUX channel :
201 DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
202 */
203 DMA_CalcDMAMUXChannelBaseAndMask(hdma);
204
205 if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
206 {
207 /* if memory to memory force the request to 0*/
208 hdma->Init.Request = DMA_REQUEST_MEM2MEM;
209 }
210
211 /* Set peripheral request to DMAMUX channel */
212 hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
213
214 /* Clear the DMAMUX synchro overrun flag */
215 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
216
217 if (((hdma->Init.Request > 0UL) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
218 {
219 /* Initialize parameters for DMAMUX request generator :
220 DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
221 */
222 DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
223
224 /* Reset the DMAMUX request generator register*/
225 hdma->DMAmuxRequestGen->RGCR = 0U;
226
227 /* Clear the DMAMUX request generator overrun flag */
228 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
229 }
230 else
231 {
232 hdma->DMAmuxRequestGen = NULL;
233 hdma->DMAmuxRequestGenStatus = NULL;
234 hdma->DMAmuxRequestGenStatusMask = 0U;
235 }
236
237 /* Initialize the error code */
238 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
239
240 /* Initialize the DMA state*/
241 hdma->State = HAL_DMA_STATE_READY;
242
243 /* Release Lock */
244 __HAL_UNLOCK(hdma);
245
246 return HAL_OK;
247 }
248
249 /**
250 * @brief DeInitialize the DMA peripheral.
251 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
252 * the configuration information for the specified DMA Channel.
253 * @retval HAL status
254 */
HAL_DMA_DeInit(DMA_HandleTypeDef * hdma)255 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
256 {
257 /* Check the DMA handle allocation */
258 if (NULL == hdma)
259 {
260 return HAL_ERROR;
261 }
262
263 /* Check the parameters */
264 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
265
266 /* Disable the selected DMA Channelx */
267 __HAL_DMA_DISABLE(hdma);
268
269 /* Compute the channel index */
270 if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
271 {
272 /* DMA1 */
273 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
274 hdma->DmaBaseAddress = DMA1;
275 }
276 else
277 {
278 /* DMA2 */
279 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
280 hdma->DmaBaseAddress = DMA2;
281 }
282
283 /* Reset DMA Channel control register */
284 hdma->Instance->CCR = 0U;
285
286 /* Clear all flags */
287 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
288
289 /* Initialize parameters for DMAMUX channel :
290 DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
291
292 DMA_CalcDMAMUXChannelBaseAndMask(hdma);
293
294 /* Reset the DMAMUX channel that corresponds to the DMA channel */
295 hdma->DMAmuxChannel->CCR = 0U;
296
297 /* Clear the DMAMUX synchro overrun flag */
298 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
299
300 /* Reset Request generator parameters if any */
301 if (((hdma->Init.Request > 0UL) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
302 {
303 /* Initialize parameters for DMAMUX request generator :
304 DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
305 */
306 DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
307
308 /* Reset the DMAMUX request generator register*/
309 hdma->DMAmuxRequestGen->RGCR = 0U;
310
311 /* Clear the DMAMUX request generator overrun flag */
312 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
313 }
314
315 hdma->DMAmuxRequestGen = NULL;
316 hdma->DMAmuxRequestGenStatus = NULL;
317 hdma->DMAmuxRequestGenStatusMask = 0U;
318
319 /* Clean callbacks */
320 hdma->XferCpltCallback = NULL;
321 hdma->XferHalfCpltCallback = NULL;
322 hdma->XferErrorCallback = NULL;
323 hdma->XferAbortCallback = NULL;
324
325 /* Initialize the error code */
326 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
327
328 /* Initialize the DMA state */
329 hdma->State = HAL_DMA_STATE_RESET;
330
331 /* Release Lock */
332 __HAL_UNLOCK(hdma);
333
334 return HAL_OK;
335 }
336
337 /**
338 * @}
339 */
340
341 /** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
342 * @brief Input and Output operation functions
343 *
344 @verbatim
345 ===============================================================================
346 ##### IO operation functions #####
347 ===============================================================================
348 [..] This section provides functions allowing to:
349 (+) Configure the source, destination address and data length and Start DMA transfer
350 (+) Configure the source, destination address and data length and
351 Start DMA transfer with interrupt
352 (+) Abort DMA transfer
353 (+) Poll for transfer complete
354 (+) Handle DMA interrupt request
355 (+) Register and Unregister DMA callbacks
356
357 @endverbatim
358 * @{
359 */
360
361 /**
362 * @brief Start the DMA Transfer.
363 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
364 * the configuration information for the specified DMA Channel.
365 * @param SrcAddress The source memory Buffer address
366 * @param DstAddress The destination memory Buffer address
367 * @param DataLength The length of data to be transferred from source to destination
368 * @retval HAL status
369 */
HAL_DMA_Start(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)370 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
371 {
372 HAL_StatusTypeDef status = HAL_OK;
373
374 /* Check the parameters */
375 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
376
377 /* Process locked */
378 __HAL_LOCK(hdma);
379
380 if (hdma->State == HAL_DMA_STATE_READY)
381 {
382 /* Change DMA peripheral state */
383 hdma->State = HAL_DMA_STATE_BUSY;
384
385 /* Initialize the error code */
386 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
387
388 /* Disable the peripheral */
389 __HAL_DMA_DISABLE(hdma);
390
391 /* Configure the source, destination address and the data length & clear flags*/
392 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
393
394 /* Enable the Peripheral */
395 __HAL_DMA_ENABLE(hdma);
396 }
397 else
398 {
399 /* Change the error code */
400 hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
401
402 /* Process Unlocked */
403 __HAL_UNLOCK(hdma);
404
405 /* Return error status */
406 status = HAL_ERROR;
407 }
408
409 return status;
410 }
411
412 /**
413 * @brief Start the DMA Transfer with interrupt enabled.
414 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
415 * the configuration information for the specified DMA Channel.
416 * @param SrcAddress The source memory Buffer address
417 * @param DstAddress The destination memory Buffer address
418 * @param DataLength The length of data to be transferred from source to destination
419 * @retval HAL status
420 */
HAL_DMA_Start_IT(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)421 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
422 {
423 HAL_StatusTypeDef status = HAL_OK;
424
425 /* Check the parameters */
426 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
427
428 /* Process locked */
429 __HAL_LOCK(hdma);
430
431 if (hdma->State == HAL_DMA_STATE_READY)
432 {
433 /* Change DMA peripheral state */
434 hdma->State = HAL_DMA_STATE_BUSY;
435 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
436
437 /* Disable the peripheral */
438 __HAL_DMA_DISABLE(hdma);
439
440 /* Configure the source, destination address and the data length & clear flags*/
441 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
442
443 /* Enable the transfer complete interrupt */
444 /* Enable the transfer Error interrupt */
445 if (NULL != hdma->XferHalfCpltCallback)
446 {
447 /* Enable the Half transfer complete interrupt as well */
448 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
449 }
450 else
451 {
452 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
453 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
454 }
455
456 /* Check if DMAMUX Synchronization is enabled*/
457 if ((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
458 {
459 /* Enable DMAMUX sync overrun IT*/
460 hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
461 }
462
463 if (hdma->DMAmuxRequestGen != NULL)
464 {
465 /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
466 /* enable the request gen overrun IT*/
467 hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
468 }
469
470 /* Enable the Peripheral */
471 __HAL_DMA_ENABLE(hdma);
472 }
473 else
474 {
475 /* Change the error code */
476 hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
477
478 /* Process Unlocked */
479 __HAL_UNLOCK(hdma);
480
481 /* Return error status */
482 status = HAL_ERROR;
483 }
484
485 return status;
486 }
487
488 /**
489 * @brief Abort the DMA Transfer.
490 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
491 * the configuration information for the specified DMA Channel.
492 * @retval HAL status
493 */
HAL_DMA_Abort(DMA_HandleTypeDef * hdma)494 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
495 {
496 /* Check the DMA peripheral handle */
497 if (NULL == hdma)
498 {
499 return HAL_ERROR;
500 }
501
502 /* Check the DMA peripheral state */
503 if (hdma->State != HAL_DMA_STATE_BUSY)
504 {
505 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
506
507 /* Process Unlocked */
508 __HAL_UNLOCK(hdma);
509
510 return HAL_ERROR;
511 }
512 else
513 {
514 /* Disable DMA IT */
515 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
516
517 /* disable the DMAMUX sync overrun IT*/
518 hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
519
520 /* Disable the channel */
521 __HAL_DMA_DISABLE(hdma);
522
523 /* Clear all flags */
524 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
525
526 /* Clear the DMAMUX synchro overrun flag */
527 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
528
529 if (hdma->DMAmuxRequestGen != NULL)
530 {
531 /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
532 /* disable the request gen overrun IT*/
533 hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
534
535 /* Clear the DMAMUX request generator overrun flag */
536 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
537 }
538
539 /* Change the DMA state */
540 hdma->State = HAL_DMA_STATE_READY;
541
542 /* Process Unlocked */
543 __HAL_UNLOCK(hdma);
544 }
545
546 return HAL_OK;
547 }
548
549 /**
550 * @brief Aborts the DMA Transfer in Interrupt mode.
551 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
552 * the configuration information for the specified DMA Channel.
553 * @retval HAL status
554 */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * hdma)555 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
556 {
557 HAL_StatusTypeDef status = HAL_OK;
558
559 if (hdma->State != HAL_DMA_STATE_BUSY)
560 {
561 /* no transfer ongoing */
562 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
563
564 status = HAL_ERROR;
565 }
566 else
567 {
568 /* Disable DMA IT */
569 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
570
571 /* Disable the channel */
572 __HAL_DMA_DISABLE(hdma);
573
574 /* disable the DMAMUX sync overrun IT*/
575 hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
576
577 /* Clear all flags */
578 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
579
580 /* Clear the DMAMUX synchro overrun flag */
581 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
582
583 if (hdma->DMAmuxRequestGen != NULL)
584 {
585 /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
586 /* disable the request gen overrun IT*/
587 hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
588
589 /* Clear the DMAMUX request generator overrun flag */
590 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
591 }
592
593 /* Change the DMA state */
594 hdma->State = HAL_DMA_STATE_READY;
595
596 /* Process Unlocked */
597 __HAL_UNLOCK(hdma);
598
599 /* Call User Abort callback */
600 if (hdma->XferAbortCallback != NULL)
601 {
602 hdma->XferAbortCallback(hdma);
603 }
604 }
605 return status;
606 }
607
608 /**
609 * @brief Polling for transfer complete.
610 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
611 * the configuration information for the specified DMA Channel.
612 * @param CompleteLevel Specifies the DMA level complete.
613 * @param Timeout Timeout duration.
614 * @retval HAL status
615 */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * hdma,HAL_DMA_LevelCompleteTypeDef CompleteLevel,uint32_t Timeout)616 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
617 {
618 uint32_t temp;
619 uint32_t tickstart;
620
621 if (hdma->State != HAL_DMA_STATE_BUSY)
622 {
623 /* no transfer ongoing */
624 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
625 __HAL_UNLOCK(hdma);
626 return HAL_ERROR;
627 }
628
629 /* Polling mode not supported in circular mode */
630 if ((hdma->Instance->CCR & DMA_CCR_CIRC) != 0U)
631 {
632 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
633 return HAL_ERROR;
634 }
635
636 /* Get the level transfer complete flag */
637 if (HAL_DMA_FULL_TRANSFER == CompleteLevel)
638 {
639 /* Transfer Complete flag */
640 temp = DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU);
641 }
642 else
643 {
644 /* Half Transfer Complete flag */
645 temp = DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU);
646 }
647
648 /* Get tick */
649 tickstart = HAL_GetTick();
650
651 while ((hdma->DmaBaseAddress->ISR & temp) == 0U)
652 {
653 if ((hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << (hdma->ChannelIndex & 0x1CU))) != 0U)
654 {
655 /* When a DMA transfer error occurs */
656 /* A hardware clear of its EN bits is performed */
657 /* Clear all flags */
658 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
659
660 /* Update error code */
661 hdma->ErrorCode = HAL_DMA_ERROR_TE;
662
663 /* Change the DMA state */
664 hdma->State = HAL_DMA_STATE_READY;
665
666 /* Process Unlocked */
667 __HAL_UNLOCK(hdma);
668
669 return HAL_ERROR;
670 }
671 /* Check for the Timeout */
672 if (Timeout != HAL_MAX_DELAY)
673 {
674 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
675 {
676 /* Update error code */
677 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
678
679 /* Change the DMA state */
680 hdma->State = HAL_DMA_STATE_READY;
681
682 /* Process Unlocked */
683 __HAL_UNLOCK(hdma);
684
685 return HAL_ERROR;
686 }
687 }
688 }
689
690 /*Check for DMAMUX Request generator (if used) overrun status */
691 if (hdma->DMAmuxRequestGen != NULL)
692 {
693 /* if using DMAMUX request generator Check for DMAMUX request generator overrun */
694 if ((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
695 {
696 /* Disable the request gen overrun interrupt */
697 hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
698
699 /* Clear the DMAMUX request generator overrun flag */
700 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
701
702 /* Update error code */
703 hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
704 }
705 }
706
707 /* Check for DMAMUX Synchronization overrun */
708 if ((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
709 {
710 /* Clear the DMAMUX synchro overrun flag */
711 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
712
713 /* Update error code */
714 hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
715 }
716
717 if (HAL_DMA_FULL_TRANSFER == CompleteLevel)
718 {
719 /* Clear the transfer complete flag */
720 hdma->DmaBaseAddress->IFCR = (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU));
721
722 /* Process unlocked */
723 __HAL_UNLOCK(hdma);
724
725 /* The selected Channelx EN bit is cleared (DMA is disabled and
726 all transfers are complete) */
727 hdma->State = HAL_DMA_STATE_READY;
728 }
729 else
730 {
731 /* Clear the half transfer complete flag */
732 hdma->DmaBaseAddress->IFCR = (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU));
733 }
734
735 return HAL_OK;
736 }
737
738 /**
739 * @brief Handle DMA interrupt request.
740 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
741 * the configuration information for the specified DMA Channel.
742 * @retval None
743 */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * hdma)744 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
745 {
746 uint32_t flag_it = hdma->DmaBaseAddress->ISR;
747 uint32_t source_it = hdma->Instance->CCR;
748
749 /* Half Transfer Complete Interrupt management ******************************/
750 if (((flag_it & (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_HT) != 0U))
751 {
752 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
753 if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
754 {
755 /* Disable the half transfer interrupt */
756 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
757 }
758 /* Clear the half transfer complete flag */
759 hdma->DmaBaseAddress->IFCR = DMA_ISR_HTIF1 << (hdma->ChannelIndex & 0x1CU);
760
761 /* DMA peripheral state is not updated in Half Transfer */
762 /* but in Transfer Complete case */
763
764 if (hdma->XferHalfCpltCallback != NULL)
765 {
766 /* Half transfer callback */
767 hdma->XferHalfCpltCallback(hdma);
768 }
769 }
770
771 /* Transfer Complete Interrupt management ***********************************/
772 else if ((0U != (flag_it & (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU)))) && (0U != (source_it & DMA_IT_TC)))
773 {
774 if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
775 {
776 /* Disable the transfer complete and error interrupt */
777 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
778
779 /* Change the DMA state */
780 hdma->State = HAL_DMA_STATE_READY;
781 }
782 /* Clear the transfer complete flag */
783 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU)));
784
785 /* Process Unlocked */
786 __HAL_UNLOCK(hdma);
787
788 if (hdma->XferCpltCallback != NULL)
789 {
790 /* Transfer complete callback */
791 hdma->XferCpltCallback(hdma);
792 }
793 }
794
795 /* Transfer Error Interrupt management **************************************/
796 else if (((flag_it & (DMA_FLAG_TE1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_TE) != 0U))
797 {
798 /* When a DMA transfer error occurs */
799 /* A hardware clear of its EN bits is performed */
800 /* Disable ALL DMA IT */
801 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
802
803 /* Clear all flags */
804 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
805
806 /* Update error code */
807 hdma->ErrorCode = HAL_DMA_ERROR_TE;
808
809 /* Change the DMA state */
810 hdma->State = HAL_DMA_STATE_READY;
811
812 /* Process Unlocked */
813 __HAL_UNLOCK(hdma);
814
815 if (hdma->XferErrorCallback != NULL)
816 {
817 /* Transfer error callback */
818 hdma->XferErrorCallback(hdma);
819 }
820 }
821 else
822 {
823 /* Nothing To Do */
824 }
825 return;
826 }
827
828 /**
829 * @brief Register callbacks
830 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
831 * the configuration information for the specified DMA Channel.
832 * @param CallbackID User Callback identifier
833 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
834 * @param pCallback Pointer to private callback function which has pointer to
835 * a DMA_HandleTypeDef structure as parameter.
836 * @retval HAL status
837 */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* pCallback)(DMA_HandleTypeDef * _hdma))838 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
839 {
840 HAL_StatusTypeDef status = HAL_OK;
841
842 /* Process locked */
843 __HAL_LOCK(hdma);
844
845 if (hdma->State == HAL_DMA_STATE_READY)
846 {
847 switch (CallbackID)
848 {
849 case HAL_DMA_XFER_CPLT_CB_ID:
850 hdma->XferCpltCallback = pCallback;
851 break;
852
853 case HAL_DMA_XFER_HALFCPLT_CB_ID:
854 hdma->XferHalfCpltCallback = pCallback;
855 break;
856
857 case HAL_DMA_XFER_ERROR_CB_ID:
858 hdma->XferErrorCallback = pCallback;
859 break;
860
861 case HAL_DMA_XFER_ABORT_CB_ID:
862 hdma->XferAbortCallback = pCallback;
863 break;
864
865 default:
866 status = HAL_ERROR;
867 break;
868 }
869 }
870 else
871 {
872 status = HAL_ERROR;
873 }
874
875 /* Release Lock */
876 __HAL_UNLOCK(hdma);
877
878 return status;
879 }
880
881 /**
882 * @brief UnRegister callbacks
883 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
884 * the configuration information for the specified DMA Channel.
885 * @param CallbackID User Callback identifier
886 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
887 * @retval HAL status
888 */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID)889 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
890 {
891 HAL_StatusTypeDef status = HAL_OK;
892
893 /* Process locked */
894 __HAL_LOCK(hdma);
895
896 if (hdma->State == HAL_DMA_STATE_READY)
897 {
898 switch (CallbackID)
899 {
900 case HAL_DMA_XFER_CPLT_CB_ID:
901 hdma->XferCpltCallback = NULL;
902 break;
903
904 case HAL_DMA_XFER_HALFCPLT_CB_ID:
905 hdma->XferHalfCpltCallback = NULL;
906 break;
907
908 case HAL_DMA_XFER_ERROR_CB_ID:
909 hdma->XferErrorCallback = NULL;
910 break;
911
912 case HAL_DMA_XFER_ABORT_CB_ID:
913 hdma->XferAbortCallback = NULL;
914 break;
915
916 case HAL_DMA_XFER_ALL_CB_ID:
917 hdma->XferCpltCallback = NULL;
918 hdma->XferHalfCpltCallback = NULL;
919 hdma->XferErrorCallback = NULL;
920 hdma->XferAbortCallback = NULL;
921 break;
922
923 default:
924 status = HAL_ERROR;
925 break;
926 }
927 }
928 else
929 {
930 status = HAL_ERROR;
931 }
932
933 /* Release Lock */
934 __HAL_UNLOCK(hdma);
935
936 return status;
937 }
938
939 /**
940 * @}
941 */
942
943
944
945 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
946 * @brief Peripheral State and Errors functions
947 *
948 @verbatim
949 ===============================================================================
950 ##### Peripheral State and Errors functions #####
951 ===============================================================================
952 [..]
953 This subsection provides functions allowing to
954 (+) Check the DMA state
955 (+) Get error code
956
957 @endverbatim
958 * @{
959 */
960
961 /**
962 * @brief Return the DMA handle state.
963 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
964 * the configuration information for the specified DMA Channel.
965 * @retval HAL state
966 */
HAL_DMA_GetState(DMA_HandleTypeDef * hdma)967 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
968 {
969 /* Return DMA handle state */
970 return hdma->State;
971 }
972
973 /**
974 * @brief Return the DMA error code.
975 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
976 * the configuration information for the specified DMA Channel.
977 * @retval DMA Error Code
978 */
HAL_DMA_GetError(DMA_HandleTypeDef * hdma)979 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
980 {
981 /* Return the DMA error code */
982 return hdma->ErrorCode;
983 }
984
985 /**
986 * @}
987 */
988
989 /**
990 * @}
991 */
992
993 #if defined(DMA_CCR_SECM) && defined(DMA_CCR_PRIV)
994 /** @defgroup DMA_Exported_Functions_Group4 Attributes management functions
995 * @brief Attributes management functions
996 *
997 @verbatim
998 ===============================================================================
999 ##### Attributes management functions #####
1000 ===============================================================================
1001 [..]
1002 This subsection provides functions allowing to
1003 (+) Configure the DMA channel(s) privilege and non-privilege attributes
1004 (+) Configure the DMA channel(s) secure and non-secure attributes from
1005 secure world when the system implements the security (ESE=1)
1006 (+) Get the DMA channel(s) attributes
1007
1008 @endverbatim
1009 * @{
1010 */
1011
1012 /**
1013 * @brief Configure the DMA channel attribute(s).
1014 * @note Available attributes are security and privilege protection.
1015 * Each field can be set independently. Not allowed configurations
1016 * are not taken into account & HAL_ERROR returned.
1017 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
1018 * the configuration information for the specified DMA Channel.
1019 * @param ChannelAttributes specifies the DMA channel secure/privilege attributes.
1020 * This parameter can be a one or a combination of @ref DMA_Channel_Attributes
1021 * @retval HAL Status
1022 */
HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef * hdma,uint32_t ChannelAttributes)1023 HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *hdma, uint32_t ChannelAttributes)
1024 {
1025 HAL_StatusTypeDef status = HAL_OK;
1026 uint32_t ccr;
1027
1028 #if defined (CORE_CM0PLUS)
1029 uint32_t ccr_SECM;
1030 #endif /* CORE_CM0PLUS */
1031
1032 /* Check the DMA peripheral handle */
1033 if (hdma == NULL)
1034 {
1035 status = HAL_ERROR;
1036 return status;
1037 }
1038
1039 /* Check the parameters */
1040 assert_param(IS_DMA_ATTRIBUTES(ChannelAttributes));
1041
1042 /* Read CCR register */
1043 ccr = READ_REG(hdma->Instance->CCR);
1044
1045 /* Apply any requested privilege/non-privilege attributes */
1046 if ((ChannelAttributes & DMA_CHANNEL_ATTR_PRIV_MASK) != 0U)
1047 {
1048 if ((ChannelAttributes & DMA_CCR_PRIV) != 0U)
1049 {
1050 SET_BIT(ccr, DMA_CCR_PRIV);
1051 }
1052 else
1053 {
1054 CLEAR_BIT(ccr, DMA_CCR_PRIV);
1055 }
1056 }
1057
1058 #if defined (CORE_CM0PLUS)
1059 /* Channel */
1060 /* Check what is the current SECM status */
1061 if ((hdma->Instance->CCR & DMA_CCR_SECM) == DMA_CCR_SECM)
1062 {
1063 /* Channel is currently secure */
1064 ccr_SECM = DMA_CCR_SECM;
1065 }
1066 else
1067 {
1068 /* Channel is currently non-secure */
1069 ccr_SECM = 0U;
1070 }
1071
1072 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_MASK) != 0U)
1073 {
1074 if ((ChannelAttributes & DMA_CCR_SECM) != 0U)
1075 {
1076 SET_BIT(ccr, DMA_CCR_SECM);
1077 /* Channel changed to secure */
1078 ccr_SECM = DMA_CCR_SECM;
1079 }
1080 else
1081 {
1082 CLEAR_BIT(ccr, DMA_CCR_SECM);
1083 /* Channel changed to non-secure */
1084 ccr_SECM = 0U;
1085 }
1086 }
1087
1088 /* Channel source */
1089 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_SRC_MASK) != 0U)
1090 {
1091 /* Configure Source security attributes */
1092 if ((ChannelAttributes & DMA_CCR_SSEC) != 0x0U)
1093 {
1094 /* SSEC can only be set if channel is secure */
1095 /* Otherwise configuration is not taken into account */
1096 if (ccr_SECM == 0U)
1097 {
1098 status = HAL_ERROR;
1099 }
1100 else
1101 {
1102 SET_BIT(ccr, DMA_CCR_SSEC);
1103 }
1104 }
1105 else
1106 {
1107 CLEAR_BIT(ccr, DMA_CCR_SSEC);
1108 }
1109 }
1110
1111 /* Channel destination */
1112 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_DEST_MASK) != 0U)
1113 {
1114 /* Configure Destination security attributes */
1115 if ((ChannelAttributes & DMA_CCR_DSEC) != 0U)
1116 {
1117 if (ccr_SECM == 0U)
1118 {
1119 /* DSEC can only be set if channel is secure */
1120 /* Destination channel is non secure */
1121 status = HAL_ERROR;
1122 }
1123 else
1124 {
1125 SET_BIT(ccr, DMA_CCR_DSEC);
1126 }
1127 }
1128 else
1129 {
1130 CLEAR_BIT(ccr, DMA_CCR_DSEC);
1131 }
1132 }
1133
1134 #endif /* CORE_CM0PLUS */
1135
1136 /* Update CCR Register: PRIV, SECM, SCEC, DSEC bits */
1137 WRITE_REG(hdma->Instance->CCR, ccr);
1138
1139 return status;
1140 }
1141
1142 /**
1143 * @brief Get the attribute of a DMA channel.
1144 * @note Secure and non-secure attributes are only available from secure state
1145 * when the system implements the security (ESE=1)
1146 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
1147 * the configuration information for the specified DMA Channel.
1148 * @param ChannelAttributes pointer to return the attributes.
1149 * @retval HAL Status.
1150 */
HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef * hdma,uint32_t * ChannelAttributes)1151 HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef *hdma, uint32_t *ChannelAttributes)
1152 {
1153 uint32_t read_attributes;
1154 uint32_t attributes;
1155
1156 /* Check the DMA peripheral handle and pointer to returned value */
1157 if ((hdma == NULL) || (ChannelAttributes == NULL))
1158 {
1159 return HAL_ERROR;
1160 }
1161
1162 #if defined (CORE_CM0PLUS)
1163 /* Get secure or non-secure attributes */
1164 read_attributes = READ_BIT(hdma->Instance->CCR, DMA_CCR_PRIV | DMA_CCR_SECM | DMA_CCR_SSEC | DMA_CCR_DSEC);
1165
1166 /* Get privilege attributes */
1167 attributes = ((read_attributes & DMA_CCR_PRIV) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
1168
1169 /* Get security attributes */
1170 attributes |= ((read_attributes & DMA_CCR_SECM) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC;
1171
1172 /* Get security attributes of the source */
1173 attributes |= ((read_attributes & DMA_CCR_SSEC) == 0U) ? DMA_CHANNEL_SRC_NSEC : DMA_CHANNEL_SRC_SEC;
1174
1175 /* Get security attributes of the destination */
1176 attributes |= ((read_attributes & DMA_CCR_DSEC) == 0U) ? DMA_CHANNEL_DEST_NSEC : DMA_CHANNEL_DEST_SEC;
1177
1178 #else
1179
1180 /* Get secure or non-secure attributes */
1181 read_attributes = READ_BIT(hdma->Instance->CCR, DMA_CCR_PRIV | DMA_CCR_SECM);
1182
1183 /* Get privilege attributes */
1184 attributes = ((read_attributes & DMA_CCR_PRIV) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
1185
1186 /* Get security attributes */
1187 attributes |= ((read_attributes & DMA_CCR_SECM) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC;
1188 #endif /* CORE_CM0PLUS */
1189
1190 /* return value */
1191 *ChannelAttributes = attributes;
1192
1193 return HAL_OK;
1194 }
1195 #endif /* DMA_SECURE_SWITCH */
1196 /** @addtogroup DMA_Private_Functions
1197 * @{
1198 */
1199
1200 /**
1201 * @brief Sets the DMA Transfer parameter.
1202 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
1203 * the configuration information for the specified DMA Channel.
1204 * @param SrcAddress The source memory Buffer address
1205 * @param DstAddress The destination memory Buffer address
1206 * @param DataLength The length of data to be transferred from source to destination
1207 * @retval HAL status
1208 */
DMA_SetConfig(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)1209 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
1210 {
1211 /* Clear the DMAMUX synchro overrun flag */
1212 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1213
1214 if (hdma->DMAmuxRequestGen != NULL)
1215 {
1216 /* Clear the DMAMUX request generator overrun flag */
1217 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
1218 }
1219
1220 /* Clear all flags */
1221 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
1222
1223 /* Configure DMA Channel data length */
1224 hdma->Instance->CNDTR = DataLength;
1225
1226 /* Memory to Peripheral */
1227 if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1228 {
1229 /* Configure DMA Channel destination address */
1230 hdma->Instance->CPAR = DstAddress;
1231
1232 /* Configure DMA Channel source address */
1233 hdma->Instance->CMAR = SrcAddress;
1234 }
1235 /* Peripheral to Memory */
1236 else
1237 {
1238 /* Configure DMA Channel source address */
1239 hdma->Instance->CPAR = SrcAddress;
1240
1241 /* Configure DMA Channel destination address */
1242 hdma->Instance->CMAR = DstAddress;
1243 }
1244 }
1245
1246 /**
1247 * @brief Updates the DMA handle with the DMAMUX channel and status mask depending on channel number
1248 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
1249 * the configuration information for the specified DMA Channel.
1250 * @retval None
1251 */
DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef * hdma)1252 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
1253 {
1254 uint32_t channel_number;
1255
1256 /* check if instance is not outside the DMA channel range */
1257 if ((uint32_t)hdma->Instance < (uint32_t)DMA2_Channel1)
1258 {
1259 /* DMA1 */
1260 /* Associate a DMA Channel to a DMAMUX channel */
1261 hdma->DMAmuxChannel = (DMAMUX1_Channel0 + (hdma->ChannelIndex >> 2U));
1262
1263 /* Prepare channel_number used for DMAmuxChannelStatusMask computation */
1264 channel_number = (((uint32_t)hdma->Instance & 0xFFU) - 8U) / 20U;
1265 }
1266 else
1267 {
1268 /* DMA2 */
1269 /* Associate a DMA Channel to a DMAMUX channel */
1270 hdma->DMAmuxChannel = (DMAMUX1_Channel7 + (hdma->ChannelIndex >> 2U));
1271
1272 /* Prepare channel_number used for DMAmuxChannelStatusMask computation */
1273 channel_number = (((((uint32_t)hdma->Instance & 0xFFU) - 8U) / 20U) + 7U);
1274 }
1275
1276 /* Initialize the field DMAmuxChannelStatus to DMAMUX1_ChannelStatus base */
1277 hdma->DMAmuxChannelStatus = DMAMUX1_ChannelStatus;
1278
1279 /* Initialize the field DMAmuxChannelStatusMask with the corresponding index of the DMAMUX channel selected for the current ChannelIndex */
1280 hdma->DMAmuxChannelStatusMask = 1UL << (channel_number & 0x1FU);
1281 }
1282
1283 /**
1284 * @brief Updates the DMA handle with the DMAMUX request generator params
1285 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
1286 * the configuration information for the specified DMA Channel.
1287 * @retval None
1288 */
1289
DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef * hdma)1290 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
1291 {
1292 uint32_t request = hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
1293
1294 /* DMA Channels are connected to DMAMUX1 request generator blocks*/
1295 hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_RequestGenerator0) + ((request - 1U) * 4U)));
1296
1297 hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
1298
1299 /* here "Request" is either DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR3, i.e. <= 4*/
1300 hdma->DMAmuxRequestGenStatusMask = 1UL << ((request - 1U) & 0x3U);
1301 }
1302
1303 /**
1304 * @}
1305 */
1306
1307 /**
1308 * @}
1309 */
1310
1311 #endif /* HAL_DMA_MODULE_ENABLED */
1312 /**
1313 * @}
1314 */
1315
1316 /**
1317 * @}
1318 */
1319