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
12 ==============================================================================
\r
13 ##### How to use this driver #####
\r
14 ==============================================================================
\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
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
27 *** Polling mode IO operation ***
\r
28 =================================
\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
35 *** Interrupt mode IO operation ***
\r
36 ===================================
\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
48 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
\r
51 (#) Use HAL_DMA_Abort() function to abort the current transfer
\r
53 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
\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
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
65 *** DMA HAL driver macros list ***
\r
66 =============================================
\r
68 Below the list of most used macros in DMA HAL driver.
\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
78 (@) You can refer to the DMA HAL driver header file for more useful macros.
\r
81 ******************************************************************************
\r
84 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics.
\r
85 * All rights reserved.</center></h2>
\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
92 ******************************************************************************
\r
95 /* Includes ------------------------------------------------------------------*/
\r
96 #include "stm32h7xx_hal.h"
\r
98 /** @addtogroup STM32H7xx_HAL_Driver
\r
102 /** @defgroup DMA DMA
\r
103 * @brief DMA HAL module driver
\r
107 #ifdef HAL_DMA_MODULE_ENABLED
\r
109 /* Private types -------------------------------------------------------------*/
\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
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
123 /* Private variables ---------------------------------------------------------*/
\r
124 /* Private constants ---------------------------------------------------------*/
\r
125 /** @addtogroup DMA_Private_Constants
\r
128 #define HAL_TIMEOUT_DMA_ABORT (5U) /* 5 ms */
\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
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
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
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
145 #define DMA_TO_BDMA_MODE(__DMA_MODE__) ((__DMA_MODE__) >> 3U)
\r
147 #define DMA_TO_BDMA_PRIORITY(__DMA_PRIORITY__) ((__DMA_PRIORITY__) >> 4U)
\r
152 /* Private macros ------------------------------------------------------------*/
\r
153 /* Private functions ---------------------------------------------------------*/
\r
154 /** @addtogroup DMA_Private_Functions
\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
167 /* Exported functions ---------------------------------------------------------*/
\r
168 /** @addtogroup DMA_Exported_Functions
\r
172 /** @addtogroup DMA_Exported_Functions_Group1
\r
175 ===============================================================================
\r
176 ##### Initialization and de-initialization functions #####
\r
177 ===============================================================================
\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
183 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
\r
185 The HAL_DMA_DeInit function allows to deinitialize the DMA stream.
\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
198 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
\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
205 /* Check the DMA peripheral handle */
\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
221 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\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
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
234 /* Allocate lock resource */
\r
235 __HAL_UNLOCK(hdma);
\r
237 /* Change DMA peripheral state */
\r
238 hdma->State = HAL_DMA_STATE_BUSY;
\r
240 /* Disable the peripheral */
\r
241 __HAL_DMA_DISABLE(hdma);
\r
243 /* Check if the DMA Stream is effectively disabled */
\r
244 while((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
\r
246 /* Check for the Timeout */
\r
247 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
\r
249 /* Update error code */
\r
250 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
\r
252 /* Change the DMA state */
\r
253 hdma->State = HAL_DMA_STATE_ERROR;
\r
259 /* Get the CR register value */
\r
260 registerValue = ((DMA_Stream_TypeDef *)hdma->Instance)->CR;
\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
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
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
277 /* Get memory burst and peripheral burst */
\r
278 registerValue |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;
\r
281 /* Write to DMA Stream CR register */
\r
282 ((DMA_Stream_TypeDef *)hdma->Instance)->CR = registerValue;
\r
284 /* Get the FCR register value */
\r
285 registerValue = ((DMA_Stream_TypeDef *)hdma->Instance)->FCR;
\r
287 /* Clear Direct mode and FIFO threshold bits */
\r
288 registerValue &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
\r
290 /* Prepare the DMA Stream FIFO configuration */
\r
291 registerValue |= hdma->Init.FIFOMode;
\r
293 /* the FIFO threshold is not used when the FIFO mode is disabled */
\r
294 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
\r
296 /* Get the FIFO threshold */
\r
297 registerValue |= hdma->Init.FIFOThreshold;
\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
303 if (DMA_CheckFifoParam(hdma) != HAL_OK)
\r
305 /* Update error code */
\r
306 hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
\r
308 /* Change the DMA state */
\r
309 hdma->State = HAL_DMA_STATE_READY;
\r
316 /* Write to DMA Stream FCR */
\r
317 ((DMA_Stream_TypeDef *)hdma->Instance)->FCR = registerValue;
\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
323 /* Clear all interrupt flags */
\r
324 regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
\r
326 else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
\r
328 /* Check the request parameter */
\r
329 assert_param(IS_BDMA_REQUEST(hdma->Init.Request));
\r
331 /* Allocate lock resource */
\r
332 __HAL_UNLOCK(hdma);
\r
334 /* Change DMA peripheral state */
\r
335 hdma->State = HAL_DMA_STATE_BUSY;
\r
337 /* Get the CR register value */
\r
338 registerValue = ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR;
\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
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
355 /* Write to DMA Channel CR register */
\r
356 ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR = registerValue;
\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
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
365 /* Clear all interrupt flags */
\r
366 regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
\r
370 hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
\r
371 hdma->State = HAL_DMA_STATE_ERROR;
\r
376 /* Initialize parameters for DMAMUX channel :
\r
377 DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
\r
379 DMA_CalcDMAMUXChannelBaseAndMask(hdma);
\r
381 if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
\r
383 /* if memory to memory force the request to 0*/
\r
384 hdma->Init.Request = DMA_REQUEST_MEM2MEM;
\r
387 /* Set peripheral request to DMAMUX channel */
\r
388 hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
\r
390 /* Clear the DMAMUX synchro overrun flag */
\r
391 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
\r
393 /* Initialize parameters for DMAMUX request generator :
\r
394 if the DMA request is DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR7
\r
396 if((hdma->Init.Request >= DMA_REQUEST_GENERATOR0) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR7))
\r
398 /* Initialize parameters for DMAMUX request generator :
\r
399 DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask */
\r
400 DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
\r
402 /* Reset the DMAMUX request generator register */
\r
403 hdma->DMAmuxRequestGen->RGCR = 0U;
\r
405 /* Clear the DMAMUX request generator overrun flag */
\r
406 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
\r
410 hdma->DMAmuxRequestGen = 0U;
\r
411 hdma->DMAmuxRequestGenStatus = 0U;
\r
412 hdma->DMAmuxRequestGenStatusMask = 0U;
\r
415 /* Initialize the error code */
\r
416 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
\r
418 /* Initialize the DMA state */
\r
419 hdma->State = HAL_DMA_STATE_READY;
\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
430 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
\r
432 DMA_Base_Registers *regs_dma;
\r
433 BDMA_Base_Registers *regs_bdma;
\r
435 /* Check the DMA peripheral handle */
\r
441 /* Disable the selected DMA Streamx */
\r
442 __HAL_DMA_DISABLE(hdma);
\r
444 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\r
446 /* Reset DMA Streamx control register */
\r
447 ((DMA_Stream_TypeDef *)hdma->Instance)->CR = 0U;
\r
449 /* Reset DMA Streamx number of data to transfer register */
\r
450 ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = 0U;
\r
452 /* Reset DMA Streamx peripheral address register */
\r
453 ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = 0U;
\r
455 /* Reset DMA Streamx memory 0 address register */
\r
456 ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = 0U;
\r
458 /* Reset DMA Streamx memory 1 address register */
\r
459 ((DMA_Stream_TypeDef *)hdma->Instance)->M1AR = 0U;
\r
461 /* Reset DMA Streamx FIFO control register */
\r
462 ((DMA_Stream_TypeDef *)hdma->Instance)->FCR = (uint32_t)0x00000021U;
\r
464 /* Get DMA steam Base Address */
\r
465 regs_dma = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
\r
467 /* Clear all interrupt flags at correct offset within the register */
\r
468 regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
\r
470 else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
\r
472 /* Reset DMA Channel control register */
\r
473 ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR = 0U;
\r
475 /* Reset DMA Channel Number of Data to Transfer register */
\r
476 ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = 0U;
\r
478 /* Reset DMA Channel peripheral address register */
\r
479 ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = 0U;
\r
481 /* Reset DMA Channel memory 0 address register */
\r
482 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = 0U;
\r
484 /* Reset DMA Channel memory 1 address register */
\r
485 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = 0U;
\r
487 /* Get DMA steam Base Address */
\r
488 regs_bdma = (BDMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
\r
490 /* Clear all interrupt flags at correct offset within the register */
\r
491 regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
\r
495 /* Return error status */
\r
499 /* Initialize parameters for DMAMUX channel :
\r
500 DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
\r
501 DMA_CalcDMAMUXChannelBaseAndMask(hdma);
\r
503 if(hdma->DMAmuxChannel != 0U)
\r
505 /* Resett he DMAMUX channel that corresponds to the DMA stream */
\r
506 hdma->DMAmuxChannel->CCR = 0U;
\r
508 /* Clear the DMAMUX synchro overrun flag */
\r
509 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
\r
512 if((hdma->Init.Request >= DMA_REQUEST_GENERATOR0) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR7))
\r
514 /* Initialize parameters for DMAMUX request generator :
\r
515 DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask */
\r
516 DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
\r
518 /* Reset the DMAMUX request generator register */
\r
519 hdma->DMAmuxRequestGen->RGCR = 0U;
\r
521 /* Clear the DMAMUX request generator overrun flag */
\r
522 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
\r
525 hdma->DMAmuxRequestGen = 0U;
\r
526 hdma->DMAmuxRequestGenStatus = 0U;
\r
527 hdma->DMAmuxRequestGenStatusMask = 0U;
\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
537 /* Initialize the error code */
\r
538 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
\r
540 /* Initialize the DMA state */
\r
541 hdma->State = HAL_DMA_STATE_RESET;
\r
544 __HAL_UNLOCK(hdma);
\r
553 /** @addtogroup DMA_Exported_Functions_Group2
\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
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
581 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
\r
583 HAL_StatusTypeDef status = HAL_OK;
\r
585 /* Check the parameters */
\r
586 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
\r
588 /* Check the DMA peripheral handle */
\r
594 /* Process locked */
\r
597 if(HAL_DMA_STATE_READY == hdma->State)
\r
599 /* Change DMA peripheral state */
\r
600 hdma->State = HAL_DMA_STATE_BUSY;
\r
602 /* Initialize the error code */
\r
603 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
\r
605 /* Disable the peripheral */
\r
606 __HAL_DMA_DISABLE(hdma);
\r
608 /* Configure the source, destination address and the data length */
\r
609 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
\r
611 /* Enable the Peripheral */
\r
612 __HAL_DMA_ENABLE(hdma);
\r
616 /* Process unlocked */
\r
617 __HAL_UNLOCK(hdma);
\r
619 /* Set the error code to busy */
\r
620 hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
\r
622 /* Return error status */
\r
623 status = HAL_ERROR;
\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
637 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
\r
639 HAL_StatusTypeDef status = HAL_OK;
\r
641 /* Check the parameters */
\r
642 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
\r
644 /* Check the DMA peripheral handle */
\r
650 /* Process locked */
\r
653 if(HAL_DMA_STATE_READY == hdma->State)
\r
655 /* Change DMA peripheral state */
\r
656 hdma->State = HAL_DMA_STATE_BUSY;
\r
658 /* Initialize the error code */
\r
659 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
\r
661 /* Disable the peripheral */
\r
662 __HAL_DMA_DISABLE(hdma);
\r
664 /* Configure the source, destination address and the data length */
\r
665 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
\r
667 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\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
672 if(hdma->XferHalfCpltCallback != NULL)
\r
674 /* Enable Half Transfer IT if corresponding Callback is set */
\r
675 ((DMA_Stream_TypeDef *)hdma->Instance)->CR |= DMA_IT_HT;
\r
678 else /* BDMA channel */
\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
683 if(hdma->XferHalfCpltCallback != NULL)
\r
685 /*Enable Half Transfer IT if corresponding Callback is set */
\r
686 ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR |= BDMA_CCR_HTIE;
\r
690 /* Check if DMAMUX Synchronization is enabled */
\r
691 if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
\r
693 /* Enable DMAMUX sync overrun IT*/
\r
694 hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
\r
697 if(hdma->DMAmuxRequestGen != 0U)
\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
704 /* Enable the Peripheral */
\r
705 __HAL_DMA_ENABLE(hdma);
\r
709 /* Process unlocked */
\r
710 __HAL_UNLOCK(hdma);
\r
712 /* Set the error code to busy */
\r
713 hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
\r
715 /* Return error status */
\r
716 status = HAL_ERROR;
\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
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
734 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
\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
741 uint32_t tickstart = HAL_GetTick();
\r
743 /* Check the DMA peripheral handle */
\r
749 /* Check the DMA peripheral state */
\r
750 if(hdma->State != HAL_DMA_STATE_BUSY)
\r
752 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
\r
754 /* Process Unlocked */
\r
755 __HAL_UNLOCK(hdma);
\r
761 /* Disable all the transfer interrupts */
\r
762 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\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
768 enableRegister = (__IO uint32_t *)(&(((DMA_Stream_TypeDef *)hdma->Instance)->CR));
\r
770 else /* BDMA channel */
\r
772 /* Disable DMA All Interrupts */
\r
773 ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);
\r
775 enableRegister = (__IO uint32_t *)(&(((BDMA_Channel_TypeDef *)hdma->Instance)->CCR));
\r
778 /* disable the DMAMUX sync overrun IT */
\r
779 hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
\r
781 /* Disable the stream */
\r
782 __HAL_DMA_DISABLE(hdma);
\r
784 /* Check if the DMA Stream is effectively disabled */
\r
785 while(((*enableRegister) & DMA_SxCR_EN) != 0U)
\r
787 /* Check for the Timeout */
\r
788 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
\r
790 /* Update error code */
\r
791 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
\r
793 /* Process Unlocked */
\r
794 __HAL_UNLOCK(hdma);
\r
796 /* Change the DMA state */
\r
797 hdma->State = HAL_DMA_STATE_ERROR;
\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
806 regs_dma = (DMA_Base_Registers *)hdma->StreamBaseAddress;
\r
807 regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
\r
809 else /* BDMA channel */
\r
811 regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
\r
812 regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
\r
815 /* Clear the DMAMUX synchro overrun flag */
\r
816 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
\r
818 if(hdma->DMAmuxRequestGen != 0U)
\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
824 /* Clear the DMAMUX request generator overrun flag */
\r
825 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
\r
828 /* Process Unlocked */
\r
829 __HAL_UNLOCK(hdma);
\r
831 /* Change the DMA state */
\r
832 hdma->State = HAL_DMA_STATE_READY;
\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
844 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
\r
846 BDMA_Base_Registers *regs_bdma;
\r
848 /* Check the DMA peripheral handle */
\r
854 if(hdma->State != HAL_DMA_STATE_BUSY)
\r
856 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
\r
861 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\r
863 /* Set Abort State */
\r
864 hdma->State = HAL_DMA_STATE_ABORT;
\r
866 /* Disable the stream */
\r
867 __HAL_DMA_DISABLE(hdma);
\r
869 else /* BDMA channel */
\r
871 /* Disable DMA All Interrupts */
\r
872 ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);
\r
874 /* Disable the channel */
\r
875 __HAL_DMA_DISABLE(hdma);
\r
877 /* disable the DMAMUX sync overrun IT */
\r
878 hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
\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
884 /* Clear the DMAMUX synchro overrun flag */
\r
885 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
\r
887 if(hdma->DMAmuxRequestGen != 0U)
\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
893 /* Clear the DMAMUX request generator overrun flag */
\r
894 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
\r
897 /* Process Unlocked */
\r
898 __HAL_UNLOCK(hdma);
\r
900 /* Change the DMA state */
\r
901 hdma->State = HAL_DMA_STATE_READY;
\r
903 /* Call User Abort callback */
\r
904 if(hdma->XferAbortCallback != NULL)
\r
906 hdma->XferAbortCallback(hdma);
\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
925 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
\r
927 HAL_StatusTypeDef status = HAL_OK;
\r
928 uint32_t cpltlevel_mask;
\r
929 uint32_t tickstart = HAL_GetTick();
\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
936 /* Check the DMA peripheral handle */
\r
942 if(HAL_DMA_STATE_BUSY != hdma->State)
\r
944 /* No transfer ongoing */
\r
945 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
\r
946 __HAL_UNLOCK(hdma);
\r
951 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\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
956 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
\r
960 /* Get the level transfer complete flag */
\r
961 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
\r
963 /* Transfer Complete flag */
\r
964 cpltlevel_mask = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
968 /* Half Transfer Complete flag */
\r
969 cpltlevel_mask = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
972 isr_reg = &(((DMA_Base_Registers *)hdma->StreamBaseAddress)->ISR);
\r
973 ifcr_reg = &(((DMA_Base_Registers *)hdma->StreamBaseAddress)->IFCR);
\r
975 else /* BDMA channel */
\r
977 /* Polling mode not supported in circular mode */
\r
978 if ((((BDMA_Channel_TypeDef *)hdma->Instance)->CCR & BDMA_CCR_CIRC) != 0U)
\r
980 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
\r
984 /* Get the level transfer complete flag */
\r
985 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
\r
987 /* Transfer Complete flag */
\r
988 cpltlevel_mask = BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU);
\r
992 /* Half Transfer Complete flag */
\r
993 cpltlevel_mask = BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU);
\r
996 isr_reg = &(((BDMA_Base_Registers *)hdma->StreamBaseAddress)->ISR);
\r
997 ifcr_reg = &(((BDMA_Base_Registers *)hdma->StreamBaseAddress)->IFCR);
\r
1000 while(((*isr_reg) & cpltlevel_mask) == 0U)
\r
1002 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\r
1004 if(((*isr_reg) & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
\r
1006 /* Update error code */
\r
1007 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
\r
1009 /* Clear the FIFO error flag */
\r
1010 (*ifcr_reg) = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
1013 if(((*isr_reg) & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
\r
1015 /* Update error code */
\r
1016 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
\r
1018 /* Clear the Direct Mode error flag */
\r
1019 (*ifcr_reg) = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
1022 if(((*isr_reg) & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
\r
1024 /* Update error code */
\r
1025 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
\r
1027 /* Clear the transfer error flag */
\r
1028 (*ifcr_reg) = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
1030 /* Change the DMA state */
\r
1031 hdma->State = HAL_DMA_STATE_READY;
\r
1033 /* Process Unlocked */
\r
1034 __HAL_UNLOCK(hdma);
\r
1039 else /* BDMA channel */
\r
1041 if(((*isr_reg) & (BDMA_FLAG_TE0 << (hdma->StreamIndex & 0x1FU))) != 0U)
\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
1048 /* Update error code */
\r
1049 hdma->ErrorCode = HAL_DMA_ERROR_TE;
\r
1051 /* Change the DMA state */
\r
1052 hdma->State = HAL_DMA_STATE_READY;
\r
1054 /* Process Unlocked */
\r
1055 __HAL_UNLOCK(hdma);
\r
1061 /* Check for the Timeout (Not applicable in circular mode)*/
\r
1062 if(Timeout != HAL_MAX_DELAY)
\r
1064 if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
\r
1066 /* Update error code */
\r
1067 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
\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
1073 Note that the Abort function will
\r
1074 - Clear the transfer error flags
\r
1083 /* Check for DMAMUX Request generator (if used) overrun status */
\r
1084 if(hdma->DMAmuxRequestGen != 0U)
\r
1086 /* if using DMAMUX request generator Check for DMAMUX request generator overrun */
\r
1087 if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
\r
1089 /* Clear the DMAMUX request generator overrun flag */
\r
1090 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
\r
1092 /* Update error code */
\r
1093 hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
\r
1097 /* Check for DMAMUX Synchronization overrun */
\r
1098 if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
\r
1100 /* Clear the DMAMUX synchro overrun flag */
\r
1101 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
\r
1103 /* Update error code */
\r
1104 hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
\r
1108 /* Get the level transfer complete flag */
\r
1109 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
\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
1114 (*ifcr_reg) = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << (hdma->StreamIndex & 0x1FU);
\r
1116 else /* BDMA channel */
\r
1118 (*ifcr_reg) = (BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU));
\r
1121 /* Process Unlocked */
\r
1122 __HAL_UNLOCK(hdma);
\r
1124 hdma->State = HAL_DMA_STATE_READY;
\r
1126 else /*CompleteLevel = HAL_DMA_HALF_TRANSFER*/
\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
1131 (*ifcr_reg) = (DMA_FLAG_HTIF0_4) << (hdma->StreamIndex & 0x1FU);
\r
1133 else /* BDMA channel */
\r
1135 (*ifcr_reg) = (BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU));
\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
1148 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
\r
1150 uint32_t tmpisr_dma, tmpisr_bdma;
\r
1152 __IO uint32_t count = 0U;
\r
1153 uint32_t timeout = SystemCoreClock / 9600U;
\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
1159 tmpisr_dma = regs_dma->ISR;
\r
1160 tmpisr_bdma = regs_bdma->ISR;
\r
1162 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\r
1164 /* Transfer Error Interrupt management ***************************************/
\r
1165 if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
\r
1167 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != 0U)
\r
1169 /* Disable the transfer error interrupt */
\r
1170 ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_TE);
\r
1172 /* Clear the transfer error flag */
\r
1173 regs_dma->IFCR = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
1175 /* Update error code */
\r
1176 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
\r
1179 /* FIFO Error Interrupt management ******************************************/
\r
1180 if ((tmpisr_dma & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
\r
1182 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != 0U)
\r
1184 /* Clear the FIFO error flag */
\r
1185 regs_dma->IFCR = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
1187 /* Update error code */
\r
1188 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
\r
1191 /* Direct Mode Error Interrupt management ***********************************/
\r
1192 if ((tmpisr_dma & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
\r
1194 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != 0U)
\r
1196 /* Clear the direct mode error flag */
\r
1197 regs_dma->IFCR = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
1199 /* Update error code */
\r
1200 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
\r
1203 /* Half Transfer Complete Interrupt management ******************************/
\r
1204 if ((tmpisr_dma & (DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
\r
1206 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
\r
1208 /* Clear the half transfer complete flag */
\r
1209 regs_dma->IFCR = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
1211 /* Multi_Buffering mode enabled */
\r
1212 if(((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
\r
1214 /* Current memory buffer used is Memory 0 */
\r
1215 if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
\r
1217 if(hdma->XferHalfCpltCallback != NULL)
\r
1219 /* Half transfer callback */
\r
1220 hdma->XferHalfCpltCallback(hdma);
\r
1223 /* Current memory buffer used is Memory 1 */
\r
1226 if(hdma->XferM1HalfCpltCallback != NULL)
\r
1228 /* Half transfer callback */
\r
1229 hdma->XferM1HalfCpltCallback(hdma);
\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
1238 /* Disable the half transfer interrupt */
\r
1239 ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_HT);
\r
1242 if(hdma->XferHalfCpltCallback != NULL)
\r
1244 /* Half transfer callback */
\r
1245 hdma->XferHalfCpltCallback(hdma);
\r
1250 /* Transfer Complete Interrupt management ***********************************/
\r
1251 if ((tmpisr_dma & (DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
\r
1253 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
\r
1255 /* Clear the transfer complete flag */
\r
1256 regs_dma->IFCR = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
\r
1258 if(HAL_DMA_STATE_ABORT == hdma->State)
\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
1264 if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
\r
1266 ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_HT);
\r
1269 /* Clear all interrupt flags at correct offset within the register */
\r
1270 regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
\r
1272 /* Process Unlocked */
\r
1273 __HAL_UNLOCK(hdma);
\r
1275 /* Change the DMA state */
\r
1276 hdma->State = HAL_DMA_STATE_READY;
\r
1278 if(hdma->XferAbortCallback != NULL)
\r
1280 hdma->XferAbortCallback(hdma);
\r
1285 if(((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
\r
1287 /* Current memory buffer used is Memory 0 */
\r
1288 if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
\r
1290 if(hdma->XferM1CpltCallback != NULL)
\r
1292 /* Transfer complete Callback for memory1 */
\r
1293 hdma->XferM1CpltCallback(hdma);
\r
1296 /* Current memory buffer used is Memory 1 */
\r
1299 if(hdma->XferCpltCallback != NULL)
\r
1301 /* Transfer complete Callback for memory0 */
\r
1302 hdma->XferCpltCallback(hdma);
\r
1306 /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
\r
1309 if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
\r
1311 /* Disable the transfer complete interrupt */
\r
1312 ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_TC);
\r
1314 /* Process Unlocked */
\r
1315 __HAL_UNLOCK(hdma);
\r
1317 /* Change the DMA state */
\r
1318 hdma->State = HAL_DMA_STATE_READY;
\r
1321 if(hdma->XferCpltCallback != NULL)
\r
1323 /* Transfer complete callback */
\r
1324 hdma->XferCpltCallback(hdma);
\r
1330 /* manage error case */
\r
1331 if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
\r
1333 if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != 0U)
\r
1335 hdma->State = HAL_DMA_STATE_ABORT;
\r
1337 /* Disable the stream */
\r
1338 __HAL_DMA_DISABLE(hdma);
\r
1342 if (++count > timeout)
\r
1347 while((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U);
\r
1349 /* Process Unlocked */
\r
1350 __HAL_UNLOCK(hdma);
\r
1352 if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
\r
1354 /* Change the DMA state to error if DMA disable fails */
\r
1355 hdma->State = HAL_DMA_STATE_ERROR;
\r
1359 /* Change the DMA state to Ready if DMA disable success */
\r
1360 hdma->State = HAL_DMA_STATE_READY;
\r
1364 if(hdma->XferErrorCallback != NULL)
\r
1366 /* Transfer error callback */
\r
1367 hdma->XferErrorCallback(hdma);
\r
1371 else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
\r
1373 ccr_reg = (((BDMA_Channel_TypeDef *)hdma->Instance)->CCR);
\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
1378 /* Clear the half transfer complete flag */
\r
1379 regs_bdma->IFCR = (BDMA_ISR_HTIF0 << (hdma->StreamIndex & 0x1FU));
\r
1381 /* Disable the transfer complete interrupt if the DMA mode is Double Buffering */
\r
1382 if((ccr_reg & BDMA_CCR_DBM) != 0U)
\r
1384 /* Current memory buffer used is Memory 0 */
\r
1385 if((ccr_reg & BDMA_CCR_CT) == 0U)
\r
1387 if(hdma->XferM1HalfCpltCallback != NULL)
\r
1389 /* Half transfer Callback for Memory 1 */
\r
1390 hdma->XferM1HalfCpltCallback(hdma);
\r
1393 /* Current memory buffer used is Memory 1 */
\r
1396 if(hdma->XferHalfCpltCallback != NULL)
\r
1398 /* Half transfer Callback for Memory 0 */
\r
1399 hdma->XferHalfCpltCallback(hdma);
\r
1405 if((ccr_reg & BDMA_CCR_CIRC) == 0U)
\r
1407 /* Disable the half transfer interrupt */
\r
1408 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
\r
1411 /* DMA peripheral state is not updated in Half Transfer */
\r
1412 /* but in Transfer Complete case */
\r
1414 if(hdma->XferHalfCpltCallback != NULL)
\r
1416 /* Half transfer callback */
\r
1417 hdma->XferHalfCpltCallback(hdma);
\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
1425 /* Clear the transfer complete flag */
\r
1426 regs_bdma->IFCR = (BDMA_ISR_TCIF0) << (hdma->StreamIndex & 0x1FU);
\r
1428 /* Disable the transfer complete interrupt if the DMA mode is Double Buffering */
\r
1429 if((ccr_reg & BDMA_CCR_DBM) != 0U)
\r
1431 /* Current memory buffer used is Memory 0 */
\r
1432 if((ccr_reg & BDMA_CCR_CT) == 0U)
\r
1434 if(hdma->XferM1CpltCallback != NULL)
\r
1436 /* Transfer complete Callback for Memory 1 */
\r
1437 hdma->XferM1CpltCallback(hdma);
\r
1440 /* Current memory buffer used is Memory 1 */
\r
1443 if(hdma->XferCpltCallback != NULL)
\r
1445 /* Transfer complete Callback for Memory 0 */
\r
1446 hdma->XferCpltCallback(hdma);
\r
1452 if((ccr_reg & BDMA_CCR_CIRC) == 0U)
\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
1457 /* Process Unlocked */
\r
1458 __HAL_UNLOCK(hdma);
\r
1460 /* Change the DMA state */
\r
1461 hdma->State = HAL_DMA_STATE_READY;
\r
1464 if(hdma->XferCpltCallback != NULL)
\r
1466 /* Transfer complete callback */
\r
1467 hdma->XferCpltCallback(hdma);
\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
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
1479 /* Clear all flags */
\r
1480 regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
\r
1482 /* Update error code */
\r
1483 hdma->ErrorCode = HAL_DMA_ERROR_TE;
\r
1485 /* Process Unlocked */
\r
1486 __HAL_UNLOCK(hdma);
\r
1488 /* Change the DMA state */
\r
1489 hdma->State = HAL_DMA_STATE_READY;
\r
1491 if (hdma->XferErrorCallback != NULL)
\r
1493 /* Transfer error callback */
\r
1494 hdma->XferErrorCallback(hdma);
\r
1499 /* Nothing To Do */
\r
1504 /* Nothing To Do */
\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
1518 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
\r
1521 HAL_StatusTypeDef status = HAL_OK;
\r
1523 /* Check the DMA peripheral handle */
\r
1529 /* Process locked */
\r
1532 if(HAL_DMA_STATE_READY == hdma->State)
\r
1534 switch (CallbackID)
\r
1536 case HAL_DMA_XFER_CPLT_CB_ID:
\r
1537 hdma->XferCpltCallback = pCallback;
\r
1540 case HAL_DMA_XFER_HALFCPLT_CB_ID:
\r
1541 hdma->XferHalfCpltCallback = pCallback;
\r
1544 case HAL_DMA_XFER_M1CPLT_CB_ID:
\r
1545 hdma->XferM1CpltCallback = pCallback;
\r
1548 case HAL_DMA_XFER_M1HALFCPLT_CB_ID:
\r
1549 hdma->XferM1HalfCpltCallback = pCallback;
\r
1552 case HAL_DMA_XFER_ERROR_CB_ID:
\r
1553 hdma->XferErrorCallback = pCallback;
\r
1556 case HAL_DMA_XFER_ABORT_CB_ID:
\r
1557 hdma->XferAbortCallback = pCallback;
\r
1566 /* Return error status */
\r
1567 status = HAL_ERROR;
\r
1570 /* Release Lock */
\r
1571 __HAL_UNLOCK(hdma);
\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
1584 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
\r
1586 HAL_StatusTypeDef status = HAL_OK;
\r
1588 /* Check the DMA peripheral handle */
\r
1594 /* Process locked */
\r
1597 if(HAL_DMA_STATE_READY == hdma->State)
\r
1599 switch (CallbackID)
\r
1601 case HAL_DMA_XFER_CPLT_CB_ID:
\r
1602 hdma->XferCpltCallback = NULL;
\r
1605 case HAL_DMA_XFER_HALFCPLT_CB_ID:
\r
1606 hdma->XferHalfCpltCallback = NULL;
\r
1609 case HAL_DMA_XFER_M1CPLT_CB_ID:
\r
1610 hdma->XferM1CpltCallback = NULL;
\r
1613 case HAL_DMA_XFER_M1HALFCPLT_CB_ID:
\r
1614 hdma->XferM1HalfCpltCallback = NULL;
\r
1617 case HAL_DMA_XFER_ERROR_CB_ID:
\r
1618 hdma->XferErrorCallback = NULL;
\r
1621 case HAL_DMA_XFER_ABORT_CB_ID:
\r
1622 hdma->XferAbortCallback = NULL;
\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
1635 status = HAL_ERROR;
\r
1641 status = HAL_ERROR;
\r
1644 /* Release Lock */
\r
1645 __HAL_UNLOCK(hdma);
\r
1654 /** @addtogroup DMA_Exported_Functions_Group3
\r
1657 ===============================================================================
\r
1658 ##### State and Errors functions #####
\r
1659 ===============================================================================
\r
1661 This subsection provides functions allowing to
\r
1662 (+) Check the DMA state
\r
1663 (+) Get error code
\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
1675 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
\r
1677 return hdma->State;
\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
1686 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
\r
1688 return hdma->ErrorCode;
\r
1699 /** @addtogroup DMA_Private_Functions
\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
1712 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
\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
1718 /* Clear the DMAMUX synchro overrun flag */
\r
1719 hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
\r
1721 if(hdma->DMAmuxRequestGen != 0U)
\r
1723 /* Clear the DMAMUX request generator overrun flag */
\r
1724 hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
\r
1727 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\r
1729 /* Clear all interrupt flags at correct offset within the register */
\r
1730 regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
\r
1732 /* Clear DBM bit */
\r
1733 ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= (uint32_t)(~DMA_SxCR_DBM);
\r
1735 /* Configure DMA Stream data length */
\r
1736 ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
\r
1738 /* Peripheral to Memory */
\r
1739 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
\r
1741 /* Configure DMA Stream destination address */
\r
1742 ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress;
\r
1744 /* Configure DMA Stream source address */
\r
1745 ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress;
\r
1747 /* Memory to Peripheral */
\r
1750 /* Configure DMA Stream source address */
\r
1751 ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress;
\r
1753 /* Configure DMA Stream destination address */
\r
1754 ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress;
\r
1757 else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
\r
1759 /* Clear all flags */
\r
1760 regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
\r
1762 /* Configure DMA Channel data length */
\r
1763 ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = DataLength;
\r
1765 /* Peripheral to Memory */
\r
1766 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
\r
1768 /* Configure DMA Channel destination address */
\r
1769 ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = DstAddress;
\r
1771 /* Configure DMA Channel source address */
\r
1772 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = SrcAddress;
\r
1774 /* Memory to Peripheral */
\r
1777 /* Configure DMA Channel source address */
\r
1778 ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = SrcAddress;
\r
1780 /* Configure DMA Channel destination address */
\r
1781 ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = DstAddress;
\r
1786 /* Nothing To Do */
\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
1796 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
\r
1798 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
\r
1800 uint32_t stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
\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
1806 if (stream_number > 3U)
\r
1808 /* return pointer to HISR and HIFCR */
\r
1809 hdma->StreamBaseAddress = (((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU)) + 4U);
\r
1813 /* return pointer to LISR and LIFCR */
\r
1814 hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU));
\r
1817 else /* BDMA instance(s) */
\r
1819 /* return pointer to ISR and IFCR */
\r
1820 hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0xFFU));
\r
1823 return hdma->StreamBaseAddress;
\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
1832 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma)
\r
1834 HAL_StatusTypeDef status = HAL_OK;
\r
1836 /* Memory Data size equal to Byte */
\r
1837 if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_BYTE)
\r
1839 switch (hdma->Init.FIFOThreshold)
\r
1841 case DMA_FIFO_THRESHOLD_1QUARTERFULL:
\r
1842 case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
\r
1844 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
\r
1846 status = HAL_ERROR;
\r
1850 case DMA_FIFO_THRESHOLD_HALFFULL:
\r
1851 if (hdma->Init.MemBurst == DMA_MBURST_INC16)
\r
1853 status = HAL_ERROR;
\r
1857 case DMA_FIFO_THRESHOLD_FULL:
\r
1865 /* Memory Data size equal to Half-Word */
\r
1866 else if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
\r
1868 switch (hdma->Init.FIFOThreshold)
\r
1870 case DMA_FIFO_THRESHOLD_1QUARTERFULL:
\r
1871 case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
\r
1872 status = HAL_ERROR;
\r
1875 case DMA_FIFO_THRESHOLD_HALFFULL:
\r
1876 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
\r
1878 status = HAL_ERROR;
\r
1882 case DMA_FIFO_THRESHOLD_FULL:
\r
1883 if (hdma->Init.MemBurst == DMA_MBURST_INC16)
\r
1885 status = HAL_ERROR;
\r
1894 /* Memory Data size equal to Word */
\r
1897 switch (hdma->Init.FIFOThreshold)
\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
1905 case DMA_FIFO_THRESHOLD_FULL:
\r
1906 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
\r
1908 status = HAL_ERROR;
\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
1926 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
\r
1928 uint32_t stream_number;
\r
1929 uint32_t stream_baseaddress = (uint32_t)((uint32_t*)hdma->Instance);
\r
1931 if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
\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
1941 /* DMA1/DMA2 Streams are connected to DMAMUX1 channels */
\r
1942 stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
\r
1944 if((stream_baseaddress <= ((uint32_t)DMA2_Stream7) ) && \
\r
1945 (stream_baseaddress >= ((uint32_t)DMA2_Stream0)))
\r
1947 stream_number += 8U;
\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
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
1961 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
\r
1963 uint32_t request = hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
\r
1965 if((request >= DMA_REQUEST_GENERATOR0) && (request <= DMA_REQUEST_GENERATOR7))
\r
1967 if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
\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
1972 hdma->DMAmuxRequestGenStatus = DMAMUX2_RequestGenStatus;
\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
1979 hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
\r
1982 hdma->DMAmuxRequestGenStatusMask = 1UL << (request - 1U);
\r
1990 #endif /* HAL_DMA_MODULE_ENABLED */
\r
1999 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r