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