generated from Template/H563ZI-HAL-CMake-Template
	
		
			
				
	
	
		
			1723 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1723 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|   **********************************************************************************************************************
 | |
|   * @file    stm32h5xx_hal_dma.c
 | |
|   * @author  MCD Application Team
 | |
|   * @brief   This file provides firmware functions to manage the following functionalities of the Direct Memory Access
 | |
|   *          (DMA) peripheral:
 | |
|   *            + Initialization/De-Initialization Functions
 | |
|   *            + I/O Operation Functions
 | |
|   *            + State and Errors Functions
 | |
|   *            + DMA Attributes Functions
 | |
|   *
 | |
|   **********************************************************************************************************************
 | |
|   * @attention
 | |
|   *
 | |
|   * Copyright (c) 2023 STMicroelectronics.
 | |
|   * All rights reserved.
 | |
|   *
 | |
|   * This software is licensed under terms that can be found in the LICENSE file
 | |
|   * in the root directory of this software component.
 | |
|   * If no LICENSE file comes with this software, it is provided AS-IS.
 | |
|   *
 | |
|   **********************************************************************************************************************
 | |
|   @verbatim
 | |
|   ======================================================================================================================
 | |
|                        ##### How to use this driver #####
 | |
|   ======================================================================================================================
 | |
| 
 | |
| 
 | |
|     [..]
 | |
|       DMA transfer modes are divided to 2 major categories :
 | |
|           (+) Normal transfers (legacy)
 | |
|           (+) Linked-list transfers
 | |
| 
 | |
|     [..]
 | |
|       Normal transfers mode is initialized via the standard module and linked-list mode is configured via the extended
 | |
|       module.
 | |
| 
 | |
|     [..]
 | |
|       Additionally to linked-list capability, all advanced DMA features are managed and configured via the extended
 | |
|       module as extensions to normal mode.
 | |
|       Advanced features are :
 | |
|           (+) Repeated block feature.
 | |
|           (+) Trigger feature.
 | |
|           (+) Data handling feature.
 | |
| 
 | |
|     [..]
 | |
|       DMA Legacy circular transfer, is replaced by circular linked-list configuration.
 | |
| 
 | |
| 
 | |
|     *** Initialization and De-Initialization ***
 | |
|     ============================================
 | |
|     [..]
 | |
|       For a given channel, enable and configure the peripheral to be connected to the DMA Channel (except for internal
 | |
|       SRAM/FLASH memories: no initialization is necessary) please refer to Reference manual for connection between
 | |
|       peripherals and DMA requests.
 | |
| 
 | |
|     [..]
 | |
|       For a given channel, use HAL_DMA_Init function to program the required configuration for normal transfer through
 | |
|       the following parameters:
 | |
| 
 | |
|           (+) Request               : Specifies the DMA channel request
 | |
|               Request parameters    :
 | |
|               (++) can be a value of DMA_Request_Selection
 | |
| 
 | |
|           (+) BlkHWRequest          : Specifies the Block hardware request mode for DMA channel
 | |
|               (++) can be a value of DMA_Block_Request
 | |
| 
 | |
|           (+) Direction             : Specifies the transfer direction for DMA channel
 | |
|               (++) can be a value of DMA_Transfer_Direction
 | |
| 
 | |
|           (+) SrcInc                : Specifies the source increment mode for the DMA channel
 | |
|               (++) can be a value of DMA_Source_Increment_Mode
 | |
| 
 | |
|           (+) DestInc               : Specifies the destination increment mode for the DMA channel
 | |
|               (++) can be a value of DMA_Destination_Increment_Mode
 | |
| 
 | |
|           (+) SrcDataWidth          : Specifies the source data width for the DMA channel
 | |
|               (++) can be a value of DMA_Source_Data_Width
 | |
| 
 | |
|           (+) DestDataWidth         : Specifies the destination data width for the DMA channel
 | |
|               (++) can be a value of DMA_Destination_Data_Width
 | |
| 
 | |
|           (+) Priority              : Specifies the priority for the DMA channel
 | |
|               (++) can be a value of DMA_Priority_Level
 | |
| 
 | |
|           (+) SrcBurstLength        : Specifies the source burst length (number of beats) for the DMA channel
 | |
|               (++) can be a value of between 1 and 64
 | |
| 
 | |
|           (+) DestBurstLength       : Specifies the destination burst length (number of beats) for the DMA channel
 | |
|               (++) can be a value of between 1 and 64
 | |
| 
 | |
|           (+) TransferAllocatedPort : Specifies the source and destination allocated ports
 | |
|               (++) can be a value of DMA_Transfer_Allocated_Port
 | |
| 
 | |
|           (+) TransferEventMode     : Specifies the transfer event mode for the DMA channel
 | |
|               (++) can be a value of DMA_Transfer_Event_Mode
 | |
| 
 | |
|           (+) Mode                  : Specifies the transfer mode for the DMA channel
 | |
|               (++) can be one of the following modes :
 | |
|                   (+++) DMA_NORMAL : Normal Mode
 | |
|                   (+++) DMA_PFCTRL : Peripheral Flow Control (peripheral early termination) Mode
 | |
| 
 | |
|     *** Polling mode IO operation ***
 | |
|     =================================
 | |
|     [..]
 | |
|           (+) Use HAL_DMA_Start() to start a DMA normal transfer after the configuration of source address, destination
 | |
|               address and the size of data to be transferred.
 | |
| 
 | |
|           (+) Use HAL_DMA_PollForTransfer() to poll for selected transfer level. In this case a fixed Timeout can be
 | |
|               configured by User depending on his application.
 | |
|               Transfer level can be :
 | |
|               (++) HAL_DMA_HALF_TRANSFER
 | |
|               (++) HAL_DMA_FULL_TRANSFER
 | |
|               For circular transfer, this API returns an HAL_ERROR with HAL_DMA_ERROR_NOT_SUPPORTED error code.
 | |
| 
 | |
|           (+) Use HAL_DMA_Abort() function to abort any ongoing DMA transfer in blocking mode.
 | |
|               This API returns HAL_ERROR when there is no ongoing transfer or timeout is reached when disabling the DMA
 | |
|               channel. (This API should not be called from an interrupt service routine)
 | |
| 
 | |
| 
 | |
|     *** Interrupt mode IO operation ***
 | |
|     ===================================
 | |
|     [..]
 | |
