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