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