|           (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
 | |
| 
 | |
|           (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
 | |
| 
 | |
|           (+) Use HAL_DMA_RegisterCallback() function to register user callbacks from the following list :
 | |
|               (++) XferCpltCallback     : transfer complete callback.
 | |
|               (++) XferHalfCpltCallback : half transfer complete callback.
 | |
|               (++) XferErrorCallback    : transfer error callback.
 | |
|               (++) XferAbortCallback    : transfer abort complete callback.
 | |
|               (++) XferSuspendCallback  : transfer suspend complete callback.
 | |
| 
 | |
|           (+) Use HAL_DMA_Start_IT() to start the DMA transfer after the enable of DMA interrupts and the configuration
 | |
|               of source address,destination address and the size of data to be transferred.
 | |
| 
 | |
|           (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() interrupt subroutine to handle any DMA interrupt.
 | |
| 
 | |
|           (+) Use HAL_DMA_Abort_IT() function to abort any on-going DMA transfer in non-blocking mode.
 | |
|               This API will suspend immediately the DMA channel execution. When the transfer is effectively suspended,
 | |
|               an interrupt is generated and HAL_DMA_IRQHandler() will reset the channel and execute the callback
 | |
|               XferAbortCallback. (This API could be called from an interrupt service routine)
 | |
| 
 | |
| 
 | |
|     *** State and errors ***
 | |
|     ========================
 | |
|     [..]
 | |
|           (+) Use HAL_DMA_GetState() function to get the DMA state.
 | |
|           (+) Use HAL_DMA_GetError() function to get the DMA error code.
 | |
| 
 | |
| 
 | |
|     *** Security and privilege attributes ***
 | |
|     =========================================
 | |
|     [..]
 | |
|           (+) Use HAL_DMA_ConfigChannelAttributes() function to configure DMA channel security and privilege attributes.
 | |
|               (++) Security  : at channel level, at source level and at destination level.
 | |
|               (++) Privilege : at channel level.
 | |
|           (+) Use HAL_DMA_GetConfigChannelAttributes() function to get the DMA channel attributes.
 | |
|           (+) Use HAL_DMA_LockChannelAttributes() function to lock the DMA channel security and privilege attributes
 | |
|               configuration. This API can be called once after each system boot.
 | |
|               If called again, HAL_DMA_ConfigChannelAttributes() API has no effect.
 | |
|               Unlock is done either by a system boot or a by an RCC reset.
 | |
|           (+) Use HAL_DMA_GetLockChannelAttributes() function to get the attributes lock status.
 | |
| 
 | |
| 
 | |
|     *** DMA HAL driver macros list ***
 | |
|     ==================================
 | |
|     [..]
 | |
|       Below the list of most used macros in DMA HAL driver.
 | |
| 
 | |
|           (+) __HAL_DMA_ENABLE        : Enable the specified DMA Channel.
 | |
|           (+) __HAL_DMA_DISABLE       : Disable the specified DMA Channel.
 | |
|           (+) __HAL_DMA_GET_FLAG      : Get the DMA Channel pending flags.
 | |
|           (+) __HAL_DMA_CLEAR_FLAG    : Clear the DMA Channel pending flags.
 | |
|           (+) __HAL_DMA_ENABLE_IT     : Enable the specified DMA Channel interrupts.
 | |
|           (+) __HAL_DMA_DISABLE_IT    : Disable the specified DMA Channel interrupts.
 | |
|           (+) __HAL_DMA_GET_IT_SOURCE : Check whether the specified DMA Channel interrupt has occurred or not.
 | |
| 
 | |
|     [..]
 | |
|      (@) You can refer to the header file of the DMA HAL driver for more useful macros.
 | |
| 
 | |
|     @endverbatim
 | |
|   **********************************************************************************************************************
 | |
|   */
 | |
| 
 | |
| /* Includes ----------------------------------------------------------------------------------------------------------*/
 | |
| #include "stm32h5xx_hal.h"
 | |
| 
 | |
| /** @addtogroup STM32H5xx_HAL_Driver
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /** @defgroup DMA DMA
 | |
|   * @brief DMA HAL module driver
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| #ifdef HAL_DMA_MODULE_ENABLED
 | |
| 
 | |
| /* Private typedef ---------------------------------------------------------------------------------------------------*/
 | |
| /* Private constants -------------------------------------------------------------------------------------------------*/
 | |
| /* Private macro -----------------------------------------------------------------------------------------------------*/
 | |
| /* Private variables -------------------------------------------------------------------------------------------------*/
 | |
| /* Private function prototypes ---------------------------------------------------------------------------------------*/
 | |
| static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
 | |
|                           uint32_t SrcAddress,
 | |
|                           uint32_t DstAddress,
 | |
|                           uint32_t SrcDataSize);
 | |
| static void DMA_Init(DMA_HandleTypeDef const *const hdma);
 | |
| 
 | |
| /* Exported functions ------------------------------------------------------------------------------------------------*/
 | |
| 
 | |
| /** @addtogroup DMA_Exported_Functions DMA Exported Functions
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /** @addtogroup DMA_Exported_Functions_Group1
 | |
|   *
 | |
| @verbatim
 | |
|   ======================================================================================================================
 | |
|                        ##### Initialization and de-initialization functions #####
 | |
|   ======================================================================================================================
 | |
|     [..]
 | |
|       This section provides functions allowing to initialize and de-initialize the DMA channel in normal mode.
 | |
| 
 | |
|     [..]
 | |
|       (+) The HAL_DMA_Init() function follows the DMA channel configuration procedures as described in reference manual.
 | |
|       (+) The HAL_DMA_DeInit() function allows to de-initialize the DMA channel.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef and
 | |
|   *         create the associated handle.
 | |
|   * @param  hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *const hdma)
 | |
| {
 | |
|   /* Get tick number */
 | |
|   uint32_t tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
 | |
|   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
 | |
|   if (hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
 | |
|   {
 | |
|     assert_param(IS_DMA_REQUEST(hdma->Init.Request));
 | |
|   }
 | |
|   assert_param(IS_DMA_BLOCK_HW_REQUEST(hdma->Init.BlkHWRequest));
 | |
|   assert_param(IS_DMA_SOURCE_INC(hdma->Init.SrcInc));
 | |
|   assert_param(IS_DMA_DESTINATION_INC(hdma->Init.DestInc));
 | |
|   assert_param(IS_DMA_SOURCE_DATA_WIDTH(hdma->Init.SrcDataWidth));
 | |
|   assert_param(IS_DMA_DESTINATION_DATA_WIDTH(hdma->Init.DestDataWidth));
 | |
|   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
 | |
|   assert_param(IS_DMA_TCEM_EVENT_MODE(hdma->Init.TransferEventMode));
 | |
|   assert_param(IS_DMA_MODE(hdma->Init.Mode));
 | |
|   if (hdma->Init.Mode == DMA_PFCTRL)
 | |
|   {
 | |
|     assert_param(IS_DMA_PFREQ_INSTANCE(hdma->Instance));
 | |
|   }
 | |
|   /* Check DMA channel instance */
 | |
|   if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
 | |
|   {
 | |
|     assert_param(IS_DMA_BURST_LENGTH(hdma->Init.SrcBurstLength));
 | |
|     assert_param(IS_DMA_BURST_LENGTH(hdma->Init.DestBurstLength));
 | |
|     assert_param(IS_DMA_TRANSFER_ALLOCATED_PORT(hdma->Init.TransferAllocatedPort));
 | |
|   }
 | |
| 
 | |
|   /* Allocate lock resource */
 | |
|   __HAL_UNLOCK(hdma);
 | |
| 
 | |
|   /* Initialize the callbacks */
 | |
|   if (hdma->State == HAL_DMA_STATE_RESET)
 | |
|   {
 | |
|     /* Clean all callbacks */
 | |
|     hdma->XferCpltCallback     = NULL;
 | |
|     hdma->XferHalfCpltCallback = NULL;
 | |
|     hdma->XferErrorCallback    = NULL;
 | |
|     hdma->XferAbortCallback    = NULL;
 | |
|     hdma->XferSuspendCallback  = NULL;
 | |
|   }
 | |
| 
 | |
|   /* Update the DMA channel state */
 | |
|   hdma->State = HAL_DMA_STATE_BUSY;
 | |
| 
 | |
|   /* Disable the DMA channel */
 | |
|   __HAL_DMA_DISABLE(hdma);
 | |
| 
 | |
|   /* Check if the DMA channel is effectively disabled */
 | |
|   while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
 | |
|   {
 | |
|     /* Check for the Timeout */
 | |
|     if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
 | |
|     {
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
 | |
| 
 | |
|       /* Update the DMA channel state */
 | |
|       hdma->State = HAL_DMA_STATE_ERROR;
 | |
| 
 | |
|       return HAL_ERROR;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Initialize the DMA channel registers */
 | |
|   DMA_Init(hdma);
 | |
| 
 | |
|   /* Update DMA channel operation mode */
 | |
|   hdma->Mode = hdma->Init.Mode;
 | |
| 
 | |
|   /* Update the DMA channel error code */
 | |
|   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
 | |
| 
 | |
|   /* Update the DMA channel state */
 | |
|   hdma->State = HAL_DMA_STATE_READY;
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DeInitialize the DMA channel when it is configured in normal mode.
 | |
|   * @param  hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *const hdma)
 | |
| {
 | |
| 
 | |
|   DMA_TypeDef *p_dma_instance;
 | |
| 
 | |
|   uint32_t tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
 | |
| 
 | |
|   /* Get DMA instance */
 | |
|   p_dma_instance = GET_DMA_INSTANCE(hdma);
 | |
| 
 | |
|   /* Disable the selected DMA Channel */
 | |
|   __HAL_DMA_DISABLE(hdma);
 | |
| 
 | |
|   /* Check if the DMA channel is effectively disabled */
 | |
|   while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
 | |
|   {
 | |
|     /* Check for the Timeout */
 | |
|     if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
 | |
|     {
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
 | |
| 
 | |
|       /* Update the DMA channel state */
 | |
|       hdma->State = HAL_DMA_STATE_ERROR;
 | |
| 
 | |
|       return HAL_ERROR;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Reset DMA Channel registers */
 | |
|   hdma->Instance->CLBAR = 0U;
 | |
|   hdma->Instance->CCR   = 0U;
 | |
|   hdma->Instance->CTR1  = 0U;
 | |
|   hdma->Instance->CTR2  = 0U;
 | |
|   hdma->Instance->CBR1  = 0U;
 | |
|   hdma->Instance->CSAR  = 0U;
 | |
|   hdma->Instance->CDAR  = 0U;
 | |
|   hdma->Instance->CLLR  = 0U;
 | |
| 
 | |
|   /* Reset 2D Addressing registers */
 | |
|   if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U)
 | |
|   {
 | |
|     hdma->Instance->CTR3 = 0U;
 | |
|     hdma->Instance->CBR2 = 0U;
 | |
|   }
 | |
| 
 | |
|   /* Clear privilege attribute */
 | |
|   CLEAR_BIT(p_dma_instance->PRIVCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU)));
 | |
| 
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|   /* Clear secure attribute */
 | |
|   CLEAR_BIT(p_dma_instance->SECCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU)));
 | |
| #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
 | |
| 
 | |
|   /* Clear all flags */
 | |
|   __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
 | |
|                               DMA_FLAG_TO));
 | |
