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