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