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 uint32_t global_active_flag_ns = IS_DMA_GLOBAL_ACTIVE_FLAG_NS(p_dma_instance, global_it_flag);
888 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
889 uint32_t global_active_flag_s = IS_DMA_GLOBAL_ACTIVE_FLAG_S(p_dma_instance, global_it_flag);
890 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
891
892 /* Global Interrupt Flag management *********************************************************************************/
893 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
894 if ((global_active_flag_s == 0U) && (global_active_flag_ns == 0U))
895 #else
896 if (global_active_flag_ns == 0U)
897 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
898 {
899 return; /* the global interrupt flag for the current channel is down , nothing to do */
900 }
901
902 /* Data Transfer Error Interrupt management *************************************************************************/
903 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_DTE) != 0U))
904 {
905 /* Check if interrupt source is enabled */
906 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DTE) != 0U)
907 {
908 /* Clear the transfer error flag */
909 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
910
911 /* Update the DMA channel error code */
912 hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
913 }
914 }
915
916 /* Update Linked-list Error Interrupt management ********************************************************************/
917 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_ULE) != 0U))
918 {
919 /* Check if interrupt source is enabled */
920 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_ULE) != 0U)
921 {
922 /* Clear the update linked-list error flag */
923 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
924
925 /* Update the DMA channel error code */
926 hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
927 }
928 }
929
930 /* User Setting Error Interrupt management **************************************************************************/
931 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_USE) != 0U))
932 {
933 /* Check if interrupt source is enabled */
934 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_USE) != 0U)
935 {
936 /* Clear the user setting error flag */
937 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
938
939 /* Update the DMA channel error code */
940 hdma->ErrorCode |= HAL_DMA_ERROR_USE;
941 }
942 }
943
944 /* Trigger Overrun Interrupt management *****************************************************************************/
945 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TO) != 0U))
946 {
947 /* Check if interrupt source is enabled */
948 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TO) != 0U)
949 {
950 /* Clear the trigger overrun flag */
951 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
952
953 /* Update the DMA channel error code */
954 hdma->ErrorCode |= HAL_DMA_ERROR_TO;
955 }
956 }
957
958 /* Half Transfer Complete Interrupt management **********************************************************************/
959 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_HT) != 0U))
960 {
961 /* Check if interrupt source is enabled */
962 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
963 {
964 /* Clear the half transfer flag */
965 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
966
967 /* Check half transfer complete callback */
968 if (hdma->XferHalfCpltCallback != NULL)
969 {
970 /* Half transfer callback */
971 hdma->XferHalfCpltCallback(hdma);
972 }
973 }
974 }
975
976 /* Suspend Transfer Interrupt management ****************************************************************************/
977 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_SUSP) != 0U))
978 {
979 /* Check if interrupt source is enabled */
980 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_SUSP) != 0U)
981 {
982 /* Clear the block transfer complete flag */
983 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_SUSP);
984
985 /* Check DMA channel state */
986 if (hdma->State == HAL_DMA_STATE_ABORT)
987 {
988 /* Disable the suspend transfer interrupt */
989 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_SUSP);
990
991 /* Reset the channel internal state and reset the FIFO */
992 hdma->Instance->CCR |= DMA_CCR_RESET;
993
994 if ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
995 {
996 /* Update the DMA channel state */
997 hdma->State = HAL_DMA_STATE_ERROR;
998 }
999 else
1000 {
1001 /* Update the DMA channel state */
1002 hdma->State = HAL_DMA_STATE_READY;
1003 }
1004
1005 /* Check DMA channel transfer mode */
1006 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1007 {
1008 /* Update the linked-list queue state */
1009 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1010
1011 /* Clear remaining data size to ensure loading linked-list from memory next start */
1012 hdma->Instance->CBR1 = 0U;
1013 }
1014
1015 /* Process Unlocked */
1016 __HAL_UNLOCK(hdma);
1017
1018 /* Check transfer abort callback */
1019 if (hdma->XferAbortCallback != NULL)
1020 {
1021 /* Transfer abort callback */
1022 hdma->XferAbortCallback(hdma);
1023 }
1024
1025 return;
1026 }
1027 else
1028 {
1029 /* Update the DMA channel state */
1030 hdma->State = HAL_DMA_STATE_SUSPEND;
1031
1032 /* Check transfer suspend callback */
1033 if (hdma->XferSuspendCallback != NULL)
1034 {
1035 /* Transfer suspend callback */
1036 hdma->XferSuspendCallback(hdma);
1037 }
1038 }
1039 }
1040 }
1041
1042 /* Transfer Complete Interrupt management ***************************************************************************/
1043 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U))
1044 {
1045 /* Check if interrupt source is enabled */
1046 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
1047 {
1048 /* Check DMA channel transfer mode */
1049 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1050 {
1051 /* If linked-list transfer */
1052 if (hdma->Instance->CLLR == 0U)
1053 {
1054 if (hdma->Instance->CBR1 == 0U)
1055 {
1056 /* Update the DMA channel state */
1057 hdma->State = HAL_DMA_STATE_READY;
1058
1059 /* Update the linked-list queue state */
1060 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1061 }
1062 }
1063 }
1064 else
1065 {
1066 /* If normal transfer */
1067 if (hdma->Instance->CBR1 == 0U)
1068 {
1069 /* Update the DMA channel state */
1070 hdma->State = HAL_DMA_STATE_READY;
1071 }
1072 }
1073
1074 /* Clear TC and HT transfer flags */
1075 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
1076
1077 /* Process Unlocked */
1078 __HAL_UNLOCK(hdma);
1079
1080 /* Check transfer complete callback */
1081 if (hdma->XferCpltCallback != NULL)
1082 {
1083 /* Channel Transfer Complete callback */
1084 hdma->XferCpltCallback(hdma);
1085 }
1086 }
1087 }
1088
1089 /* Manage error case ************************************************************************************************/
1090 if (hdma->ErrorCode != HAL_DMA_ERROR_NONE)
1091 {
1092 /* Reset the channel internal state and reset the FIFO */
1093 hdma->Instance->CCR |= DMA_CCR_RESET;
1094
1095 if ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
1096 {
1097 /* Update the DMA channel state */
1098 hdma->State = HAL_DMA_STATE_ERROR;
1099 }
1100 else
1101 {
1102 /* Update the DMA channel state */
1103 hdma->State = HAL_DMA_STATE_READY;
1104 }
1105
1106 /* Check DMA channel transfer mode */
1107 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1108 {
1109 /* Update the linked-list queue state */
1110 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1111 }
1112
1113 /* Process Unlocked */
1114 __HAL_UNLOCK(hdma);
1115
1116 /* Check transfer error callback */
1117 if (hdma->XferErrorCallback != NULL)
1118 {
1119 /* Transfer error callback */
1120 hdma->XferErrorCallback(hdma);
1121 }
1122 }
1123 }
1124
1125 /**
1126 * @brief Register callback according to specified ID.
1127 * @note The HAL_DMA_RegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
1128 * to register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
1129 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1130 * specified DMA Channel.
1131 * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enumeration.
1132 * @param pCallback : Pointer to private callback function.
1133 * @retval HAL status.
1134 */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * const hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* const pCallback)(DMA_HandleTypeDef * const _hdma))1135 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *const hdma,
1136 HAL_DMA_CallbackIDTypeDef CallbackID,
1137 void (*const pCallback)(DMA_HandleTypeDef *const _hdma))
1138 {
1139 HAL_StatusTypeDef status = HAL_OK;
1140
1141 /* Check the DMA peripheral handle parameter */
1142 if (hdma == NULL)
1143 {
1144 return HAL_ERROR;
1145 }
1146
1147 /* Check DMA channel state */
1148 if (hdma->State == HAL_DMA_STATE_READY)
1149 {
1150 /* Check callback ID */
1151 switch (CallbackID)
1152 {
1153 case HAL_DMA_XFER_CPLT_CB_ID:
1154 {
1155 /* Register transfer complete callback */
1156 hdma->XferCpltCallback = pCallback;
1157 break;
1158 }
1159
1160 case HAL_DMA_XFER_HALFCPLT_CB_ID:
1161 {
1162 /* Register half transfer callback */
1163 hdma->XferHalfCpltCallback = pCallback;
1164 break;
1165 }
1166
1167 case HAL_DMA_XFER_ERROR_CB_ID:
1168 {
1169 /* Register transfer error callback */
1170 hdma->XferErrorCallback = pCallback;
1171 break;
1172 }
1173
1174 case HAL_DMA_XFER_ABORT_CB_ID:
1175 {
1176 /* Register abort callback */
1177 hdma->XferAbortCallback = pCallback;
1178 break;
1179 }
1180
1181 case HAL_DMA_XFER_SUSPEND_CB_ID:
1182 {
1183 /* Register suspend callback */
1184 hdma->XferSuspendCallback = pCallback;
1185 break;
1186 }
1187
1188 default:
1189 {
1190 /* Update error status */
1191 status = HAL_ERROR;
1192 break;
1193 }
1194 }
1195 }
1196 else
1197 {
1198 /* Update error status */
1199 status = HAL_ERROR;
1200 }
1201
1202 return status;
1203 }
1204
1205 /**
1206 * @brief Unregister callback according to specified ID.
1207 * @note The HAL_DMA_UnRegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
1208 * to un-register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
1209 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1210 * specified DMA Channel.
1211 * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enum.
1212 * @retval HAL status.
1213 */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * const hdma,HAL_DMA_CallbackIDTypeDef CallbackID)1214 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *const hdma,
1215 HAL_DMA_CallbackIDTypeDef CallbackID)
1216 {
1217 HAL_StatusTypeDef status = HAL_OK;
1218
1219 /* Check the DMA peripheral handle parameter */
1220 if (hdma == NULL)
1221 {
1222 return HAL_ERROR;
1223 }
1224
1225 /* Check DMA channel state */
1226 if (hdma->State == HAL_DMA_STATE_READY)
1227 {
1228 /* Check callback ID */
1229 switch (CallbackID)
1230 {
1231 case HAL_DMA_XFER_CPLT_CB_ID:
1232 {
1233 /* UnRegister transfer complete callback */
1234 hdma->XferCpltCallback = NULL;
1235 break;
1236 }
1237
1238 case HAL_DMA_XFER_HALFCPLT_CB_ID:
1239 {
1240 /* UnRegister half transfer callback */
1241 hdma->XferHalfCpltCallback = NULL;
1242 break;
1243 }
1244
1245 case HAL_DMA_XFER_ERROR_CB_ID:
1246 {
1247 /* UnRegister transfer error callback */
1248 hdma->XferErrorCallback = NULL;
1249 break;
1250 }
1251
1252 case HAL_DMA_XFER_ABORT_CB_ID:
1253 {
1254 /* UnRegister abort callback */
1255 hdma->XferAbortCallback = NULL;
1256 break;
1257 }
1258
1259 case HAL_DMA_XFER_SUSPEND_CB_ID:
1260 {
1261 /* UnRegister suspend callback */
1262 hdma->XferSuspendCallback = NULL;
1263 break;
1264 }
1265
1266 case HAL_DMA_XFER_ALL_CB_ID:
1267 {
1268 /* UnRegister all available callbacks */
1269 hdma->XferCpltCallback = NULL;
1270 hdma->XferHalfCpltCallback = NULL;
1271 hdma->XferErrorCallback = NULL;
1272 hdma->XferAbortCallback = NULL;
1273 hdma->XferSuspendCallback = NULL;
1274 break;
1275 }
1276
1277 default:
1278 {
1279 /* Update error status */
1280 status = HAL_ERROR;
1281 break;
1282 }
1283 }
1284 }
1285 else
1286 {
1287 /* Update error status */
1288 status = HAL_ERROR;
1289 }
1290
1291 return status;
1292 }
1293 /**
1294 * @}
1295 */
1296
1297 /** @addtogroup DMA_Exported_Functions_Group3
1298 *
1299 @verbatim
1300 ======================================================================================================================
1301 ############### State and Errors functions ###############
1302 ======================================================================================================================
1303 [..]
1304 This section provides functions allowing to :
1305 (+) Check the DMA state
1306 (+) Get error code
1307
1308 [..]
1309 (+) The HAL_DMA_GetState() function allows to get the DMA channel state.
1310 (+) The HAL_DMA_DeInit() function allows to get the DMA channel error code.
1311
1312 @endverbatim
1313 * @{
1314 */
1315
1316 /**
1317 * @brief Returns the DMA channel state.
1318 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1319 * specified DMA Channel.
1320 * @retval DMA state.
1321 */
HAL_DMA_GetState(DMA_HandleTypeDef const * const hdma)1322 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef const *const hdma)
1323 {
1324 /* Return the DMA channel state */
1325 return hdma->State;
1326 }
1327
1328 /**
1329 * @brief Return the DMA channel error code.
1330 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1331 * specified DMA Channel.
1332 * @retval DMA Error Code.
1333 */
HAL_DMA_GetError(DMA_HandleTypeDef const * const hdma)1334 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef const *const hdma)
1335 {
1336 /* Return the DMA channel error code */
1337 return hdma->ErrorCode;
1338 }
1339 /**
1340 * @}
1341 */
1342
1343 /** @addtogroup DMA_Exported_Functions_Group4
1344 *
1345 @verbatim
1346 ======================================================================================================================
1347 ############### DMA Attributes functions ###############
1348 ======================================================================================================================
1349 [..]
1350 This section provides functions allowing to :
1351 (+) Configure DMA channel secure and privilege attributes.
1352 (+) Get DMA channel secure and privilege attributes.
1353 (+) Lock DMA channel secure and privilege attributes configuration.
1354 (+) Check whether DMA channel secure and privilege attributes configuration is locked or not.
1355
1356 [..]
1357 (+) The HAL_DMA_ConfigChannelAttributes() function allows to configure DMA channel security and privilege
1358 attributes.
1359 (+) The HAL_DMA_GetConfigChannelAttributes() function allows to get DMA channel security and privilege attributes
1360 configuration.
1361 (+) The HAL_DMA_LockChannelAttributes() function allows to lock the DMA channel security and privilege attributes.
1362 (+) The HAL_DMA_GetLockChannelAttributes() function allows to get the DMA channel security and privilege
1363 attributes lock status.
1364
1365 @endverbatim
1366 * @{
1367 */
1368
1369 /**
1370 * @brief Configure the DMA channel security and privilege attribute(s).
1371 * @note These attributes cannot be modified when the corresponding lock state is enabled.
1372 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
1373 * the specified DMA Channel.
1374 * @param ChannelAttributes : Specifies the DMA channel secure/privilege attributes.
1375 * This parameter can be a one or a combination of @ref DMA_Channel_Attributes.
1376 * @retval HAL Status.
1377 */
HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef * const hdma,uint32_t ChannelAttributes)1378 HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *const hdma, uint32_t ChannelAttributes)
1379 {
1380 DMA_TypeDef *p_dma_instance;
1381 uint32_t channel_idx;
1382
1383 /* Check the DMA peripheral handle parameter */
1384 if (hdma == NULL)
1385 {
1386 return HAL_ERROR;
1387 }
1388
1389 /* Check the parameters */
1390 assert_param(IS_DMA_ATTRIBUTES(ChannelAttributes));
1391
1392 /* Get DMA instance */
1393 p_dma_instance = GET_DMA_INSTANCE(hdma);
1394
1395 /* Get channel index */
1396 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1397
1398 /* Check DMA channel privilege attribute management */
1399 if ((ChannelAttributes & DMA_CHANNEL_ATTR_PRIV_MASK) == DMA_CHANNEL_ATTR_PRIV_MASK)
1400 {
1401 /* Configure DMA channel privilege attribute */
1402 if ((ChannelAttributes & DMA_CHANNEL_PRIV) == DMA_CHANNEL_PRIV)
1403 {
1404 p_dma_instance->PRIVCFGR |= channel_idx;
1405 }
1406 else
1407 {
1408 p_dma_instance->PRIVCFGR &= (~channel_idx);
1409 }
1410 }
1411
1412 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1413 /* Check DMA channel security attribute management */
1414 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_MASK) == DMA_CHANNEL_ATTR_SEC_MASK)
1415 {
1416 /* Configure DMA channel security attribute */
1417 if ((ChannelAttributes & DMA_CHANNEL_SEC) == DMA_CHANNEL_SEC)
1418 {
1419 p_dma_instance->SECCFGR |= channel_idx;
1420 }
1421 else
1422 {
1423 p_dma_instance->SECCFGR &= (~channel_idx);
1424 }
1425 }
1426
1427 /* Channel source security attribute management */
1428 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_SRC_MASK) == DMA_CHANNEL_ATTR_SEC_SRC_MASK)
1429 {
1430 /* Configure DMA channel source security attribute */
1431 if ((ChannelAttributes & DMA_CHANNEL_SRC_SEC) == DMA_CHANNEL_SRC_SEC)
1432 {
1433 hdma->Instance->CTR1 |= DMA_CTR1_SSEC;
1434 }
1435 else
1436 {
1437 hdma->Instance->CTR1 &= (~DMA_CTR1_SSEC);
1438 }
1439 }
1440
1441 /* Channel destination security attribute management */
1442 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_DEST_MASK) == DMA_CHANNEL_ATTR_SEC_DEST_MASK)
1443 {
1444 /* Configure DMA channel destination security attribute */
1445 if ((ChannelAttributes & DMA_CHANNEL_DEST_SEC) == DMA_CHANNEL_DEST_SEC)
1446 {
1447 hdma->Instance->CTR1 |= DMA_CTR1_DSEC;
1448 }
1449 else
1450 {
1451 hdma->Instance->CTR1 &= (~DMA_CTR1_DSEC);
1452 }
1453 }
1454 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
1455
1456 return HAL_OK;
1457 }
1458
1459 /**
1460 * @brief Get the DMA channel security and privilege attributes.
1461 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information
1462 * for the specified DMA Channel.
1463 * @param pChannelAttributes : Pointer to the returned attributes.
1464 * @retval HAL Status.
1465 */
HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const * const hdma,uint32_t * const pChannelAttributes)1466 HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const *const hdma,
1467 uint32_t *const pChannelAttributes)
1468 {
1469 DMA_TypeDef *p_dma_instance;
1470 uint32_t attributes;
1471 uint32_t channel_idx;
1472
1473 /* Check the DMA peripheral handle and channel attributes parameters */
1474 if ((hdma == NULL) || (pChannelAttributes == NULL))
1475 {
1476 return HAL_ERROR;
1477 }
1478
1479 /* Get DMA instance */
1480 p_dma_instance = GET_DMA_INSTANCE(hdma);
1481
1482 /* Get channel index */
1483 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1484
1485 /* Get DMA channel privilege attribute */
1486 attributes = ((p_dma_instance->PRIVCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
1487
1488 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1489 /* Get DMA channel security attribute */
1490 attributes |= ((p_dma_instance->SECCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC;
1491
1492 /* Get DMA channel source security attribute */
1493 attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_SSEC) == 0U) ? DMA_CHANNEL_SRC_NSEC : DMA_CHANNEL_SRC_SEC;
1494
1495 /* Get DMA channel destination security attribute */
1496 attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_DSEC) == 0U) ? DMA_CHANNEL_DEST_NSEC : DMA_CHANNEL_DEST_SEC;
1497
1498 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
1499 /* return value */
1500 *pChannelAttributes = attributes;
1501
1502 return HAL_OK;
1503 }
1504
1505 #if defined (DMA_RCFGLOCKR_LOCK0)
1506 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1507 /**
1508 * @brief Lock the DMA channel security and privilege attribute(s).
1509 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1510 * specified DMA Channel.
1511 * @retval HAL Status.
1512 */
HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const * const hdma)1513 HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const hdma)
1514 {
1515 DMA_TypeDef *p_dma_instance;
1516 uint32_t channel_idx;
1517
1518 /* Check the DMA peripheral handle parameter */
1519 if (hdma == NULL)
1520 {
1521 return HAL_ERROR;
1522 }
1523
1524 /* Get DMA instance */
1525 p_dma_instance = GET_DMA_INSTANCE(hdma);
1526
1527 /* Get channel index */
1528 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1529
1530 /* Lock the DMA channel privilege and security attributes */
1531 p_dma_instance->RCFGLOCKR |= channel_idx;
1532
1533 return HAL_OK;
1534 }
1535 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
1536
1537 /**
1538 * @brief Get the security and privilege attribute lock state of a DMA channel.
1539 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1540 * specified DMA Channel.
1541 * @param pLockState : Pointer to lock state (returned value can be DMA_CHANNEL_ATTRIBUTE_UNLOCKED or
1542 * DMA_CHANNEL_ATTRIBUTE_LOCKED).
1543 * @retval HAL status.
1544 */
HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const * const hdma,uint32_t * const pLockState)1545 HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, uint32_t *const pLockState)
1546 {
1547 DMA_TypeDef *p_dma_instance;
1548 uint32_t channel_idx;
1549
1550 /* Check the DMA peripheral handle and lock state parameters */
1551 if ((hdma == NULL) || (pLockState == NULL))
1552 {
1553 return HAL_ERROR;
1554 }
1555
1556 /* Get DMA instance */
1557 p_dma_instance = GET_DMA_INSTANCE(hdma);
1558
1559 /* Get channel index */
1560 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1561
1562 /* Get channel lock attribute state */
1563 *pLockState = ((p_dma_instance->RCFGLOCKR & channel_idx) == 0U) ? DMA_CHANNEL_ATTRIBUTE_UNLOCKED : \
1564 DMA_CHANNEL_ATTRIBUTE_LOCKED;
1565
1566 return HAL_OK;
1567 }
1568 #endif /* defined (DMA_RCFGLOCKR_LOCK0) */
1569 /**
1570 * @}
1571 */
1572
1573 /**
1574 * @}
1575 */
1576
1577
1578 /* Private functions -------------------------------------------------------------------------------------------------*/
1579 /** @defgroup DMA_Private_Functions DMA Private Functions
1580 * @brief DMA Private Functions
1581 * @{
1582 */
1583
1584 /**
1585 * @brief Set the DMA channel normal transfer parameters.
1586 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1587 * specified DMA Channel.
1588 * @param SrcAddress : The source data address.
1589 * @param DstAddress : The destination data address.
1590 * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
1591 * @retval None.
1592 */
DMA_SetConfig(DMA_HandleTypeDef const * const hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SrcDataSize)1593 static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
1594 uint32_t SrcAddress,
1595 uint32_t DstAddress,
1596 uint32_t SrcDataSize)
1597 {
1598 /* Configure the DMA channel data size */
1599 MODIFY_REG(hdma->Instance->CBR1, DMA_CBR1_BNDT, (SrcDataSize & DMA_CBR1_BNDT));
1600
1601 /* Clear all interrupt flags */
1602 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
1603 DMA_FLAG_TO);
1604
1605 /* Configure DMA channel source address */
1606 hdma->Instance->CSAR = SrcAddress;
1607
1608 /* Configure DMA channel destination address */
1609 hdma->Instance->CDAR = DstAddress;
1610 }
1611
1612 /**
1613 * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef.
1614 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1615 * specified DMA Channel.
1616 * @retval None.
1617 */
DMA_Init(DMA_HandleTypeDef const * const hdma)1618 static void DMA_Init(DMA_HandleTypeDef const *const hdma)
1619 {
1620 uint32_t tmpreg;
1621
1622 /* Prepare DMA Channel Control Register (CCR) value *****************************************************************/
1623 tmpreg = hdma->Init.Priority;
1624
1625 /* Write DMA Channel Control Register (CCR) */
1626 MODIFY_REG(hdma->Instance->CCR, DMA_CCR_PRIO | DMA_CCR_LAP | DMA_CCR_LSM, tmpreg);
1627
1628
1629 /* Prepare DMA Channel Transfer Register (CTR1) value ***************************************************************/
1630 tmpreg = hdma->Init.DestInc | hdma->Init.DestDataWidth | hdma->Init.SrcInc | hdma->Init.SrcDataWidth;
1631
1632 /* Add parameters specific to GPDMA */
1633 if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
1634 {
1635 tmpreg |= (hdma->Init.TransferAllocatedPort |
1636 (((hdma->Init.DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1) |
1637 (((hdma->Init.SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1));
1638 }
1639
1640 /* Write DMA Channel Transfer Register 1 (CTR1) */
1641 #if defined (DMA_CTR1_SSEC)
1642 MODIFY_REG(hdma->Instance->CTR1, ~(DMA_CTR1_SSEC | DMA_CTR1_DSEC), tmpreg);
1643 #else
1644 WRITE_REG(hdma->Instance->CTR1, tmpreg);
1645 #endif /* defined (DMA_CTR1_SSEC) */
1646
1647 /* Prepare DMA Channel Transfer Register 2 (CTR2) value *************************************************************/
1648 tmpreg = hdma->Init.BlkHWRequest | (hdma->Init.Request & DMA_CTR2_REQSEL) | hdma->Init.TransferEventMode;
1649
1650 /* Memory to Peripheral Transfer */
1651 if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1652 {
1653 if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
1654 {
1655 tmpreg |= DMA_CTR2_DREQ;
1656 }
1657 }
1658 /* Memory to Memory Transfer */
1659 else if ((hdma->Init.Direction) == DMA_MEMORY_TO_MEMORY)
1660 {
1661 tmpreg |= DMA_CTR2_SWREQ;
1662 }
1663 else
1664 {
1665 /* Nothing to do */
1666 }
1667
1668 /* Write DMA Channel Transfer Register 2 (CTR2) */
1669 MODIFY_REG(hdma->Instance->CTR2, (DMA_CTR2_TCEM | DMA_CTR2_TRIGPOL | DMA_CTR2_TRIGSEL | DMA_CTR2_TRIGM |
1670 DMA_CTR2_BREQ | DMA_CTR2_DREQ | DMA_CTR2_SWREQ | DMA_CTR2_REQSEL), tmpreg);
1671
1672
1673 /* Write DMA Channel Block Register 1 (CBR1) ************************************************************************/
1674 WRITE_REG(hdma->Instance->CBR1, 0U);
1675
1676
1677 /* If 2D Addressing is supported by current channel */
1678 if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U)
1679 {
1680 /* Write DMA Channel Transfer Register 3 (CTR3) *******************************************************************/
1681 WRITE_REG(hdma->Instance->CTR3, 0U);
1682
1683
1684 /* Write DMA Channel Block Register 2 (CBR2) **********************************************************************/
1685 WRITE_REG(hdma->Instance->CBR2, 0U);
1686 }
1687
1688
1689 /* Write DMA Channel linked-list address register (CLLR) ************************************************************/
1690 WRITE_REG(hdma->Instance->CLLR, 0U);
1691 }
1692 /**
1693 * @}
1694 */
1695
1696 #endif /* HAL_DMA_MODULE_ENABLED */
1697
1698 /**
1699 * @}
1700 */
1701
1702 /**
1703 * @}
1704 */
1705