| 
 | |
|   /* Clean all callbacks */
 | |
|   hdma->XferCpltCallback     = NULL;
 | |
|   hdma->XferHalfCpltCallback = NULL;
 | |
|   hdma->XferErrorCallback    = NULL;
 | |
|   hdma->XferAbortCallback    = NULL;
 | |
|   hdma->XferSuspendCallback  = NULL;
 | |
| 
 | |
|   /* Clean DMA queue */
 | |
|   hdma->LinkedListQueue = NULL;
 | |
| 
 | |
|   /* Clean DMA parent */
 | |
|   if (hdma->Parent != NULL)
 | |
|   {
 | |
|     hdma->Parent = NULL;
 | |
|   }
 | |
| 
 | |
|   /* Update DMA channel operation mode */
 | |
|   hdma->Mode = DMA_NORMAL;
 | |
| 
 | |
|   /* Update the DMA channel error code */
 | |
|   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
 | |
| 
 | |
|   /* Update the DMA channel state */
 | |
|   hdma->State = HAL_DMA_STATE_RESET;
 | |
| 
 | |
|   /* Release Lock */
 | |
|   __HAL_UNLOCK(hdma);
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @addtogroup DMA_Exported_Functions_Group2
 | |
|   *
 | |
| @verbatim
 | |
|   ======================================================================================================================
 | |
|                                 ##### IO operation functions #####
 | |
|   ======================================================================================================================
 | |
|     [..]
 | |
|       This section provides functions allowing to :
 | |
|       (+) Configure the source, destination address and data size and Start DMA transfer in normal mode
 | |
|       (+) Abort DMA transfer
 | |
|       (+) Poll for transfer complete
 | |
|       (+) Handle DMA interrupt request
 | |
|       (+) Register and Unregister DMA callbacks
 | |
| 
 | |
|     [..]
 | |
|       (+) The HAL_DMA_Start() function allows to start the DMA channel transfer in normal mode (Blocking mode).
 | |
|       (+) The HAL_DMA_Start_IT() function allows to start the DMA channel transfer in normal mode (Non-blocking mode).
 | |
|       (+) The HAL_DMA_Abort() function allows to abort any on-going transfer (Blocking mode).
 | |
|       (+) The HAL_DMA_Abort_IT() function allows to abort any on-going transfer (Non-blocking mode).
 | |
|       (+) The HAL_DMA_PollForTransfer() function allows to poll on half transfer and transfer complete (Blocking mode).
 | |
|           This API cannot be used for circular transfers.
 | |
|       (+) The HAL_DMA_IRQHandler() function allows to handle any DMA channel interrupt (Non-blocking mode).
 | |
|       (+) The HAL_DMA_RegisterCallback() and HAL_DMA_UnRegisterCallback() functions allow respectively to register and
 | |
|           unregister user customized callbacks.
 | |
|           User callbacks are called under HAL_DMA_IRQHandler().
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Start the DMA channel transfer in normal mode (Blocking mode).
 | |
|   * @param  hdma        : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
 | |
|   *                       the specified DMA Channel.
 | |
|   * @param  SrcAddress  : The source data address.
 | |
|   * @param  DstAddress  : The destination data address.
 | |
|   * @param  SrcDataSize : The length of data to be transferred from source to destination in bytes.
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *const hdma,
 | |
|                                 uint32_t SrcAddress,
 | |
|                                 uint32_t DstAddress,
 | |
|                                 uint32_t SrcDataSize)
 | |
