1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_dma.c
4   * @author  MCD Application Team
5   * @brief   DMA HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Direct Memory Access (DMA) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral State and errors functions
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2017 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                         ##### How to use this driver #####
25   ==============================================================================
26   [..]
27    (#) Enable and configure the peripheral to be connected to the DMA Stream
28        (except for internal SRAM/FLASH memories: no initialization is
29        necessary) please refer to Reference manual for connection between peripherals
30        and DMA requests .
31 
32    (#) For a given Stream, program the required configuration through the following parameters:
33        Transfer Direction, Source and Destination data formats,
34        Circular, Normal or peripheral flow control mode, Stream Priority level,
35        Source and Destination Increment mode, FIFO mode and its Threshold (if needed),
36        Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.
37 
38      *** Polling mode IO operation ***
39      =================================
40     [..]
41           (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
42               address and destination address and the Length of data to be transferred
43           (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
44               case a fixed Timeout can be configured by User depending from his application.
45 
46      *** Interrupt mode IO operation ***
47      ===================================
48     [..]
49           (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
50           (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
51           (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
52               Source address and destination address and the Length of data to be transferred. In this
53               case the DMA interrupt is configured
54           (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
55           (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
56               add his own function by customization of function pointer XferCpltCallback and
57               XferErrorCallback (i.e a member of DMA handle structure).
58     [..]
59      (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
60          detection.
61 
62      (#) Use HAL_DMA_Abort() function to abort the current transfer
63 
64      -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.
65 
66      -@-   The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
67            possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
68            Half-Word data size for the peripheral to access its data register and set Word data size
69            for the Memory to gain in access time. Each two half words will be packed and written in
70            a single access to a Word in the Memory).
71 
72      -@-   When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
73            and Destination. In this case the Peripheral Data Size will be applied to both Source
74            and Destination.
75 
76      *** DMA HAL driver macros list ***
77      =============================================
78      [..]
79        Below the list of most used macros in DMA HAL driver.
80 
81       (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.
82       (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.
83       (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level.
84       (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts.
85       (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts.
86       (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not.
87 
88      [..]
89       (@) You can refer to the DMA HAL driver header file for more useful macros.
90 
91   @endverbatim
92   */
93 
94 /* Includes ------------------------------------------------------------------*/
95 #include "stm32h7xx_hal.h"
96 
97 /** @addtogroup STM32H7xx_HAL_Driver
98   * @{
99   */
100 
101 /** @defgroup DMA DMA
102   * @brief DMA HAL module driver
103   * @{
104   */
105 
106 #ifdef HAL_DMA_MODULE_ENABLED
107 
108 /* Private types -------------------------------------------------------------*/
109 /** @addtogroup DMA_Private_Types
110   * @{
111   */
112 typedef struct
113 {
114   __IO uint32_t ISR;   /*!< DMA interrupt status register */
115   __IO uint32_t Reserved0;
116   __IO uint32_t IFCR;  /*!< DMA interrupt flag clear register */
117 } DMA_Base_Registers;
118 
119 typedef struct
120 {
121   __IO uint32_t ISR;   /*!< BDMA interrupt status register */
122   __IO uint32_t IFCR;  /*!< BDMA interrupt flag clear register */
123 } BDMA_Base_Registers;
124 /**
125   * @}
126   */
127 
128 /* Private variables ---------------------------------------------------------*/
129 /* Private constants ---------------------------------------------------------*/
130 /** @addtogroup DMA_Private_Constants
131  * @{
132  */
133 #define HAL_TIMEOUT_DMA_ABORT         (5U)  /* 5 ms */
134 
135 #define BDMA_PERIPH_TO_MEMORY         (0x00000000U)                /*!< Peripheral to memory direction */
136 #define BDMA_MEMORY_TO_PERIPH         ((uint32_t)BDMA_CCR_DIR)     /*!< Memory to peripheral direction */
137 #define BDMA_MEMORY_TO_MEMORY         ((uint32_t)BDMA_CCR_MEM2MEM) /*!< Memory to memory direction     */
138 
139 /* DMA to BDMA conversion */
140 #define DMA_TO_BDMA_DIRECTION(__DMA_DIRECTION__) (((__DMA_DIRECTION__) == DMA_MEMORY_TO_PERIPH)? BDMA_MEMORY_TO_PERIPH: \
141                                                   ((__DMA_DIRECTION__) == DMA_MEMORY_TO_MEMORY)? BDMA_MEMORY_TO_MEMORY: \
142                                                   BDMA_PERIPH_TO_MEMORY)
143 
144 #define DMA_TO_BDMA_PERIPHERAL_INC(__DMA_PERIPHERAL_INC__) ((__DMA_PERIPHERAL_INC__) >> 3U)
145 #define DMA_TO_BDMA_MEMORY_INC(__DMA_MEMORY_INC__) ((__DMA_MEMORY_INC__) >> 3U)
146 
147 #define DMA_TO_BDMA_PDATA_SIZE(__DMA_PDATA_SIZE__) ((__DMA_PDATA_SIZE__) >> 3U)
148 #define DMA_TO_BDMA_MDATA_SIZE(__DMA_MDATA_SIZE__) ((__DMA_MDATA_SIZE__) >> 3U)
149 
150 #define DMA_TO_BDMA_MODE(__DMA_MODE__) ((__DMA_MODE__) >> 3U)
151 
152 #define DMA_TO_BDMA_PRIORITY(__DMA_PRIORITY__) ((__DMA_PRIORITY__) >> 4U)
153 
154 #if defined(UART9)
155 #define IS_DMA_UART_USART_REQUEST(__REQUEST__) ((((__REQUEST__) >= DMA_REQUEST_USART1_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART3_TX)) || \
156                                                  (((__REQUEST__) >= DMA_REQUEST_UART4_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART5_TX )) || \
157                                                  (((__REQUEST__) >= DMA_REQUEST_USART6_RX) &&  ((__REQUEST__) <= DMA_REQUEST_USART6_TX)) || \
158                                                  (((__REQUEST__) >= DMA_REQUEST_UART7_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART8_TX )) || \
159                                                  (((__REQUEST__) >= DMA_REQUEST_UART9_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART10_TX )))
160 #else
161 #define IS_DMA_UART_USART_REQUEST(__REQUEST__) ((((__REQUEST__) >= DMA_REQUEST_USART1_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART3_TX)) || \
162                                                  (((__REQUEST__) >= DMA_REQUEST_UART4_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART5_TX )) || \
163                                                  (((__REQUEST__) >= DMA_REQUEST_USART6_RX) &&  ((__REQUEST__) <= DMA_REQUEST_USART6_TX)) || \
164                                                  (((__REQUEST__) >= DMA_REQUEST_UART7_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART8_TX )))
165 
166 #endif
167 /**
168   * @}
169   */
170 /* Private macros ------------------------------------------------------------*/
171 /* Private functions ---------------------------------------------------------*/
172 /** @addtogroup DMA_Private_Functions
173   * @{
174   */
175 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
176 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
177 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma);
178 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma);
179 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma);
180 
181 /**
182   * @}
183   */
184 
185 /* Exported functions ---------------------------------------------------------*/
186 /** @addtogroup DMA_Exported_Functions
187   * @{
188   */
189 
190 /** @addtogroup DMA_Exported_Functions_Group1
191   *
192 @verbatim
193  ===============================================================================
194              ##### Initialization and de-initialization functions  #####
195  ===============================================================================
196     [..]
197     This section provides functions allowing to initialize the DMA Stream source
198     and destination incrementation and data sizes, transfer direction,
199     circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
200     [..]
201     The HAL_DMA_Init() function follows the DMA configuration procedures as described in
202     reference manual.
203     The HAL_DMA_DeInit function allows to deinitialize the DMA stream.
204 
205 @endverbatim
206   * @{
207   */
208 
209 /**
210   * @brief  Initialize the DMA according to the specified
211   *         parameters in the DMA_InitTypeDef and create the associated handle.
212   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
213   *               the configuration information for the specified DMA Stream.
214   * @retval HAL status
215   */
HAL_DMA_Init(DMA_HandleTypeDef * hdma)216 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
217 {
218   uint32_t registerValue;
219   uint32_t tickstart = HAL_GetTick();
220   DMA_Base_Registers *regs_dma;
221   BDMA_Base_Registers *regs_bdma;
222 
223   /* Check the DMA peripheral handle */
224   if(hdma == NULL)
225   {
226     return HAL_ERROR;
227   }
228 
229   /* Check the parameters */
230   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
231   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
232   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
233   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
234   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
235   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
236   assert_param(IS_DMA_MODE(hdma->Init.Mode));
237   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
238 
239   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
240   {
241     assert_param(IS_DMA_REQUEST(hdma->Init.Request));
242     assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
243     /* Check the memory burst, peripheral burst and FIFO threshold parameters only
244        when FIFO mode is enabled */
245     if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
246     {
247       assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
248       assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
249       assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
250     }
251 
252     /* Change DMA peripheral state */
253     hdma->State = HAL_DMA_STATE_BUSY;
254 
255     /* Allocate lock resource */
256     __HAL_UNLOCK(hdma);
257 
258     /* Disable the peripheral */
259     __HAL_DMA_DISABLE(hdma);
260 
261     /* Check if the DMA Stream is effectively disabled */
262     while((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
263     {
264       /* Check for the Timeout */
265       if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
266       {
267         /* Update error code */
268         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
269 
270         /* Change the DMA state */
271         hdma->State = HAL_DMA_STATE_ERROR;
272 
273         return HAL_ERROR;
274       }
275     }
276 
277     /* Get the CR register value */
278     registerValue = ((DMA_Stream_TypeDef   *)hdma->Instance)->CR;
279 
280     /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
281     registerValue &= ((uint32_t)~(DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
282                         DMA_SxCR_PL    | DMA_SxCR_MSIZE  | DMA_SxCR_PSIZE  | \
283                         DMA_SxCR_MINC  | DMA_SxCR_PINC   | DMA_SxCR_CIRC   | \
284                         DMA_SxCR_DIR   | DMA_SxCR_CT     | DMA_SxCR_DBM));
285 
286     /* Prepare the DMA Stream configuration */
287     registerValue |=  hdma->Init.Direction           |
288             hdma->Init.PeriphInc           | hdma->Init.MemInc           |
289             hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
290             hdma->Init.Mode                | hdma->Init.Priority;
291 
292     /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
293     if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
294     {
295       /* Get memory burst and peripheral burst */
296       registerValue |=  hdma->Init.MemBurst | hdma->Init.PeriphBurst;
297     }
298 
299     /* Work around for Errata 2.22: UART/USART- DMA transfer lock: DMA stream could be
300                                     lock when transferring data to/from USART/UART */
301 #if (STM32H7_DEV_ID == 0x450UL)
302     if((DBGMCU->IDCODE & 0xFFFF0000U) >= 0x20000000U)
303     {
304 #endif /* STM32H7_DEV_ID == 0x450UL */
305       if(IS_DMA_UART_USART_REQUEST(hdma->Init.Request) != 0U)
306       {
307         registerValue |= DMA_SxCR_TRBUFF;
308       }
309 #if (STM32H7_DEV_ID == 0x450UL)
310     }
311 #endif /* STM32H7_DEV_ID == 0x450UL */
312 
313     /* Write to DMA Stream CR register */
314     ((DMA_Stream_TypeDef   *)hdma->Instance)->CR = registerValue;
315 
316     /* Get the FCR register value */
317     registerValue = ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR;
318 
319     /* Clear Direct mode and FIFO threshold bits */
320     registerValue &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
321 
322     /* Prepare the DMA Stream FIFO configuration */
323     registerValue |= hdma->Init.FIFOMode;
324 
325     /* the FIFO threshold is not used when the FIFO mode is disabled */
326     if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
327     {
328       /* Get the FIFO threshold */
329       registerValue |= hdma->Init.FIFOThreshold;
330 
331       /* Check compatibility between FIFO threshold level and size of the memory burst */
332       /* for INCR4, INCR8, INCR16 */
333       if(hdma->Init.MemBurst != DMA_MBURST_SINGLE)
334       {
335         if (DMA_CheckFifoParam(hdma) != HAL_OK)
336         {
337           /* Update error code */
338           hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
339 
340           /* Change the DMA state */
341           hdma->State = HAL_DMA_STATE_READY;
342 
343           return HAL_ERROR;
344         }
345       }
346     }
347 
348     /* Write to DMA Stream FCR */
349     ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR = registerValue;
350 
351     /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
352        DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
353     regs_dma = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
354 
355     /* Clear all interrupt flags */
356     regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
357   }
358   else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
359   {
360     if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
361     {
362       /* Check the request parameter */
363       assert_param(IS_BDMA_REQUEST(hdma->Init.Request));
364     }
365 
366     /* Change DMA peripheral state */
367     hdma->State = HAL_DMA_STATE_BUSY;
368 
369     /* Allocate lock resource */
370     __HAL_UNLOCK(hdma);
371 
372     /* Get the CR register value */
373     registerValue = ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR;
374 
375     /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, MEM2MEM, DBM and CT bits */
376     registerValue &= ((uint32_t)~(BDMA_CCR_PL    | BDMA_CCR_MSIZE   | BDMA_CCR_PSIZE  | \
377                                   BDMA_CCR_MINC  | BDMA_CCR_PINC    | BDMA_CCR_CIRC   | \
378                                   BDMA_CCR_DIR   | BDMA_CCR_MEM2MEM | BDMA_CCR_DBM    | \
379                                   BDMA_CCR_CT));
380 
381     /* Prepare the DMA Channel configuration */
382     registerValue |=  DMA_TO_BDMA_DIRECTION(hdma->Init.Direction)            |
383                       DMA_TO_BDMA_PERIPHERAL_INC(hdma->Init.PeriphInc)       |
384                       DMA_TO_BDMA_MEMORY_INC(hdma->Init.MemInc)              |
385                       DMA_TO_BDMA_PDATA_SIZE(hdma->Init.PeriphDataAlignment) |
386                       DMA_TO_BDMA_MDATA_SIZE(hdma->Init.MemDataAlignment)    |
387                       DMA_TO_BDMA_MODE(hdma->Init.Mode)                      |
388                       DMA_TO_BDMA_PRIORITY(hdma->Init.Priority);
389 
390     /* Write to DMA Channel CR register */
391     ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR = registerValue;
392 
393     /* calculation of the channel index */
394     hdma->StreamIndex = (((uint32_t)((uint32_t*)hdma->Instance) - (uint32_t)BDMA_Channel0) / ((uint32_t)BDMA_Channel1 - (uint32_t)BDMA_Channel0)) << 2U;
395 
396     /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
397     DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
398     regs_bdma = (BDMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
399 
400     /* Clear all interrupt flags */
401     regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
402   }
403   else
404   {
405     hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
406     hdma->State     = HAL_DMA_STATE_ERROR;
407 
408     return HAL_ERROR;
409   }
410 
411   if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
412   {
413     /* Initialize parameters for DMAMUX channel :
414     DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
415     */
416     DMA_CalcDMAMUXChannelBaseAndMask(hdma);
417 
418     if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
419     {
420       /* if memory to memory force the request to 0*/
421       hdma->Init.Request = DMA_REQUEST_MEM2MEM;
422     }
423 
424     /* Set peripheral request  to DMAMUX channel */
425     hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
426 
427     /* Clear the DMAMUX synchro overrun flag */
428     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
429 
430     /* Initialize parameters for DMAMUX request generator :
431     if the DMA request is DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR7
432     */
433     if((hdma->Init.Request >= DMA_REQUEST_GENERATOR0) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR7))
434     {
435       /* Initialize parameters for DMAMUX request generator :
436       DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask */
437       DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
438 
439       /* Reset the DMAMUX request generator register */
440       hdma->DMAmuxRequestGen->RGCR = 0U;
441 
442       /* Clear the DMAMUX request generator overrun flag */
443       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
444     }
445     else
446     {
447       hdma->DMAmuxRequestGen = 0U;
448       hdma->DMAmuxRequestGenStatus = 0U;
449       hdma->DMAmuxRequestGenStatusMask = 0U;
450     }
451   }
452 
453   /* Initialize the error code */
454   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
455 
456   /* Initialize the DMA state */
457   hdma->State = HAL_DMA_STATE_READY;
458 
459   return HAL_OK;
460 }
461 
462 /**
463   * @brief  DeInitializes the DMA peripheral
464   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
465   *               the configuration information for the specified DMA Stream.
466   * @retval HAL status
467   */
HAL_DMA_DeInit(DMA_HandleTypeDef * hdma)468 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
469 {
470   DMA_Base_Registers *regs_dma;
471   BDMA_Base_Registers *regs_bdma;
472 
473   /* Check the DMA peripheral handle */
474   if(hdma == NULL)
475   {
476     return HAL_ERROR;
477   }
478 
479   /* Disable the selected DMA Streamx */
480   __HAL_DMA_DISABLE(hdma);
481 
482   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
483   {
484     /* Reset DMA Streamx control register */
485     ((DMA_Stream_TypeDef   *)hdma->Instance)->CR   = 0U;
486 
487     /* Reset DMA Streamx number of data to transfer register */
488     ((DMA_Stream_TypeDef   *)hdma->Instance)->NDTR = 0U;
489 
490     /* Reset DMA Streamx peripheral address register */
491     ((DMA_Stream_TypeDef   *)hdma->Instance)->PAR  = 0U;
492 
493     /* Reset DMA Streamx memory 0 address register */
494     ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = 0U;
495 
496     /* Reset DMA Streamx memory 1 address register */
497     ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = 0U;
498 
499     /* Reset DMA Streamx FIFO control register */
500     ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR  = (uint32_t)0x00000021U;
501 
502     /* Get DMA steam Base Address */
503     regs_dma = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
504 
505     /* Clear all interrupt flags at correct offset within the register */
506     regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
507   }
508   else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
509   {
510     /* Reset DMA Channel control register */
511     ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR  = 0U;
512 
513     /* Reset DMA Channel Number of Data to Transfer register */
514     ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = 0U;
515 
516     /* Reset DMA Channel peripheral address register */
517     ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR  = 0U;
518 
519     /* Reset DMA Channel memory 0 address register */
520     ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = 0U;
521 
522     /* Reset DMA Channel memory 1 address register */
523     ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = 0U;
524 
525     /* Get DMA steam Base Address */
526     regs_bdma = (BDMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
527 
528     /* Clear all interrupt flags at correct offset within the register */
529     regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
530   }
531   else
532   {
533     /* Return error status */
534     return HAL_ERROR;
535   }
536 
537 #if defined (BDMA1) /* No DMAMUX available for BDMA1 available on  STM32H7Ax/Bx devices only */
538   if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
539 #endif /* BDMA1 */
540   {
541     /* Initialize parameters for DMAMUX channel :
542     DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
543     DMA_CalcDMAMUXChannelBaseAndMask(hdma);
544 
545     if(hdma->DMAmuxChannel != 0U)
546     {
547       /* Resett he DMAMUX channel that corresponds to the DMA stream */
548       hdma->DMAmuxChannel->CCR = 0U;
549 
550       /* Clear the DMAMUX synchro overrun flag */
551       hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
552     }
553 
554     if((hdma->Init.Request >= DMA_REQUEST_GENERATOR0) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR7))
555     {
556       /* Initialize parameters for DMAMUX request generator :
557       DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask */
558       DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
559 
560       /* Reset the DMAMUX request generator register */
561       hdma->DMAmuxRequestGen->RGCR = 0U;
562 
563       /* Clear the DMAMUX request generator overrun flag */
564       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
565     }
566 
567     hdma->DMAmuxRequestGen = 0U;
568     hdma->DMAmuxRequestGenStatus = 0U;
569     hdma->DMAmuxRequestGenStatusMask = 0U;
570   }
571 
572 
573   /* Clean callbacks */
574   hdma->XferCpltCallback       = NULL;
575   hdma->XferHalfCpltCallback   = NULL;
576   hdma->XferM1CpltCallback     = NULL;
577   hdma->XferM1HalfCpltCallback = NULL;
578   hdma->XferErrorCallback      = NULL;
579   hdma->XferAbortCallback      = NULL;
580 
581   /* Initialize the error code */
582   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
583 
584   /* Initialize the DMA state */
585   hdma->State = HAL_DMA_STATE_RESET;
586 
587   /* Release Lock */
588   __HAL_UNLOCK(hdma);
589 
590   return HAL_OK;
591 }
592 
593 /**
594   * @}
595   */
596 
597 /** @addtogroup DMA_Exported_Functions_Group2
598   *
599 @verbatim
600  ===============================================================================
601                       #####  IO operation functions  #####
602  ===============================================================================
603     [..]  This section provides functions allowing to:
604       (+) Configure the source, destination address and data length and Start DMA transfer
605       (+) Configure the source, destination address and data length and
606           Start DMA transfer with interrupt
607       (+) Register and Unregister DMA callbacks
608       (+) Abort DMA transfer
609       (+) Poll for transfer complete
610       (+) Handle DMA interrupt request
611 
612 @endverbatim
613   * @{
614   */
615 
616 /**
617   * @brief  Starts the DMA Transfer.
618   * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains
619   *                     the configuration information for the specified DMA Stream.
620   * @param  SrcAddress: The source memory Buffer address
621   * @param  DstAddress: The destination memory Buffer address
622   * @param  DataLength: The length of data to be transferred from source to destination
623   * @retval HAL status
624   */
HAL_DMA_Start(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)625 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
626 {
627   HAL_StatusTypeDef status = HAL_OK;
628 
629   /* Check the parameters */
630   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
631 
632   /* Check the DMA peripheral handle */
633   if(hdma == NULL)
634   {
635     return HAL_ERROR;
636   }
637 
638   /* Process locked */
639   __HAL_LOCK(hdma);
640 
641   if(HAL_DMA_STATE_READY == hdma->State)
642   {
643     /* Change DMA peripheral state */
644     hdma->State = HAL_DMA_STATE_BUSY;
645 
646     /* Initialize the error code */
647     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
648 
649     /* Disable the peripheral */
650     __HAL_DMA_DISABLE(hdma);
651 
652     /* Configure the source, destination address and the data length */
653     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
654 
655     /* Enable the Peripheral */
656     __HAL_DMA_ENABLE(hdma);
657   }
658   else
659   {
660     /* Set the error code to busy */
661     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
662 
663     /* Process unlocked */
664     __HAL_UNLOCK(hdma);
665 
666     /* Return error status */
667     status = HAL_ERROR;
668   }
669   return status;
670 }
671 
672 /**
673   * @brief  Start the DMA Transfer with interrupt enabled.
674   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
675   *                     the configuration information for the specified DMA Stream.
676   * @param  SrcAddress: The source memory Buffer address
677   * @param  DstAddress: The destination memory Buffer address
678   * @param  DataLength: The length of data to be transferred from source to destination
679   * @retval HAL status
680   */
HAL_DMA_Start_IT(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)681 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
682 {
683   HAL_StatusTypeDef status = HAL_OK;
684 
685   /* Check the parameters */
686   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
687 
688   /* Check the DMA peripheral handle */
689   if(hdma == NULL)
690   {
691     return HAL_ERROR;
692   }
693 
694   /* Process locked */
695   __HAL_LOCK(hdma);
696 
697   if(HAL_DMA_STATE_READY == hdma->State)
698   {
699     /* Change DMA peripheral state */
700     hdma->State = HAL_DMA_STATE_BUSY;
701 
702     /* Initialize the error code */
703     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
704 
705     /* Disable the peripheral */
706     __HAL_DMA_DISABLE(hdma);
707 
708     /* Configure the source, destination address and the data length */
709     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
710 
711     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
712     {
713       /* Enable Common interrupts*/
714       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));
715 
716       if(hdma->XferHalfCpltCallback != NULL)
717       {
718         /* Enable Half Transfer IT if corresponding Callback is set */
719         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  |= DMA_IT_HT;
720       }
721     }
722     else /* BDMA channel */
723     {
724       /* Enable Common interrupts */
725       MODIFY_REG(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR, (BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE), (BDMA_CCR_TCIE | BDMA_CCR_TEIE));
726 
727       if(hdma->XferHalfCpltCallback != NULL)
728       {
729         /*Enable Half Transfer IT if corresponding Callback is set */
730         ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  |= BDMA_CCR_HTIE;
731       }
732     }
733 
734     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
735     {
736       /* Check if DMAMUX Synchronization is enabled */
737       if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
738       {
739         /* Enable DMAMUX sync overrun IT*/
740         hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
741       }
742 
743       if(hdma->DMAmuxRequestGen != 0U)
744       {
745         /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
746         /* enable the request gen overrun IT */
747         hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
748       }
749     }
750 
751     /* Enable the Peripheral */
752     __HAL_DMA_ENABLE(hdma);
753   }
754   else
755   {
756     /* Set the error code to busy */
757     hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
758 
759     /* Process unlocked */
760     __HAL_UNLOCK(hdma);
761 
762     /* Return error status */
763     status = HAL_ERROR;
764   }
765 
766   return status;
767 }
768 
769 /**
770   * @brief  Aborts the DMA Transfer.
771   * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
772   *                 the configuration information for the specified DMA Stream.
773   *
774   * @note  After disabling a DMA Stream, a check for wait until the DMA Stream is
775   *        effectively disabled is added. If a Stream is disabled
776   *        while a data transfer is ongoing, the current data will be transferred
777   *        and the Stream will be effectively disabled only after the transfer of
778   *        this single data is finished.
779   * @retval HAL status
780   */
HAL_DMA_Abort(DMA_HandleTypeDef * hdma)781 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
782 {
783   /* calculate DMA base and stream number */
784   DMA_Base_Registers *regs_dma;
785   BDMA_Base_Registers *regs_bdma;
786   const __IO uint32_t *enableRegister;
787 
788   uint32_t tickstart = HAL_GetTick();
789 
790  /* Check the DMA peripheral handle */
791   if(hdma == NULL)
792   {
793     return HAL_ERROR;
794   }
795 
796   /* Check the DMA peripheral state */
797   if(hdma->State != HAL_DMA_STATE_BUSY)
798   {
799     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
800 
801     /* Process Unlocked */
802     __HAL_UNLOCK(hdma);
803 
804     return HAL_ERROR;
805   }
806   else
807   {
808     /* Disable all the transfer interrupts */
809     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
810     {
811        /* Disable DMA All Interrupts  */
812       ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT);
813       ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR &= ~(DMA_IT_FE);
814 
815       enableRegister = (__IO uint32_t *)(&(((DMA_Stream_TypeDef   *)hdma->Instance)->CR));
816     }
817     else /* BDMA channel */
818     {
819       /* Disable DMA All Interrupts */
820       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);
821 
822       enableRegister = (__IO uint32_t *)(&(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR));
823     }
824 
825     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
826     {
827       /* disable the DMAMUX sync overrun IT */
828       hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
829     }
830 
831     /* Disable the stream */
832     __HAL_DMA_DISABLE(hdma);
833 
834     /* Check if the DMA Stream is effectively disabled */
835     while(((*enableRegister) & DMA_SxCR_EN) != 0U)
836     {
837       /* Check for the Timeout */
838       if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
839       {
840         /* Update error code */
841         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
842 
843         /* Change the DMA state */
844         hdma->State = HAL_DMA_STATE_ERROR;
845 
846         /* Process Unlocked */
847         __HAL_UNLOCK(hdma);
848 
849         return HAL_ERROR;
850       }
851     }
852 
853     /* Clear all interrupt flags at correct offset within the register */
854     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
855     {
856       regs_dma = (DMA_Base_Registers *)hdma->StreamBaseAddress;
857       regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
858     }
859     else /* BDMA channel */
860     {
861       regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
862       regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
863     }
864 
865     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
866     {
867       /* Clear the DMAMUX synchro overrun flag */
868       hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
869 
870       if(hdma->DMAmuxRequestGen != 0U)
871       {
872         /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT */
873         /* disable the request gen overrun IT */
874         hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
875 
876         /* Clear the DMAMUX request generator overrun flag */
877         hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
878       }
879     }
880 
881     /* Change the DMA state */
882     hdma->State = HAL_DMA_STATE_READY;
883 
884     /* Process Unlocked */
885     __HAL_UNLOCK(hdma);
886   }
887 
888   return HAL_OK;
889 }
890 
891 /**
892   * @brief  Aborts the DMA Transfer in Interrupt mode.
893   * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
894   *                 the configuration information for the specified DMA Stream.
895   * @retval HAL status
896   */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * hdma)897 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
898 {
899   BDMA_Base_Registers *regs_bdma;
900 
901   /* Check the DMA peripheral handle */
902   if(hdma == NULL)
903   {
904     return HAL_ERROR;
905   }
906 
907   if(hdma->State != HAL_DMA_STATE_BUSY)
908   {
909     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
910     return HAL_ERROR;
911   }
912   else
913   {
914     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
915     {
916       /* Set Abort State  */
917       hdma->State = HAL_DMA_STATE_ABORT;
918 
919       /* Disable the stream */
920       __HAL_DMA_DISABLE(hdma);
921     }
922     else /* BDMA channel */
923     {
924       /* Disable DMA All Interrupts  */
925       ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);
926 
927       /* Disable the channel */
928       __HAL_DMA_DISABLE(hdma);
929 
930       if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
931       {
932         /* disable the DMAMUX sync overrun IT */
933         hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
934 
935         /* Clear all flags */
936         regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
937         regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
938 
939         /* Clear the DMAMUX synchro overrun flag */
940         hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
941 
942         if(hdma->DMAmuxRequestGen != 0U)
943         {
944           /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
945           /* disable the request gen overrun IT */
946           hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
947 
948           /* Clear the DMAMUX request generator overrun flag */
949           hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
950         }
951       }
952 
953       /* Change the DMA state */
954       hdma->State = HAL_DMA_STATE_READY;
955 
956       /* Process Unlocked */
957       __HAL_UNLOCK(hdma);
958 
959       /* Call User Abort callback */
960       if(hdma->XferAbortCallback != NULL)
961       {
962         hdma->XferAbortCallback(hdma);
963       }
964     }
965   }
966 
967   return HAL_OK;
968 }
969 
970 /**
971   * @brief  Polling for transfer complete.
972   * @param  hdma:          pointer to a DMA_HandleTypeDef structure that contains
973   *                        the configuration information for the specified DMA Stream.
974   * @param  CompleteLevel: Specifies the DMA level complete.
975   * @note   The polling mode is kept in this version for legacy. it is recommended to use the IT model instead.
976   *         This model could be used for debug purpose.
977   * @note   The HAL_DMA_PollForTransfer API cannot be used in circular and double buffering mode (automatic circular mode).
978   * @param  Timeout:       Timeout duration.
979   * @retval HAL status
980   */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * hdma,HAL_DMA_LevelCompleteTypeDef CompleteLevel,uint32_t Timeout)981 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
982 {
983   HAL_StatusTypeDef status = HAL_OK;
984   uint32_t cpltlevel_mask;
985   uint32_t tickstart = HAL_GetTick();
986 
987   /* IT status register */
988   __IO uint32_t *isr_reg;
989   /* IT clear flag register */
990   __IO uint32_t *ifcr_reg;
991 
992   /* Check the DMA peripheral handle */
993   if(hdma == NULL)
994   {
995     return HAL_ERROR;
996   }
997 
998   if(HAL_DMA_STATE_BUSY != hdma->State)
999   {
1000     /* No transfer ongoing */
1001     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
1002     __HAL_UNLOCK(hdma);
1003 
1004     return HAL_ERROR;
1005   }
1006 
1007   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1008   {
1009     /* Polling mode not supported in circular mode and double buffering mode */
1010     if ((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) != 0U)
1011     {
1012       hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
1013       return HAL_ERROR;
1014     }
1015 
1016     /* Get the level transfer complete flag */
1017     if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
1018     {
1019       /* Transfer Complete flag */
1020       cpltlevel_mask = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
1021     }
1022     else
1023     {
1024       /* Half Transfer Complete flag */
1025       cpltlevel_mask = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
1026     }
1027 
1028     isr_reg  = &(((DMA_Base_Registers *)hdma->StreamBaseAddress)->ISR);
1029     ifcr_reg = &(((DMA_Base_Registers *)hdma->StreamBaseAddress)->IFCR);
1030   }
1031   else /* BDMA channel */
1032   {
1033     /* Polling mode not supported in circular mode */
1034     if ((((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR & BDMA_CCR_CIRC) != 0U)
1035     {
1036       hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
1037       return HAL_ERROR;
1038     }
1039 
1040     /* Get the level transfer complete flag */
1041     if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
1042     {
1043       /* Transfer Complete flag */
1044       cpltlevel_mask = BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU);
1045     }
1046     else
1047     {
1048       /* Half Transfer Complete flag */
1049       cpltlevel_mask = BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU);
1050     }
1051 
1052     isr_reg  = &(((BDMA_Base_Registers *)hdma->StreamBaseAddress)->ISR);
1053     ifcr_reg = &(((BDMA_Base_Registers *)hdma->StreamBaseAddress)->IFCR);
1054   }
1055 
1056   while(((*isr_reg) & cpltlevel_mask) == 0U)
1057   {
1058     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1059     {
1060       if(((*isr_reg) & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1061       {
1062         /* Update error code */
1063         hdma->ErrorCode |= HAL_DMA_ERROR_FE;
1064 
1065         /* Clear the FIFO error flag */
1066         (*ifcr_reg) = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
1067       }
1068 
1069       if(((*isr_reg) & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1070       {
1071         /* Update error code */
1072         hdma->ErrorCode |= HAL_DMA_ERROR_DME;
1073 
1074         /* Clear the Direct Mode error flag */
1075         (*ifcr_reg) = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
1076       }
1077 
1078       if(((*isr_reg) & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1079       {
1080         /* Update error code */
1081         hdma->ErrorCode |= HAL_DMA_ERROR_TE;
1082 
1083         /* Clear the transfer error flag */
1084         (*ifcr_reg) = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
1085 
1086         /* Change the DMA state */
1087         hdma->State = HAL_DMA_STATE_READY;
1088 
1089         /* Process Unlocked */
1090         __HAL_UNLOCK(hdma);
1091 
1092         return HAL_ERROR;
1093       }
1094     }
1095     else /* BDMA channel */
1096     {
1097       if(((*isr_reg) & (BDMA_FLAG_TE0 << (hdma->StreamIndex & 0x1FU))) != 0U)
1098       {
1099         /* When a DMA transfer error occurs */
1100         /* A hardware clear of its EN bits is performed */
1101         /* Clear all flags */
1102         (*isr_reg) = ((BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU));
1103 
1104         /* Update error code */
1105         hdma->ErrorCode = HAL_DMA_ERROR_TE;
1106 
1107         /* Change the DMA state */
1108         hdma->State = HAL_DMA_STATE_READY;
1109 
1110         /* Process Unlocked */
1111         __HAL_UNLOCK(hdma);
1112 
1113         return HAL_ERROR;
1114       }
1115     }
1116 
1117     /* Check for the Timeout (Not applicable in circular mode)*/
1118     if(Timeout != HAL_MAX_DELAY)
1119     {
1120       if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
1121       {
1122         /* Update error code */
1123         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
1124 
1125         /* if timeout then abort the current transfer */
1126         /* No need to check return value: as in this case we will return HAL_ERROR with HAL_DMA_ERROR_TIMEOUT error code  */
1127         (void) HAL_DMA_Abort(hdma);
1128           /*
1129             Note that the Abort function will
1130               - Clear the transfer error flags
1131               - Unlock
1132               - Set the State
1133           */
1134 
1135         return HAL_ERROR;
1136       }
1137     }
1138 
1139     if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
1140     {
1141       /* Check for DMAMUX Request generator (if used) overrun status */
1142       if(hdma->DMAmuxRequestGen != 0U)
1143       {
1144         /* if using DMAMUX request generator Check for DMAMUX request generator overrun */
1145         if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
1146         {
1147           /* Clear the DMAMUX request generator overrun flag */
1148           hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
1149 
1150           /* Update error code */
1151           hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
1152         }
1153       }
1154 
1155       /* Check for DMAMUX Synchronization overrun */
1156       if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
1157       {
1158         /* Clear the DMAMUX synchro overrun flag */
1159         hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1160 
1161         /* Update error code */
1162         hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
1163       }
1164     }
1165   }
1166 
1167 
1168   /* Get the level transfer complete flag */
1169   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
1170   {
1171     /* Clear the half transfer and transfer complete flags */
1172     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1173     {
1174       (*ifcr_reg) = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << (hdma->StreamIndex & 0x1FU);
1175     }
1176     else /* BDMA channel */
1177     {
1178       (*ifcr_reg) = (BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU));
1179     }
1180 
1181     hdma->State = HAL_DMA_STATE_READY;
1182 
1183     /* Process Unlocked */
1184     __HAL_UNLOCK(hdma);
1185   }
1186   else /*CompleteLevel = HAL_DMA_HALF_TRANSFER*/
1187   {
1188     /* Clear the half transfer and transfer complete flags */
1189     if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1190     {
1191       (*ifcr_reg) = (DMA_FLAG_HTIF0_4) << (hdma->StreamIndex & 0x1FU);
1192     }
1193     else /* BDMA channel */
1194     {
1195       (*ifcr_reg) = (BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU));
1196     }
1197   }
1198 
1199   return status;
1200 }
1201 
1202 /**
1203   * @brief  Handles DMA interrupt request.
1204   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1205   *               the configuration information for the specified DMA Stream.
1206   * @retval None
1207   */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * hdma)1208 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
1209 {
1210   uint32_t tmpisr_dma, tmpisr_bdma;
1211   uint32_t ccr_reg;
1212   __IO uint32_t count = 0U;
1213   uint32_t timeout = SystemCoreClock / 9600U;
1214 
1215   /* calculate DMA base and stream number */
1216   DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
1217   BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
1218 
1219   tmpisr_dma  = regs_dma->ISR;
1220   tmpisr_bdma = regs_bdma->ISR;
1221 
1222   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U)  /* DMA1 or DMA2 instance */
1223   {
1224     /* Transfer Error Interrupt management ***************************************/
1225     if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1226     {
1227       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != 0U)
1228       {
1229         /* Disable the transfer error interrupt */
1230         ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TE);
1231 
1232         /* Clear the transfer error flag */
1233         regs_dma->IFCR = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
1234 
1235         /* Update error code */
1236         hdma->ErrorCode |= HAL_DMA_ERROR_TE;
1237       }
1238     }
1239     /* FIFO Error Interrupt management ******************************************/
1240     if ((tmpisr_dma & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1241     {
1242       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != 0U)
1243       {
1244         /* Clear the FIFO error flag */
1245         regs_dma->IFCR = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
1246 
1247         /* Update error code */
1248         hdma->ErrorCode |= HAL_DMA_ERROR_FE;
1249       }
1250     }
1251     /* Direct Mode Error Interrupt management ***********************************/
1252     if ((tmpisr_dma & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1253     {
1254       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != 0U)
1255       {
1256         /* Clear the direct mode error flag */
1257         regs_dma->IFCR = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
1258 
1259         /* Update error code */
1260         hdma->ErrorCode |= HAL_DMA_ERROR_DME;
1261       }
1262     }
1263     /* Half Transfer Complete Interrupt management ******************************/
1264     if ((tmpisr_dma & (DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1265     {
1266       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
1267       {
1268         /* Clear the half transfer complete flag */
1269         regs_dma->IFCR = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
1270 
1271         /* Multi_Buffering mode enabled */
1272         if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
1273         {
1274           /* Current memory buffer used is Memory 0 */
1275           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
1276           {
1277             if(hdma->XferHalfCpltCallback != NULL)
1278             {
1279               /* Half transfer callback */
1280               hdma->XferHalfCpltCallback(hdma);
1281             }
1282           }
1283           /* Current memory buffer used is Memory 1 */
1284           else
1285           {
1286             if(hdma->XferM1HalfCpltCallback != NULL)
1287             {
1288               /* Half transfer callback */
1289               hdma->XferM1HalfCpltCallback(hdma);
1290             }
1291           }
1292         }
1293         else
1294         {
1295           /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
1296           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
1297           {
1298             /* Disable the half transfer interrupt */
1299             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_HT);
1300           }
1301 
1302           if(hdma->XferHalfCpltCallback != NULL)
1303           {
1304             /* Half transfer callback */
1305             hdma->XferHalfCpltCallback(hdma);
1306           }
1307         }
1308       }
1309     }
1310     /* Transfer Complete Interrupt management ***********************************/
1311     if ((tmpisr_dma & (DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1312     {
1313       if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
1314       {
1315         /* Clear the transfer complete flag */
1316         regs_dma->IFCR = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
1317 
1318         if(HAL_DMA_STATE_ABORT == hdma->State)
1319         {
1320           /* Disable all the transfer interrupts */
1321           ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
1322           ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR &= ~(DMA_IT_FE);
1323 
1324           if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
1325           {
1326             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_HT);
1327           }
1328 
1329           /* Clear all interrupt flags at correct offset within the register */
1330           regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
1331 
1332           /* Change the DMA state */
1333           hdma->State = HAL_DMA_STATE_READY;
1334 
1335           /* Process Unlocked */
1336           __HAL_UNLOCK(hdma);
1337 
1338           if(hdma->XferAbortCallback != NULL)
1339           {
1340             hdma->XferAbortCallback(hdma);
1341           }
1342           return;
1343         }
1344 
1345         if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
1346         {
1347           /* Current memory buffer used is Memory 0 */
1348           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
1349           {
1350             if(hdma->XferM1CpltCallback != NULL)
1351             {
1352               /* Transfer complete Callback for memory1 */
1353               hdma->XferM1CpltCallback(hdma);
1354             }
1355           }
1356           /* Current memory buffer used is Memory 1 */
1357           else
1358           {
1359             if(hdma->XferCpltCallback != NULL)
1360             {
1361               /* Transfer complete Callback for memory0 */
1362               hdma->XferCpltCallback(hdma);
1363             }
1364           }
1365         }
1366         /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
1367         else
1368         {
1369           if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
1370           {
1371             /* Disable the transfer complete interrupt */
1372             ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC);
1373 
1374             /* Change the DMA state */
1375             hdma->State = HAL_DMA_STATE_READY;
1376 
1377             /* Process Unlocked */
1378             __HAL_UNLOCK(hdma);
1379           }
1380 
1381           if(hdma->XferCpltCallback != NULL)
1382           {
1383             /* Transfer complete callback */
1384             hdma->XferCpltCallback(hdma);
1385           }
1386         }
1387       }
1388     }
1389 
1390     /* manage error case */
1391     if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
1392     {
1393       if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != 0U)
1394       {
1395         hdma->State = HAL_DMA_STATE_ABORT;
1396 
1397         /* Disable the stream */
1398         __HAL_DMA_DISABLE(hdma);
1399 
1400         do
1401         {
1402           if (++count > timeout)
1403           {
1404             break;
1405           }
1406         }
1407         while((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U);
1408 
1409         if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
1410         {
1411           /* Change the DMA state to error if DMA disable fails */
1412           hdma->State = HAL_DMA_STATE_ERROR;
1413         }
1414         else
1415         {
1416           /* Change the DMA state to Ready if DMA disable success */
1417           hdma->State = HAL_DMA_STATE_READY;
1418         }
1419 
1420         /* Process Unlocked */
1421         __HAL_UNLOCK(hdma);
1422       }
1423 
1424       if(hdma->XferErrorCallback != NULL)
1425       {
1426         /* Transfer error callback */
1427         hdma->XferErrorCallback(hdma);
1428       }
1429     }
1430   }
1431   else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U)  /* BDMA instance(s) */
1432   {
1433     ccr_reg = (((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR);
1434 
1435     /* Half Transfer Complete Interrupt management ******************************/
1436     if (((tmpisr_bdma & (BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_HTIE) != 0U))
1437     {
1438       /* Clear the half transfer complete flag */
1439       regs_bdma->IFCR = (BDMA_ISR_HTIF0 << (hdma->StreamIndex & 0x1FU));
1440 
1441       /* Disable the transfer complete interrupt if the DMA mode is Double Buffering */
1442       if((ccr_reg & BDMA_CCR_DBM) != 0U)
1443       {
1444         /* Current memory buffer used is Memory 0 */
1445         if((ccr_reg & BDMA_CCR_CT) == 0U)
1446         {
1447           if(hdma->XferM1HalfCpltCallback != NULL)
1448           {
1449             /* Half transfer Callback for Memory 1 */
1450             hdma->XferM1HalfCpltCallback(hdma);
1451           }
1452         }
1453         /* Current memory buffer used is Memory 1 */
1454         else
1455         {
1456           if(hdma->XferHalfCpltCallback != NULL)
1457           {
1458             /* Half transfer Callback for Memory 0 */
1459             hdma->XferHalfCpltCallback(hdma);
1460           }
1461         }
1462       }
1463       else
1464       {
1465         if((ccr_reg & BDMA_CCR_CIRC) == 0U)
1466         {
1467           /* Disable the half transfer interrupt */
1468           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
1469         }
1470 
1471         /* DMA peripheral state is not updated in Half Transfer */
1472         /* but in Transfer Complete case */
1473 
1474        if(hdma->XferHalfCpltCallback != NULL)
1475         {
1476           /* Half transfer callback */
1477           hdma->XferHalfCpltCallback(hdma);
1478         }
1479       }
1480     }
1481 
1482     /* Transfer Complete Interrupt management ***********************************/
1483     else if (((tmpisr_bdma & (BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_TCIE) != 0U))
1484     {
1485       /* Clear the transfer complete flag */
1486       regs_bdma->IFCR = (BDMA_ISR_TCIF0) << (hdma->StreamIndex & 0x1FU);
1487 
1488       /* Disable the transfer complete interrupt if the DMA mode is Double Buffering */
1489       if((ccr_reg & BDMA_CCR_DBM) != 0U)
1490       {
1491         /* Current memory buffer used is Memory 0 */
1492         if((ccr_reg & BDMA_CCR_CT) == 0U)
1493         {
1494           if(hdma->XferM1CpltCallback != NULL)
1495           {
1496             /* Transfer complete Callback for Memory 1 */
1497             hdma->XferM1CpltCallback(hdma);
1498           }
1499         }
1500         /* Current memory buffer used is Memory 1 */
1501         else
1502         {
1503           if(hdma->XferCpltCallback != NULL)
1504           {
1505             /* Transfer complete Callback for Memory 0 */
1506             hdma->XferCpltCallback(hdma);
1507           }
1508         }
1509       }
1510       else
1511       {
1512         if((ccr_reg & BDMA_CCR_CIRC) == 0U)
1513         {
1514           /* Disable the transfer complete and error interrupt, if the DMA mode is not CIRCULAR */
1515           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
1516 
1517           /* Change the DMA state */
1518           hdma->State = HAL_DMA_STATE_READY;
1519 
1520           /* Process Unlocked */
1521           __HAL_UNLOCK(hdma);
1522         }
1523 
1524         if(hdma->XferCpltCallback != NULL)
1525         {
1526           /* Transfer complete callback */
1527           hdma->XferCpltCallback(hdma);
1528         }
1529       }
1530     }
1531     /* Transfer Error Interrupt management **************************************/
1532     else if (((tmpisr_bdma & (BDMA_FLAG_TE0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_TEIE) != 0U))
1533     {
1534       /* When a DMA transfer error occurs */
1535       /* A hardware clear of its EN bits is performed */
1536       /* Disable ALL DMA IT */
1537       __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
1538 
1539       /* Clear all flags */
1540       regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
1541 
1542       /* Update error code */
1543       hdma->ErrorCode = HAL_DMA_ERROR_TE;
1544 
1545       /* Change the DMA state */
1546       hdma->State = HAL_DMA_STATE_READY;
1547 
1548       /* Process Unlocked */
1549       __HAL_UNLOCK(hdma);
1550 
1551       if (hdma->XferErrorCallback != NULL)
1552       {
1553         /* Transfer error callback */
1554         hdma->XferErrorCallback(hdma);
1555       }
1556     }
1557     else
1558     {
1559       /* Nothing To Do */
1560     }
1561   }
1562   else
1563   {
1564     /* Nothing To Do */
1565   }
1566 }
1567 
1568 /**
1569   * @brief  Register callbacks
1570   * @param  hdma:                 pointer to a DMA_HandleTypeDef structure that contains
1571   *                               the configuration information for the specified DMA Stream.
1572   * @param  CallbackID:           User Callback identifier
1573   *                               a DMA_HandleTypeDef structure as parameter.
1574   * @param  pCallback:            pointer to private callback function which has pointer to
1575   *                               a DMA_HandleTypeDef structure as parameter.
1576   * @retval HAL status
1577   */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* pCallback)(DMA_HandleTypeDef * _hdma))1578 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
1579 {
1580 
1581   HAL_StatusTypeDef status = HAL_OK;
1582 
1583   /* Check the DMA peripheral handle */
1584   if(hdma == NULL)
1585   {
1586     return HAL_ERROR;
1587   }
1588 
1589   /* Process locked */
1590   __HAL_LOCK(hdma);
1591 
1592   if(HAL_DMA_STATE_READY == hdma->State)
1593   {
1594     switch (CallbackID)
1595     {
1596     case  HAL_DMA_XFER_CPLT_CB_ID:
1597       hdma->XferCpltCallback = pCallback;
1598       break;
1599 
1600     case  HAL_DMA_XFER_HALFCPLT_CB_ID:
1601       hdma->XferHalfCpltCallback = pCallback;
1602       break;
1603 
1604     case  HAL_DMA_XFER_M1CPLT_CB_ID:
1605       hdma->XferM1CpltCallback = pCallback;
1606       break;
1607 
1608     case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
1609       hdma->XferM1HalfCpltCallback = pCallback;
1610       break;
1611 
1612     case  HAL_DMA_XFER_ERROR_CB_ID:
1613       hdma->XferErrorCallback = pCallback;
1614       break;
1615 
1616     case  HAL_DMA_XFER_ABORT_CB_ID:
1617       hdma->XferAbortCallback = pCallback;
1618       break;
1619 
1620     default:
1621       status =  HAL_ERROR;
1622       break;
1623     }
1624   }
1625   else
1626   {
1627     /* Return error status */
1628     status =  HAL_ERROR;
1629   }
1630 
1631   /* Release Lock */
1632   __HAL_UNLOCK(hdma);
1633 
1634   return status;
1635 }
1636 
1637 /**
1638   * @brief  UnRegister callbacks
1639   * @param  hdma:                 pointer to a DMA_HandleTypeDef structure that contains
1640   *                               the configuration information for the specified DMA Stream.
1641   * @param  CallbackID:           User Callback identifier
1642   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
1643   * @retval HAL status
1644   */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID)1645 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
1646 {
1647   HAL_StatusTypeDef status = HAL_OK;
1648 
1649   /* Check the DMA peripheral handle */
1650   if(hdma == NULL)
1651   {
1652     return HAL_ERROR;
1653   }
1654 
1655   /* Process locked */
1656   __HAL_LOCK(hdma);
1657 
1658   if(HAL_DMA_STATE_READY == hdma->State)
1659   {
1660     switch (CallbackID)
1661     {
1662     case  HAL_DMA_XFER_CPLT_CB_ID:
1663       hdma->XferCpltCallback = NULL;
1664       break;
1665 
1666     case  HAL_DMA_XFER_HALFCPLT_CB_ID:
1667       hdma->XferHalfCpltCallback = NULL;
1668       break;
1669 
1670     case  HAL_DMA_XFER_M1CPLT_CB_ID:
1671       hdma->XferM1CpltCallback = NULL;
1672       break;
1673 
1674     case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
1675       hdma->XferM1HalfCpltCallback = NULL;
1676       break;
1677 
1678     case  HAL_DMA_XFER_ERROR_CB_ID:
1679       hdma->XferErrorCallback = NULL;
1680       break;
1681 
1682     case  HAL_DMA_XFER_ABORT_CB_ID:
1683       hdma->XferAbortCallback = NULL;
1684       break;
1685 
1686     case   HAL_DMA_XFER_ALL_CB_ID:
1687       hdma->XferCpltCallback = NULL;
1688       hdma->XferHalfCpltCallback = NULL;
1689       hdma->XferM1CpltCallback = NULL;
1690       hdma->XferM1HalfCpltCallback = NULL;
1691       hdma->XferErrorCallback = NULL;
1692       hdma->XferAbortCallback = NULL;
1693       break;
1694 
1695     default:
1696       status = HAL_ERROR;
1697       break;
1698     }
1699   }
1700   else
1701   {
1702     status = HAL_ERROR;
1703   }
1704 
1705   /* Release Lock */
1706   __HAL_UNLOCK(hdma);
1707 
1708   return status;
1709 }
1710 
1711 /**
1712   * @}
1713   */
1714 
1715 /** @addtogroup DMA_Exported_Functions_Group3
1716   *
1717 @verbatim
1718  ===============================================================================
1719                     ##### State and Errors functions #####
1720  ===============================================================================
1721     [..]
1722     This subsection provides functions allowing to
1723       (+) Check the DMA state
1724       (+) Get error code
1725 
1726 @endverbatim
1727   * @{
1728   */
1729 
1730 /**
1731   * @brief  Returns the DMA state.
1732   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1733   *               the configuration information for the specified DMA Stream.
1734   * @retval HAL state
1735   */
HAL_DMA_GetState(DMA_HandleTypeDef * hdma)1736 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
1737 {
1738   return hdma->State;
1739 }
1740 
1741 /**
1742   * @brief  Return the DMA error code
1743   * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains
1744   *              the configuration information for the specified DMA Stream.
1745   * @retval DMA Error Code
1746   */
HAL_DMA_GetError(DMA_HandleTypeDef * hdma)1747 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
1748 {
1749   return hdma->ErrorCode;
1750 }
1751 
1752 /**
1753   * @}
1754   */
1755 
1756 /**
1757   * @}
1758   */
1759 
1760 /** @addtogroup DMA_Private_Functions
1761   * @{
1762   */
1763 
1764 /**
1765   * @brief  Sets the DMA Transfer parameter.
1766   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
1767   *                     the configuration information for the specified DMA Stream.
1768   * @param  SrcAddress: The source memory Buffer address
1769   * @param  DstAddress: The destination memory Buffer address
1770   * @param  DataLength: The length of data to be transferred from source to destination
1771   * @retval None
1772   */
DMA_SetConfig(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)1773 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
1774 {
1775   /* calculate DMA base and stream number */
1776   DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
1777   BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
1778 
1779   if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
1780   {
1781     /* Clear the DMAMUX synchro overrun flag */
1782     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1783 
1784     if(hdma->DMAmuxRequestGen != 0U)
1785     {
1786       /* Clear the DMAMUX request generator overrun flag */
1787       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
1788     }
1789   }
1790 
1791   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1792   {
1793     /* Clear all interrupt flags at correct offset within the register */
1794     regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
1795 
1796     /* Clear DBM bit */
1797     ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= (uint32_t)(~DMA_SxCR_DBM);
1798 
1799     /* Configure DMA Stream data length */
1800     ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
1801 
1802     /* Peripheral to Memory */
1803     if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1804     {
1805       /* Configure DMA Stream destination address */
1806       ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress;
1807 
1808       /* Configure DMA Stream source address */
1809       ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress;
1810     }
1811     /* Memory to Peripheral */
1812     else
1813     {
1814       /* Configure DMA Stream source address */
1815       ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress;
1816 
1817       /* Configure DMA Stream destination address */
1818       ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress;
1819     }
1820   }
1821   else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
1822   {
1823     /* Clear all flags */
1824     regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
1825 
1826     /* Configure DMA Channel data length */
1827     ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = DataLength;
1828 
1829     /* Peripheral to Memory */
1830     if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1831     {
1832       /* Configure DMA Channel destination address */
1833       ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = DstAddress;
1834 
1835       /* Configure DMA Channel source address */
1836       ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = SrcAddress;
1837     }
1838     /* Memory to Peripheral */
1839     else
1840     {
1841       /* Configure DMA Channel source address */
1842       ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = SrcAddress;
1843 
1844       /* Configure DMA Channel destination address */
1845       ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = DstAddress;
1846     }
1847   }
1848   else
1849   {
1850     /* Nothing To Do */
1851   }
1852 }
1853 
1854 /**
1855   * @brief  Returns the DMA Stream base address depending on stream number
1856   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
1857   *                     the configuration information for the specified DMA Stream.
1858   * @retval Stream base address
1859   */
DMA_CalcBaseAndBitshift(DMA_HandleTypeDef * hdma)1860 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
1861 {
1862   if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1863   {
1864     uint32_t stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
1865 
1866     /* lookup table for necessary bitshift of flags within status registers */
1867     static const uint8_t flagBitshiftOffset[8U] = {0U, 6U, 16U, 22U, 0U, 6U, 16U, 22U};
1868     hdma->StreamIndex = flagBitshiftOffset[stream_number & 0x7U];
1869 
1870     if (stream_number > 3U)
1871     {
1872       /* return pointer to HISR and HIFCR */
1873       hdma->StreamBaseAddress = (((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU)) + 4U);
1874     }
1875     else
1876     {
1877       /* return pointer to LISR and LIFCR */
1878       hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU));
1879     }
1880   }
1881   else /* BDMA instance(s) */
1882   {
1883     /* return pointer to ISR and IFCR */
1884     hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0xFFU));
1885   }
1886 
1887   return hdma->StreamBaseAddress;
1888 }
1889 
1890 /**
1891   * @brief  Check compatibility between FIFO threshold level and size of the memory burst
1892   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
1893   *                     the configuration information for the specified DMA Stream.
1894   * @retval HAL status
1895   */
DMA_CheckFifoParam(DMA_HandleTypeDef * hdma)1896 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma)
1897 {
1898   HAL_StatusTypeDef status = HAL_OK;
1899 
1900   /* Memory Data size equal to Byte */
1901   if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_BYTE)
1902   {
1903     switch (hdma->Init.FIFOThreshold)
1904     {
1905       case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1906       case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1907 
1908         if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1909         {
1910           status = HAL_ERROR;
1911         }
1912         break;
1913 
1914       case DMA_FIFO_THRESHOLD_HALFFULL:
1915         if (hdma->Init.MemBurst == DMA_MBURST_INC16)
1916         {
1917           status = HAL_ERROR;
1918         }
1919         break;
1920 
1921       case DMA_FIFO_THRESHOLD_FULL:
1922         break;
1923 
1924       default:
1925         break;
1926     }
1927   }
1928 
1929   /* Memory Data size equal to Half-Word */
1930   else if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
1931   {
1932     switch (hdma->Init.FIFOThreshold)
1933     {
1934       case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1935       case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1936         status = HAL_ERROR;
1937         break;
1938 
1939       case DMA_FIFO_THRESHOLD_HALFFULL:
1940         if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1941         {
1942           status = HAL_ERROR;
1943         }
1944         break;
1945 
1946       case DMA_FIFO_THRESHOLD_FULL:
1947         if (hdma->Init.MemBurst == DMA_MBURST_INC16)
1948         {
1949           status = HAL_ERROR;
1950         }
1951         break;
1952 
1953       default:
1954         break;
1955     }
1956   }
1957 
1958   /* Memory Data size equal to Word */
1959   else
1960   {
1961     switch (hdma->Init.FIFOThreshold)
1962     {
1963       case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1964       case DMA_FIFO_THRESHOLD_HALFFULL:
1965       case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1966         status = HAL_ERROR;
1967         break;
1968 
1969       case DMA_FIFO_THRESHOLD_FULL:
1970         if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1971         {
1972           status = HAL_ERROR;
1973         }
1974     break;
1975 
1976       default:
1977         break;
1978     }
1979   }
1980 
1981   return status;
1982 }
1983 
1984 /**
1985   * @brief  Updates the DMA handle with the DMAMUX  channel and status mask depending on stream number
1986   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
1987   *                     the configuration information for the specified DMA Stream.
1988   * @retval HAL status
1989   */
DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef * hdma)1990 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
1991 {
1992   uint32_t stream_number;
1993   uint32_t stream_baseaddress = (uint32_t)((uint32_t*)hdma->Instance);
1994 
1995   if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
1996   {
1997     /* BDMA Channels are connected to DMAMUX2 channels */
1998     stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 8U) / 20U;
1999     hdma->DMAmuxChannel = (DMAMUX_Channel_TypeDef *)((uint32_t)(((uint32_t)DMAMUX2_Channel0) + (stream_number * 4U)));
2000     hdma->DMAmuxChannelStatus = DMAMUX2_ChannelStatus;
2001     hdma->DMAmuxChannelStatusMask = 1UL << (stream_number & 0x1FU);
2002   }
2003   else
2004   {
2005     /* DMA1/DMA2 Streams are connected to DMAMUX1 channels */
2006     stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
2007 
2008     if((stream_baseaddress <= ((uint32_t)DMA2_Stream7) ) && \
2009        (stream_baseaddress >= ((uint32_t)DMA2_Stream0)))
2010     {
2011       stream_number += 8U;
2012     }
2013     hdma->DMAmuxChannel = (DMAMUX_Channel_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_Channel0) + (stream_number * 4U)));
2014     hdma->DMAmuxChannelStatus = DMAMUX1_ChannelStatus;
2015     hdma->DMAmuxChannelStatusMask = 1UL << (stream_number & 0x1FU);
2016   }
2017 }
2018 
2019 /**
2020   * @brief  Updates the DMA handle with the DMAMUX  request generator params
2021   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
2022   *                     the configuration information for the specified DMA Stream.
2023   * @retval HAL status
2024   */
DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef * hdma)2025 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
2026 {
2027   uint32_t request =  hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
2028 
2029   if((request >= DMA_REQUEST_GENERATOR0) && (request <= DMA_REQUEST_GENERATOR7))
2030   {
2031     if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
2032     {
2033       /* BDMA Channels are connected to DMAMUX2 request generator blocks */
2034       hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX2_RequestGenerator0) + ((request - 1U) * 4U)));
2035 
2036       hdma->DMAmuxRequestGenStatus = DMAMUX2_RequestGenStatus;
2037     }
2038     else
2039     {
2040       /* DMA1 and DMA2 Streams use DMAMUX1 request generator blocks */
2041       hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_RequestGenerator0) + ((request - 1U) * 4U)));
2042 
2043       hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
2044     }
2045 
2046     hdma->DMAmuxRequestGenStatusMask = 1UL << (request - 1U);
2047   }
2048 }
2049 
2050 /**
2051   * @}
2052   */
2053 
2054 #endif /* HAL_DMA_MODULE_ENABLED */
2055 /**
2056   * @}
2057   */
2058 
2059 /**
2060   * @}
2061   */
2062 
2063