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