1 /**
2 **********************************************************************************************************************
3 * @file stm32u5xx_hal_dma.c
4 * @author MCD Application Team
5 * @brief This file provides firmware functions to manage the following functionalities of the Direct Memory Access
6 * (DMA) peripheral:
7 * + Initialization/De-Initialization Functions
8 * + I/O Operation Functions
9 * + State and Errors Functions
10 * + DMA Attributes Functions
11 *
12 **********************************************************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2021 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 [..]
29 DMA transfer modes are divided to 2 major categories :
30 (+) Normal transfers (legacy)
31 (+) Linked-list transfers
32
33 [..]
34 Normal transfers mode is initialized via the standard module and linked-list mode is configured via the extended
35 module.
36
37 [..]
38 Additionally to linked-list capability, all advanced DMA features are managed and configured via the extended
39 module as extensions to normal mode.
40 Advanced features are :
41 (+) Repeated block feature.
42 (+) Trigger feature.
43 (+) Data handling feature.
44
45 [..]
46 DMA Legacy circular transfer, is replaced by circular linked-list configuration.
47
48
49 *** Initialization and De-Initialization ***
50 ============================================
51 [..]
52 For a given channel, enable and configure the peripheral to be connected to the DMA Channel (except for internal
53 SRAM/FLASH memories: no initialization is necessary) please refer to Reference manual for connection between
54 peripherals and DMA requests.
55
56 [..]
57 For a given channel, use HAL_DMA_Init function to program the required configuration for normal transfer through
58 the following parameters:
59
60 (+) Request : Specifies the DMA channel request
61 Request parameters :
62 (++) can be a value of DMA_Request_Selection
63
64 (+) BlkHWRequest : Specifies the Block hardware request mode for DMA channel
65 (++) can be a value of DMA_Block_Request
66
67 (+) Direction : Specifies the transfer direction for DMA channel
68 (++) can be a value of DMA_Transfer_Direction
69
70 (+) SrcInc : Specifies the source increment mode for the DMA channel
71 (++) can be a value of DMA_Source_Increment_Mode
72
73 (+) DestInc : Specifies the destination increment mode for the DMA channel
74 (++) can be a value of DMA_Destination_Increment_Mode
75
76 (+) SrcDataWidth : Specifies the source data width for the DMA channel
77 (++) can be a value of DMA_Source_Data_Width
78
79 (+) DestDataWidth : Specifies the destination data width for the DMA channel
80 (++) can be a value of DMA_Destination_Data_Width
81
82 (+) Priority : Specifies the priority for the DMA channel
83 (++) can be a value of DMA_Priority_Level
84
85 (+) SrcBurstLength : Specifies the source burst length (number of beats) for the DMA channel
86 (++) can be a value of between 1 and 64
87
88 (+) DestBurstLength : Specifies the destination burst length (number of beats) for the DMA channel
89 (++) can be a value of between 1 and 64
90
91 (+) TransferAllocatedPort : Specifies the source and destination allocated ports
92 (++) can be a value of DMA_Transfer_Allocated_Port
93
94 (+) TransferEventMode : Specifies the transfer event mode for the DMA channel
95 (++) can be a value of DMA_Transfer_Event_Mode
96
97 (+) Mode : Specifies the transfer mode for the DMA channel
98 (++) can be DMA_NORMAL
99
100 *** Polling mode IO operation ***
101 =================================
102 [..]
103 (+) Use HAL_DMA_Start() to start a DMA normal transfer after the configuration of source address, destination
104 address and the size of data to be transferred.
105
106 (+) Use HAL_DMA_PollForTransfer() to poll for selected transfer level. In this case a fixed Timeout can be
107 configured by User depending on his application.
108 Transfer level can be :
109 (++) HAL_DMA_HALF_TRANSFER
110 (++) HAL_DMA_FULL_TRANSFER
111 For circular transfer, this API returns an HAL_ERROR with HAL_DMA_ERROR_NOT_SUPPORTED error code.
112
113 (+) Use HAL_DMA_Abort() function to abort any ongoing DMA transfer in blocking mode.
114 This API returns HAL_ERROR when there is no ongoing transfer or timeout is reached when disabling the DMA
115 channel. (This API should not be called from an interrupt service routine)
116
117
118 *** Interrupt mode IO operation ***
119 ===================================
120 [..]
121 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
122
123 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
124
125 (+) Use HAL_DMA_RegisterCallback() function to register user callbacks from the following list :
126 (++) XferCpltCallback : transfer complete callback.
127 (++) XferHalfCpltCallback : half transfer complete callback.
128 (++) XferErrorCallback : transfer error callback.
129 (++) XferAbortCallback : transfer abort complete callback.
130 (++) XferSuspendCallback : transfer suspend complete callback.
131
132 (+) Use HAL_DMA_Start_IT() to start the DMA transfer after the enable of DMA interrupts and the configuration
133 of source address,destination address and the size of data to be transferred.
134
135 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() interrupt subroutine to handle any DMA interrupt.
136
137 (+) Use HAL_DMA_Abort_IT() function to abort any on-going DMA transfer in non-blocking mode.
138 This API will suspend immediately the DMA channel execution. When the transfer is effectively suspended,
139 an interrupt is generated and HAL_DMA_IRQHandler() will reset the channel and execute the callback
140 XferAbortCallback. (This API could be called from an interrupt service routine)
141
142
143 *** State and errors ***
144 ========================
145 [..]
146 (+) Use HAL_DMA_GetState() function to get the DMA state.
147 (+) Use HAL_DMA_GetError() function to get the DMA error code.
148
149
150 *** Security and privilege attributes ***
151 =========================================
152 [..]
153 (+) Use HAL_DMA_ConfigChannelAttributes() function to configure DMA channel security and privilege attributes.
154 (++) Security : at channel level, at source level and at destination level.
155 (++) Privilege : at channel level.
156 (+) Use HAL_DMA_GetConfigChannelAttributes() function to get the DMA channel attributes.
157 (+) Use HAL_DMA_LockChannelAttributes() function to lock the DMA channel security and privilege attributes
158 configuration. This API can be called once after each system boot.
159 If called again, HAL_DMA_ConfigChannelAttributes() API has no effect.
160 Unlock is done either by a system boot or a by an RCC reset.
161 (+) Use HAL_DMA_GetLockChannelAttributes() function to get the attributes lock status.
162
163
164 *** DMA HAL driver macros list ***
165 ==================================
166 [..]
167 Below the list of most used macros in DMA HAL driver.
168
169 (+) __HAL_DMA_ENABLE : Enable the specified DMA Channel.
170 (+) __HAL_DMA_DISABLE : Disable the specified DMA Channel.
171 (+) __HAL_DMA_GET_FLAG : Get the DMA Channel pending flags.
172 (+) __HAL_DMA_CLEAR_FLAG : Clear the DMA Channel pending flags.
173 (+) __HAL_DMA_ENABLE_IT : Enable the specified DMA Channel interrupts.
174 (+) __HAL_DMA_DISABLE_IT : Disable the specified DMA Channel interrupts.
175 (+) __HAL_DMA_GET_IT_SOURCE : Check whether the specified DMA Channel interrupt has occurred or not.
176
177 [..]
178 (@) You can refer to the header file of the DMA HAL driver for more useful macros.
179
180 @endverbatim
181 **********************************************************************************************************************
182 */
183
184 /* Includes ----------------------------------------------------------------------------------------------------------*/
185 #include "stm32u5xx_hal.h"
186
187 /** @addtogroup STM32U5xx_HAL_Driver
188 * @{
189 */
190
191 /** @defgroup DMA DMA
192 * @brief DMA HAL module driver
193 * @{
194 */
195
196 #ifdef HAL_DMA_MODULE_ENABLED
197
198 /* Private typedef ---------------------------------------------------------------------------------------------------*/
199 /* Private constants -------------------------------------------------------------------------------------------------*/
200 /* Private macro -----------------------------------------------------------------------------------------------------*/
201 /* Private variables -------------------------------------------------------------------------------------------------*/
202 /* Private function prototypes ---------------------------------------------------------------------------------------*/
203 static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
204 uint32_t SrcAddress,
205 uint32_t DstAddress,
206 uint32_t SrcDataSize);
207 static void DMA_Init(DMA_HandleTypeDef const *const hdma);
208
209 /* Exported functions ------------------------------------------------------------------------------------------------*/
210
211 /** @addtogroup DMA_Exported_Functions DMA Exported Functions
212 * @{
213 */
214
215 /** @addtogroup DMA_Exported_Functions_Group1
216 *
217 @verbatim
218 ======================================================================================================================
219 ##### Initialization and de-initialization functions #####
220 ======================================================================================================================
221 [..]
222 This section provides functions allowing to initialize and de-initialize the DMA channel in normal mode.
223
224 [..]
225 (+) The HAL_DMA_Init() function follows the DMA channel configuration procedures as described in reference manual.
226 (+) The HAL_DMA_DeInit() function allows to de-initialize the DMA channel.
227
228 @endverbatim
229 * @{
230 */
231
232 /**
233 * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef and
234 * create the associated handle.
235 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
236 * specified DMA Channel.
237 * @retval HAL status.
238 */
HAL_DMA_Init(DMA_HandleTypeDef * const hdma)239 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *const hdma)
240 {
241 /* Get tick number */
242 uint32_t tickstart = HAL_GetTick();
243
244 /* Check the DMA peripheral handle parameter */
245 if (hdma == NULL)
246 {
247 return HAL_ERROR;
248 }
249
250 /* Check the parameters */
251 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
252 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
253 if (hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
254 {
255 assert_param(IS_DMA_REQUEST(hdma->Init.Request));
256 }
257 assert_param(IS_DMA_BLOCK_HW_REQUEST(hdma->Init.BlkHWRequest));
258 assert_param(IS_DMA_SOURCE_INC(hdma->Init.SrcInc));
259 assert_param(IS_DMA_DESTINATION_INC(hdma->Init.DestInc));
260 assert_param(IS_DMA_SOURCE_DATA_WIDTH(hdma->Init.SrcDataWidth));
261 assert_param(IS_DMA_DESTINATION_DATA_WIDTH(hdma->Init.DestDataWidth));
262 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
263 assert_param(IS_DMA_TCEM_EVENT_MODE(hdma->Init.TransferEventMode));
264 assert_param(IS_DMA_MODE(hdma->Init.Mode));
265 /* Check DMA channel instance */
266 if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
267 {
268 assert_param(IS_DMA_BURST_LENGTH(hdma->Init.SrcBurstLength));
269 assert_param(IS_DMA_BURST_LENGTH(hdma->Init.DestBurstLength));
270 assert_param(IS_DMA_TRANSFER_ALLOCATED_PORT(hdma->Init.TransferAllocatedPort));
271 }
272
273 /* Allocate lock resource */
274 __HAL_UNLOCK(hdma);
275
276 /* Update the DMA channel state */
277 hdma->State = HAL_DMA_STATE_BUSY;
278
279 /* Disable the DMA channel */
280 __HAL_DMA_DISABLE(hdma);
281
282 /* Check if the DMA channel is effectively disabled */
283 while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
284 {
285 /* Check for the Timeout */
286 if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
287 {
288 /* Update the DMA channel error code */
289 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
290
291 /* Update the DMA channel state */
292 hdma->State = HAL_DMA_STATE_ERROR;
293
294 return HAL_ERROR;
295 }
296 }
297
298 /* Initialize the DMA channel registers */
299 DMA_Init(hdma);
300
301 /* Update DMA channel operation mode */
302 hdma->Mode = hdma->Init.Mode;
303
304 /* Update the DMA channel error code */
305 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
306
307 /* Update the DMA channel state */
308 hdma->State = HAL_DMA_STATE_READY;
309
310 return HAL_OK;
311 }
312
313 /**
314 * @brief DeInitialize the DMA channel when it is configured in normal mode.
315 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
316 * specified DMA Channel.
317 * @retval HAL status.
318 */
HAL_DMA_DeInit(DMA_HandleTypeDef * const hdma)319 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *const hdma)
320 {
321
322 DMA_TypeDef *p_dma_instance;
323
324 uint32_t tickstart = HAL_GetTick();
325
326 /* Check the DMA peripheral handle parameter */
327 if (hdma == NULL)
328 {
329 return HAL_ERROR;
330 }
331
332 /* Check the parameters */
333 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
334
335 /* Get DMA instance */
336 p_dma_instance = GET_DMA_INSTANCE(hdma);
337
338 /* Disable the selected DMA Channel */
339 __HAL_DMA_DISABLE(hdma);
340
341 /* Check if the DMA channel is effectively disabled */
342 while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
343 {
344 /* Check for the Timeout */
345 if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
346 {
347 /* Update the DMA channel error code */
348 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
349
350 /* Update the DMA channel state */
351 hdma->State = HAL_DMA_STATE_ERROR;
352
353 return HAL_ERROR;
354 }
355 }
356
357 /* Reset DMA Channel registers */
358 hdma->Instance->CLBAR = 0U;
359 hdma->Instance->CCR = 0U;
360 hdma->Instance->CTR1 = 0U;
361 hdma->Instance->CTR2 = 0U;
362 hdma->Instance->CBR1 = 0U;
363 hdma->Instance->CSAR = 0U;
364 hdma->Instance->CDAR = 0U;
365 hdma->Instance->CLLR = 0U;
366
367 /* Reset 2D Addressing registers */
368 if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U)
369 {
370 hdma->Instance->CTR3 = 0U;
371 hdma->Instance->CBR2 = 0U;
372 }
373
374 /* Clear privilege attribute */
375 CLEAR_BIT(p_dma_instance->PRIVCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU)));
376
377 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
378 /* Clear secure attribute */
379 CLEAR_BIT(p_dma_instance->SECCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU)));
380 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
381
382 /* Clear all flags */
383 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
384 DMA_FLAG_TO));
385
386 /* Clean all callbacks */
387 hdma->XferCpltCallback = NULL;
388 hdma->XferHalfCpltCallback = NULL;
389 hdma->XferErrorCallback = NULL;
390 hdma->XferAbortCallback = NULL;
391 hdma->XferSuspendCallback = NULL;
392
393 /* Clean DMA queue */
394 hdma->LinkedListQueue = NULL;
395
396 /* Clean DMA parent */
397 if (hdma->Parent != NULL)
398 {
399 hdma->Parent = NULL;
400 }
401
402 /* Update DMA channel operation mode */
403 hdma->Mode = DMA_NORMAL;
404
405 /* Update the DMA channel error code */
406 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
407
408 /* Update the DMA channel state */
409 hdma->State = HAL_DMA_STATE_RESET;
410
411 /* Release Lock */
412 __HAL_UNLOCK(hdma);
413
414 return HAL_OK;
415 }
416 /**
417 * @}
418 */
419
420 /** @addtogroup DMA_Exported_Functions_Group2
421 *
422 @verbatim
423 ======================================================================================================================
424 ##### IO operation functions #####
425 ======================================================================================================================
426 [..]
427 This section provides functions allowing to :
428 (+) Configure the source, destination address and data size and Start DMA transfer in normal mode
429 (+) Abort DMA transfer
430 (+) Poll for transfer complete
431 (+) Handle DMA interrupt request
432 (+) Register and Unregister DMA callbacks
433
434 [..]
435 (+) The HAL_DMA_Start() function allows to start the DMA channel transfer in normal mode (Blocking mode).
436 (+) The HAL_DMA_Start_IT() function allows to start the DMA channel transfer in normal mode (Non-blocking mode).
437 (+) The HAL_DMA_Abort() function allows to abort any on-going transfer (Blocking mode).
438 (+) The HAL_DMA_Abort_IT() function allows to abort any on-going transfer (Non-blocking mode).
439 (+) The HAL_DMA_PollForTransfer() function allows to poll on half transfer and transfer complete (Blocking mode).
440 This API cannot be used for circular transfers.
441 (+) The HAL_DMA_IRQHandler() function allows to handle any DMA channel interrupt (Non-blocking mode).
442 (+) The HAL_DMA_RegisterCallback() and HAL_DMA_UnRegisterCallback() functions allow respectively to register and
443 unregister user customized callbacks.
444 User callbacks are called under HAL_DMA_IRQHandler().
445
446 @endverbatim
447 * @{
448 */
449
450 /**
451 * @brief Start the DMA channel transfer in normal mode (Blocking mode).
452 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
453 * the specified DMA Channel.
454 * @param SrcAddress : The source data address.
455 * @param DstAddress : The destination data address.
456 * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
457 * @retval HAL status.
458 */
HAL_DMA_Start(DMA_HandleTypeDef * const hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SrcDataSize)459 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *const hdma,
460 uint32_t SrcAddress,
461 uint32_t DstAddress,
462 uint32_t SrcDataSize)
463 {
464 /* Check the DMA peripheral handle parameter */
465 if (hdma == NULL)
466 {
467 return HAL_ERROR;
468 }
469
470 /* Check the parameters */
471 assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
472
473 /* Process locked */
474 __HAL_LOCK(hdma);
475
476 /* Check DMA channel state */
477 if (hdma->State == HAL_DMA_STATE_READY)
478 {
479 /* Update the DMA channel state */
480 hdma->State = HAL_DMA_STATE_BUSY;
481
482 /* Update the DMA channel error code */
483 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
484
485 /* Configure the source address, destination address, the data size and clear flags */
486 DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize);
487
488 /* Enable DMA channel */
489 __HAL_DMA_ENABLE(hdma);
490 }
491 else
492 {
493 /* Update the DMA channel error code */
494 hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
495
496 /* Process unlocked */
497 __HAL_UNLOCK(hdma);
498
499 return HAL_ERROR;
500 }
501
502 return HAL_OK;
503 }
504
505 /**
506 * @brief Starts the DMA channel transfer in normal mode with interrupts enabled (Non-blocking mode).
507 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
508 * specified DMA Channel.
509 * @param SrcAddress : The source data address.
510 * @param DstAddress : The destination data address.
511 * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
512 * @retval HAL status.
513 */
HAL_DMA_Start_IT(DMA_HandleTypeDef * const hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SrcDataSize)514 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *const hdma,
515 uint32_t SrcAddress,
516 uint32_t DstAddress,
517 uint32_t SrcDataSize)
518 {
519 /* Check the DMA peripheral handle parameter */
520 if (hdma == NULL)
521 {
522 return HAL_ERROR;
523 }
524
525 /* Check the parameters */
526 assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
527
528 /* Process locked */
529 __HAL_LOCK(hdma);
530
531 /* Check DMA channel state */
532 if (hdma->State == HAL_DMA_STATE_READY)
533 {
534 /* Update the DMA channel state */
535 hdma->State = HAL_DMA_STATE_BUSY;
536
537 /* Update the DMA channel error code */
538 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
539
540 /* Configure the source address, destination address, the data size and clear flags */
541 DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize);
542
543 /* Enable common interrupts: Transfer Complete and Transfer Errors ITs */
544 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_DTE | DMA_IT_ULE | DMA_IT_USE | DMA_IT_TO));
545
546 /* Check half transfer complete callback */
547 if (hdma->XferHalfCpltCallback != NULL)
548 {
549 /* If Half Transfer complete callback is set, enable the corresponding IT */
550 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
551 }
552
553 /* Check Half suspend callback */
554 if (hdma->XferSuspendCallback != NULL)
555 {
556 /* If Transfer suspend callback is set, enable the corresponding IT */
557 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_SUSP);
558 }
559
560 /* Enable DMA channel */
561 __HAL_DMA_ENABLE(hdma);
562 }
563 else
564 {
565 /* Update the DMA channel error code */
566 hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
567
568 /* Process unlocked */
569 __HAL_UNLOCK(hdma);
570
571 return HAL_ERROR;
572 }
573
574 return HAL_OK;
575 }
576
577 /**
578 * @brief Abort any on-going DMA channel transfer (Blocking mode).
579 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
580 * specified DMA Channel.
581 * @note After suspending a DMA channel, a wait until the DMA channel is effectively stopped is added. If a channel
582 * is suspended while a data transfer is on-going, the current data will be transferred and the channel will be
583 * effectively suspended only after the transfer of any on-going data is finished.
584 * @retval HAL status.
585 */
HAL_DMA_Abort(DMA_HandleTypeDef * const hdma)586 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *const hdma)
587 {
588 /* Get tick number */
589 uint32_t tickstart = HAL_GetTick();
590
591 /* Check the DMA peripheral handle parameter */
592 if (hdma == NULL)
593 {
594 return HAL_ERROR;
595 }
596
597 /* Check DMA channel state */
598 if (hdma->State != HAL_DMA_STATE_BUSY)
599 {
600 /* Update the DMA channel error code */
601 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
602
603 /* Process Unlocked */
604 __HAL_UNLOCK(hdma);
605
606 return HAL_ERROR;
607 }
608 else
609 {
610 /* Suspend the channel */
611 hdma->Instance->CCR |= DMA_CCR_SUSP;
612
613 /* Update the DMA channel state */
614 hdma->State = HAL_DMA_STATE_SUSPEND;
615
616 /* Check if the DMA Channel is suspended */
617 while ((hdma->Instance->CSR & DMA_CSR_SUSPF) == 0U)
618 {
619 /* Check for the Timeout */
620 if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
621 {
622 /* Update the DMA channel error code */
623 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
624
625 /* Update the DMA channel state */
626 hdma->State = HAL_DMA_STATE_ERROR;
627
628 /* Check DMA channel transfer mode */
629 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
630 {
631 /* Update the linked-list queue state */
632 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
633 }
634
635 /* Process Unlocked */
636 __HAL_UNLOCK(hdma);
637
638 return HAL_ERROR;
639 }
640 }
641
642 /* Reset the channel */
643 hdma->Instance->CCR |= DMA_CCR_RESET;
644
645 /* Update the DMA channel state */
646 hdma->State = HAL_DMA_STATE_ABORT;
647
648 /* Clear all status flags */
649 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
650 DMA_FLAG_TO));
651
652 /* Update the DMA channel state */
653 hdma->State = HAL_DMA_STATE_READY;
654
655 /* Check DMA channel transfer mode */
656 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
657 {
658 /* Update the linked-list queue state */
659 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
660
661 /* Clear remaining data size to ensure loading linked-list from memory next start */
662 hdma->Instance->CBR1 = 0U;
663 }
664
665 /* Process Unlocked */
666 __HAL_UNLOCK(hdma);
667 }
668
669 return HAL_OK;
670 }
671
672 /**
673 * @brief Abort any on-going DMA channel transfer in interrupt mode (Non-blocking mode).
674 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
675 * specified DMA Channel.
676 * @retval HAL status.
677 */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * const hdma)678 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *const hdma)
679 {
680 /* Check the DMA peripheral handle parameter */
681 if (hdma == NULL)
682 {
683 return HAL_ERROR;
684 }
685
686 /* Check DMA channel state */
687 if (hdma->State != HAL_DMA_STATE_BUSY)
688 {
689 /* Update the DMA channel error code */
690 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
691
692 return HAL_ERROR;
693 }
694 else
695 {
696 /* Update the DMA channel state */
697 hdma->State = HAL_DMA_STATE_ABORT;
698
699 /* Suspend the channel and activate suspend interrupt */
700 hdma->Instance->CCR |= (DMA_CCR_SUSP | DMA_CCR_SUSPIE);
701 }
702
703 return HAL_OK;
704 }
705
706 /**
707 * @brief Polling for transfer status (Blocking mode).
708 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
709 * specified DMA Channel.
710 * @param CompleteLevel : Specifies the DMA level complete.
711 * @param Timeout : Timeout duration.
712 * @retval HAL status
713 */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * const hdma,HAL_DMA_LevelCompleteTypeDef CompleteLevel,uint32_t Timeout)714 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *const hdma,
715 HAL_DMA_LevelCompleteTypeDef CompleteLevel,
716 uint32_t Timeout)
717 {
718 /* Get tick number */
719 uint32_t tickstart = HAL_GetTick();
720 uint32_t level_flag;
721 uint32_t tmp_csr;
722
723 /* Check the DMA peripheral handle parameter */
724 if (hdma == NULL)
725 {
726 return HAL_ERROR;
727 }
728
729 /* Check the parameters */
730 assert_param(IS_DMA_LEVEL_COMPLETE(CompleteLevel));
731
732 /* Check DMA channel state */
733 if (hdma->State != HAL_DMA_STATE_BUSY)
734 {
735 /* Update the DMA channel error code */
736 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
737
738 /* Process Unlocked */
739 __HAL_UNLOCK(hdma);
740
741 return HAL_ERROR;
742 }
743
744 /* Polling mode is not supported in circular mode */
745 if ((hdma->Mode & DMA_LINKEDLIST_CIRCULAR) == DMA_LINKEDLIST_CIRCULAR)
746 {
747 /* Update the DMA channel error code */
748 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
749
750 return HAL_ERROR;
751 }
752
753 /* Get the level transfer complete flag */
754 level_flag = ((CompleteLevel == HAL_DMA_FULL_TRANSFER) ? DMA_FLAG_IDLE : DMA_FLAG_HT);
755
756 /* Get DMA channel status */
757 tmp_csr = hdma->Instance->CSR;
758
759 while ((tmp_csr & level_flag) == 0U)
760 {
761 /* Check for the timeout */
762 if (Timeout != HAL_MAX_DELAY)
763 {
764 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
765 {
766 /* Update the DMA channel error code */
767 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
768
769 /*
770 If timeout, abort the current transfer.
771 Note that the Abort function will
772 - Clear all transfer flags.
773 - Unlock.
774 - Set the State.
775 */
776 (void)HAL_DMA_Abort(hdma);
777
778 return HAL_ERROR;
779 }
780 }
781
782 /* Get a newer CSR register value */
783 tmp_csr = hdma->Instance->CSR;
784 }
785
786 /* Check trigger overrun flag */
787 if ((tmp_csr & DMA_FLAG_TO) != 0U)
788 {
789 /* Update the DMA channel error code */
790 hdma->ErrorCode |= HAL_DMA_ERROR_TO;
791
792 /* Clear the error flag */
793 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
794 }
795
796 /* Check error flags */
797 if ((tmp_csr & (DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE)) != 0U)
798 {
799 /* Check the data transfer error flag */
800 if ((tmp_csr & DMA_FLAG_DTE) != 0U)
801 {
802 /* Update the DMA channel error code */
803 hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
804
805 /* Clear the error flag */
806 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
807 }
808
809 /* Check the update link error flag */
810 if ((tmp_csr & DMA_FLAG_ULE) != 0U)
811 {
812 /* Update the DMA channel error code */
813 hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
814
815 /* Clear the error flag */
816 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
817 }
818
819 /* Check the user setting error flag */
820 if ((tmp_csr & DMA_FLAG_USE) != 0U)
821 {
822 /* Update the DMA channel error code */
823 hdma->ErrorCode |= HAL_DMA_ERROR_USE;
824
825 /* Clear the error flag */
826 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
827 }
828
829 /* Reset the channel */
830 hdma->Instance->CCR |= DMA_CCR_RESET;
831
832 /* Update the DMA channel state */
833 hdma->State = HAL_DMA_STATE_READY;
834
835 /* Check DMA channel transfer mode */
836 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
837 {
838 /* Update the linked-list queue state */
839 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
840 }
841
842 /* Process Unlocked */
843 __HAL_UNLOCK(hdma);
844
845 return HAL_ERROR;
846 }
847
848 /* Clear the transfer level flag */
849 if (CompleteLevel == HAL_DMA_HALF_TRANSFER)
850 {
851 /* Clear the Half Transfer flag */
852 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
853 }
854 else if (CompleteLevel == HAL_DMA_FULL_TRANSFER)
855 {
856 /* Clear the transfer flags */
857 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
858
859 /* Update the DMA channel state */
860 hdma->State = HAL_DMA_STATE_READY;
861
862 /* Check DMA channel transfer mode */
863 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
864 {
865 /* Update the linked-list queue state */
866 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
867 }
868
869 /* Process unlocked */
870 __HAL_UNLOCK(hdma);
871 }
872 else
873 {
874 return HAL_ERROR;
875 }
876
877 return HAL_OK;
878 }
879
880 /**
881 * @brief Handle DMA interrupt request (Non-blocking mode).
882 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
883 * specified DMA Channel.
884 * @retval None.
885 */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * const hdma)886 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
887 {
888 const DMA_TypeDef *p_dma_instance = GET_DMA_INSTANCE(hdma);
889 uint32_t global_it_flag = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
890 uint32_t global_active_flag_ns = IS_DMA_GLOBAL_ACTIVE_FLAG_NS(p_dma_instance, global_it_flag);
891 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
892 uint32_t global_active_flag_s = IS_DMA_GLOBAL_ACTIVE_FLAG_S(p_dma_instance, global_it_flag);
893 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
894
895 /* Global Interrupt Flag management *********************************************************************************/
896 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
897 if ((global_active_flag_s == 0U) && (global_active_flag_ns == 0U))
898 #else
899 if (global_active_flag_ns == 0U)
900 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
901 {
902 return; /* the global interrupt flag for the current channel is down , nothing to do */
903 }
904
905 /* Data Transfer Error Interrupt management *************************************************************************/
906 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_DTE) != 0U))
907 {
908 /* Check if interrupt source is enabled */
909 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DTE) != 0U)
910 {
911 /* Clear the transfer error flag */
912 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
913
914 /* Update the DMA channel error code */
915 hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
916 }
917 }
918
919 /* Update Linked-list Error Interrupt management ********************************************************************/
920 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_ULE) != 0U))
921 {
922 /* Check if interrupt source is enabled */
923 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_ULE) != 0U)
924 {
925 /* Clear the update linked-list error flag */
926 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
927
928 /* Update the DMA channel error code */
929 hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
930 }
931 }
932
933 /* User Setting Error Interrupt management **************************************************************************/
934 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_USE) != 0U))
935 {
936 /* Check if interrupt source is enabled */
937 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_USE) != 0U)
938 {
939 /* Clear the user setting error flag */
940 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
941
942 /* Update the DMA channel error code */
943 hdma->ErrorCode |= HAL_DMA_ERROR_USE;
944 }
945 }
946
947 /* Trigger Overrun Interrupt management *****************************************************************************/
948 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TO) != 0U))
949 {
950 /* Check if interrupt source is enabled */
951 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TO) != 0U)
952 {
953 /* Clear the trigger overrun flag */
954 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
955
956 /* Update the DMA channel error code */
957 hdma->ErrorCode |= HAL_DMA_ERROR_TO;
958 }
959 }
960
961 /* Half Transfer Complete Interrupt management **********************************************************************/
962 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_HT) != 0U))
963 {
964 /* Check if interrupt source is enabled */
965 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
966 {
967 /* Clear the half transfer flag */
968 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
969
970 /* Check half transfer complete callback */
971 if (hdma->XferHalfCpltCallback != NULL)
972 {
973 /* Half transfer callback */
974 hdma->XferHalfCpltCallback(hdma);
975 }
976 }
977 }
978
979 /* Suspend Transfer Interrupt management ****************************************************************************/
980 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_SUSP) != 0U))
981 {
982 /* Check if interrupt source is enabled */
983 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_SUSP) != 0U)
984 {
985 /* Clear the block transfer complete flag */
986 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_SUSP);
987
988 /* Check DMA channel state */
989 if (hdma->State == HAL_DMA_STATE_ABORT)
990 {
991 /* Disable the suspend transfer interrupt */
992 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_SUSP);
993
994 /* Reset the channel internal state and reset the FIFO */
995 hdma->Instance->CCR |= DMA_CCR_RESET;
996
997 /* Update the DMA channel state */
998 hdma->State = HAL_DMA_STATE_READY;
999
1000 /* Check DMA channel transfer mode */
1001 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1002 {
1003 /* Update the linked-list queue state */
1004 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1005
1006 /* Clear remaining data size to ensure loading linked-list from memory next start */
1007 hdma->Instance->CBR1 = 0U;
1008 }
1009
1010 /* Process Unlocked */
1011 __HAL_UNLOCK(hdma);
1012
1013 /* Check transfer abort callback */
1014 if (hdma->XferAbortCallback != NULL)
1015 {
1016 /* Transfer abort callback */
1017 hdma->XferAbortCallback(hdma);
1018 }
1019
1020 return;
1021 }
1022 else
1023 {
1024 /* Update the DMA channel state */
1025 hdma->State = HAL_DMA_STATE_SUSPEND;
1026
1027 /* Check transfer suspend callback */
1028 if (hdma->XferSuspendCallback != NULL)
1029 {
1030 /* Transfer suspend callback */
1031 hdma->XferSuspendCallback(hdma);
1032 }
1033 }
1034 }
1035 }
1036
1037 /* Transfer Complete Interrupt management ***************************************************************************/
1038 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U))
1039 {
1040 /* Check if interrupt source is enabled */
1041 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
1042 {
1043 /* Check DMA channel transfer mode */
1044 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1045 {
1046 /* If linked-list transfer */
1047 if (hdma->Instance->CLLR == 0U)
1048 {
1049 if (hdma->Instance->CBR1 == 0U)
1050 {
1051 /* Update the DMA channel state */
1052 hdma->State = HAL_DMA_STATE_READY;
1053
1054 /* Update the linked-list queue state */
1055 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1056 }
1057 }
1058 }
1059 else
1060 {
1061 /* If normal transfer */
1062 if (hdma->Instance->CBR1 == 0U)
1063 {
1064 /* Update the DMA channel state */
1065 hdma->State = HAL_DMA_STATE_READY;
1066 }
1067 }
1068
1069 /* Clear TC and HT transfer flags */
1070 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
1071
1072 /* Process Unlocked */
1073 __HAL_UNLOCK(hdma);
1074
1075 /* Check transfer complete callback */
1076 if (hdma->XferCpltCallback != NULL)
1077 {
1078 /* Channel Transfer Complete callback */
1079 hdma->XferCpltCallback(hdma);
1080 }
1081 }
1082 }
1083
1084 /* Manage error case ************************************************************************************************/
1085 if (hdma->ErrorCode != HAL_DMA_ERROR_NONE)
1086 {
1087 /* Reset the channel internal state and reset the FIFO */
1088 hdma->Instance->CCR |= DMA_CCR_RESET;
1089
1090 /* Update the DMA channel state */
1091 hdma->State = HAL_DMA_STATE_READY;
1092
1093 /* Check DMA channel transfer mode */
1094 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1095 {
1096 /* Update the linked-list queue state */
1097 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1098 }
1099
1100 /* Process Unlocked */
1101 __HAL_UNLOCK(hdma);
1102
1103 /* Check transfer error callback */
1104 if (hdma->XferErrorCallback != NULL)
1105 {
1106 /* Transfer error callback */
1107 hdma->XferErrorCallback(hdma);
1108 }
1109 }
1110 }
1111
1112 /**
1113 * @brief Register callback according to specified ID.
1114 * @note The HAL_DMA_RegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
1115 * to register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
1116 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1117 * specified DMA Channel.
1118 * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enumeration.
1119 * @param pCallback : Pointer to private callback function.
1120 * @retval HAL status.
1121 */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * const hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* const pCallback)(DMA_HandleTypeDef * const _hdma))1122 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *const hdma,
1123 HAL_DMA_CallbackIDTypeDef CallbackID,
1124 void (*const pCallback)(DMA_HandleTypeDef *const _hdma))
1125 {
1126 HAL_StatusTypeDef status = HAL_OK;
1127
1128 /* Check the DMA peripheral handle parameter */
1129 if (hdma == NULL)
1130 {
1131 return HAL_ERROR;
1132 }
1133
1134 /* Check DMA channel state */
1135 if (hdma->State == HAL_DMA_STATE_READY)
1136 {
1137 /* Check callback ID */
1138 switch (CallbackID)
1139 {
1140 case HAL_DMA_XFER_CPLT_CB_ID:
1141 {
1142 /* Register transfer complete callback */
1143 hdma->XferCpltCallback = pCallback;
1144 break;
1145 }
1146
1147 case HAL_DMA_XFER_HALFCPLT_CB_ID:
1148 {
1149 /* Register half transfer callback */
1150 hdma->XferHalfCpltCallback = pCallback;
1151 break;
1152 }
1153
1154 case HAL_DMA_XFER_ERROR_CB_ID:
1155 {
1156 /* Register transfer error callback */
1157 hdma->XferErrorCallback = pCallback;
1158 break;
1159 }
1160
1161 case HAL_DMA_XFER_ABORT_CB_ID:
1162 {
1163 /* Register abort callback */
1164 hdma->XferAbortCallback = pCallback;
1165 break;
1166 }
1167
1168 case HAL_DMA_XFER_SUSPEND_CB_ID:
1169 {
1170 /* Register suspend callback */
1171 hdma->XferSuspendCallback = pCallback;
1172 break;
1173 }
1174
1175 default:
1176 {
1177 /* Update error status */
1178 status = HAL_ERROR;
1179 break;
1180 }
1181 }
1182 }
1183 else
1184 {
1185 /* Update error status */
1186 status = HAL_ERROR;
1187 }
1188
1189 return status;
1190 }
1191
1192 /**
1193 * @brief Unregister callback according to specified ID.
1194 * @note The HAL_DMA_UnRegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
1195 * to un-register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
1196 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1197 * specified DMA Channel.
1198 * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enum.
1199 * @retval HAL status.
1200 */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * const hdma,HAL_DMA_CallbackIDTypeDef CallbackID)1201 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *const hdma,
1202 HAL_DMA_CallbackIDTypeDef CallbackID)
1203 {
1204 HAL_StatusTypeDef status = HAL_OK;
1205
1206 /* Check the DMA peripheral handle parameter */
1207 if (hdma == NULL)
1208 {
1209 return HAL_ERROR;
1210 }
1211
1212 /* Check DMA channel state */
1213 if (hdma->State == HAL_DMA_STATE_READY)
1214 {
1215 /* Check callback ID */
1216 switch (CallbackID)
1217 {
1218 case HAL_DMA_XFER_CPLT_CB_ID:
1219 {
1220 /* UnRegister transfer complete callback */
1221 hdma->XferCpltCallback = NULL;
1222 break;
1223 }
1224
1225 case HAL_DMA_XFER_HALFCPLT_CB_ID:
1226 {
1227 /* UnRegister half transfer callback */
1228 hdma->XferHalfCpltCallback = NULL;
1229 break;
1230 }
1231
1232 case HAL_DMA_XFER_ERROR_CB_ID:
1233 {
1234 /* UnRegister transfer error callback */
1235 hdma->XferErrorCallback = NULL;
1236 break;
1237 }
1238
1239 case HAL_DMA_XFER_ABORT_CB_ID:
1240 {
1241 /* UnRegister abort callback */
1242 hdma->XferAbortCallback = NULL;
1243 break;
1244 }
1245
1246 case HAL_DMA_XFER_SUSPEND_CB_ID:
1247 {
1248 /* UnRegister suspend callback */
1249 hdma->XferSuspendCallback = NULL;
1250 break;
1251 }
1252
1253 case HAL_DMA_XFER_ALL_CB_ID:
1254 {
1255 /* UnRegister all available callbacks */
1256 hdma->XferCpltCallback = NULL;
1257 hdma->XferHalfCpltCallback = NULL;
1258 hdma->XferErrorCallback = NULL;
1259 hdma->XferAbortCallback = NULL;
1260 hdma->XferSuspendCallback = NULL;
1261 break;
1262 }
1263
1264 default:
1265 {
1266 /* Update error status */
1267 status = HAL_ERROR;
1268 break;
1269 }
1270 }
1271 }
1272 else
1273 {
1274 /* Update error status */
1275 status = HAL_ERROR;
1276 }
1277
1278 return status;
1279 }
1280 /**
1281 * @}
1282 */
1283
1284 /** @addtogroup DMA_Exported_Functions_Group3
1285 *
1286 @verbatim
1287 ======================================================================================================================
1288 ##### State and Errors functions #####
1289 ======================================================================================================================
1290 [..]
1291 This section provides functions allowing to :
1292 (+) Check the DMA state
1293 (+) Get error code
1294
1295 [..]
1296 (+) The HAL_DMA_GetState() function allows to get the DMA channel state.
1297 (+) The HAL_DMA_DeInit() function allows to get the DMA channel error code.
1298
1299 @endverbatim
1300 * @{
1301 */
1302
1303 /**
1304 * @brief Returns the DMA channel state.
1305 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1306 * specified DMA Channel.
1307 * @retval DMA state.
1308 */
HAL_DMA_GetState(DMA_HandleTypeDef const * const hdma)1309 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef const *const hdma)
1310 {
1311 /* Return the DMA channel state */
1312 return hdma->State;
1313 }
1314
1315 /**
1316 * @brief Return the DMA channel error code.
1317 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1318 * specified DMA Channel.
1319 * @retval DMA Error Code.
1320 */
HAL_DMA_GetError(DMA_HandleTypeDef const * const hdma)1321 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef const *const hdma)
1322 {
1323 /* Return the DMA channel error code */
1324 return hdma->ErrorCode;
1325 }
1326 /**
1327 * @}
1328 */
1329
1330 /** @addtogroup DMA_Exported_Functions_Group4
1331 *
1332 @verbatim
1333 ======================================================================================================================
1334 ##### DMA Attributes functions #####
1335 ======================================================================================================================
1336 [..]
1337 This section provides functions allowing to :
1338 (+) Configure DMA channel secure and privilege attributes.
1339 (+) Get DMA channel secure and privilege attributes.
1340 (+) Lock DMA channel secure and privilege attributes configuration.
1341 (+) Check whether DMA channel secure and privilege attributes configuration is locked or not.
1342
1343 [..]
1344 (+) The HAL_DMA_ConfigChannelAttributes() function allows to configure DMA channel security and privilege
1345 attributes.
1346 (+) The HAL_DMA_GetConfigChannelAttributes() function allows to get DMA channel security and privilege attributes
1347 configuration.
1348 (+) The HAL_DMA_LockChannelAttributes() function allows to lock the DMA channel security and privilege attributes.
1349 (+) The HAL_DMA_GetLockChannelAttributes() function allows to get the DMA channel security and privilege
1350 attributes lock status.
1351
1352 @endverbatim
1353 * @{
1354 */
1355
1356 /**
1357 * @brief Configure the DMA channel security and privilege attribute(s).
1358 * @note These attributes cannot be modified when the corresponding lock state is enabled.
1359 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
1360 * the specified DMA Channel.
1361 * @param ChannelAttributes : Specifies the DMA channel secure/privilege attributes.
1362 * This parameter can be a one or a combination of @ref DMA_Channel_Attributes.
1363 * @retval HAL Status.
1364 */
HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef * const hdma,uint32_t ChannelAttributes)1365 HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *const hdma, uint32_t ChannelAttributes)
1366 {
1367 DMA_TypeDef *p_dma_instance;
1368 uint32_t channel_idx;
1369
1370 /* Check the DMA peripheral handle parameter */
1371 if (hdma == NULL)
1372 {
1373 return HAL_ERROR;
1374 }
1375
1376 /* Check the parameters */
1377 assert_param(IS_DMA_ATTRIBUTES(ChannelAttributes));
1378
1379 /* Get DMA instance */
1380 p_dma_instance = GET_DMA_INSTANCE(hdma);
1381
1382 /* Get channel index */
1383 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1384
1385 /* Check DMA channel privilege attribute management */
1386 if ((ChannelAttributes & DMA_CHANNEL_ATTR_PRIV_MASK) == DMA_CHANNEL_ATTR_PRIV_MASK)
1387 {
1388 /* Configure DMA channel privilege attribute */
1389 if ((ChannelAttributes & DMA_CHANNEL_PRIV) == DMA_CHANNEL_PRIV)
1390 {
1391 p_dma_instance->PRIVCFGR |= channel_idx;
1392 }
1393 else
1394 {
1395 p_dma_instance->PRIVCFGR &= (~channel_idx);
1396 }
1397 }
1398
1399 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1400 /* Check DMA channel security attribute management */
1401 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_MASK) == DMA_CHANNEL_ATTR_SEC_MASK)
1402 {
1403 /* Configure DMA channel security attribute */
1404 if ((ChannelAttributes & DMA_CHANNEL_SEC) == DMA_CHANNEL_SEC)
1405 {
1406 p_dma_instance->SECCFGR |= channel_idx;
1407 }
1408 else
1409 {
1410 p_dma_instance->SECCFGR &= (~channel_idx);
1411 }
1412 }
1413
1414 /* Channel source security attribute management */
1415 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_SRC_MASK) == DMA_CHANNEL_ATTR_SEC_SRC_MASK)
1416 {
1417 /* Configure DMA channel source security attribute */
1418 if ((ChannelAttributes & DMA_CHANNEL_SRC_SEC) == DMA_CHANNEL_SRC_SEC)
1419 {
1420 hdma->Instance->CTR1 |= DMA_CTR1_SSEC;
1421 }
1422 else
1423 {
1424 hdma->Instance->CTR1 &= (~DMA_CTR1_SSEC);
1425 }
1426 }
1427
1428 /* Channel destination security attribute management */
1429 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_DEST_MASK) == DMA_CHANNEL_ATTR_SEC_DEST_MASK)
1430 {
1431 /* Configure DMA channel destination security attribute */
1432 if ((ChannelAttributes & DMA_CHANNEL_DEST_SEC) == DMA_CHANNEL_DEST_SEC)
1433 {
1434 hdma->Instance->CTR1 |= DMA_CTR1_DSEC;
1435 }
1436 else
1437 {
1438 hdma->Instance->CTR1 &= (~DMA_CTR1_DSEC);
1439 }
1440 }
1441 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
1442
1443 return HAL_OK;
1444 }
1445
1446 /**
1447 * @brief Get the DMA channel security and privilege attributes.
1448 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information
1449 * for the specified DMA Channel.
1450 * @param pChannelAttributes : Pointer to the returned attributes.
1451 * @retval HAL Status.
1452 */
HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const * const hdma,uint32_t * const pChannelAttributes)1453 HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const *const hdma,
1454 uint32_t *const pChannelAttributes)
1455 {
1456 const DMA_TypeDef *p_dma_instance;
1457 uint32_t attributes;
1458 uint32_t channel_idx;
1459
1460 /* Check the DMA peripheral handle and channel attributes parameters */
1461 if ((hdma == NULL) || (pChannelAttributes == NULL))
1462 {
1463 return HAL_ERROR;
1464 }
1465
1466 /* Get DMA instance */
1467 p_dma_instance = GET_DMA_INSTANCE(hdma);
1468
1469 /* Get channel index */
1470 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1471
1472 /* Get DMA channel privilege attribute */
1473 attributes = ((p_dma_instance->PRIVCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
1474
1475 /* Get DMA channel security attribute */
1476 attributes |= ((p_dma_instance->SECCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC;
1477
1478 /* Get DMA channel source security attribute */
1479 attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_SSEC) == 0U) ? DMA_CHANNEL_SRC_NSEC : DMA_CHANNEL_SRC_SEC;
1480
1481 /* Get DMA channel destination security attribute */
1482 attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_DSEC) == 0U) ? DMA_CHANNEL_DEST_NSEC : DMA_CHANNEL_DEST_SEC;
1483
1484 /* return value */
1485 *pChannelAttributes = attributes;
1486
1487 return HAL_OK;
1488 }
1489
1490
1491 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1492 /**
1493 * @brief Lock the DMA channel security and privilege attribute(s).
1494 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1495 * specified DMA Channel.
1496 * @retval HAL Status.
1497 */
HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const * const hdma)1498 HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const hdma)
1499 {
1500 DMA_TypeDef *p_dma_instance;
1501 uint32_t channel_idx;
1502
1503 /* Check the DMA peripheral handle parameter */
1504 if (hdma == NULL)
1505 {
1506 return HAL_ERROR;
1507 }
1508
1509 /* Get DMA instance */
1510 p_dma_instance = GET_DMA_INSTANCE(hdma);
1511
1512 /* Get channel index */
1513 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1514
1515 /* Lock the DMA channel privilege and security attributes */
1516 p_dma_instance->RCFGLOCKR |= channel_idx;
1517
1518 return HAL_OK;
1519 }
1520 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
1521
1522 /**
1523 * @brief Get the security and privilege attribute lock state of a DMA channel.
1524 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1525 * specified DMA Channel.
1526 * @param pLockState : Pointer to lock state (returned value can be DMA_CHANNEL_ATTRIBUTE_UNLOCKED or
1527 * DMA_CHANNEL_ATTRIBUTE_LOCKED).
1528 * @retval HAL status.
1529 */
HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const * const hdma,uint32_t * const pLockState)1530 HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, uint32_t *const pLockState)
1531 {
1532 DMA_TypeDef *p_dma_instance;
1533 uint32_t channel_idx;
1534
1535 /* Check the DMA peripheral handle and lock state parameters */
1536 if ((hdma == NULL) || (pLockState == NULL))
1537 {
1538 return HAL_ERROR;
1539 }
1540
1541 /* Get DMA instance */
1542 p_dma_instance = GET_DMA_INSTANCE(hdma);
1543
1544 /* Get channel index */
1545 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1546
1547 /* Get channel lock attribute state */
1548 *pLockState = ((p_dma_instance->RCFGLOCKR & channel_idx) == 0U) ? DMA_CHANNEL_ATTRIBUTE_UNLOCKED : \
1549 DMA_CHANNEL_ATTRIBUTE_LOCKED;
1550
1551 return HAL_OK;
1552 }
1553 /**
1554 * @}
1555 */
1556
1557 /**
1558 * @}
1559 */
1560
1561
1562 /* Private functions -------------------------------------------------------------------------------------------------*/
1563 /** @defgroup DMA_Private_Functions DMA Private Functions
1564 * @brief DMA Private Functions
1565 * @{
1566 */
1567
1568 /**
1569 * @brief Set the DMA channel normal transfer parameters.
1570 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1571 * specified DMA Channel.
1572 * @param SrcAddress : The source data address.
1573 * @param DstAddress : The destination data address.
1574 * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
1575 * @retval None.
1576 */
DMA_SetConfig(DMA_HandleTypeDef const * const hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SrcDataSize)1577 static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
1578 uint32_t SrcAddress,
1579 uint32_t DstAddress,
1580 uint32_t SrcDataSize)
1581 {
1582 /* Configure the DMA channel data size */
1583 MODIFY_REG(hdma->Instance->CBR1, DMA_CBR1_BNDT, (SrcDataSize & DMA_CBR1_BNDT));
1584
1585 /* Clear all interrupt flags */
1586 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
1587 DMA_FLAG_TO);
1588
1589 /* Configure DMA channel source address */
1590 hdma->Instance->CSAR = SrcAddress;
1591
1592 /* Configure DMA channel destination address */
1593 hdma->Instance->CDAR = DstAddress;
1594 }
1595
1596 /**
1597 * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef.
1598 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1599 * specified DMA Channel.
1600 * @retval None.
1601 */
DMA_Init(DMA_HandleTypeDef const * const hdma)1602 static void DMA_Init(DMA_HandleTypeDef const *const hdma)
1603 {
1604 uint32_t tmpreg;
1605
1606 /* Prepare DMA Channel Control Register (CCR) value *****************************************************************/
1607 tmpreg = hdma->Init.Priority;
1608
1609 /* Write DMA Channel Control Register (CCR) */
1610 MODIFY_REG(hdma->Instance->CCR, DMA_CCR_PRIO | DMA_CCR_LAP | DMA_CCR_LSM, tmpreg);
1611
1612 /* Prepare DMA Channel Transfer Register (CTR1) value ***************************************************************/
1613 tmpreg = hdma->Init.DestInc | hdma->Init.DestDataWidth | hdma->Init.SrcInc | hdma->Init.SrcDataWidth;
1614
1615 /* Add parameters specific to GPDMA */
1616 if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
1617 {
1618 tmpreg |= (hdma->Init.TransferAllocatedPort |
1619 (((hdma->Init.DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1) |
1620 (((hdma->Init.SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1));
1621 }
1622
1623 /* Write DMA Channel Transfer Register 1 (CTR1) */
1624 MODIFY_REG(hdma->Instance->CTR1, ~(DMA_CTR1_SSEC | DMA_CTR1_DSEC), tmpreg);
1625
1626 /* Prepare DMA Channel Transfer Register 2 (CTR2) value *************************************************************/
1627 tmpreg = hdma->Init.BlkHWRequest | (hdma->Init.Request & DMA_CTR2_REQSEL) | hdma->Init.TransferEventMode;
1628
1629 /* Memory to Peripheral Transfer */
1630 if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1631 {
1632 if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
1633 {
1634 tmpreg |= DMA_CTR2_DREQ;
1635 }
1636 }
1637 /* Memory to Memory Transfer */
1638 else if ((hdma->Init.Direction) == DMA_MEMORY_TO_MEMORY)
1639 {
1640 tmpreg |= DMA_CTR2_SWREQ;
1641 }
1642 else
1643 {
1644 /* Nothing to do */
1645 }
1646
1647 /* Write DMA Channel Transfer Register 2 (CTR2) */
1648 MODIFY_REG(hdma->Instance->CTR2, (DMA_CTR2_TCEM | DMA_CTR2_TRIGPOL | DMA_CTR2_TRIGSEL | DMA_CTR2_TRIGM |
1649 DMA_CTR2_BREQ | DMA_CTR2_DREQ | DMA_CTR2_SWREQ | DMA_CTR2_REQSEL), tmpreg);
1650
1651
1652 /* Write DMA Channel Block Register 1 (CBR1) ************************************************************************/
1653 WRITE_REG(hdma->Instance->CBR1, 0U);
1654
1655 /* If 2D Addressing is supported by current channel */
1656 if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U)
1657 {
1658 /* Write DMA Channel Transfer Register 3 (CTR3) *******************************************************************/
1659 WRITE_REG(hdma->Instance->CTR3, 0U);
1660
1661 /* Write DMA Channel Block Register 2 (CBR2) **********************************************************************/
1662 WRITE_REG(hdma->Instance->CBR2, 0U);
1663 }
1664
1665 /* Write DMA Channel linked-list address register (CLLR) ************************************************************/
1666 WRITE_REG(hdma->Instance->CLLR, 0U);
1667 }
1668 /**
1669 * @}
1670 */
1671
1672 #endif /* HAL_DMA_MODULE_ENABLED */
1673
1674 /**
1675 * @}
1676 */
1677
1678 /**
1679 * @}
1680 */
1681