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