1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_dma.c
4 * @author MCD Application Team
5 * @brief DMA HAL module driver.
6 *
7 * This file provides firmware functions to manage the following
8 * functionalities of the Direct Memory Access (DMA) peripheral:
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral State and errors functions
12 @verbatim
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
16 [..]
17 (#) Enable and configure the peripheral to be connected to the DMA Stream
18 (except for internal SRAM/FLASH memories: no initialization is
19 necessary) please refer to Reference manual for connection between peripherals
20 and DMA requests.
21
22 (#) For a given Stream, program the required configuration through the following parameters:
23 Transfer Direction, Source and Destination data formats,
24 Circular, Normal or peripheral flow control mode, Stream Priority level,
25 Source and Destination Increment mode, FIFO mode and its Threshold (if needed),
26 Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.
27
28 -@- Prior to HAL_DMA_Init() the clock must be enabled for DMA through the following macros:
29 __HAL_RCC_DMA1_CLK_ENABLE() or __HAL_RCC_DMA2_CLK_ENABLE().
30
31 *** Polling mode IO operation ***
32 =================================
33 [..]
34 (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
35 address and destination address and the Length of data to be transferred.
36 (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
37 case a fixed Timeout can be configured by User depending from his application.
38 (+) Use HAL_DMA_Abort() function to abort the current transfer.
39
40 *** Interrupt mode IO operation ***
41 ===================================
42 [..]
43 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
44 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
45 (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
46 Source address and destination address and the Length of data to be transferred. In this
47 case the DMA interrupt is configured
48 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
49 (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
50 add his own function by customization of function pointer XferCpltCallback and
51 XferErrorCallback (i.e a member of DMA handle structure).
52 [..]
53 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
54 detection.
55
56 (#) Use HAL_DMA_Abort_IT() function to abort the current transfer
57
58 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
59
60 -@- The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
61 possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
62 Half-Word data size for the peripheral to access its data register and set Word data size
63 for the Memory to gain in access time. Each two half words will be packed and written in
64 a single access to a Word in the Memory).
65
66 -@- When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
67 and Destination. In this case the Peripheral Data Size will be applied to both Source
68 and Destination.
69
70 *** DMA HAL driver macros list ***
71 =============================================
72 [..]
73 Below the list of most used macros in DMA HAL driver.
74
75 (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.
76 (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.
77 (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not.
78
79 [..]
80 (@) You can refer to the DMA HAL driver header file for more useful macros
81
82 @endverbatim
83 ******************************************************************************
84 * @attention
85 *
86 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
87 * All rights reserved.</center></h2>
88 *
89 * This software component is licensed by ST under BSD 3-Clause license,
90 * the "License"; You may not use this file except in compliance with the
91 * License. You may obtain a copy of the License at:
92 * opensource.org/licenses/BSD-3-Clause
93 *
94 ******************************************************************************
95 */
96
97 /* Includes ------------------------------------------------------------------*/
98 #include "stm32f4xx_hal.h"
99
100 /** @addtogroup STM32F4xx_HAL_Driver
101 * @{
102 */
103
104 /** @defgroup DMA DMA
105 * @brief DMA HAL module driver
106 * @{
107 */
108
109 #ifdef HAL_DMA_MODULE_ENABLED
110
111 /* Private types -------------------------------------------------------------*/
112 typedef struct
113 {
114 __IO uint32_t ISR; /*!< DMA interrupt status register */
115 __IO uint32_t Reserved0;
116 __IO uint32_t IFCR; /*!< DMA interrupt flag clear register */
117 } DMA_Base_Registers;
118
119 /* Private variables ---------------------------------------------------------*/
120 /* Private constants ---------------------------------------------------------*/
121 /** @addtogroup DMA_Private_Constants
122 * @{
123 */
124 #define HAL_TIMEOUT_DMA_ABORT 5U /* 5 ms */
125 /**
126 * @}
127 */
128 /* Private macros ------------------------------------------------------------*/
129 /* Private functions ---------------------------------------------------------*/
130 /** @addtogroup DMA_Private_Functions
131 * @{
132 */
133 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
134 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
135 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma);
136
137 /**
138 * @}
139 */
140
141 /* Exported functions ---------------------------------------------------------*/
142 /** @addtogroup DMA_Exported_Functions
143 * @{
144 */
145
146 /** @addtogroup DMA_Exported_Functions_Group1
147 *
148 @verbatim
149 ===============================================================================
150 ##### Initialization and de-initialization functions #####
151 ===============================================================================
152 [..]
153 This section provides functions allowing to initialize the DMA Stream source
154 and destination addresses, incrementation and data sizes, transfer direction,
155 circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
156 [..]
157 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
158 reference manual.
159
160 @endverbatim
161 * @{
162 */
163
164 /**
165 * @brief Initialize the DMA according to the specified
166 * parameters in the DMA_InitTypeDef and create the associated handle.
167 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
168 * the configuration information for the specified DMA Stream.
169 * @retval HAL status
170 */
HAL_DMA_Init(DMA_HandleTypeDef * hdma)171 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
172 {
173 uint32_t tmp = 0U;
174 uint32_t tickstart = HAL_GetTick();
175 DMA_Base_Registers *regs;
176
177 /* Check the DMA peripheral state */
178 if(hdma == NULL)
179 {
180 return HAL_ERROR;
181 }
182
183 /* Check the parameters */
184 assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
185 assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));
186 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
187 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
188 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
189 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
190 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
191 assert_param(IS_DMA_MODE(hdma->Init.Mode));
192 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
193 assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
194 /* Check the memory burst, peripheral burst and FIFO threshold parameters only
195 when FIFO mode is enabled */
196 if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
197 {
198 assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
199 assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
200 assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
201 }
202
203 /* Allocate lock resource */
204 __HAL_UNLOCK(hdma);
205
206 /* Change DMA peripheral state */
207 hdma->State = HAL_DMA_STATE_BUSY;
208
209 /* Disable the peripheral */
210 __HAL_DMA_DISABLE(hdma);
211
212 /* Check if the DMA Stream is effectively disabled */
213 while((hdma->Instance->CR & DMA_SxCR_EN) != RESET)
214 {
215 /* Check for the Timeout */
216 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
217 {
218 /* Update error code */
219 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
220
221 /* Change the DMA state */
222 hdma->State = HAL_DMA_STATE_TIMEOUT;
223
224 return HAL_TIMEOUT;
225 }
226 }
227
228 /* Get the CR register value */
229 tmp = hdma->Instance->CR;
230
231 /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
232 tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
233 DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \
234 DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \
235 DMA_SxCR_DIR | DMA_SxCR_CT | DMA_SxCR_DBM));
236
237 /* Prepare the DMA Stream configuration */
238 tmp |= hdma->Init.Channel | hdma->Init.Direction |
239 hdma->Init.PeriphInc | hdma->Init.MemInc |
240 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
241 hdma->Init.Mode | hdma->Init.Priority;
242
243 /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
244 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
245 {
246 /* Get memory burst and peripheral burst */
247 tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;
248 }
249
250 /* Write to DMA Stream CR register */
251 hdma->Instance->CR = tmp;
252
253 /* Get the FCR register value */
254 tmp = hdma->Instance->FCR;
255
256 /* Clear Direct mode and FIFO threshold bits */
257 tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
258
259 /* Prepare the DMA Stream FIFO configuration */
260 tmp |= hdma->Init.FIFOMode;
261
262 /* The FIFO threshold is not used when the FIFO mode is disabled */
263 if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
264 {
265 /* Get the FIFO threshold */
266 tmp |= hdma->Init.FIFOThreshold;
267
268 /* Check compatibility between FIFO threshold level and size of the memory burst */
269 /* for INCR4, INCR8, INCR16 bursts */
270 if (hdma->Init.MemBurst != DMA_MBURST_SINGLE)
271 {
272 if (DMA_CheckFifoParam(hdma) != HAL_OK)
273 {
274 /* Update error code */
275 hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
276
277 /* Change the DMA state */
278 hdma->State = HAL_DMA_STATE_READY;
279
280 return HAL_ERROR;
281 }
282 }
283 }
284
285 /* Write to DMA Stream FCR */
286 hdma->Instance->FCR = tmp;
287
288 /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
289 DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
290 regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
291
292 /* Clear all interrupt flags */
293 regs->IFCR = 0x3FU << hdma->StreamIndex;
294
295 /* Initialize the error code */
296 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
297
298 /* Initialize the DMA state */
299 hdma->State = HAL_DMA_STATE_READY;
300
301 return HAL_OK;
302 }
303
304 /**
305 * @brief DeInitializes the DMA peripheral
306 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
307 * the configuration information for the specified DMA Stream.
308 * @retval HAL status
309 */
HAL_DMA_DeInit(DMA_HandleTypeDef * hdma)310 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
311 {
312 DMA_Base_Registers *regs;
313
314 /* Check the DMA peripheral state */
315 if(hdma == NULL)
316 {
317 return HAL_ERROR;
318 }
319
320 /* Check the DMA peripheral state */
321 if(hdma->State == HAL_DMA_STATE_BUSY)
322 {
323 /* Return error status */
324 return HAL_BUSY;
325 }
326
327 /* Check the parameters */
328 assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
329
330 /* Disable the selected DMA Streamx */
331 __HAL_DMA_DISABLE(hdma);
332
333 /* Reset DMA Streamx control register */
334 hdma->Instance->CR = 0U;
335
336 /* Reset DMA Streamx number of data to transfer register */
337 hdma->Instance->NDTR = 0U;
338
339 /* Reset DMA Streamx peripheral address register */
340 hdma->Instance->PAR = 0U;
341
342 /* Reset DMA Streamx memory 0 address register */
343 hdma->Instance->M0AR = 0U;
344
345 /* Reset DMA Streamx memory 1 address register */
346 hdma->Instance->M1AR = 0U;
347
348 /* Reset DMA Streamx FIFO control register */
349 hdma->Instance->FCR = 0x00000021U;
350
351 /* Get DMA steam Base Address */
352 regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
353
354 /* Clean all callbacks */
355 hdma->XferCpltCallback = NULL;
356 hdma->XferHalfCpltCallback = NULL;
357 hdma->XferM1CpltCallback = NULL;
358 hdma->XferM1HalfCpltCallback = NULL;
359 hdma->XferErrorCallback = NULL;
360 hdma->XferAbortCallback = NULL;
361
362 /* Clear all interrupt flags at correct offset within the register */
363 regs->IFCR = 0x3FU << hdma->StreamIndex;
364
365 /* Reset the error code */
366 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
367
368 /* Reset the DMA state */
369 hdma->State = HAL_DMA_STATE_RESET;
370
371 /* Release Lock */
372 __HAL_UNLOCK(hdma);
373
374 return HAL_OK;
375 }
376
377 /**
378 * @}
379 */
380
381 /** @addtogroup DMA_Exported_Functions_Group2
382 *
383 @verbatim
384 ===============================================================================
385 ##### IO operation functions #####
386 ===============================================================================
387 [..] This section provides functions allowing to:
388 (+) Configure the source, destination address and data length and Start DMA transfer
389 (+) Configure the source, destination address and data length and
390 Start DMA transfer with interrupt
391 (+) Abort DMA transfer
392 (+) Poll for transfer complete
393 (+) Handle DMA interrupt request
394
395 @endverbatim
396 * @{
397 */
398
399 /**
400 * @brief Starts the DMA Transfer.
401 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
402 * the configuration information for the specified DMA Stream.
403 * @param SrcAddress The source memory Buffer address
404 * @param DstAddress The destination memory Buffer address
405 * @param DataLength The length of data to be transferred from source to destination
406 * @retval HAL status
407 */
HAL_DMA_Start(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)408 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
409 {
410 HAL_StatusTypeDef status = HAL_OK;
411
412 /* Check the parameters */
413 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
414
415 /* Process locked */
416 __HAL_LOCK(hdma);
417
418 if(HAL_DMA_STATE_READY == hdma->State)
419 {
420 /* Change DMA peripheral state */
421 hdma->State = HAL_DMA_STATE_BUSY;
422
423 /* Initialize the error code */
424 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
425
426 /* Configure the source, destination address and the data length */
427 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
428
429 /* Enable the Peripheral */
430 __HAL_DMA_ENABLE(hdma);
431 }
432 else
433 {
434 /* Process unlocked */
435 __HAL_UNLOCK(hdma);
436
437 /* Return error status */
438 status = HAL_BUSY;
439 }
440 return status;
441 }
442
443 /**
444 * @brief Start the DMA Transfer with interrupt enabled.
445 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
446 * the configuration information for the specified DMA Stream.
447 * @param SrcAddress The source memory Buffer address
448 * @param DstAddress The destination memory Buffer address
449 * @param DataLength The length of data to be transferred from source to destination
450 * @retval HAL status
451 */
HAL_DMA_Start_IT(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)452 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
453 {
454 HAL_StatusTypeDef status = HAL_OK;
455
456 /* calculate DMA base and stream number */
457 DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
458
459 /* Check the parameters */
460 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
461
462 /* Process locked */
463 __HAL_LOCK(hdma);
464
465 if(HAL_DMA_STATE_READY == hdma->State)
466 {
467 /* Change DMA peripheral state */
468 hdma->State = HAL_DMA_STATE_BUSY;
469
470 /* Initialize the error code */
471 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
472
473 /* Configure the source, destination address and the data length */
474 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
475
476 /* Clear all interrupt flags at correct offset within the register */
477 regs->IFCR = 0x3FU << hdma->StreamIndex;
478
479 /* Enable Common interrupts*/
480 hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
481 hdma->Instance->FCR |= DMA_IT_FE;
482
483 if(hdma->XferHalfCpltCallback != NULL)
484 {
485 hdma->Instance->CR |= DMA_IT_HT;
486 }
487
488 /* Enable the Peripheral */
489 __HAL_DMA_ENABLE(hdma);
490 }
491 else
492 {
493 /* Process unlocked */
494 __HAL_UNLOCK(hdma);
495
496 /* Return error status */
497 status = HAL_BUSY;
498 }
499
500 return status;
501 }
502
503 /**
504 * @brief Aborts the DMA Transfer.
505 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
506 * the configuration information for the specified DMA Stream.
507 *
508 * @note After disabling a DMA Stream, a check for wait until the DMA Stream is
509 * effectively disabled is added. If a Stream is disabled
510 * while a data transfer is ongoing, the current data will be transferred
511 * and the Stream will be effectively disabled only after the transfer of
512 * this single data is finished.
513 * @retval HAL status
514 */
HAL_DMA_Abort(DMA_HandleTypeDef * hdma)515 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
516 {
517 /* calculate DMA base and stream number */
518 DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
519
520 uint32_t tickstart = HAL_GetTick();
521
522 if(hdma->State != HAL_DMA_STATE_BUSY)
523 {
524 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
525
526 /* Process Unlocked */
527 __HAL_UNLOCK(hdma);
528
529 return HAL_ERROR;
530 }
531 else
532 {
533 /* Disable all the transfer interrupts */
534 hdma->Instance->CR &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
535 hdma->Instance->FCR &= ~(DMA_IT_FE);
536
537 if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
538 {
539 hdma->Instance->CR &= ~(DMA_IT_HT);
540 }
541
542 /* Disable the stream */
543 __HAL_DMA_DISABLE(hdma);
544
545 /* Check if the DMA Stream is effectively disabled */
546 while((hdma->Instance->CR & DMA_SxCR_EN) != RESET)
547 {
548 /* Check for the Timeout */
549 if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
550 {
551 /* Update error code */
552 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
553
554 /* Process Unlocked */
555 __HAL_UNLOCK(hdma);
556
557 /* Change the DMA state */
558 hdma->State = HAL_DMA_STATE_TIMEOUT;
559
560 return HAL_TIMEOUT;
561 }
562 }
563
564 /* Clear all interrupt flags at correct offset within the register */
565 regs->IFCR = 0x3FU << hdma->StreamIndex;
566
567 /* Process Unlocked */
568 __HAL_UNLOCK(hdma);
569
570 /* Change the DMA state*/
571 hdma->State = HAL_DMA_STATE_READY;
572 }
573 return HAL_OK;
574 }
575
576 /**
577 * @brief Aborts the DMA Transfer in Interrupt mode.
578 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
579 * the configuration information for the specified DMA Stream.
580 * @retval HAL status
581 */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * hdma)582 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
583 {
584 if(hdma->State != HAL_DMA_STATE_BUSY)
585 {
586 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
587 return HAL_ERROR;
588 }
589 else
590 {
591 /* Set Abort State */
592 hdma->State = HAL_DMA_STATE_ABORT;
593
594 /* Disable the stream */
595 __HAL_DMA_DISABLE(hdma);
596 }
597
598 return HAL_OK;
599 }
600
601 /**
602 * @brief Polling for transfer complete.
603 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
604 * the configuration information for the specified DMA Stream.
605 * @param CompleteLevel Specifies the DMA level complete.
606 * @note The polling mode is kept in this version for legacy. it is recommanded to use the IT model instead.
607 * This model could be used for debug purpose.
608 * @note The HAL_DMA_PollForTransfer API cannot be used in circular and double buffering mode (automatic circular mode).
609 * @param Timeout Timeout duration.
610 * @retval HAL status
611 */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * hdma,HAL_DMA_LevelCompleteTypeDef CompleteLevel,uint32_t Timeout)612 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
613 {
614 HAL_StatusTypeDef status = HAL_OK;
615 uint32_t mask_cpltlevel;
616 uint32_t tickstart = HAL_GetTick();
617 uint32_t tmpisr;
618
619 /* calculate DMA base and stream number */
620 DMA_Base_Registers *regs;
621
622 if(HAL_DMA_STATE_BUSY != hdma->State)
623 {
624 /* No transfer ongoing */
625 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
626 __HAL_UNLOCK(hdma);
627 return HAL_ERROR;
628 }
629
630 /* Polling mode not supported in circular mode and double buffering mode */
631 if ((hdma->Instance->CR & DMA_SxCR_CIRC) != RESET)
632 {
633 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
634 return HAL_ERROR;
635 }
636
637 /* Get the level transfer complete flag */
638 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
639 {
640 /* Transfer Complete flag */
641 mask_cpltlevel = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
642 }
643 else
644 {
645 /* Half Transfer Complete flag */
646 mask_cpltlevel = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
647 }
648
649 regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
650 tmpisr = regs->ISR;
651
652 while(((tmpisr & mask_cpltlevel) == RESET) && ((hdma->ErrorCode & HAL_DMA_ERROR_TE) == RESET))
653 {
654 /* Check for the Timeout (Not applicable in circular mode)*/
655 if(Timeout != HAL_MAX_DELAY)
656 {
657 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
658 {
659 /* Update error code */
660 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
661
662 /* Process Unlocked */
663 __HAL_UNLOCK(hdma);
664
665 /* Change the DMA state */
666 hdma->State = HAL_DMA_STATE_READY;
667
668 return HAL_TIMEOUT;
669 }
670 }
671
672 /* Get the ISR register value */
673 tmpisr = regs->ISR;
674
675 if((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
676 {
677 /* Update error code */
678 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
679
680 /* Clear the transfer error flag */
681 regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
682 }
683
684 if((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
685 {
686 /* Update error code */
687 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
688
689 /* Clear the FIFO error flag */
690 regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
691 }
692
693 if((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
694 {
695 /* Update error code */
696 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
697
698 /* Clear the Direct Mode error flag */
699 regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
700 }
701 }
702
703 if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
704 {
705 if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
706 {
707 HAL_DMA_Abort(hdma);
708
709 /* Clear the half transfer and transfer complete flags */
710 regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
711
712 /* Process Unlocked */
713 __HAL_UNLOCK(hdma);
714
715 /* Change the DMA state */
716 hdma->State= HAL_DMA_STATE_READY;
717
718 return HAL_ERROR;
719 }
720 }
721
722 /* Get the level transfer complete flag */
723 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
724 {
725 /* Clear the half transfer and transfer complete flags */
726 regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
727
728 /* Process Unlocked */
729 __HAL_UNLOCK(hdma);
730
731 hdma->State = HAL_DMA_STATE_READY;
732 }
733 else
734 {
735 /* Clear the half transfer and transfer complete flags */
736 regs->IFCR = (DMA_FLAG_HTIF0_4) << hdma->StreamIndex;
737 }
738
739 return status;
740 }
741
742 /**
743 * @brief Handles DMA interrupt request.
744 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
745 * the configuration information for the specified DMA Stream.
746 * @retval None
747 */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * hdma)748 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
749 {
750 uint32_t tmpisr;
751 __IO uint32_t count = 0U;
752 uint32_t timeout = SystemCoreClock / 9600U;
753
754 /* calculate DMA base and stream number */
755 DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
756
757 tmpisr = regs->ISR;
758
759 /* Transfer Error Interrupt management ***************************************/
760 if ((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
761 {
762 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
763 {
764 /* Disable the transfer error interrupt */
765 hdma->Instance->CR &= ~(DMA_IT_TE);
766
767 /* Clear the transfer error flag */
768 regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
769
770 /* Update error code */
771 hdma->ErrorCode |= HAL_DMA_ERROR_TE;
772 }
773 }
774 /* FIFO Error Interrupt management ******************************************/
775 if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
776 {
777 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
778 {
779 /* Clear the FIFO error flag */
780 regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
781
782 /* Update error code */
783 hdma->ErrorCode |= HAL_DMA_ERROR_FE;
784 }
785 }
786 /* Direct Mode Error Interrupt management ***********************************/
787 if ((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
788 {
789 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
790 {
791 /* Clear the direct mode error flag */
792 regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
793
794 /* Update error code */
795 hdma->ErrorCode |= HAL_DMA_ERROR_DME;
796 }
797 }
798 /* Half Transfer Complete Interrupt management ******************************/
799 if ((tmpisr & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET)
800 {
801 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
802 {
803 /* Clear the half transfer complete flag */
804 regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
805
806 /* Multi_Buffering mode enabled */
807 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
808 {
809 /* Current memory buffer used is Memory 0 */
810 if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
811 {
812 if(hdma->XferHalfCpltCallback != NULL)
813 {
814 /* Half transfer callback */
815 hdma->XferHalfCpltCallback(hdma);
816 }
817 }
818 /* Current memory buffer used is Memory 1 */
819 else
820 {
821 if(hdma->XferM1HalfCpltCallback != NULL)
822 {
823 /* Half transfer callback */
824 hdma->XferM1HalfCpltCallback(hdma);
825 }
826 }
827 }
828 else
829 {
830 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
831 if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
832 {
833 /* Disable the half transfer interrupt */
834 hdma->Instance->CR &= ~(DMA_IT_HT);
835 }
836
837 if(hdma->XferHalfCpltCallback != NULL)
838 {
839 /* Half transfer callback */
840 hdma->XferHalfCpltCallback(hdma);
841 }
842 }
843 }
844 }
845 /* Transfer Complete Interrupt management ***********************************/
846 if ((tmpisr & (DMA_FLAG_TCIF0_4 << hdma->StreamIndex)) != RESET)
847 {
848 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
849 {
850 /* Clear the transfer complete flag */
851 regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
852
853 if(HAL_DMA_STATE_ABORT == hdma->State)
854 {
855 /* Disable all the transfer interrupts */
856 hdma->Instance->CR &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
857 hdma->Instance->FCR &= ~(DMA_IT_FE);
858
859 if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
860 {
861 hdma->Instance->CR &= ~(DMA_IT_HT);
862 }
863
864 /* Clear all interrupt flags at correct offset within the register */
865 regs->IFCR = 0x3FU << hdma->StreamIndex;
866
867 /* Process Unlocked */
868 __HAL_UNLOCK(hdma);
869
870 /* Change the DMA state */
871 hdma->State = HAL_DMA_STATE_READY;
872
873 if(hdma->XferAbortCallback != NULL)
874 {
875 hdma->XferAbortCallback(hdma);
876 }
877 return;
878 }
879
880 if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
881 {
882 /* Current memory buffer used is Memory 0 */
883 if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
884 {
885 if(hdma->XferM1CpltCallback != NULL)
886 {
887 /* Transfer complete Callback for memory1 */
888 hdma->XferM1CpltCallback(hdma);
889 }
890 }
891 /* Current memory buffer used is Memory 1 */
892 else
893 {
894 if(hdma->XferCpltCallback != NULL)
895 {
896 /* Transfer complete Callback for memory0 */
897 hdma->XferCpltCallback(hdma);
898 }
899 }
900 }
901 /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
902 else
903 {
904 if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
905 {
906 /* Disable the transfer complete interrupt */
907 hdma->Instance->CR &= ~(DMA_IT_TC);
908
909 /* Process Unlocked */
910 __HAL_UNLOCK(hdma);
911
912 /* Change the DMA state */
913 hdma->State = HAL_DMA_STATE_READY;
914 }
915
916 if(hdma->XferCpltCallback != NULL)
917 {
918 /* Transfer complete callback */
919 hdma->XferCpltCallback(hdma);
920 }
921 }
922 }
923 }
924
925 /* manage error case */
926 if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
927 {
928 if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
929 {
930 hdma->State = HAL_DMA_STATE_ABORT;
931
932 /* Disable the stream */
933 __HAL_DMA_DISABLE(hdma);
934
935 do
936 {
937 if (++count > timeout)
938 {
939 break;
940 }
941 }
942 while((hdma->Instance->CR & DMA_SxCR_EN) != RESET);
943
944 /* Process Unlocked */
945 __HAL_UNLOCK(hdma);
946
947 /* Change the DMA state */
948 hdma->State = HAL_DMA_STATE_READY;
949 }
950
951 if(hdma->XferErrorCallback != NULL)
952 {
953 /* Transfer error callback */
954 hdma->XferErrorCallback(hdma);
955 }
956 }
957 }
958
959 /**
960 * @brief Register callbacks
961 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
962 * the configuration information for the specified DMA Stream.
963 * @param CallbackID User Callback identifer
964 * a DMA_HandleTypeDef structure as parameter.
965 * @param pCallback pointer to private callbacsk function which has pointer to
966 * a DMA_HandleTypeDef structure as parameter.
967 * @retval HAL status
968 */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* pCallback)(DMA_HandleTypeDef * _hdma))969 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
970 {
971
972 HAL_StatusTypeDef status = HAL_OK;
973
974 /* Process locked */
975 __HAL_LOCK(hdma);
976
977 if(HAL_DMA_STATE_READY == hdma->State)
978 {
979 switch (CallbackID)
980 {
981 case HAL_DMA_XFER_CPLT_CB_ID:
982 hdma->XferCpltCallback = pCallback;
983 break;
984
985 case HAL_DMA_XFER_HALFCPLT_CB_ID:
986 hdma->XferHalfCpltCallback = pCallback;
987 break;
988
989 case HAL_DMA_XFER_M1CPLT_CB_ID:
990 hdma->XferM1CpltCallback = pCallback;
991 break;
992
993 case HAL_DMA_XFER_M1HALFCPLT_CB_ID:
994 hdma->XferM1HalfCpltCallback = pCallback;
995 break;
996
997 case HAL_DMA_XFER_ERROR_CB_ID:
998 hdma->XferErrorCallback = pCallback;
999 break;
1000
1001 case HAL_DMA_XFER_ABORT_CB_ID:
1002 hdma->XferAbortCallback = pCallback;
1003 break;
1004
1005 default:
1006 break;
1007 }
1008 }
1009 else
1010 {
1011 /* Return error status */
1012 status = HAL_ERROR;
1013 }
1014
1015 /* Release Lock */
1016 __HAL_UNLOCK(hdma);
1017
1018 return status;
1019 }
1020
1021 /**
1022 * @brief UnRegister callbacks
1023 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1024 * the configuration information for the specified DMA Stream.
1025 * @param CallbackID User Callback identifer
1026 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
1027 * @retval HAL status
1028 */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID)1029 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
1030 {
1031 HAL_StatusTypeDef status = HAL_OK;
1032
1033 /* Process locked */
1034 __HAL_LOCK(hdma);
1035
1036 if(HAL_DMA_STATE_READY == hdma->State)
1037 {
1038 switch (CallbackID)
1039 {
1040 case HAL_DMA_XFER_CPLT_CB_ID:
1041 hdma->XferCpltCallback = NULL;
1042 break;
1043
1044 case HAL_DMA_XFER_HALFCPLT_CB_ID:
1045 hdma->XferHalfCpltCallback = NULL;
1046 break;
1047
1048 case HAL_DMA_XFER_M1CPLT_CB_ID:
1049 hdma->XferM1CpltCallback = NULL;
1050 break;
1051
1052 case HAL_DMA_XFER_M1HALFCPLT_CB_ID:
1053 hdma->XferM1HalfCpltCallback = NULL;
1054 break;
1055
1056 case HAL_DMA_XFER_ERROR_CB_ID:
1057 hdma->XferErrorCallback = NULL;
1058 break;
1059
1060 case HAL_DMA_XFER_ABORT_CB_ID:
1061 hdma->XferAbortCallback = NULL;
1062 break;
1063
1064 case HAL_DMA_XFER_ALL_CB_ID:
1065 hdma->XferCpltCallback = NULL;
1066 hdma->XferHalfCpltCallback = NULL;
1067 hdma->XferM1CpltCallback = NULL;
1068 hdma->XferM1HalfCpltCallback = NULL;
1069 hdma->XferErrorCallback = NULL;
1070 hdma->XferAbortCallback = NULL;
1071 break;
1072
1073 default:
1074 status = HAL_ERROR;
1075 break;
1076 }
1077 }
1078 else
1079 {
1080 status = HAL_ERROR;
1081 }
1082
1083 /* Release Lock */
1084 __HAL_UNLOCK(hdma);
1085
1086 return status;
1087 }
1088
1089 /**
1090 * @}
1091 */
1092
1093 /** @addtogroup DMA_Exported_Functions_Group3
1094 *
1095 @verbatim
1096 ===============================================================================
1097 ##### State and Errors functions #####
1098 ===============================================================================
1099 [..]
1100 This subsection provides functions allowing to
1101 (+) Check the DMA state
1102 (+) Get error code
1103
1104 @endverbatim
1105 * @{
1106 */
1107
1108 /**
1109 * @brief Returns the DMA state.
1110 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1111 * the configuration information for the specified DMA Stream.
1112 * @retval HAL state
1113 */
HAL_DMA_GetState(DMA_HandleTypeDef * hdma)1114 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
1115 {
1116 return hdma->State;
1117 }
1118
1119 /**
1120 * @brief Return the DMA error code
1121 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1122 * the configuration information for the specified DMA Stream.
1123 * @retval DMA Error Code
1124 */
HAL_DMA_GetError(DMA_HandleTypeDef * hdma)1125 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
1126 {
1127 return hdma->ErrorCode;
1128 }
1129
1130 /**
1131 * @}
1132 */
1133
1134 /**
1135 * @}
1136 */
1137
1138 /** @addtogroup DMA_Private_Functions
1139 * @{
1140 */
1141
1142 /**
1143 * @brief Sets the DMA Transfer parameter.
1144 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1145 * the configuration information for the specified DMA Stream.
1146 * @param SrcAddress The source memory Buffer address
1147 * @param DstAddress The destination memory Buffer address
1148 * @param DataLength The length of data to be transferred from source to destination
1149 * @retval HAL status
1150 */
DMA_SetConfig(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)1151 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
1152 {
1153 /* Clear DBM bit */
1154 hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
1155
1156 /* Configure DMA Stream data length */
1157 hdma->Instance->NDTR = DataLength;
1158
1159 /* Memory to Peripheral */
1160 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1161 {
1162 /* Configure DMA Stream destination address */
1163 hdma->Instance->PAR = DstAddress;
1164
1165 /* Configure DMA Stream source address */
1166 hdma->Instance->M0AR = SrcAddress;
1167 }
1168 /* Peripheral to Memory */
1169 else
1170 {
1171 /* Configure DMA Stream source address */
1172 hdma->Instance->PAR = SrcAddress;
1173
1174 /* Configure DMA Stream destination address */
1175 hdma->Instance->M0AR = DstAddress;
1176 }
1177 }
1178
1179 /**
1180 * @brief Returns the DMA Stream base address depending on stream number
1181 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1182 * the configuration information for the specified DMA Stream.
1183 * @retval Stream base address
1184 */
DMA_CalcBaseAndBitshift(DMA_HandleTypeDef * hdma)1185 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
1186 {
1187 uint32_t stream_number = (((uint32_t)hdma->Instance & 0xFFU) - 16U) / 24U;
1188
1189 /* lookup table for necessary bitshift of flags within status registers */
1190 static const uint8_t flagBitshiftOffset[8U] = {0U, 6U, 16U, 22U, 0U, 6U, 16U, 22U};
1191 hdma->StreamIndex = flagBitshiftOffset[stream_number];
1192
1193 if (stream_number > 3U)
1194 {
1195 /* return pointer to HISR and HIFCR */
1196 hdma->StreamBaseAddress = (((uint32_t)hdma->Instance & (uint32_t)(~0x3FFU)) + 4U);
1197 }
1198 else
1199 {
1200 /* return pointer to LISR and LIFCR */
1201 hdma->StreamBaseAddress = ((uint32_t)hdma->Instance & (uint32_t)(~0x3FFU));
1202 }
1203
1204 return hdma->StreamBaseAddress;
1205 }
1206
1207 /**
1208 * @brief Check compatibility between FIFO threshold level and size of the memory burst
1209 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1210 * the configuration information for the specified DMA Stream.
1211 * @retval HAL status
1212 */
DMA_CheckFifoParam(DMA_HandleTypeDef * hdma)1213 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma)
1214 {
1215 HAL_StatusTypeDef status = HAL_OK;
1216 uint32_t tmp = hdma->Init.FIFOThreshold;
1217
1218 /* Memory Data size equal to Byte */
1219 if(hdma->Init.MemDataAlignment == DMA_MDATAALIGN_BYTE)
1220 {
1221 switch (tmp)
1222 {
1223 case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1224 case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1225 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1226 {
1227 status = HAL_ERROR;
1228 }
1229 break;
1230 case DMA_FIFO_THRESHOLD_HALFFULL:
1231 if (hdma->Init.MemBurst == DMA_MBURST_INC16)
1232 {
1233 status = HAL_ERROR;
1234 }
1235 break;
1236 case DMA_FIFO_THRESHOLD_FULL:
1237 break;
1238 default:
1239 break;
1240 }
1241 }
1242
1243 /* Memory Data size equal to Half-Word */
1244 else if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
1245 {
1246 switch (tmp)
1247 {
1248 case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1249 case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1250 status = HAL_ERROR;
1251 break;
1252 case DMA_FIFO_THRESHOLD_HALFFULL:
1253 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1254 {
1255 status = HAL_ERROR;
1256 }
1257 break;
1258 case DMA_FIFO_THRESHOLD_FULL:
1259 if (hdma->Init.MemBurst == DMA_MBURST_INC16)
1260 {
1261 status = HAL_ERROR;
1262 }
1263 break;
1264 default:
1265 break;
1266 }
1267 }
1268
1269 /* Memory Data size equal to Word */
1270 else
1271 {
1272 switch (tmp)
1273 {
1274 case DMA_FIFO_THRESHOLD_1QUARTERFULL:
1275 case DMA_FIFO_THRESHOLD_HALFFULL:
1276 case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
1277 status = HAL_ERROR;
1278 break;
1279 case DMA_FIFO_THRESHOLD_FULL:
1280 if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
1281 {
1282 status = HAL_ERROR;
1283 }
1284 break;
1285 default:
1286 break;
1287 }
1288 }
1289
1290 return status;
1291 }
1292
1293 /**
1294 * @}
1295 */
1296
1297 #endif /* HAL_DMA_MODULE_ENABLED */
1298 /**
1299 * @}
1300 */
1301
1302 /**
1303 * @}
1304 */
1305
1306 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1307