| {
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the DMA Mode is DMA_NORMAL */
 | |
|   if (hdma->Mode != DMA_NORMAL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
 | |
| 
 | |
|   /* Process locked */
 | |
|   __HAL_LOCK(hdma);
 | |
| 
 | |
|   /* Check DMA channel state */
 | |
|   if (hdma->State == HAL_DMA_STATE_READY)
 | |
|   {
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_BUSY;
 | |
| 
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
 | |
| 
 | |
|     /* Configure the source address, destination address, the data size and clear flags */
 | |
|     DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize);
 | |
| 
 | |
|     /* Enable DMA channel */
 | |
|     __HAL_DMA_ENABLE(hdma);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
 | |
| 
 | |
|     /* Process unlocked */
 | |
|     __HAL_UNLOCK(hdma);
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Starts the DMA channel transfer in normal mode with interrupts enabled (Non-blocking mode).
 | |
|   * @param  hdma         : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                        specified DMA Channel.
 | |
|   * @param  SrcAddress   : The source data address.
 | |
|   * @param  DstAddress   : The destination data address.
 | |
|   * @param  SrcDataSize  : The length of data to be transferred from source to destination in bytes.
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *const hdma,
 | |
|                                    uint32_t SrcAddress,
 | |
|                                    uint32_t DstAddress,
 | |
|                                    uint32_t SrcDataSize)
 | |
| {
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the DMA Mode is DMA_NORMAL */
 | |
|   if (hdma->Mode != DMA_NORMAL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
 | |
| 
 | |
|   /* Process locked */
 | |
|   __HAL_LOCK(hdma);
 | |
| 
 | |
|   /* Check DMA channel state */
 | |
|   if (hdma->State == HAL_DMA_STATE_READY)
 | |
|   {
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_BUSY;
 | |
| 
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
 | |
| 
 | |
|     /* Configure the source address, destination address, the data size and clear flags */
 | |
|     DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize);
 | |
| 
 | |
|     /* Enable common interrupts: Transfer Complete and Transfer Errors ITs */
 | |
|     __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_DTE | DMA_IT_ULE | DMA_IT_USE | DMA_IT_TO));
 | |
| 
 | |
|     /* Check half transfer complete callback */
 | |
|     if (hdma->XferHalfCpltCallback != NULL)
 | |
|     {
 | |
|       /* If Half Transfer complete callback is set, enable the corresponding IT */
 | |
|       __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
 | |
|     }
 | |
| 
 | |
|     /* Check Half suspend callback */
 | |
|     if (hdma->XferSuspendCallback != NULL)
 | |
|     {
 | |
|       /* If Transfer suspend callback is set, enable the corresponding IT */
 | |
|       __HAL_DMA_ENABLE_IT(hdma, DMA_IT_SUSP);
 | |
|     }
 | |
| 
 | |
|     /* Enable DMA channel */
 | |
|     __HAL_DMA_ENABLE(hdma);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
 | |
| 
 | |
|     /* Process unlocked */
 | |
|     __HAL_UNLOCK(hdma);
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Abort any on-going DMA channel transfer (Blocking mode).
 | |
|   * @param  hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @note   After suspending a DMA channel, a wait until the DMA channel is effectively stopped is added. If a channel
 | |
|   *         is suspended while a data transfer is on-going, the current data will be transferred and the channel will be
 | |
|   *         effectively suspended only after the transfer of any on-going data is finished.
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *const hdma)
 | |
