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