Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_dma.c
0004   * @author  MCD Application Team
0005   * @brief   DMA HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Direct Memory Access (DMA) peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *           + Peripheral State and errors functions
0011   ******************************************************************************
0012   * @attention
0013   *
0014   * Copyright (c) 2017 STMicroelectronics.
0015   * All rights reserved.
0016   *
0017   * This software is licensed under terms that can be found in the LICENSE file
0018   * in the root directory of this software component.
0019   * If no LICENSE file comes with this software, it is provided AS-IS.
0020   *
0021   ******************************************************************************
0022   @verbatim
0023   ==============================================================================
0024                         ##### How to use this driver #####
0025   ==============================================================================
0026   [..]
0027    (#) Enable and configure the peripheral to be connected to the DMA Stream
0028        (except for internal SRAM/FLASH memories: no initialization is
0029        necessary) please refer to Reference manual for connection between peripherals
0030        and DMA requests .
0031 
0032    (#) For a given Stream, program the required configuration through the following parameters:
0033        Transfer Direction, Source and Destination data formats,
0034        Circular, Normal or peripheral flow control mode, Stream Priority level,
0035        Source and Destination Increment mode, FIFO mode and its Threshold (if needed),
0036        Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.
0037 
0038      *** Polling mode IO operation ***
0039      =================================
0040     [..]
0041           (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
0042               address and destination address and the Length of data to be transferred
0043           (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
0044               case a fixed Timeout can be configured by User depending from his application.
0045 
0046      *** Interrupt mode IO operation ***
0047      ===================================
0048     [..]
0049           (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
0050           (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
0051           (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
0052               Source address and destination address and the Length of data to be transferred. In this
0053               case the DMA interrupt is configured
0054           (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
0055           (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
0056               add his own function by customization of function pointer XferCpltCallback and
0057               XferErrorCallback (i.e a member of DMA handle structure).
0058     [..]
0059      (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
0060          detection.
0061 
0062      (#) Use HAL_DMA_Abort() function to abort the current transfer
0063 
0064      -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.
0065 
0066      -@-   The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
0067            possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
0068            Half-Word data size for the peripheral to access its data register and set Word data size
0069            for the Memory to gain in access time. Each two half words will be packed and written in
0070            a single access to a Word in the Memory).
0071 
0072      -@-   When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
0073            and Destination. In this case the Peripheral Data Size will be applied to both Source
0074            and Destination.
0075 
0076      *** DMA HAL driver macros list ***
0077      =============================================
0078      [..]
0079        Below the list of most used macros in DMA HAL driver.
0080 
0081       (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.
0082       (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.
0083       (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level.
0084       (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts.
0085       (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts.
0086       (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not.
0087 
0088      [..]
0089       (@) You can refer to the DMA HAL driver header file for more useful macros.
0090 
0091   @endverbatim
0092   */
0093 
0094 /* Includes ------------------------------------------------------------------*/
0095 #include "stm32h7xx_hal.h"
0096 
0097 /** @addtogroup STM32H7xx_HAL_Driver
0098   * @{
0099   */
0100 
0101 /** @defgroup DMA DMA
0102   * @ingroup RTEMSBSPsARMSTM32H7
0103   * @brief DMA HAL module driver
0104   * @{
0105   */
0106 
0107 #ifdef HAL_DMA_MODULE_ENABLED
0108 
0109 /* Private types -------------------------------------------------------------*/
0110 /** @addtogroup DMA_Private_Types
0111   * @{
0112   */
0113 typedef struct
0114 {
0115   __IO uint32_t ISR;   /*!< DMA interrupt status register */
0116   __IO uint32_t Reserved0;
0117   __IO uint32_t IFCR;  /*!< DMA interrupt flag clear register */
0118 } DMA_Base_Registers;
0119 
0120 typedef struct
0121 {
0122   __IO uint32_t ISR;   /*!< BDMA interrupt status register */
0123   __IO uint32_t IFCR;  /*!< BDMA interrupt flag clear register */
0124 } BDMA_Base_Registers;
0125 /**
0126   * @}
0127   */
0128 
0129 /* Private variables ---------------------------------------------------------*/
0130 /* Private constants ---------------------------------------------------------*/
0131 /** @addtogroup DMA_Private_Constants
0132  * @{
0133  */
0134 #define HAL_TIMEOUT_DMA_ABORT         (5U)  /* 5 ms */
0135 
0136 #define BDMA_PERIPH_TO_MEMORY         (0x00000000U)                /*!< Peripheral to memory direction */
0137 #define BDMA_MEMORY_TO_PERIPH         ((uint32_t)BDMA_CCR_DIR)     /*!< Memory to peripheral direction */
0138 #define BDMA_MEMORY_TO_MEMORY         ((uint32_t)BDMA_CCR_MEM2MEM) /*!< Memory to memory direction     */
0139 
0140 /* DMA to BDMA conversion */
0141 #define DMA_TO_BDMA_DIRECTION(__DMA_DIRECTION__) (((__DMA_DIRECTION__) == DMA_MEMORY_TO_PERIPH)? BDMA_MEMORY_TO_PERIPH: \
0142                                                   ((__DMA_DIRECTION__) == DMA_MEMORY_TO_MEMORY)? BDMA_MEMORY_TO_MEMORY: \
0143                                                   BDMA_PERIPH_TO_MEMORY)
0144 
0145 #define DMA_TO_BDMA_PERIPHERAL_INC(__DMA_PERIPHERAL_INC__) ((__DMA_PERIPHERAL_INC__) >> 3U)
0146 #define DMA_TO_BDMA_MEMORY_INC(__DMA_MEMORY_INC__) ((__DMA_MEMORY_INC__) >> 3U)
0147 
0148 #define DMA_TO_BDMA_PDATA_SIZE(__DMA_PDATA_SIZE__) ((__DMA_PDATA_SIZE__) >> 3U)
0149 #define DMA_TO_BDMA_MDATA_SIZE(__DMA_MDATA_SIZE__) ((__DMA_MDATA_SIZE__) >> 3U)
0150 
0151 #define DMA_TO_BDMA_MODE(__DMA_MODE__) ((__DMA_MODE__) >> 3U)
0152 
0153 #define DMA_TO_BDMA_PRIORITY(__DMA_PRIORITY__) ((__DMA_PRIORITY__) >> 4U)
0154 
0155 #if defined(UART9)
0156 #define IS_DMA_UART_USART_REQUEST(__REQUEST__) ((((__REQUEST__) >= DMA_REQUEST_USART1_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART3_TX)) || \
0157                                                  (((__REQUEST__) >= DMA_REQUEST_UART4_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART5_TX )) || \
0158                                                  (((__REQUEST__) >= DMA_REQUEST_USART6_RX) &&  ((__REQUEST__) <= DMA_REQUEST_USART6_TX)) || \
0159                                                  (((__REQUEST__) >= DMA_REQUEST_UART7_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART8_TX )) || \
0160                                                  (((__REQUEST__) >= DMA_REQUEST_UART9_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART10_TX )))
0161 #else
0162 #define IS_DMA_UART_USART_REQUEST(__REQUEST__) ((((__REQUEST__) >= DMA_REQUEST_USART1_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART3_TX)) || \
0163                                                  (((__REQUEST__) >= DMA_REQUEST_UART4_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART5_TX )) || \
0164                                                  (((__REQUEST__) >= DMA_REQUEST_USART6_RX) &&  ((__REQUEST__) <= DMA_REQUEST_USART6_TX)) || \
0165                                                  (((__REQUEST__) >= DMA_REQUEST_UART7_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART8_TX )))
0166 
0167 #endif
0168 /**
0169   * @}
0170   */
0171 /* Private macros ------------------------------------------------------------*/
0172 /* Private functions ---------------------------------------------------------*/
0173 /** @addtogroup DMA_Private_Functions
0174   * @{
0175   */
0176 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
0177 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
0178 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma);
0179 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma);
0180 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma);
0181 
0182 /**
0183   * @}
0184   */
0185 
0186 /* Exported functions ---------------------------------------------------------*/
0187 /** @addtogroup DMA_Exported_Functions
0188   * @{
0189   */
0190 
0191 /** @addtogroup DMA_Exported_Functions_Group1
0192   *
0193 @verbatim
0194  ===============================================================================
0195              ##### Initialization and de-initialization functions  #####
0196  ===============================================================================
0197     [..]
0198     This section provides functions allowing to initialize the DMA Stream source
0199     and destination incrementation and data sizes, transfer direction,
0200     circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
0201     [..]
0202     The HAL_DMA_Init() function follows the DMA configuration procedures as described in
0203     reference manual.
0204     The HAL_DMA_DeInit function allows to deinitialize the DMA stream.
0205 
0206 @endverbatim
0207   * @{
0208   */
0209 
0210 /**
0211   * @brief  Initialize the DMA according to the specified
0212   *         parameters in the DMA_InitTypeDef and create the associated handle.
0213   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
0214   *               the configuration information for the specified DMA Stream.
0215   * @retval HAL status
0216   */
0217 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
0218 {
0219   uint32_t registerValue;
0220   uint32_t tickstart = HAL_GetTick();
0221   DMA_Base_Registers *regs_dma;
0222   BDMA_Base_Registers *regs_bdma;
0223 
0224   /* Check the DMA peripheral handle */
0225   if(hdma == NULL)
0226   {
0227     return HAL_ERROR;
0228   }
0229 
0230   /* Check the parameters */
0231   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
0232   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
0233   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
0234   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
0235   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
0236   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
0237   assert_param(IS_DMA_MODE(hdma->Init.Mode));
0238   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
0239 
0240   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0241   {
0242     assert_param(IS_DMA_REQUEST(hdma->Init.Request));
0243     assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
0244     /* Check the memory burst, peripheral burst and FIFO threshold parameters only
0245        when FIFO mode is enabled */
0246     if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
0247     {
0248       assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
0249       assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
0250       assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
0251     }
0252 
0253     /* Change DMA peripheral state */
0254     hdma->State = HAL_DMA_STATE_BUSY;
0255 
0256     /* Allocate lock resource */
0257     __HAL_UNLOCK(hdma);
0258 
0259     /* Disable the peripheral */
0260     __HAL_DMA_DISABLE(hdma);
0261 
0262     /* Check if the DMA Stream is effectively disabled */
0263     while((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
0264     {
0265       /* Check for the Timeout */
0266       if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
0267       {
0268         /* Update error code */
0269         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
0270 
0271         /* Change the DMA state */
0272         hdma->State = HAL_DMA_STATE_ERROR;
0273 
0274         return HAL_ERROR;
0275       }
0276     }
0277 
0278     /* Get the CR register value */
0279     registerValue = ((DMA_Stream_TypeDef   *)hdma->Instance)->CR;
0280 
0281     /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
0282     registerValue &= ((uint32_t)~(DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
0283                         DMA_SxCR_PL    | DMA_SxCR_MSIZE  | DMA_SxCR_PSIZE  | \
0284                         DMA_SxCR_MINC  | DMA_SxCR_PINC   | DMA_SxCR_CIRC   | \
0285                         DMA_SxCR_DIR   | DMA_SxCR_CT     | DMA_SxCR_DBM));
0286 
0287     /* Prepare the DMA Stream configuration */
0288     registerValue |=  hdma->Init.Direction           |
0289             hdma->Init.PeriphInc           | hdma->Init.MemInc           |
0290             hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
0291             hdma->Init.Mode                | hdma->Init.Priority;
0292 
0293     /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
0294     if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
0295     {
0296       /* Get memory burst and peripheral burst */
0297       registerValue |=  hdma->Init.MemBurst | hdma->Init.PeriphBurst;
0298     }
0299 
0300     /* Work around for Errata 2.22: UART/USART- DMA transfer lock: DMA stream could be
0301                                     lock when transferring data to/from USART/UART */
0302 #if (STM32H7_DEV_ID == 0x450UL)
0303     if((DBGMCU->IDCODE & 0xFFFF0000U) >= 0x20000000U)
0304     {
0305 #endif /* STM32H7_DEV_ID == 0x450UL */
0306       if(IS_DMA_UART_USART_REQUEST(hdma->Init.Request) != 0U)
0307       {
0308         registerValue |= DMA_SxCR_TRBUFF;
0309       }
0310 #if (STM32H7_DEV_ID == 0x450UL)
0311     }
0312 #endif /* STM32H7_DEV_ID == 0x450UL */
0313 
0314     /* Write to DMA Stream CR register */
0315     ((DMA_Stream_TypeDef   *)hdma->Instance)->CR = registerValue;
0316 
0317     /* Get the FCR register value */
0318     registerValue = ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR;
0319 
0320     /* Clear Direct mode and FIFO threshold bits */
0321     registerValue &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
0322 
0323     /* Prepare the DMA Stream FIFO configuration */
0324     registerValue |= hdma->Init.FIFOMode;
0325 
0326     /* the FIFO threshold is not used when the FIFO mode is disabled */
0327     if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
0328     {
0329       /* Get the FIFO threshold */
0330       registerValue |= hdma->Init.FIFOThreshold;
0331 
0332       /* Check compatibility between FIFO threshold level and size of the memory burst */
0333       /* for INCR4, INCR8, INCR16 */
0334       if(hdma->Init.MemBurst != DMA_MBURST_SINGLE)
0335       {
0336         if (DMA_CheckFifoParam(hdma) != HAL_OK)
0337         {
0338           /* Update error code */
0339           hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
0340 
0341           /* Change the DMA state */
0342           hdma->State = HAL_DMA_STATE_READY;
0343 
0344           return HAL_ERROR;
0345         }
0346       }
0347     }
0348 
0349     /* Write to DMA Stream FCR */
0350     ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR = registerValue;
0351 
0352     /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
0353        DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
0354     regs_dma = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
0355 
0356     /* Clear all interrupt flags */
0357     regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
0358   }
0359   else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
0360   {
0361     if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
0362     {
0363       /* Check the request parameter */
0364       assert_param(IS_BDMA_REQUEST(hdma->Init.Request));
0365     }
0366 
0367     /* Change DMA peripheral state */
0368     hdma->State = HAL_DMA_STATE_BUSY;
0369 
0370     /* Allocate lock resource */
0371     __HAL_UNLOCK(hdma);
0372 
0373     /* Get the CR register value */
0374     registerValue = ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR;
0375 
0376     /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, MEM2MEM, DBM and CT bits */
0377     registerValue &= ((uint32_t)~(BDMA_CCR_PL    | BDMA_CCR_MSIZE   | BDMA_CCR_PSIZE  | \
0378                                   BDMA_CCR_MINC  | BDMA_CCR_PINC    | BDMA_CCR_CIRC   | \
0379                                   BDMA_CCR_DIR   | BDMA_CCR_MEM2MEM | BDMA_CCR_DBM    | \
0380                                   BDMA_CCR_CT));
0381 
0382     /* Prepare the DMA Channel configuration */
0383     registerValue |=  DMA_TO_BDMA_DIRECTION(hdma->Init.Direction)            |
0384                       DMA_TO_BDMA_PERIPHERAL_INC(hdma->Init.PeriphInc)       |
0385                       DMA_TO_BDMA_MEMORY_INC(hdma->Init.MemInc)              |
0386                       DMA_TO_BDMA_PDATA_SIZE(hdma->Init.PeriphDataAlignment) |
0387                       DMA_TO_BDMA_MDATA_SIZE(hdma->Init.MemDataAlignment)    |
0388                       DMA_TO_BDMA_MODE(hdma->Init.Mode)                      |
0389                       DMA_TO_BDMA_PRIORITY(hdma->Init.Priority);
0390 
0391     /* Write to DMA Channel CR register */
0392     ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR = registerValue;
0393 
0394     /* calculation of the channel index */
0395     hdma->StreamIndex = (((uint32_t)((uint32_t*)hdma->Instance) - (uint32_t)BDMA_Channel0) / ((uint32_t)BDMA_Channel1 - (uint32_t)BDMA_Channel0)) << 2U;
0396 
0397     /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
0398     DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
0399     regs_bdma = (BDMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
0400 
0401     /* Clear all interrupt flags */
0402     regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
0403   }
0404   else
0405   {
0406     hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
0407     hdma->State     = HAL_DMA_STATE_ERROR;
0408 
0409     return HAL_ERROR;
0410   }
0411 
0412   if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0413   {
0414     /* Initialize parameters for DMAMUX channel :
0415     DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
0416     */
0417     DMA_CalcDMAMUXChannelBaseAndMask(hdma);
0418 
0419     if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
0420     {
0421       /* if memory to memory force the request to 0*/
0422       hdma->Init.Request = DMA_REQUEST_MEM2MEM;
0423     }
0424 
0425     /* Set peripheral request  to DMAMUX channel */
0426     hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
0427 
0428     /* Clear the DMAMUX synchro overrun flag */
0429     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
0430 
0431     /* Initialize parameters for DMAMUX request generator :
0432     if the DMA request is DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR7
0433     */
0434     if((hdma->Init.Request >= DMA_REQUEST_GENERATOR0) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR7))
0435     {
0436       /* Initialize parameters for DMAMUX request generator :
0437       DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask */
0438       DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
0439 
0440       /* Reset the DMAMUX request generator register */
0441       hdma->DMAmuxRequestGen->RGCR = 0U;
0442 
0443       /* Clear the DMAMUX request generator overrun flag */
0444       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
0445     }
0446     else
0447     {
0448       hdma->DMAmuxRequestGen = 0U;
0449       hdma->DMAmuxRequestGenStatus = 0U;
0450       hdma->DMAmuxRequestGenStatusMask = 0U;
0451     }
0452   }
0453 
0454   /* Initialize the error code */
0455   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
0456 
0457   /* Initialize the DMA state */
0458   hdma->State = HAL_DMA_STATE_READY;
0459 
0460   return HAL_OK;
0461 }
0462 
0463 /**
0464   * @brief  DeInitializes the DMA peripheral
0465   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
0466   *               the configuration information for the specified DMA Stream.
0467   * @retval HAL status
0468   */
0469 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
0470 {
0471   DMA_Base_Registers *regs_dma;
0472   BDMA_Base_Registers *regs_bdma;
0473 
0474   /* Check the DMA peripheral handle */
0475   if(hdma == NULL)
0476   {
0477     return HAL_ERROR;
0478   }
0479 
0480   /* Disable the selected DMA Streamx */
0481   __HAL_DMA_DISABLE(hdma);
0482 
0483   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0484   {
0485     /* Reset DMA Streamx control register */
0486     ((DMA_Stream_TypeDef   *)hdma->Instance)->CR   = 0U;
0487 
0488     /* Reset DMA Streamx number of data to transfer register */
0489     ((DMA_Stream_TypeDef   *)hdma->Instance)->NDTR = 0U;
0490 
0491     /* Reset DMA Streamx peripheral address register */
0492     ((DMA_Stream_TypeDef   *)hdma->Instance)->PAR  = 0U;
0493 
0494     /* Reset DMA Streamx memory 0 address register */
0495     ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = 0U;
0496 
0497     /* Reset DMA Streamx memory 1 address register */
0498     ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = 0U;
0499 
0500     /* Reset DMA Streamx FIFO control register */
0501     ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR  = (uint32_t)0x00000021U;
0502 
0503     /* Get DMA steam Base Address */
0504     regs_dma = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
0505 
0506     /* Clear all interrupt flags at correct offset within the register */
0507     regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
0508   }
0509   else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
0510   {
0511     /* Reset DMA Channel control register */
0512     ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR  = 0U;
0513 
0514     /* Reset DMA Channel Number of Data to Transfer register */
0515     ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = 0U;
0516 
0517     /* Reset DMA Channel peripheral address register */
0518     ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR  = 0U;
0519 
0520     /* Reset DMA Channel memory 0 address register */
0521     ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = 0U;
0522 
0523     /* Reset DMA Channel memory 1 address register */
0524     ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = 0U;
0525 
0526     /* Get DMA steam Base Address */
0527     regs_bdma = (BDMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
0528 
0529     /* Clear all interrupt flags at correct offset within the register */
0530     regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
0531   }
0532   else
0533   {
0534     /* Return error status */
0535     return HAL_ERROR;
0536   }
0537 
0538 #if defined (BDMA1) /* No DMAMUX available for BDMA1 available on  STM32H7Ax/Bx devices only */
0539   if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0540 #endif /* BDMA1 */
0541   {
0542     /* Initialize parameters for DMAMUX channel :
0543     DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
0544     DMA_CalcDMAMUXChannelBaseAndMask(hdma);
0545 
0546     if(hdma->DMAmuxChannel != 0U)
0547     {
0548       /* Resett he DMAMUX channel that corresponds to the DMA stream */
0549       hdma->DMAmuxChannel->CCR = 0U;
0550 
0551       /* Clear the DMAMUX synchro overrun flag */
0552       hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
0553     }
0554 
0555     if((hdma->Init.Request >= DMA_REQUEST_GENERATOR0) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR7))
0556     {
0557       /* Initialize parameters for DMAMUX request generator :
0558       DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask */
0559       DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
0560 
0561       /* Reset the DMAMUX request generator register */
0562       hdma->DMAmuxRequestGen->RGCR = 0U;
0563 
0564       /* Clear the DMAMUX request generator overrun flag */
0565       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
0566     }
0567 
0568     hdma->DMAmuxRequestGen = 0U;
0569     hdma->DMAmuxRequestGenStatus = 0U;
0570     hdma->DMAmuxRequestGenStatusMask = 0U;
0571   }
0572 
0573 
0574   /* Clean callbacks */
0575   hdma->XferCpltCallback       = NULL;
0576   hdma->XferHalfCpltCallback   = NULL;
0577   hdma->XferM1CpltCallback     = NULL;
0578   hdma->XferM1HalfCpltCallback = NULL;
0579   hdma->XferErrorCallback      = NULL;
0580   hdma->XferAbortCallback      = NULL;
0581 
0582   /* Initialize the error code */
0583   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
0584 
0585   /* Initialize the DMA state */
0586   hdma->State = HAL_DMA_STATE_RESET;
0587 
0588   /* Release Lock */
0589   __HAL_UNLOCK(hdma);
0590 
0591   return HAL_OK;
0592 }
0593 
0594 /**
0595   * @}
0596   */
0597 
0598 /** @addtogroup DMA_Exported_Functions_Group2
0599   *
0600 @verbatim
0601  ===============================================================================
0602                       #####  IO operation functions  #####
0603  ===============================================================================
0604     [..]  This section provides functions allowing to:
0605       (+) Configure the source, destination address and data length and Start DMA transfer
0606       (+) Configure the source, destination address and data length and
0607           Start DMA transfer with interrupt
0608       (+) Register and Unregister DMA callbacks
0609       (+) Abort DMA transfer
0610       (+) Poll for transfer complete
0611       (+) Handle DMA interrupt request
0612 
0613 @endverbatim
0614   * @{
0615   */
0616 
0617 /**
0618   * @brief  Starts the DMA Transfer.
0619   * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains
0620   *                     the configuration information for the specified DMA Stream.
0621   * @param  SrcAddress: The source memory Buffer address
0622   * @param  DstAddress: The destination memory Buffer address
0623   * @param  DataLength: The length of data to be transferred from source to destination
0624   * @retval HAL status
0625   */
0626 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
0627 {
0628   HAL_StatusTypeDef status = HAL_OK;
0629 
0630   /* Check the parameters */
0631   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
0632 
0633   /* Check the DMA peripheral handle */
0634   if(hdma == NULL)
0635   {
0636     return HAL_ERROR;
0637   }
0638 
0639   /* Process locked */
0640   __HAL_LOCK(hdma);
0641 
0642   if(HAL_DMA_STATE_READY == hdma->State)
0643   {
0644     /* Change DMA peripheral state */
0645     hdma->State = HAL_DMA_STATE_BUSY;
0646 
0647     /* Initialize the error code */
0648     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
0649 
0650     /* Disable the peripheral */
0651     __HAL_DMA_DISABLE(hdma);
0652 
0653     /* Configure the source, destination address and the data length */
0654     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
0655 
0656     /* Enable the Peripheral */
0657     __HAL_DMA_ENABLE(hdma);
0658   }
0659   else
0660   {
0661     /* Set the error code to busy */
0662     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
0663 
0664     /* Process unlocked */
0665     __HAL_UNLOCK(hdma);
0666 
0667     /* Return error status */
0668     status = HAL_ERROR;
0669   }
0670   return status;
0671 }
0672 
0673 /**
0674   * @brief  Start the DMA Transfer with interrupt enabled.
0675   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
0676   *                     the configuration information for the specified DMA Stream.
0677   * @param  SrcAddress: The source memory Buffer address
0678   * @param  DstAddress: The destination memory Buffer address
0679   * @param  DataLength: The length of data to be transferred from source to destination
0680   * @retval HAL status
0681   */
0682 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
0683 {
0684   HAL_StatusTypeDef status = HAL_OK;
0685 
0686   /* Check the parameters */
0687   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
0688 
0689   /* Check the DMA peripheral handle */
0690   if(hdma == NULL)
0691   {
0692     return HAL_ERROR;
0693   }
0694 
0695   /* Process locked */
0696   __HAL_LOCK(hdma);
0697 
0698   if(HAL_DMA_STATE_READY == hdma->State)
0699   {
0700     /* Change DMA peripheral state */
0701     hdma->State = HAL_DMA_STATE_BUSY;
0702 
0703     /* Initialize the error code */
0704     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
0705 
0706     /* Disable the peripheral */
0707     __HAL_DMA_DISABLE(hdma);
0708 
0709     /* Configure the source, destination address and the data length */
0710     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
0711 
0712     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0713     {
0714       /* Enable Common interrupts*/
0715       MODIFY_REG(((DMA_Stream_TypeDef   *)hdma->Instance)->CR, (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT), (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME));
0716 
0717       if(hdma->XferHalfCpltCallback != NULL)
0718       {
0719         /* Enable Half Transfer IT if corresponding Callback is set */
0720         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  |= DMA_IT_HT;
0721       }
0722     }
0723     else /* BDMA channel */
0724     {
0725       /* Enable Common interrupts */
0726       MODIFY_REG(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR, (BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE), (BDMA_CCR_TCIE | BDMA_CCR_TEIE));
0727 
0728       if(hdma->XferHalfCpltCallback != NULL)
0729       {
0730         /*Enable Half Transfer IT if corresponding Callback is set */
0731         ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  |= BDMA_CCR_HTIE;
0732       }
0733     }
0734 
0735     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0736     {
0737       /* Check if DMAMUX Synchronization is enabled */
0738       if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
0739       {
0740         /* Enable DMAMUX sync overrun IT*/
0741         hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
0742       }
0743 
0744       if(hdma->DMAmuxRequestGen != 0U)
0745       {
0746         /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
0747         /* enable the request gen overrun IT */
0748         hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
0749       }
0750     }
0751 
0752     /* Enable the Peripheral */
0753     __HAL_DMA_ENABLE(hdma);
0754   }
0755   else
0756   {
0757     /* Set the error code to busy */
0758     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
0759 
0760     /* Process unlocked */
0761     __HAL_UNLOCK(hdma);
0762 
0763     /* Return error status */
0764     status = HAL_ERROR;
0765   }
0766 
0767   return status;
0768 }
0769 
0770 /**
0771   * @brief  Aborts the DMA Transfer.
0772   * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
0773   *                 the configuration information for the specified DMA Stream.
0774   *
0775   * @note  After disabling a DMA Stream, a check for wait until the DMA Stream is
0776   *        effectively disabled is added. If a Stream is disabled
0777   *        while a data transfer is ongoing, the current data will be transferred
0778   *        and the Stream will be effectively disabled only after the transfer of
0779   *        this single data is finished.
0780   * @retval HAL status
0781   */
0782 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
0783 {
0784   /* calculate DMA base and stream number */
0785   DMA_Base_Registers *regs_dma;
0786   BDMA_Base_Registers *regs_bdma;
0787   const __IO uint32_t *enableRegister;
0788 
0789   uint32_t tickstart = HAL_GetTick();
0790 
0791  /* Check the DMA peripheral handle */
0792   if(hdma == NULL)
0793   {
0794     return HAL_ERROR;
0795   }
0796 
0797   /* Check the DMA peripheral state */
0798   if(hdma->State != HAL_DMA_STATE_BUSY)
0799   {
0800     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
0801 
0802     /* Process Unlocked */
0803     __HAL_UNLOCK(hdma);
0804 
0805     return HAL_ERROR;
0806   }
0807   else
0808   {
0809     /* Disable all the transfer interrupts */
0810     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0811     {
0812        /* Disable DMA All Interrupts  */
0813       ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT);
0814       ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR &= ~(DMA_IT_FE);
0815 
0816       enableRegister = (__IO uint32_t *)(&(((DMA_Stream_TypeDef   *)hdma->Instance)->CR));
0817     }
0818     else /* BDMA channel */
0819     {
0820       /* Disable DMA All Interrupts */
0821       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);
0822 
0823       enableRegister = (__IO uint32_t *)(&(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR));
0824     }
0825 
0826     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0827     {
0828       /* disable the DMAMUX sync overrun IT */
0829       hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
0830     }
0831 
0832     /* Disable the stream */
0833     __HAL_DMA_DISABLE(hdma);
0834 
0835     /* Check if the DMA Stream is effectively disabled */
0836     while(((*enableRegister) & DMA_SxCR_EN) != 0U)
0837     {
0838       /* Check for the Timeout */
0839       if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
0840       {
0841         /* Update error code */
0842         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
0843 
0844         /* Change the DMA state */
0845         hdma->State = HAL_DMA_STATE_ERROR;
0846 
0847         /* Process Unlocked */
0848         __HAL_UNLOCK(hdma);
0849 
0850         return HAL_ERROR;
0851       }
0852     }
0853 
0854     /* Clear all interrupt flags at correct offset within the register */
0855     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0856     {
0857       regs_dma = (DMA_Base_Registers *)hdma->StreamBaseAddress;
0858       regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
0859     }
0860     else /* BDMA channel */
0861     {
0862       regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
0863       regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
0864     }
0865 
0866     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0867     {
0868       /* Clear the DMAMUX synchro overrun flag */
0869       hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
0870 
0871       if(hdma->DMAmuxRequestGen != 0U)
0872       {
0873         /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT */
0874         /* disable the request gen overrun IT */
0875         hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
0876 
0877         /* Clear the DMAMUX request generator overrun flag */
0878         hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
0879       }
0880     }
0881 
0882     /* Change the DMA state */
0883     hdma->State = HAL_DMA_STATE_READY;
0884 
0885     /* Process Unlocked */
0886     __HAL_UNLOCK(hdma);
0887   }
0888 
0889   return HAL_OK;
0890 }
0891 
0892 /**
0893   * @brief  Aborts the DMA Transfer in Interrupt mode.
0894   * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
0895   *                 the configuration information for the specified DMA Stream.
0896   * @retval HAL status
0897   */
0898 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
0899 {
0900   BDMA_Base_Registers *regs_bdma;
0901 
0902   /* Check the DMA peripheral handle */
0903   if(hdma == NULL)
0904   {
0905     return HAL_ERROR;
0906   }
0907 
0908   if(hdma->State != HAL_DMA_STATE_BUSY)
0909   {
0910     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
0911     return HAL_ERROR;
0912   }
0913   else
0914   {
0915     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
0916     {
0917       /* Set Abort State  */
0918       hdma->State = HAL_DMA_STATE_ABORT;
0919 
0920       /* Disable the stream */
0921       __HAL_DMA_DISABLE(hdma);
0922     }
0923     else /* BDMA channel */
0924     {
0925       /* Disable DMA All Interrupts  */
0926       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);
0927 
0928       /* Disable the channel */
0929       __HAL_DMA_DISABLE(hdma);
0930 
0931       if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
0932       {
0933         /* disable the DMAMUX sync overrun IT */
0934         hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
0935 
0936         /* Clear all flags */
0937         regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
0938         regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
0939 
0940         /* Clear the DMAMUX synchro overrun flag */
0941         hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
0942 
0943         if(hdma->DMAmuxRequestGen != 0U)
0944         {
0945           /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
0946           /* disable the request gen overrun IT */
0947           hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
0948 
0949           /* Clear the DMAMUX request generator overrun flag */
0950           hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
0951         }
0952       }
0953 
0954       /* Change the DMA state */
0955       hdma->State = HAL_DMA_STATE_READY;
0956 
0957       /* Process Unlocked */
0958       __HAL_UNLOCK(hdma);
0959 
0960       /* Call User Abort callback */
0961       if(hdma->XferAbortCallback != NULL)
0962       {
0963         hdma->XferAbortCallback(hdma);
0964       }
0965     }
0966   }
0967 
0968   return HAL_OK;
0969 }
0970 
0971 /**
0972   * @brief  Polling for transfer complete.
0973   * @param  hdma:          pointer to a DMA_HandleTypeDef structure that contains
0974   *                        the configuration information for the specified DMA Stream.
0975   * @param  CompleteLevel: Specifies the DMA level complete.
0976   * @note   The polling mode is kept in this version for legacy. it is recommended to use the IT model instead.
0977   *         This model could be used for debug purpose.
0978   * @note   The HAL_DMA_PollForTransfer API cannot be used in circular and double buffering mode (automatic circular mode).
0979   * @param  Timeout:       Timeout duration.
0980   * @retval HAL status
0981   */
0982 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
0983 {
0984   HAL_StatusTypeDef status = HAL_OK;
0985   uint32_t cpltlevel_mask;
0986   uint32_t tickstart = HAL_GetTick();
0987 
0988   /* IT status register */
0989   __IO uint32_t *isr_reg;
0990   /* IT clear flag register */
0991   __IO uint32_t *ifcr_reg;
0992 
0993   /* Check the DMA peripheral handle */
0994   if(hdma == NULL)
0995   {
0996     return HAL_ERROR;
0997   }
0998 
0999   if(HAL_DMA_STATE_BUSY != hdma->State)
1000   {
1001     /* No transfer ongoing */
1002     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
1003     __HAL_UNLOCK(hdma);
1004 
1005     return HAL_ERROR;
1006   }
1007 
1008   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1009   {
1010     /* Polling mode not supported in circular mode and double buffering mode */
1011     if ((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) != 0U)
1012     {
1013       hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
1014       return HAL_ERROR;
1015     }
1016 
1017     /* Get the level transfer complete flag */
1018     if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
1019     {
1020       /* Transfer Complete flag */
1021       cpltlevel_mask = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
1022     }
1023     else
1024     {
1025       /* Half Transfer Complete flag */
1026       cpltlevel_mask = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
1027     }
1028 
1029     isr_reg  = &(((DMA_Base_Registers *)hdma->StreamBaseAddress)->ISR);
1030     ifcr_reg = &(((DMA_Base_Registers *)hdma->StreamBaseAddress)->IFCR);
1031   }
1032   else /* BDMA channel */
1033   {
1034     /* Polling mode not supported in circular mode */
1035     if ((((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR & BDMA_CCR_CIRC) != 0U)
1036     {
1037       hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
1038       return HAL_ERROR;
1039     }
1040 
1041     /* Get the level transfer complete flag */
1042     if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
1043     {
1044       /* Transfer Complete flag */
1045       cpltlevel_mask = BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU);
1046     }
1047     else
1048     {
1049       /* Half Transfer Complete flag */
1050       cpltlevel_mask = BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU);
1051     }
1052 
1053     isr_reg  = &(((BDMA_Base_Registers *)hdma->StreamBaseAddress)->ISR);
1054     ifcr_reg = &(((BDMA_Base_Registers *)hdma->StreamBaseAddress)->IFCR);
1055   }
1056 
1057   while(((*isr_reg) & cpltlevel_mask) == 0U)
1058   {
1059     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1060     {
1061       if(((*isr_reg) & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1062       {
1063         /* Update error code */
1064         hdma->ErrorCode |= HAL_DMA_ERROR_FE;
1065 
1066         /* Clear the FIFO error flag */
1067         (*ifcr_reg) = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
1068       }
1069 
1070       if(((*isr_reg) & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1071       {
1072         /* Update error code */
1073         hdma->ErrorCode |= HAL_DMA_ERROR_DME;
1074 
1075         /* Clear the Direct Mode error flag */
1076         (*ifcr_reg) = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
1077       }
1078 
1079       if(((*isr_reg) & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1080       {
1081         /* Update error code */
1082         hdma->ErrorCode |= HAL_DMA_ERROR_TE;
1083 
1084         /* Clear the transfer error flag */
1085         (*ifcr_reg) = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
1086 
1087         /* Change the DMA state */
1088         hdma->State = HAL_DMA_STATE_READY;
1089 
1090         /* Process Unlocked */
1091         __HAL_UNLOCK(hdma);
1092 
1093         return HAL_ERROR;
1094       }
1095     }
1096     else /* BDMA channel */
1097     {
1098       if(((*isr_reg) & (BDMA_FLAG_TE0 << (hdma->StreamIndex & 0x1FU))) != 0U)
1099       {
1100         /* When a DMA transfer error occurs */
1101         /* A hardware clear of its EN bits is performed */
1102         /* Clear all flags */
1103         (*isr_reg) = ((BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU));
1104 
1105         /* Update error code */
1106         hdma->ErrorCode = HAL_DMA_ERROR_TE;
1107 
1108         /* Change the DMA state */
1109         hdma->State = HAL_DMA_STATE_READY;
1110 
1111         /* Process Unlocked */
1112         __HAL_UNLOCK(hdma);
1113 
1114         return HAL_ERROR;
1115       }
1116     }
1117 
1118     /* Check for the Timeout (Not applicable in circular mode)*/
1119     if(Timeout != HAL_MAX_DELAY)
1120     {
1121       if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
1122       {
1123         /* Update error code */
1124         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
1125 
1126         /* if timeout then abort the current transfer */
1127         /* No need to check return value: as in this case we will return HAL_ERROR with HAL_DMA_ERROR_TIMEOUT error code  */
1128         (void) HAL_DMA_Abort(hdma);
1129           /*
1130             Note that the Abort function will
1131               - Clear the transfer error flags
1132               - Unlock
1133               - Set the State
1134           */
1135 
1136         return HAL_ERROR;
1137       }
1138     }
1139 
1140     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
1141     {
1142       /* Check for DMAMUX Request generator (if used) overrun status */
1143       if(hdma->DMAmuxRequestGen != 0U)
1144       {
1145         /* if using DMAMUX request generator Check for DMAMUX request generator overrun */
1146         if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
1147         {
1148           /* Clear the DMAMUX request generator overrun flag */
1149           hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
1150 
1151           /* Update error code */
1152           hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
1153         }
1154       }
1155 
1156       /* Check for DMAMUX Synchronization overrun */
1157       if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
1158       {
1159         /* Clear the DMAMUX synchro overrun flag */
1160         hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1161 
1162         /* Update error code */
1163         hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
1164       }
1165     }
1166   }
1167 
1168 
1169   /* Get the level transfer complete flag */
1170   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
1171   {
1172     /* Clear the half transfer and transfer complete flags */
1173     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1174     {
1175       (*ifcr_reg) = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << (hdma->StreamIndex & 0x1FU);
1176     }
1177     else /* BDMA channel */
1178     {
1179       (*ifcr_reg) = (BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU));
1180     }
1181 
1182     hdma->State = HAL_DMA_STATE_READY;
1183 
1184     /* Process Unlocked */
1185     __HAL_UNLOCK(hdma);
1186   }
1187   else /*CompleteLevel = HAL_DMA_HALF_TRANSFER*/
1188   {
1189     /* Clear the half transfer and transfer complete flags */
1190     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1191     {
1192       (*ifcr_reg) = (DMA_FLAG_HTIF0_4) << (hdma->StreamIndex & 0x1FU);
1193     }
1194     else /* BDMA channel */
1195     {
1196       (*ifcr_reg) = (BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU));
1197     }
1198   }
1199 
1200   return status;
1201 }
1202 
1203 /**
1204   * @brief  Handles DMA interrupt request.
1205   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1206   *               the configuration information for the specified DMA Stream.
1207   * @retval None
1208   */
1209 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
1210 {
1211   uint32_t tmpisr_dma, tmpisr_bdma;
1212   uint32_t ccr_reg;
1213   __IO uint32_t count = 0U;
1214   uint32_t timeout = SystemCoreClock / 9600U;
1215 
1216   /* calculate DMA base and stream number */
1217   DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
1218   BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
1219 
1220   tmpisr_dma  = regs_dma->ISR;
1221   tmpisr_bdma = regs_bdma->ISR;
1222 
1223   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U)  /* DMA1 or DMA2 instance */
1224   {
1225     /* Transfer Error Interrupt management ***************************************/
1226     if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1227     {
1228       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != 0U)
1229       {
1230         /* Disable the transfer error interrupt */
1231         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TE);
1232 
1233         /* Clear the transfer error flag */
1234         regs_dma->IFCR = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
1235 
1236         /* Update error code */
1237         hdma->ErrorCode |= HAL_DMA_ERROR_TE;
1238       }
1239     }
1240     /* FIFO Error Interrupt management ******************************************/
1241     if ((tmpisr_dma & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1242     {
1243       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != 0U)
1244       {
1245         /* Clear the FIFO error flag */
1246         regs_dma->IFCR = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
1247 
1248         /* Update error code */
1249         hdma->ErrorCode |= HAL_DMA_ERROR_FE;
1250       }
1251     }
1252     /* Direct Mode Error Interrupt management ***********************************/
1253     if ((tmpisr_dma & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1254     {
1255       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != 0U)
1256       {
1257         /* Clear the direct mode error flag */
1258         regs_dma->IFCR = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
1259 
1260         /* Update error code */
1261         hdma->ErrorCode |= HAL_DMA_ERROR_DME;
1262       }
1263     }
1264     /* Half Transfer Complete Interrupt management ******************************/
1265     if ((tmpisr_dma & (DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1266     {
1267       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
1268       {
1269         /* Clear the half transfer complete flag */
1270         regs_dma->IFCR = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
1271 
1272         /* Multi_Buffering mode enabled */
1273         if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
1274         {
1275           /* Current memory buffer used is Memory 0 */
1276           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
1277           {
1278             if(hdma->XferHalfCpltCallback != NULL)
1279             {
1280               /* Half transfer callback */
1281               hdma->XferHalfCpltCallback(hdma);
1282             }
1283           }
1284           /* Current memory buffer used is Memory 1 */
1285           else
1286           {
1287             if(hdma->XferM1HalfCpltCallback != NULL)
1288             {
1289               /* Half transfer callback */
1290               hdma->XferM1HalfCpltCallback(hdma);
1291             }
1292           }
1293         }
1294         else
1295         {
1296           /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
1297           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
1298           {
1299             /* Disable the half transfer interrupt */
1300             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_HT);
1301           }
1302 
1303           if(hdma->XferHalfCpltCallback != NULL)
1304           {
1305             /* Half transfer callback */
1306             hdma->XferHalfCpltCallback(hdma);
1307           }
1308         }
1309       }
1310     }
1311     /* Transfer Complete Interrupt management ***********************************/
1312     if ((tmpisr_dma & (DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1313     {
1314       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
1315       {
1316         /* Clear the transfer complete flag */
1317         regs_dma->IFCR = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
1318 
1319         if(HAL_DMA_STATE_ABORT == hdma->State)
1320         {
1321           /* Disable all the transfer interrupts */
1322           ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
1323           ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR &= ~(DMA_IT_FE);
1324 
1325           if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
1326           {
1327             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_HT);
1328           }
1329 
1330           /* Clear all interrupt flags at correct offset within the register */
1331           regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
1332 
1333           /* Change the DMA state */
1334           hdma->State = HAL_DMA_STATE_READY;
1335 
1336           /* Process Unlocked */
1337           __HAL_UNLOCK(hdma);
1338 
1339           if(hdma->XferAbortCallback != NULL)
1340           {
1341             hdma->XferAbortCallback(hdma);
1342           }
1343           return;
1344         }
1345 
1346         if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
1347         {
1348           /* Current memory buffer used is Memory 0 */
1349           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
1350           {
1351             if(hdma->XferM1CpltCallback != NULL)
1352             {
1353               /* Transfer complete Callback for memory1 */
1354               hdma->XferM1CpltCallback(hdma);
1355             }
1356           }
1357           /* Current memory buffer used is Memory 1 */
1358           else
1359           {
1360             if(hdma->XferCpltCallback != NULL)
1361             {
1362               /* Transfer complete Callback for memory0 */
1363               hdma->XferCpltCallback(hdma);
1364             }
1365           }
1366         }
1367         /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
1368         else
1369         {
1370           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
1371           {
1372             /* Disable the transfer complete interrupt */
1373             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC);
1374 
1375             /* Change the DMA state */
1376             hdma->State = HAL_DMA_STATE_READY;
1377 
1378             /* Process Unlocked */
1379             __HAL_UNLOCK(hdma);
1380           }
1381 
1382           if(hdma->XferCpltCallback != NULL)
1383           {
1384             /* Transfer complete callback */
1385             hdma->XferCpltCallback(hdma);
1386           }
1387         }
1388       }
1389     }
1390 
1391     /* manage error case */
1392     if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
1393     {
1394       if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != 0U)
1395       {
1396         hdma->State = HAL_DMA_STATE_ABORT;
1397 
1398         /* Disable the stream */
1399         __HAL_DMA_DISABLE(hdma);
1400 
1401         do
1402         {
1403           if (++count > timeout)
1404           {
1405             break;
1406           }
1407         }
1408         while((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U);
1409 
1410         if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
1411         {
1412           /* Change the DMA state to error if DMA disable fails */
1413           hdma->State = HAL_DMA_STATE_ERROR;
1414         }
1415         else
1416         {
1417           /* Change the DMA state to Ready if DMA disable success */
1418           hdma->State = HAL_DMA_STATE_READY;
1419         }
1420 
1421         /* Process Unlocked */
1422         __HAL_UNLOCK(hdma);
1423       }
1424 
1425       if(hdma->XferErrorCallback != NULL)
1426       {
1427         /* Transfer error callback */
1428         hdma->XferErrorCallback(hdma);
1429       }
1430     }
1431   }
1432   else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U)  /* BDMA instance(s) */
1433   {
1434     ccr_reg = (((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR);
1435 
1436     /* Half Transfer Complete Interrupt management ******************************/
1437     if (((tmpisr_bdma & (BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_HTIE) != 0U))
1438     {
1439       /* Clear the half transfer complete flag */
1440       regs_bdma->IFCR = (BDMA_ISR_HTIF0 << (hdma->StreamIndex & 0x1FU));
1441 
1442       /* Disable the transfer complete interrupt if the DMA mode is Double Buffering */
1443       if((ccr_reg & BDMA_CCR_DBM) != 0U)
1444       {
1445         /* Current memory buffer used is Memory 0 */
1446         if((ccr_reg & BDMA_CCR_CT) == 0U)
1447         {
1448           if(hdma->XferM1HalfCpltCallback != NULL)
1449           {
1450             /* Half transfer Callback for Memory 1 */
1451             hdma->XferM1HalfCpltCallback(hdma);
1452           }
1453         }
1454         /* Current memory buffer used is Memory 1 */
1455         else
1456         {
1457           if(hdma->XferHalfCpltCallback != NULL)
1458           {
1459             /* Half transfer Callback for Memory 0 */
1460             hdma->XferHalfCpltCallback(hdma);
1461           }
1462         }
1463       }
1464       else
1465       {
1466         if((ccr_reg & BDMA_CCR_CIRC) == 0U)
1467         {
1468           /* Disable the half transfer interrupt */
1469           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
1470         }
1471 
1472         /* DMA peripheral state is not updated in Half Transfer */
1473         /* but in Transfer Complete case */
1474 
1475        if(hdma->XferHalfCpltCallback != NULL)
1476         {
1477           /* Half transfer callback */
1478           hdma->XferHalfCpltCallback(hdma);
1479         }
1480       }
1481     }
1482 
1483     /* Transfer Complete Interrupt management ***********************************/
1484     else if (((tmpisr_bdma & (BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_TCIE) != 0U))
1485     {
1486       /* Clear the transfer complete flag */
1487       regs_bdma->IFCR = (BDMA_ISR_TCIF0) << (hdma->StreamIndex & 0x1FU);
1488 
1489       /* Disable the transfer complete interrupt if the DMA mode is Double Buffering */
1490       if((ccr_reg & BDMA_CCR_DBM) != 0U)
1491       {
1492         /* Current memory buffer used is Memory 0 */
1493         if((ccr_reg & BDMA_CCR_CT) == 0U)
1494         {
1495           if(hdma->XferM1CpltCallback != NULL)
1496           {
1497             /* Transfer complete Callback for Memory 1 */
1498             hdma->XferM1CpltCallback(hdma);
1499           }
1500         }
1501         /* Current memory buffer used is Memory 1 */
1502         else
1503         {
1504           if(hdma->XferCpltCallback != NULL)
1505           {
1506             /* Transfer complete Callback for Memory 0 */
1507             hdma->XferCpltCallback(hdma);
1508           }
1509         }
1510       }
1511       else
1512       {
1513         if((ccr_reg & BDMA_CCR_CIRC) == 0U)
1514         {
1515           /* Disable the transfer complete and error interrupt, if the DMA mode is not CIRCULAR */
1516           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
1517 
1518           /* Change the DMA state */
1519           hdma->State = HAL_DMA_STATE_READY;
1520 
1521           /* Process Unlocked */
1522           __HAL_UNLOCK(hdma);
1523         }
1524 
1525         if(hdma->XferCpltCallback != NULL)
1526         {
1527           /* Transfer complete callback */
1528           hdma->XferCpltCallback(hdma);
1529         }
1530       }
1531     }
1532     /* Transfer Error Interrupt management **************************************/
1533     else if (((tmpisr_bdma & (BDMA_FLAG_TE0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_TEIE) != 0U))
1534     {
1535       /* When a DMA transfer error occurs */
1536       /* A hardware clear of its EN bits is performed */
1537       /* Disable ALL DMA IT */
1538       __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
1539 
1540       /* Clear all flags */
1541       regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
1542 
1543       /* Update error code */
1544       hdma->ErrorCode = HAL_DMA_ERROR_TE;
1545 
1546       /* Change the DMA state */
1547       hdma->State = HAL_DMA_STATE_READY;
1548 
1549       /* Process Unlocked */
1550       __HAL_UNLOCK(hdma);
1551 
1552       if (hdma->XferErrorCallback != NULL)
1553       {
1554         /* Transfer error callback */
1555         hdma->XferErrorCallback(hdma);
1556       }
1557     }
1558     else
1559     {
1560       /* Nothing To Do */
1561     }
1562   }
1563   else
1564   {
1565     /* Nothing To Do */
1566   }
1567 }
1568 
1569 /**
1570   * @brief  Register callbacks
1571   * @param  hdma:                 pointer to a DMA_HandleTypeDef structure that contains
1572   *                               the configuration information for the specified DMA Stream.
1573   * @param  CallbackID:           User Callback identifier
1574   *                               a DMA_HandleTypeDef structure as parameter.
1575   * @param  pCallback:            pointer to private callback function which has pointer to
1576   *                               a DMA_HandleTypeDef structure as parameter.
1577   * @retval HAL status
1578   */
1579 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
1580 {
1581 
1582   HAL_StatusTypeDef status = HAL_OK;
1583 
1584   /* Check the DMA peripheral handle */
1585   if(hdma == NULL)
1586   {
1587     return HAL_ERROR;
1588   }
1589 
1590   /* Process locked */
1591   __HAL_LOCK(hdma);
1592 
1593   if(HAL_DMA_STATE_READY == hdma->State)
1594   {
1595     switch (CallbackID)
1596     {
1597     case  HAL_DMA_XFER_CPLT_CB_ID:
1598       hdma->XferCpltCallback = pCallback;
1599       break;
1600 
1601     case  HAL_DMA_XFER_HALFCPLT_CB_ID:
1602       hdma->XferHalfCpltCallback = pCallback;
1603       break;
1604 
1605     case  HAL_DMA_XFER_M1CPLT_CB_ID:
1606       hdma->XferM1CpltCallback = pCallback;
1607       break;
1608 
1609     case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
1610       hdma->XferM1HalfCpltCallback = pCallback;
1611       break;
1612 
1613     case  HAL_DMA_XFER_ERROR_CB_ID:
1614       hdma->XferErrorCallback = pCallback;
1615       break;
1616 
1617     case  HAL_DMA_XFER_ABORT_CB_ID:
1618       hdma->XferAbortCallback = pCallback;
1619       break;
1620 
1621     default:
1622       status =  HAL_ERROR;
1623       break;
1624     }
1625   }
1626   else
1627   {
1628     /* Return error status */
1629     status =  HAL_ERROR;
1630   }
1631 
1632   /* Release Lock */
1633   __HAL_UNLOCK(hdma);
1634 
1635   return status;
1636 }
1637 
1638 /**
1639   * @brief  UnRegister callbacks
1640   * @param  hdma:                 pointer to a DMA_HandleTypeDef structure that contains
1641   *                               the configuration information for the specified DMA Stream.
1642   * @param  CallbackID:           User Callback identifier
1643   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
1644   * @retval HAL status
1645   */
1646 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
1647 {
1648   HAL_StatusTypeDef status = HAL_OK;
1649 
1650   /* Check the DMA peripheral handle */
1651   if(hdma == NULL)
1652   {
1653     return HAL_ERROR;
1654   }
1655 
1656   /* Process locked */
1657   __HAL_LOCK(hdma);
1658 
1659   if(HAL_DMA_STATE_READY == hdma->State)
1660   {
1661     switch (CallbackID)
1662     {
1663     case  HAL_DMA_XFER_CPLT_CB_ID:
1664       hdma->XferCpltCallback = NULL;
1665       break;
1666 
1667     case  HAL_DMA_XFER_HALFCPLT_CB_ID:
1668       hdma->XferHalfCpltCallback = NULL;
1669       break;
1670 
1671     case  HAL_DMA_XFER_M1CPLT_CB_ID:
1672       hdma->XferM1CpltCallback = NULL;
1673       break;
1674 
1675     case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
1676       hdma->XferM1HalfCpltCallback = NULL;
1677       break;
1678 
1679     case  HAL_DMA_XFER_ERROR_CB_ID:
1680       hdma->XferErrorCallback = NULL;
1681       break;
1682 
1683     case  HAL_DMA_XFER_ABORT_CB_ID:
1684       hdma->XferAbortCallback = NULL;
1685       break;
1686 
1687     case   HAL_DMA_XFER_ALL_CB_ID:
1688       hdma->XferCpltCallback = NULL;
1689       hdma->XferHalfCpltCallback = NULL;
1690       hdma->XferM1CpltCallback = NULL;
1691       hdma->XferM1HalfCpltCallback = NULL;
1692       hdma->XferErrorCallback = NULL;
1693       hdma->XferAbortCallback = NULL;
1694       break;
1695 
1696     default:
1697       status = HAL_ERROR;
1698       break;
1699     }
1700   }
1701   else
1702   {
1703     status = HAL_ERROR;
1704   }
1705 
1706   /* Release Lock */
1707   __HAL_UNLOCK(hdma);
1708 
1709   return status;
1710 }
1711 
1712 /**
1713   * @}
1714   */
1715 
1716 /** @addtogroup DMA_Exported_Functions_Group3
1717   *
1718 @verbatim
1719  ===============================================================================
1720                     ##### State and Errors functions #####
1721  ===============================================================================
1722     [..]
1723     This subsection provides functions allowing to
1724       (+) Check the DMA state
1725       (+) Get error code
1726 
1727 @endverbatim
1728   * @{
1729   */
1730 
1731 /**
1732   * @brief  Returns the DMA state.
1733   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1734   *               the configuration information for the specified DMA Stream.
1735   * @retval HAL state
1736   */
1737 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
1738 {
1739   return hdma->State;
1740 }
1741 
1742 /**
1743   * @brief  Return the DMA error code
1744   * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains
1745   *              the configuration information for the specified DMA Stream.
1746   * @retval DMA Error Code
1747   */
1748 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
1749 {
1750   return hdma->ErrorCode;
1751 }
1752 
1753 /**
1754   * @}
1755   */
1756 
1757 /**
1758   * @}
1759   */
1760 
1761 /** @addtogroup DMA_Private_Functions
1762   * @{
1763   */
1764 
1765 /**
1766   * @brief  Sets the DMA Transfer parameter.
1767   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
1768   *                     the configuration information for the specified DMA Stream.
1769   * @param  SrcAddress: The source memory Buffer address
1770   * @param  DstAddress: The destination memory Buffer address
1771   * @param  DataLength: The length of data to be transferred from source to destination
1772   * @retval None
1773   */
1774 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
1775 {
1776   /* calculate DMA base and stream number */
1777   DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
1778   BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
1779 
1780   if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
1781   {
1782     /* Clear the DMAMUX synchro overrun flag */
1783     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1784 
1785     if(hdma->DMAmuxRequestGen != 0U)
1786     {
1787       /* Clear the DMAMUX request generator overrun flag */
1788       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
1789     }
1790   }
1791 
1792   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1793   {
1794     /* Clear all interrupt flags at correct offset within the register */
1795     regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
1796 
1797     /* Clear DBM bit */
1798     ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= (uint32_t)(~DMA_SxCR_DBM);
1799 
1800     /* Configure DMA Stream data length */
1801     ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
1802 
1803     /* Peripheral to Memory */
1804     if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1805     {
1806       /* Configure DMA Stream destination address */
1807       ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress;
1808 
1809       /* Configure DMA Stream source address */
1810       ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress;
1811     }
1812     /* Memory to Peripheral */
1813     else
1814     {
1815       /* Configure DMA Stream source address */
1816       ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress;
1817 
1818       /* Configure DMA Stream destination address */
1819       ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress;
1820     }
1821   }
1822   else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
1823   {
1824     /* Clear all flags */
1825     regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
1826 
1827     /* Configure DMA Channel data length */
1828     ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = DataLength;
1829 
1830     /* Peripheral to Memory */
1831     if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1832     {
1833       /* Configure DMA Channel destination address */
1834       ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = DstAddress;
1835 
1836       /* Configure DMA Channel source address */
1837       ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = SrcAddress;
1838     }
1839     /* Memory to Peripheral */
1840     else
1841     {
1842       /* Configure DMA Channel source address */
1843       ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = SrcAddress;
1844 
1845       /* Configure DMA Channel destination address */
1846       ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = DstAddress;
1847     }
1848   }
1849   else
1850   {
1851     /* Nothing To Do */
1852   }
1853 }
1854 
1855 /**
1856   * @brief  Returns the DMA Stream base address depending on stream number
1857   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
1858   *                     the configuration information for the specified DMA Stream.
1859   * @retval Stream base address
1860   */
1861 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
1862 {
1863   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1864   {
1865     uint32_t stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
1866 
1867     /* lookup table for necessary bitshift of flags within status registers */
1868     static const uint8_t flagBitshiftOffset[8U] = {0U, 6U, 16U, 22U, 0U, 6U, 16U, 22U};
1869     hdma->StreamIndex = flagBitshiftOffset[stream_number & 0x7U];
1870 
1871     if (stream_number > 3U)
1872     {
1873       /* return pointer to HISR and HIFCR */
1874       hdma->StreamBaseAddress = (((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU)) + 4U);
1875     }
1876     else
1877     {
1878       /* return pointer to LISR and LIFCR */
1879       hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU));
1880     }
1881   }
1882   else /* BDMA instance(s) */
1883   {
1884     /* return pointer to ISR and IFCR */
1885     hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0xFFU));
1886   }
1887 
1888   return hdma->StreamBaseAddress;
1889 }
1890 
1891 /**
1892   * @brief  Check compatibility between FIFO threshold level and size of the memory burst
1893   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
1894   *                     the configuration information for the specified DMA Stream.
1895   * @retval HAL status
1896   */
1897 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma)
1898 {
1899   HAL_StatusTypeDef status = HAL_OK;
1900 
1901   /* Memory Data size equal to Byte */
1902   if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_BYTE)
1903   {
1904     switch (hdma->Init.FIFOThreshold)
1905     {
1906       case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1907       case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1908 
1909         if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1910         {
1911           status = HAL_ERROR;
1912         }
1913         break;
1914 
1915       case DMA_FIFO_THRESHOLD_HALFFULL:
1916         if (hdma->Init.MemBurst == DMA_MBURST_INC16)
1917         {
1918           status = HAL_ERROR;
1919         }
1920         break;
1921 
1922       case DMA_FIFO_THRESHOLD_FULL:
1923         break;
1924 
1925       default:
1926         break;
1927     }
1928   }
1929 
1930   /* Memory Data size equal to Half-Word */
1931   else if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
1932   {
1933     switch (hdma->Init.FIFOThreshold)
1934     {
1935       case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1936       case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1937         status = HAL_ERROR;
1938         break;
1939 
1940       case DMA_FIFO_THRESHOLD_HALFFULL:
1941         if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1942         {
1943           status = HAL_ERROR;
1944         }
1945         break;
1946 
1947       case DMA_FIFO_THRESHOLD_FULL:
1948         if (hdma->Init.MemBurst == DMA_MBURST_INC16)
1949         {
1950           status = HAL_ERROR;
1951         }
1952         break;
1953 
1954       default:
1955         break;
1956     }
1957   }
1958 
1959   /* Memory Data size equal to Word */
1960   else
1961   {
1962     switch (hdma->Init.FIFOThreshold)
1963     {
1964       case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1965       case DMA_FIFO_THRESHOLD_HALFFULL:
1966       case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1967         status = HAL_ERROR;
1968         break;
1969 
1970       case DMA_FIFO_THRESHOLD_FULL:
1971         if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1972         {
1973           status = HAL_ERROR;
1974         }
1975     break;
1976 
1977       default:
1978         break;
1979     }
1980   }
1981 
1982   return status;
1983 }
1984 
1985 /**
1986   * @brief  Updates the DMA handle with the DMAMUX  channel and status mask depending on stream number
1987   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
1988   *                     the configuration information for the specified DMA Stream.
1989   * @retval HAL status
1990   */
1991 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
1992 {
1993   uint32_t stream_number;
1994   uint32_t stream_baseaddress = (uint32_t)((uint32_t*)hdma->Instance);
1995 
1996   if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
1997   {
1998     /* BDMA Channels are connected to DMAMUX2 channels */
1999     stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 8U) / 20U;
2000     hdma->DMAmuxChannel = (DMAMUX_Channel_TypeDef *)((uint32_t)(((uint32_t)DMAMUX2_Channel0) + (stream_number * 4U)));
2001     hdma->DMAmuxChannelStatus = DMAMUX2_ChannelStatus;
2002     hdma->DMAmuxChannelStatusMask = 1UL << (stream_number & 0x1FU);
2003   }
2004   else
2005   {
2006     /* DMA1/DMA2 Streams are connected to DMAMUX1 channels */
2007     stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
2008 
2009     if((stream_baseaddress <= ((uint32_t)DMA2_Stream7) ) && \
2010        (stream_baseaddress >= ((uint32_t)DMA2_Stream0)))
2011     {
2012       stream_number += 8U;
2013     }
2014     hdma->DMAmuxChannel = (DMAMUX_Channel_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_Channel0) + (stream_number * 4U)));
2015     hdma->DMAmuxChannelStatus = DMAMUX1_ChannelStatus;
2016     hdma->DMAmuxChannelStatusMask = 1UL << (stream_number & 0x1FU);
2017   }
2018 }
2019 
2020 /**
2021   * @brief  Updates the DMA handle with the DMAMUX  request generator params
2022   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
2023   *                     the configuration information for the specified DMA Stream.
2024   * @retval HAL status
2025   */
2026 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
2027 {
2028   uint32_t request =  hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
2029 
2030   if((request >= DMA_REQUEST_GENERATOR0) && (request <= DMA_REQUEST_GENERATOR7))
2031   {
2032     if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
2033     {
2034       /* BDMA Channels are connected to DMAMUX2 request generator blocks */
2035       hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX2_RequestGenerator0) + ((request - 1U) * 4U)));
2036 
2037       hdma->DMAmuxRequestGenStatus = DMAMUX2_RequestGenStatus;
2038     }
2039     else
2040     {
2041       /* DMA1 and DMA2 Streams use DMAMUX1 request generator blocks */
2042       hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_RequestGenerator0) + ((request - 1U) * 4U)));
2043 
2044       hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
2045     }
2046 
2047     hdma->DMAmuxRequestGenStatusMask = 1UL << (request - 1U);
2048   }
2049 }
2050 
2051 /**
2052   * @}
2053   */
2054 
2055 #endif /* HAL_DMA_MODULE_ENABLED */
2056 /**
2057   * @}
2058   */
2059 
2060 /**
2061   * @}
2062   */
2063