| {
 | |
|   /* Get tick number */
 | |
|   uint32_t tickstart =  HAL_GetTick();
 | |
| 
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check DMA channel state */
 | |
|   if (hdma->State != HAL_DMA_STATE_BUSY)
 | |
|   {
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
 | |
| 
 | |
|     /* Process Unlocked */
 | |
|     __HAL_UNLOCK(hdma);
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Suspend the channel */
 | |
|     hdma->Instance->CCR |= DMA_CCR_SUSP;
 | |
| 
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_SUSPEND;
 | |
| 
 | |
|     /* Check if the DMA Channel is suspended */
 | |
|     while ((hdma->Instance->CSR & DMA_CSR_SUSPF) == 0U)
 | |
|     {
 | |
|       /* Check for the Timeout */
 | |
|       if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
 | |
|       {
 | |
|         /* Update the DMA channel error code */
 | |
|         hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
 | |
| 
 | |
|         /* Update the DMA channel state */
 | |
|         hdma->State = HAL_DMA_STATE_ERROR;
 | |
| 
 | |
|         /* Check DMA channel transfer mode */
 | |
|         if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
 | |
|         {
 | |
|           /* Update the linked-list queue state */
 | |
|           hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
 | |
|         }
 | |
| 
 | |
|         /* Process Unlocked */
 | |
|         __HAL_UNLOCK(hdma);
 | |
| 
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     /* Reset the channel */
 | |
|     hdma->Instance->CCR |= DMA_CCR_RESET;
 | |
| 
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_ABORT;
 | |
| 
 | |
|     /* Clear all status flags */
 | |
|     __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
 | |
|                                 DMA_FLAG_TO));
 | |
| 
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_READY;
 | |
| 
 | |
|     /* Check DMA channel transfer mode */
 | |
|     if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
 | |
|     {
 | |
|       /* Update the linked-list queue state */
 | |
|       hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
 | |
| 
 | |
|       /* Clear remaining data size to ensure loading linked-list from memory next start */
 | |
|       hdma->Instance->CBR1 = 0U;
 | |
|     }
 | |
| 
 | |
|     /* Process Unlocked */
 | |
|     __HAL_UNLOCK(hdma);
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Abort any on-going DMA channel transfer in interrupt mode (Non-blocking mode).
 | |
|   * @param  hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *const hdma)
 | |
| {
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check DMA channel state */
 | |
|   if (hdma->State != HAL_DMA_STATE_BUSY)
 | |
|   {
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_ABORT;
 | |
| 
 | |
|     /* Suspend the channel and activate suspend interrupt */
 | |
|     hdma->Instance->CCR |= (DMA_CCR_SUSP | DMA_CCR_SUSPIE);
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Polling for transfer status (Blocking mode).
 | |
|   * @param  hdma          : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                         specified DMA Channel.
 | |
|   * @param  CompleteLevel : Specifies the DMA level complete.
 | |
|   * @param  Timeout       : Timeout duration.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *const hdma,
 | |
|                                           HAL_DMA_LevelCompleteTypeDef CompleteLevel,
 | |
|                                           uint32_t Timeout)
 | |
| {
 | |
|   /* Get tick number */
 | |
|   uint32_t tickstart = HAL_GetTick();
 | |
|   uint32_t level_flag;
 | |
|   uint32_t tmp_csr;
 | |
| 
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_DMA_LEVEL_COMPLETE(CompleteLevel));
 | |
| 
 | |
|   /* Check DMA channel state */
 | |
|   if (hdma->State != HAL_DMA_STATE_BUSY)
 | |
|   {
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
 | |
| 
 | |
|     /* Process Unlocked */
 | |
|     __HAL_UNLOCK(hdma);
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Polling mode is not supported in circular mode */
 | |
|   if ((hdma->Mode & DMA_LINKEDLIST_CIRCULAR) == DMA_LINKEDLIST_CIRCULAR)
 | |
|   {
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Get the level transfer complete flag */
 | |
|   level_flag = ((CompleteLevel == HAL_DMA_FULL_TRANSFER) ? DMA_FLAG_IDLE : DMA_FLAG_HT);
 | |
| 
 | |
|   /* Get DMA channel status */
 | |
|   tmp_csr = hdma->Instance->CSR;
 | |
| 
 | |
|   while ((tmp_csr & level_flag) == 0U)
 | |
|   {
 | |
|     /* Check for the timeout */
 | |
|     if (Timeout != HAL_MAX_DELAY)
 | |
|     {
 | |
|       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
 | |
|       {
 | |
|         /* Update the DMA channel error code */
 | |
|         hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
 | |
| 
 | |
|         /*
 | |
|           If timeout, abort the current transfer.
 | |
|           Note that the Abort function will
 | |
|           - Clear all transfer flags.
 | |
|           - Unlock.
 | |
|           - Set the State.
 | |
|         */
 | |
|         (void)HAL_DMA_Abort(hdma);
 | |
| 
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     /* Get a newer CSR register value */
 | |
|     tmp_csr = hdma->Instance->CSR;
 | |
|   }
 | |
| 
 | |
|   /* Check trigger overrun flag */
 | |
|   if ((tmp_csr & DMA_FLAG_TO) != 0U)
 | |
|   {
 | |
|     /* Update the DMA channel error code */
 | |
|     hdma->ErrorCode |= HAL_DMA_ERROR_TO;
 | |
| 
 | |
|     /* Clear the error flag */
 | |
|     __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
 | |
|   }
 | |
| 
 | |
|   /* Check error flags */
 | |
|   if ((tmp_csr & (DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE)) != 0U)
 | |
|   {
 | |
|     /* Check the data transfer error flag */
 | |
|     if ((tmp_csr & DMA_FLAG_DTE) != 0U)
 | |
|     {
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
 | |
| 
 | |
|       /* Clear the error flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
 | |
|     }
 | |
| 
 | |
|     /* Check the update link error flag */
 | |
|     if ((tmp_csr & DMA_FLAG_ULE) != 0U)
 | |
|     {
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
 | |
| 
 | |
|       /* Clear the error flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
 | |
|     }
 | |
| 
 | |
|     /* Check the user setting error flag */
 | |
|     if ((tmp_csr & DMA_FLAG_USE) != 0U)
 | |
|     {
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode |= HAL_DMA_ERROR_USE;
 | |
| 
 | |
|       /* Clear the error flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
 | |
|     }
 | |
| 
 | |
|     /* Reset the channel */
 | |
|     hdma->Instance->CCR |= DMA_CCR_RESET;
 | |
| 
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_READY;
 | |
| 
 | |
|     /* Check DMA channel transfer mode */
 | |
|     if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
 | |
|     {
 | |
|       /* Update the linked-list queue state */
 | |
|       hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
 | |
|     }
 | |
| 
 | |
|     /* Process Unlocked */
 | |
|     __HAL_UNLOCK(hdma);
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Clear the transfer level flag */
 | |
|   if (CompleteLevel == HAL_DMA_HALF_TRANSFER)
 | |
|   {
 | |
|     /* Clear the Half Transfer flag */
 | |
|     __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
 | |
|   }
 | |
|   else if (CompleteLevel == HAL_DMA_FULL_TRANSFER)
 | |
|   {
 | |
|     /* Clear the transfer flags */
 | |
|     __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
 | |
| 
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_READY;
 | |
| 
 | |
|     /* Check DMA channel transfer mode */
 | |
|     if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
 | |
|     {
 | |
|       /* Update the linked-list queue state */
 | |
|       hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
 | |
|     }
 | |
| 
 | |
|     /* Process unlocked */
 | |
|     __HAL_UNLOCK(hdma);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle DMA interrupt request (Non-blocking mode).
 | |
|   * @param  hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @retval None.
 | |
|   */
 | |
| void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
 | |
| {
 | |
|   const DMA_TypeDef *p_dma_instance = GET_DMA_INSTANCE(hdma);
 | |
|   uint32_t global_it_flag =  1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
 | |
|   uint32_t global_active_flag_ns = IS_DMA_GLOBAL_ACTIVE_FLAG_NS(p_dma_instance, global_it_flag);
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|   uint32_t global_active_flag_s = IS_DMA_GLOBAL_ACTIVE_FLAG_S(p_dma_instance, global_it_flag);
 | |
| #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
 | |
| 
 | |
|   /* Global Interrupt Flag management *********************************************************************************/
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|   if ((global_active_flag_s == 0U) && (global_active_flag_ns == 0U))
 | |
| #else
 | |
|   if (global_active_flag_ns == 0U)
 | |
| #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
 | |
|   {
 | |
|     return; /* the global interrupt flag for the current channel is down , nothing to do */
 | |
|   }
 | |
| 
 | |
|   /* Data Transfer Error Interrupt management *************************************************************************/
 | |
|   if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_DTE) != 0U)
 | |
|   {
 | |
|     /* Check if interrupt source is enabled */
 | |
|     if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DTE) != 0U)
 | |
|     {
 | |
|       /* Clear the transfer error flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
 | |
| 
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Update Linked-list Error Interrupt management ********************************************************************/
 | |
|   if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_ULE) != 0U)
 | |
|   {
 | |
|     /* Check if interrupt source is enabled */
 | |
|     if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_ULE) != 0U)
 | |
|     {
 | |
|       /* Clear the update linked-list error flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
 | |
| 
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* User Setting Error Interrupt management **************************************************************************/
 | |
|   if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_USE) != 0U)
 | |
|   {
 | |
|     /* Check if interrupt source is enabled */
 | |
|     if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_USE) != 0U)
 | |
|     {
 | |
|       /* Clear the user setting error flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
 | |
| 
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode |= HAL_DMA_ERROR_USE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Trigger Overrun Interrupt management *****************************************************************************/
 | |
|   if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TO) != 0U)
 | |
|   {
 | |
|     /* Check if interrupt source is enabled */
 | |
|     if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TO) != 0U)
 | |
|     {
 | |
|       /* Clear the trigger overrun flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
 | |
| 
 | |
|       /* Update the DMA channel error code */
 | |
|       hdma->ErrorCode |= HAL_DMA_ERROR_TO;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Half Transfer Complete Interrupt management **********************************************************************/
 | |
|   if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_HT) != 0U)
 | |
|   {
 | |
|     /* Check if interrupt source is enabled */
 | |
|     if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
 | |
|     {
 | |
|       /* Clear the half transfer flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
 | |
| 
 | |
|       /* Check half transfer complete callback */
 | |
|       if (hdma->XferHalfCpltCallback != NULL)
 | |
|       {
 | |
|         /* Half transfer callback */
 | |
|         hdma->XferHalfCpltCallback(hdma);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Suspend Transfer Interrupt management ****************************************************************************/
 | |
|   if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_SUSP) != 0U)
 | |
|   {
 | |
|     /* Check if interrupt source is enabled */
 | |
|     if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_SUSP) != 0U)
 | |
|     {
 | |
|       /* Clear the block transfer complete flag */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_SUSP);
 | |
| 
 | |
|       /* Check DMA channel state */
 | |
|       if (hdma->State == HAL_DMA_STATE_ABORT)
 | |
|       {
 | |
|         /* Disable the suspend transfer interrupt */
 | |
|         __HAL_DMA_DISABLE_IT(hdma, DMA_IT_SUSP);
 | |
| 
 | |
|         /* Reset the channel internal state and reset the FIFO */
 | |
|         hdma->Instance->CCR |= DMA_CCR_RESET;
 | |
| 
 | |
|         /* Update the DMA channel state */
 | |
|         hdma->State = HAL_DMA_STATE_READY;
 | |
| 
 | |
|         /* Check DMA channel transfer mode */
 | |
|         if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
 | |
|         {
 | |
|           /* Update the linked-list queue state */
 | |
|           hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
 | |
| 
 | |
|           /* Clear remaining data size to ensure loading linked-list from memory next start */
 | |
|           hdma->Instance->CBR1 = 0U;
 | |
|         }
 | |
| 
 | |
|         /* Process Unlocked */
 | |
|         __HAL_UNLOCK(hdma);
 | |
| 
 | |
|         /* Check transfer abort callback */
 | |
|         if (hdma->XferAbortCallback != NULL)
 | |
|         {
 | |
|           /* Transfer abort callback */
 | |
|           hdma->XferAbortCallback(hdma);
 | |
|         }
 | |
| 
 | |
|         return;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Update the DMA channel state */
 | |
|         hdma->State = HAL_DMA_STATE_SUSPEND;
 | |
| 
 | |
|         /* Check transfer suspend callback */
 | |
|         if (hdma->XferSuspendCallback != NULL)
 | |
|         {
 | |
|           /* Transfer suspend callback */
 | |
|           hdma->XferSuspendCallback(hdma);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Transfer Complete Interrupt management ***************************************************************************/
 | |
|   if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U)
 | |
|   {
 | |
|     /* Check if interrupt source is enabled */
 | |
|     if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
 | |
|     {
 | |
|       /* Check DMA channel transfer mode */
 | |
|       if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
 | |
|       {
 | |
|         /* If linked-list transfer */
 | |
|         if (hdma->Instance->CLLR == 0U)
 | |
|         {
 | |
|           if (hdma->Instance->CBR1 == 0U)
 | |
|           {
 | |
|             /* Update the DMA channel state */
 | |
|             hdma->State = HAL_DMA_STATE_READY;
 | |
| 
 | |
|             /* Update the linked-list queue state */
 | |
|             hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* If normal transfer */
 | |
|         if (hdma->Instance->CBR1 == 0U)
 | |
|         {
 | |
|           /* Update the DMA channel state */
 | |
|           hdma->State = HAL_DMA_STATE_READY;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       /* Clear TC and HT transfer flags */
 | |
|       __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
 | |
| 
 | |
|       /* Process Unlocked */
 | |
|       __HAL_UNLOCK(hdma);
 | |
| 
 | |
|       /* Check transfer complete callback */
 | |
|       if (hdma->XferCpltCallback != NULL)
 | |
|       {
 | |
|         /* Channel Transfer Complete callback */
 | |
|         hdma->XferCpltCallback(hdma);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Manage error case ************************************************************************************************/
 | |
|   if (hdma->ErrorCode != HAL_DMA_ERROR_NONE)
 | |
|   {
 | |
|     /* Reset the channel internal state and reset the FIFO */
 | |
|     hdma->Instance->CCR |= DMA_CCR_RESET;
 | |
| 
 | |
|     /* Update the DMA channel state */
 | |
|     hdma->State = HAL_DMA_STATE_READY;
 | |
| 
 | |
|     /* Check DMA channel transfer mode */
 | |
|     if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
 | |
|     {
 | |
|       /* Update the linked-list queue state */
 | |
|       hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
 | |
|     }
 | |
| 
 | |
|     /* Process Unlocked */
 | |
|     __HAL_UNLOCK(hdma);
 | |
| 
 | |
|     /* Check transfer error callback */
 | |
|     if (hdma->XferErrorCallback != NULL)
 | |
|     {
 | |
|       /* Transfer error callback */
 | |
|       hdma->XferErrorCallback(hdma);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Register callback according to specified ID.
 | |
|   * @note   The HAL_DMA_RegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
 | |
|   *         to register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
 | |
|   * @param  hdma       : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                      specified DMA Channel.
 | |
|   * @param  CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enumeration.
 | |
|   * @param  pCallback  : Pointer to private callback function.
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *const hdma,
 | |
|                                            HAL_DMA_CallbackIDTypeDef CallbackID,
 | |
|                                            void (*const pCallback)(DMA_HandleTypeDef *const _hdma))
 | |
| {
 | |
|   HAL_StatusTypeDef status = HAL_OK;
 | |
| 
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check DMA channel state */
 | |
|   if (hdma->State == HAL_DMA_STATE_READY)
 | |
|   {
 | |
|     /* Check callback ID */
 | |
|     switch (CallbackID)
 | |
|     {
 | |
|       case HAL_DMA_XFER_CPLT_CB_ID:
 | |
|       {
 | |
|         /* Register transfer complete callback */
 | |
|         hdma->XferCpltCallback = pCallback;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_HALFCPLT_CB_ID:
 | |
|       {
 | |
|         /* Register half transfer callback */
 | |
|         hdma->XferHalfCpltCallback = pCallback;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_ERROR_CB_ID:
 | |
|       {
 | |
|         /* Register transfer error callback */
 | |
|         hdma->XferErrorCallback = pCallback;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_ABORT_CB_ID:
 | |
|       {
 | |
|         /* Register abort callback */
 | |
|         hdma->XferAbortCallback = pCallback;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_SUSPEND_CB_ID:
 | |
|       {
 | |
|         /* Register suspend callback */
 | |
|         hdma->XferSuspendCallback = pCallback;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       default:
 | |
|       {
 | |
|         /* Update error status */
 | |
|         status = HAL_ERROR;
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Update error status */
 | |
|     status =  HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Unregister callback according to specified ID.
 | |
|   * @note   The HAL_DMA_UnRegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
 | |
|   *         to un-register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
 | |
|   * @param  hdma       : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                      specified DMA Channel.
 | |
|   * @param  CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enum.
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *const hdma,
 | |
|                                              HAL_DMA_CallbackIDTypeDef CallbackID)
 | |
| {
 | |
|   HAL_StatusTypeDef status = HAL_OK;
 | |
| 
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check DMA channel state */
 | |
|   if (hdma->State == HAL_DMA_STATE_READY)
 | |
|   {
 | |
|     /* Check callback ID */
 | |
|     switch (CallbackID)
 | |
|     {
 | |
|       case HAL_DMA_XFER_CPLT_CB_ID:
 | |
|       {
 | |
|         /* UnRegister transfer complete callback */
 | |
|         hdma->XferCpltCallback = NULL;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_HALFCPLT_CB_ID:
 | |
|       {
 | |
|         /* UnRegister half transfer callback */
 | |
|         hdma->XferHalfCpltCallback = NULL;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_ERROR_CB_ID:
 | |
|       {
 | |
|         /* UnRegister transfer error callback */
 | |
|         hdma->XferErrorCallback = NULL;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_ABORT_CB_ID:
 | |
|       {
 | |
|         /* UnRegister abort callback */
 | |
|         hdma->XferAbortCallback = NULL;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_SUSPEND_CB_ID:
 | |
|       {
 | |
|         /* UnRegister suspend callback */
 | |
|         hdma->XferSuspendCallback = NULL;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       case HAL_DMA_XFER_ALL_CB_ID:
 | |
|       {
 | |
|         /* UnRegister all available callbacks */
 | |
|         hdma->XferCpltCallback     = NULL;
 | |
|         hdma->XferHalfCpltCallback = NULL;
 | |
|         hdma->XferErrorCallback    = NULL;
 | |
|         hdma->XferAbortCallback    = NULL;
 | |
|         hdma->XferSuspendCallback  = NULL;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       default:
 | |
|       {
 | |
|         /* Update error status */
 | |
|         status = HAL_ERROR;
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Update error status */
 | |
|     status = HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   return status;
 | |
| }
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @addtogroup DMA_Exported_Functions_Group3
 | |
|   *
 | |
| @verbatim
 | |
|   ======================================================================================================================
 | |
|                               ##### State and Errors functions #####
 | |
|   ======================================================================================================================
 | |
|     [..]
 | |
|       This section provides functions allowing to :
 | |
|       (+) Check the DMA state
 | |
|       (+) Get error code
 | |
| 
 | |
|     [..]
 | |
|       (+) The HAL_DMA_GetState() function allows to get the DMA channel state.
 | |
|       (+) The HAL_DMA_DeInit() function allows to get the DMA channel error code.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Returns the DMA channel state.
 | |
|   * @param  hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @retval DMA state.
 | |
|   */
 | |
| HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef const *const hdma)
 | |
| {
 | |
|   /* Return the DMA channel state */
 | |
|   return hdma->State;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Return the DMA channel error code.
 | |
|   * @param  hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @retval DMA Error Code.
 | |
|   */
 | |
| uint32_t HAL_DMA_GetError(DMA_HandleTypeDef const *const hdma)
 | |
| {
 | |
|   /* Return the DMA channel error code */
 | |
|   return hdma->ErrorCode;
 | |
| }
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @addtogroup DMA_Exported_Functions_Group4
 | |
|   *
 | |
| @verbatim
 | |
|   ======================================================================================================================
 | |
|                            ##### DMA Attributes functions #####
 | |
|   ======================================================================================================================
 | |
|     [..]
 | |
|       This section provides functions allowing to :
 | |
|       (+) Configure DMA channel secure and privilege attributes.
 | |
|       (+) Get DMA channel secure and privilege attributes.
 | |
|       (+) Lock DMA channel secure and privilege attributes configuration.
 | |
|       (+) Check whether DMA channel secure and privilege attributes configuration is locked or not.
 | |
| 
 | |
|     [..]
 | |
|       (+) The HAL_DMA_ConfigChannelAttributes() function allows to configure DMA channel security and privilege
 | |
|           attributes.
 | |
|       (+) The HAL_DMA_GetConfigChannelAttributes() function allows to get DMA channel security and privilege attributes
 | |
|           configuration.
 | |
|       (+) The HAL_DMA_LockChannelAttributes() function allows to lock the DMA channel security and privilege attributes.
 | |
|       (+) The HAL_DMA_GetLockChannelAttributes() function allows to get the DMA channel security and privilege
 | |
|           attributes lock status.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Configure the DMA channel security and privilege attribute(s).
 | |
|   * @note   These attributes cannot be modified when the corresponding lock state is enabled.
 | |
|   * @param  hdma              : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
 | |
|   *                             the specified DMA Channel.
 | |
|   * @param  ChannelAttributes : Specifies the DMA channel secure/privilege attributes.
 | |
|   *                             This parameter can be a one or a combination of @ref DMA_Channel_Attributes.
 | |
|   * @retval HAL Status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *const hdma, uint32_t ChannelAttributes)
 | |
| {
 | |
|   DMA_TypeDef *p_dma_instance;
 | |
|   uint32_t channel_idx;
 | |
| 
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_DMA_ATTRIBUTES(ChannelAttributes));
 | |
| 
 | |
|   /* Get DMA instance */
 | |
|   p_dma_instance = GET_DMA_INSTANCE(hdma);
 | |
| 
 | |
|   /* Get channel index */
 | |
|   channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
 | |
| 
 | |
|   /* Check DMA channel privilege attribute management */
 | |
|   if ((ChannelAttributes & DMA_CHANNEL_ATTR_PRIV_MASK) == DMA_CHANNEL_ATTR_PRIV_MASK)
 | |
|   {
 | |
|     /* Configure DMA channel privilege attribute */
 | |
|     if ((ChannelAttributes & DMA_CHANNEL_PRIV) == DMA_CHANNEL_PRIV)
 | |
|     {
 | |
|       p_dma_instance->PRIVCFGR |= channel_idx;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       p_dma_instance->PRIVCFGR &= (~channel_idx);
 | |
|     }
 | |
|   }
 | |
| 
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|   /* Check DMA channel security attribute management */
 | |
|   if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_MASK) == DMA_CHANNEL_ATTR_SEC_MASK)
 | |
|   {
 | |
|     /* Configure DMA channel security attribute */
 | |
|     if ((ChannelAttributes & DMA_CHANNEL_SEC) == DMA_CHANNEL_SEC)
 | |
|     {
 | |
|       p_dma_instance->SECCFGR |= channel_idx;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       p_dma_instance->SECCFGR &= (~channel_idx);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Channel source security attribute management */
 | |
|   if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_SRC_MASK) == DMA_CHANNEL_ATTR_SEC_SRC_MASK)
 | |
|   {
 | |
|     /* Configure DMA channel source security attribute */
 | |
|     if ((ChannelAttributes & DMA_CHANNEL_SRC_SEC) == DMA_CHANNEL_SRC_SEC)
 | |
|     {
 | |
|       hdma->Instance->CTR1 |= DMA_CTR1_SSEC;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       hdma->Instance->CTR1 &= (~DMA_CTR1_SSEC);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Channel destination security attribute management */
 | |
|   if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_DEST_MASK) == DMA_CHANNEL_ATTR_SEC_DEST_MASK)
 | |
|   {
 | |
|     /* Configure DMA channel destination security attribute */
 | |
|     if ((ChannelAttributes & DMA_CHANNEL_DEST_SEC) == DMA_CHANNEL_DEST_SEC)
 | |
|     {
 | |
|       hdma->Instance->CTR1 |= DMA_CTR1_DSEC;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       hdma->Instance->CTR1 &= (~DMA_CTR1_DSEC);
 | |
|     }
 | |
|   }
 | |
| #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Get the DMA channel security and privilege attributes.
 | |
|   * @param  hdma               : Pointer to a DMA_HandleTypeDef structure that contains the configuration information
 | |
|   *                              for the specified DMA Channel.
 | |
|   * @param  pChannelAttributes : Pointer to the returned attributes.
 | |
|   * @retval HAL Status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const *const hdma,
 | |
|                                                      uint32_t *const pChannelAttributes)
 | |
| {
 | |
|   const DMA_TypeDef *p_dma_instance;
 | |
|   uint32_t attributes;
 | |
|   uint32_t channel_idx;
 | |
| 
 | |
|   /* Check the DMA peripheral handle and channel attributes parameters */
 | |
|   if ((hdma == NULL) || (pChannelAttributes == NULL))
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Get DMA instance */
 | |
|   p_dma_instance = GET_DMA_INSTANCE(hdma);
 | |
| 
 | |
|   /* Get channel index */
 | |
|   channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
 | |
| 
 | |
|   /* Get DMA channel privilege attribute */
 | |
|   attributes = ((p_dma_instance->PRIVCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
 | |
| 
 | |
| #if defined (DMA_SECCFGR_SEC0)
 | |
|   /* Get DMA channel security attribute */
 | |
|   attributes |= ((p_dma_instance->SECCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC;
 | |
| 
 | |
|   /* Get DMA channel source security attribute */
 | |
|   attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_SSEC) == 0U) ? DMA_CHANNEL_SRC_NSEC : DMA_CHANNEL_SRC_SEC;
 | |
| 
 | |
|   /* Get DMA channel destination security attribute */
 | |
|   attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_DSEC) == 0U) ? DMA_CHANNEL_DEST_NSEC : DMA_CHANNEL_DEST_SEC;
 | |
| #endif /* DMA_SECCFGR_SEC0 */
 | |
| 
 | |
|   /* return value */
 | |
|   *pChannelAttributes = attributes;
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| #if defined (DMA_RCFGLOCKR_LOCK0)
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
| /**
 | |
|   * @brief  Lock the DMA channel security and privilege attribute(s).
 | |
|   * @param  hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @retval HAL Status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const hdma)
 | |
| {
 | |
|   DMA_TypeDef *p_dma_instance;
 | |
|   uint32_t channel_idx;
 | |
| 
 | |
|   /* Check the DMA peripheral handle parameter */
 | |
|   if (hdma == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Get DMA instance */
 | |
|   p_dma_instance = GET_DMA_INSTANCE(hdma);
 | |
| 
 | |
|   /* Get channel index */
 | |
|   channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
 | |
| 
 | |
|   /* Lock the DMA channel privilege and security attributes */
 | |
|   p_dma_instance->RCFGLOCKR |= channel_idx;
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
 | |
| 
 | |
| /**
 | |
|   * @brief  Get the security and privilege attribute lock state of a DMA channel.
 | |
|   * @param  hdma       : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                      specified DMA Channel.
 | |
|   * @param  pLockState : Pointer to lock state (returned value can be DMA_CHANNEL_ATTRIBUTE_UNLOCKED or
 | |
|   *                      DMA_CHANNEL_ATTRIBUTE_LOCKED).
 | |
|   * @retval HAL status.
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, uint32_t *const pLockState)
 | |
| {
 | |
|   const DMA_TypeDef *p_dma_instance;
 | |
|   uint32_t channel_idx;
 | |
| 
 | |
|   /* Check the DMA peripheral handle and lock state parameters */
 | |
|   if ((hdma == NULL) || (pLockState == NULL))
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Get DMA instance */
 | |
|   p_dma_instance = GET_DMA_INSTANCE(hdma);
 | |
| 
 | |
|   /* Get channel index */
 | |
|   channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
 | |
| 
 | |
|   /* Get channel lock attribute state */
 | |
|   *pLockState = ((p_dma_instance->RCFGLOCKR & channel_idx) == 0U) ? DMA_CHANNEL_ATTRIBUTE_UNLOCKED : \
 | |
|                 DMA_CHANNEL_ATTRIBUTE_LOCKED;
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| #endif /* DMA_RCFGLOCKR_LOCK0 */
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| 
 | |
| /* Private functions -------------------------------------------------------------------------------------------------*/
 | |
| /** @defgroup DMA_Private_Functions DMA Private Functions
 | |
|   * @brief    DMA Private Functions
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Set the DMA channel normal transfer parameters.
 | |
|   * @param  hdma        : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                       specified DMA Channel.
 | |
|   * @param  SrcAddress  : The source data address.
 | |
|   * @param  DstAddress  : The destination data address.
 | |
|   * @param  SrcDataSize : The length of data to be transferred from source to destination in bytes.
 | |
|   * @retval None.
 | |
|   */
 | |
| static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
 | |
|                           uint32_t SrcAddress,
 | |
|                           uint32_t DstAddress,
 | |
|                           uint32_t SrcDataSize)
 | |
| {
 | |
|   /* Configure the DMA channel data size */
 | |
|   MODIFY_REG(hdma->Instance->CBR1, DMA_CBR1_BNDT, (SrcDataSize & DMA_CBR1_BNDT));
 | |
| 
 | |
|   /* Clear all interrupt flags */
 | |
|   __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
 | |
|                        DMA_FLAG_TO);
 | |
| 
 | |
|   /* Configure DMA channel source address */
 | |
|   hdma->Instance->CSAR = SrcAddress;
 | |
| 
 | |
|   /* Configure DMA channel destination address */
 | |
|   hdma->Instance->CDAR = DstAddress;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef.
 | |
|   * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
 | |
|   *                specified DMA Channel.
 | |
|   * @retval None.
 | |
|   */
 | |
| static void DMA_Init(DMA_HandleTypeDef const *const hdma)
 | |
| {
 | |
|   uint32_t tmpreg;
 | |
| 
 | |
|   /* Prepare DMA Channel Control Register (CCR) value *****************************************************************/
 | |
|   tmpreg = hdma->Init.Priority;
 | |
| 
 | |
|   /* Write DMA Channel Control Register (CCR) */
 | |
|   MODIFY_REG(hdma->Instance->CCR, DMA_CCR_PRIO | DMA_CCR_LAP | DMA_CCR_LSM, tmpreg);
 | |
| 
 | |
|   /* Prepare DMA Channel Transfer Register (CTR1) value ***************************************************************/
 | |
|   tmpreg = hdma->Init.DestInc | hdma->Init.DestDataWidth | hdma->Init.SrcInc | hdma->Init.SrcDataWidth;
 | |
| 
 | |
|   /* Add parameters specific to GPDMA */
 | |
|   if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
 | |
|   {
 | |
|     tmpreg |= (hdma->Init.TransferAllocatedPort                                             |
 | |
|                (((hdma->Init.DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1) |
 | |
|                (((hdma->Init.SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1));
 | |
|   }
 | |
| 
 | |
|   /* Write DMA Channel Transfer Register 1 (CTR1) */
 | |
| #if defined (DMA_CTR1_SSEC)
 | |
|   MODIFY_REG(hdma->Instance->CTR1, ~(DMA_CTR1_SSEC | DMA_CTR1_DSEC), tmpreg);
 | |
| #else
 | |
|   WRITE_REG(hdma->Instance->CTR1, tmpreg);
 | |
| #endif /* DMA_CTR1_SSEC */
 | |
| 
 | |
|   /* Prepare DMA Channel Transfer Register 2 (CTR2) value *************************************************************/
 | |
|   tmpreg = hdma->Init.BlkHWRequest | (hdma->Init.Request & DMA_CTR2_REQSEL) | hdma->Init.TransferEventMode;
 | |
| 
 | |
|   /* Memory to Peripheral Transfer */
 | |
|   if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
 | |
|   {
 | |
|     if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
 | |
|     {
 | |
|       tmpreg |= DMA_CTR2_DREQ;
 | |
|     }
 | |
|   }
 | |
|   /* Memory to Memory Transfer */
 | |
|   else if ((hdma->Init.Direction) == DMA_MEMORY_TO_MEMORY)
 | |
|   {
 | |
|     tmpreg |= DMA_CTR2_SWREQ;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Nothing to do */
 | |
|   }
 | |
| 
 | |
|   /* Set DMA channel operation mode */
 | |
|   tmpreg |= hdma->Init.Mode;
 | |
| 
 | |
|   /* Write DMA Channel Transfer Register 2 (CTR2) */
 | |
|   MODIFY_REG(hdma->Instance->CTR2, (DMA_CTR2_TCEM  | DMA_CTR2_TRIGPOL | DMA_CTR2_TRIGSEL | DMA_CTR2_TRIGM |
 | |
|                                     DMA_CTR2_PFREQ | DMA_CTR2_BREQ  | DMA_CTR2_DREQ    | DMA_CTR2_SWREQ   |
 | |
|                                     DMA_CTR2_REQSEL), tmpreg);
 | |
| 
 | |
| 
 | |
|   /* Write DMA Channel Block Register 1 (CBR1) ************************************************************************/
 | |
|   WRITE_REG(hdma->Instance->CBR1, 0U);
 | |
| 
 | |
|   /* If 2D Addressing is supported by current channel */
 | |
|   if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U)
 | |
|   {
 | |
|     /* Write DMA Channel Transfer Register 3 (CTR3) *******************************************************************/
 | |
|     WRITE_REG(hdma->Instance->CTR3, 0U);
 | |
| 
 | |
|     /* Write DMA Channel Block Register 2 (CBR2) **********************************************************************/
 | |
|     WRITE_REG(hdma->Instance->CBR2, 0U);
 | |
|   }
 | |
| 
 | |
|   /* Write DMA Channel linked-list address register (CLLR) ************************************************************/
 | |
|   WRITE_REG(hdma->Instance->CLLR, 0U);
 | |
| }
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| #endif /* HAL_DMA_MODULE_ENABLED */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 |