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