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