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