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   * Copyright (c) 2017 STMicroelectronics.
87   * All rights reserved.
88   *
89   * This software is licensed under terms that can be found in the LICENSE file in
90   * the root directory of this software component.
91   * If no LICENSE file comes with this software, it is provided AS-IS.
92   *
93   ******************************************************************************
94   */
95 
96 /* Includes ------------------------------------------------------------------*/
97 #include "stm32f4xx_hal.h"
98 
99 /** @addtogroup STM32F4xx_HAL_Driver
100   * @{
101   */
102 
103 /** @defgroup DMA DMA
104   * @brief DMA HAL module driver
105   * @{
106   */
107 
108 #ifdef HAL_DMA_MODULE_ENABLED
109 
110 /* Private types -------------------------------------------------------------*/
111 typedef struct
112 {
113   __IO uint32_t ISR;   /*!< DMA interrupt status register */
114   __IO uint32_t Reserved0;
115   __IO uint32_t IFCR;  /*!< DMA interrupt flag clear register */
116 } DMA_Base_Registers;
117 
118 /* Private variables ---------------------------------------------------------*/
119 /* Private constants ---------------------------------------------------------*/
120 /** @addtogroup DMA_Private_Constants
121  * @{
122  */
123  #define HAL_TIMEOUT_DMA_ABORT    5U  /* 5 ms */
124 /**
125   * @}
126   */
127 /* Private macros ------------------------------------------------------------*/
128 /* Private functions ---------------------------------------------------------*/
129 /** @addtogroup DMA_Private_Functions
130   * @{
131   */
132 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
133 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
134 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma);
135 
136 /**
137   * @}
138   */
139 
140 /* Exported functions ---------------------------------------------------------*/
141 /** @addtogroup DMA_Exported_Functions
142   * @{
143   */
144 
145 /** @addtogroup DMA_Exported_Functions_Group1
146   *
147 @verbatim
148  ===============================================================================
149              ##### Initialization and de-initialization functions  #####
150  ===============================================================================
151     [..]
152     This section provides functions allowing to initialize the DMA Stream source
153     and destination addresses, incrementation and data sizes, transfer direction,
154     circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
155     [..]
156     The HAL_DMA_Init() function follows the DMA configuration procedures as described in
157     reference manual.
158 
159 @endverbatim
160   * @{
161   */
162 
163 /**
164   * @brief  Initialize the DMA according to the specified
165   *         parameters in the DMA_InitTypeDef and create the associated handle.
166   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
167   *               the configuration information for the specified DMA Stream.
168   * @retval HAL status
169   */
HAL_DMA_Init(DMA_HandleTypeDef * hdma)170 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
171 {
172   uint32_t tmp = 0U;
173   uint32_t tickstart = HAL_GetTick();
174   DMA_Base_Registers *regs;
175 
176   /* Check the DMA peripheral state */
177   if(hdma == NULL)
178   {
179     return HAL_ERROR;
180   }
181 
182   /* Check the parameters */
183   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
184   assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));
185   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
186   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
187   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
188   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
189   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
190   assert_param(IS_DMA_MODE(hdma->Init.Mode));
191   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
192   assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
193   /* Check the memory burst, peripheral burst and FIFO threshold parameters only
194      when FIFO mode is enabled */
195   if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
196   {
197     assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
198     assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
199     assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
200   }
201 
202   /* Change DMA peripheral state */
203   hdma->State = HAL_DMA_STATE_BUSY;
204 
205   /* Allocate lock resource */
206   __HAL_UNLOCK(hdma);
207 
208   /* Disable the peripheral */
209   __HAL_DMA_DISABLE(hdma);
210 
211   /* Check if the DMA Stream is effectively disabled */
212   while((hdma->Instance->CR & DMA_SxCR_EN) != RESET)
213   {
214     /* Check for the Timeout */
215     if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
216     {
217       /* Update error code */
218       hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
219 
220       /* Change the DMA state */
221       hdma->State = HAL_DMA_STATE_TIMEOUT;
222 
223       return HAL_TIMEOUT;
224     }
225   }
226 
227   /* Get the CR register value */
228   tmp = hdma->Instance->CR;
229 
230   /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
231   tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
232                       DMA_SxCR_PL    | DMA_SxCR_MSIZE  | DMA_SxCR_PSIZE  | \
233                       DMA_SxCR_MINC  | DMA_SxCR_PINC   | DMA_SxCR_CIRC   | \
234                       DMA_SxCR_DIR   | DMA_SxCR_CT     | DMA_SxCR_DBM));
235 
236   /* Prepare the DMA Stream configuration */
237   tmp |=  hdma->Init.Channel             | hdma->Init.Direction        |
238           hdma->Init.PeriphInc           | hdma->Init.MemInc           |
239           hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
240           hdma->Init.Mode                | hdma->Init.Priority;
241 
242   /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
243   if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
244   {
245     /* Get memory burst and peripheral burst */
246     tmp |=  hdma->Init.MemBurst | hdma->Init.PeriphBurst;
247   }
248 
249   /* Write to DMA Stream CR register */
250   hdma->Instance->CR = tmp;
251 
252   /* Get the FCR register value */
253   tmp = hdma->Instance->FCR;
254 
255   /* Clear Direct mode and FIFO threshold bits */
256   tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
257 
258   /* Prepare the DMA Stream FIFO configuration */
259   tmp |= hdma->Init.FIFOMode;
260 
261   /* The FIFO threshold is not used when the FIFO mode is disabled */
262   if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
263   {
264     /* Get the FIFO threshold */
265     tmp |= hdma->Init.FIFOThreshold;
266 
267     /* Check compatibility between FIFO threshold level and size of the memory burst */
268     /* for INCR4, INCR8, INCR16 bursts */
269     if (hdma->Init.MemBurst != DMA_MBURST_SINGLE)
270     {
271       if (DMA_CheckFifoParam(hdma) != HAL_OK)
272       {
273         /* Update error code */
274         hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
275 
276         /* Change the DMA state */
277         hdma->State = HAL_DMA_STATE_READY;
278 
279         return HAL_ERROR;
280       }
281     }
282   }
283 
284   /* Write to DMA Stream FCR */
285   hdma->Instance->FCR = tmp;
286 
287   /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
288      DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
289   regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
290 
291   /* Clear all interrupt flags */
292   regs->IFCR = 0x3FU << hdma->StreamIndex;
293 
294   /* Initialize the error code */
295   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
296 
297   /* Initialize the DMA state */
298   hdma->State = HAL_DMA_STATE_READY;
299 
300   return HAL_OK;
301 }
302 
303 /**
304   * @brief  DeInitializes the DMA peripheral
305   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
306   *               the configuration information for the specified DMA Stream.
307   * @retval HAL status
308   */
HAL_DMA_DeInit(DMA_HandleTypeDef * hdma)309 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
310 {
311   DMA_Base_Registers *regs;
312 
313   /* Check the DMA peripheral state */
314   if(hdma == NULL)
315   {
316     return HAL_ERROR;
317   }
318 
319   /* Check the DMA peripheral state */
320   if(hdma->State == HAL_DMA_STATE_BUSY)
321   {
322     /* Return error status */
323     return HAL_BUSY;
324   }
325 
326   /* Check the parameters */
327   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
328 
329   /* Disable the selected DMA Streamx */
330   __HAL_DMA_DISABLE(hdma);
331 
332   /* Reset DMA Streamx control register */
333   hdma->Instance->CR   = 0U;
334 
335   /* Reset DMA Streamx number of data to transfer register */
336   hdma->Instance->NDTR = 0U;
337 
338   /* Reset DMA Streamx peripheral address register */
339   hdma->Instance->PAR  = 0U;
340 
341   /* Reset DMA Streamx memory 0 address register */
342   hdma->Instance->M0AR = 0U;
343 
344   /* Reset DMA Streamx memory 1 address register */
345   hdma->Instance->M1AR = 0U;
346 
347   /* Reset DMA Streamx FIFO control register */
348   hdma->Instance->FCR  = 0x00000021U;
349 
350   /* Get DMA steam Base Address */
351   regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
352 
353   /* Clean all callbacks */
354   hdma->XferCpltCallback = NULL;
355   hdma->XferHalfCpltCallback = NULL;
356   hdma->XferM1CpltCallback = NULL;
357   hdma->XferM1HalfCpltCallback = NULL;
358   hdma->XferErrorCallback = NULL;
359   hdma->XferAbortCallback = NULL;
360 
361   /* Clear all interrupt flags at correct offset within the register */
362   regs->IFCR = 0x3FU << hdma->StreamIndex;
363 
364   /* Reset the error code */
365   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
366 
367   /* Reset the DMA state */
368   hdma->State = HAL_DMA_STATE_RESET;
369 
370   /* Release Lock */
371   __HAL_UNLOCK(hdma);
372 
373   return HAL_OK;
374 }
375 
376 /**
377   * @}
378   */
379 
380 /** @addtogroup DMA_Exported_Functions_Group2
381   *
382 @verbatim
383  ===============================================================================
384                       #####  IO operation functions  #####
385  ===============================================================================
386     [..]  This section provides functions allowing to:
387       (+) Configure the source, destination address and data length and Start DMA transfer
388       (+) Configure the source, destination address and data length and
389           Start DMA transfer with interrupt
390       (+) Abort DMA transfer
391       (+) Poll for transfer complete
392       (+) Handle DMA interrupt request
393 
394 @endverbatim
395   * @{
396   */
397 
398 /**
399   * @brief  Starts the DMA Transfer.
400   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
401   *                     the configuration information for the specified DMA Stream.
402   * @param  SrcAddress The source memory Buffer address
403   * @param  DstAddress The destination memory Buffer address
404   * @param  DataLength The length of data to be transferred from source to destination
405   * @retval HAL status
406   */
HAL_DMA_Start(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)407 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
408 {
409   HAL_StatusTypeDef status = HAL_OK;
410 
411   /* Check the parameters */
412   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
413 
414   /* Process locked */
415   __HAL_LOCK(hdma);
416 
417   if(HAL_DMA_STATE_READY == hdma->State)
418   {
419     /* Change DMA peripheral state */
420     hdma->State = HAL_DMA_STATE_BUSY;
421 
422     /* Initialize the error code */
423     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
424 
425     /* Configure the source, destination address and the data length */
426     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
427 
428     /* Enable the Peripheral */
429     __HAL_DMA_ENABLE(hdma);
430   }
431   else
432   {
433     /* Process unlocked */
434     __HAL_UNLOCK(hdma);
435 
436     /* Return error status */
437     status = HAL_BUSY;
438   }
439   return status;
440 }
441 
442 /**
443   * @brief  Start the DMA Transfer with interrupt enabled.
444   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
445   *                     the configuration information for the specified DMA Stream.
446   * @param  SrcAddress The source memory Buffer address
447   * @param  DstAddress The destination memory Buffer address
448   * @param  DataLength The length of data to be transferred from source to destination
449   * @retval HAL status
450   */
HAL_DMA_Start_IT(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)451 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
452 {
453   HAL_StatusTypeDef status = HAL_OK;
454 
455   /* calculate DMA base and stream number */
456   DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
457 
458   /* Check the parameters */
459   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
460 
461   /* Process locked */
462   __HAL_LOCK(hdma);
463 
464   if(HAL_DMA_STATE_READY == hdma->State)
465   {
466     /* Change DMA peripheral state */
467     hdma->State = HAL_DMA_STATE_BUSY;
468 
469     /* Initialize the error code */
470     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
471 
472     /* Configure the source, destination address and the data length */
473     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
474 
475     /* Clear all interrupt flags at correct offset within the register */
476     regs->IFCR = 0x3FU << hdma->StreamIndex;
477 
478     /* Enable Common interrupts*/
479     hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
480 
481     if(hdma->XferHalfCpltCallback != NULL)
482     {
483       hdma->Instance->CR  |= DMA_IT_HT;
484     }
485 
486     /* Enable the Peripheral */
487     __HAL_DMA_ENABLE(hdma);
488   }
489   else
490   {
491     /* Process unlocked */
492     __HAL_UNLOCK(hdma);
493 
494     /* Return error status */
495     status = HAL_BUSY;
496   }
497 
498   return status;
499 }
500 
501 /**
502   * @brief  Aborts the DMA Transfer.
503   * @param  hdma   pointer to a DMA_HandleTypeDef structure that contains
504   *                 the configuration information for the specified DMA Stream.
505   *
506   * @note  After disabling a DMA Stream, a check for wait until the DMA Stream is
507   *        effectively disabled is added. If a Stream is disabled
508   *        while a data transfer is ongoing, the current data will be transferred
509   *        and the Stream will be effectively disabled only after the transfer of
510   *        this single data is finished.
511   * @retval HAL status
512   */
HAL_DMA_Abort(DMA_HandleTypeDef * hdma)513 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
514 {
515   /* calculate DMA base and stream number */
516   DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
517 
518   uint32_t tickstart = HAL_GetTick();
519 
520   if(hdma->State != HAL_DMA_STATE_BUSY)
521   {
522     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
523 
524     /* Process Unlocked */
525     __HAL_UNLOCK(hdma);
526 
527     return HAL_ERROR;
528   }
529   else
530   {
531     /* Disable all the transfer interrupts */
532     hdma->Instance->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
533     hdma->Instance->FCR &= ~(DMA_IT_FE);
534 
535     if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
536     {
537       hdma->Instance->CR  &= ~(DMA_IT_HT);
538     }
539 
540     /* Disable the stream */
541     __HAL_DMA_DISABLE(hdma);
542 
543     /* Check if the DMA Stream is effectively disabled */
544     while((hdma->Instance->CR & DMA_SxCR_EN) != RESET)
545     {
546       /* Check for the Timeout */
547       if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
548       {
549         /* Update error code */
550         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
551 
552         /* Change the DMA state */
553         hdma->State = HAL_DMA_STATE_TIMEOUT;
554 
555         /* Process Unlocked */
556         __HAL_UNLOCK(hdma);
557 
558         return HAL_TIMEOUT;
559       }
560     }
561 
562     /* Clear all interrupt flags at correct offset within the register */
563     regs->IFCR = 0x3FU << hdma->StreamIndex;
564 
565     /* Change the DMA state*/
566     hdma->State = HAL_DMA_STATE_READY;
567 
568     /* Process Unlocked */
569     __HAL_UNLOCK(hdma);
570   }
571   return HAL_OK;
572 }
573 
574 /**
575   * @brief  Aborts the DMA Transfer in Interrupt mode.
576   * @param  hdma   pointer to a DMA_HandleTypeDef structure that contains
577   *                 the configuration information for the specified DMA Stream.
578   * @retval HAL status
579   */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * hdma)580 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
581 {
582   if(hdma->State != HAL_DMA_STATE_BUSY)
583   {
584     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
585     return HAL_ERROR;
586   }
587   else
588   {
589     /* Set Abort State  */
590     hdma->State = HAL_DMA_STATE_ABORT;
591 
592     /* Disable the stream */
593     __HAL_DMA_DISABLE(hdma);
594   }
595 
596   return HAL_OK;
597 }
598 
599 /**
600   * @brief  Polling for transfer complete.
601   * @param  hdma          pointer to a DMA_HandleTypeDef structure that contains
602   *                        the configuration information for the specified DMA Stream.
603   * @param  CompleteLevel Specifies the DMA level complete.
604   * @note   The polling mode is kept in this version for legacy. it is recommended to use the IT model instead.
605   *         This model could be used for debug purpose.
606   * @note   The HAL_DMA_PollForTransfer API cannot be used in circular and double buffering mode (automatic circular mode).
607   * @param  Timeout       Timeout duration.
608   * @retval HAL status
609   */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * hdma,HAL_DMA_LevelCompleteTypeDef CompleteLevel,uint32_t Timeout)610 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
611 {
612   HAL_StatusTypeDef status = HAL_OK;
613   uint32_t mask_cpltlevel;
614   uint32_t tickstart = HAL_GetTick();
615   uint32_t tmpisr;
616 
617   /* calculate DMA base and stream number */
618   DMA_Base_Registers *regs;
619 
620   if(HAL_DMA_STATE_BUSY != hdma->State)
621   {
622     /* No transfer ongoing */
623     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
624     __HAL_UNLOCK(hdma);
625     return HAL_ERROR;
626   }
627 
628   /* Polling mode not supported in circular mode and double buffering mode */
629   if ((hdma->Instance->CR & DMA_SxCR_CIRC) != RESET)
630   {
631     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
632     return HAL_ERROR;
633   }
634 
635   /* Get the level transfer complete flag */
636   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
637   {
638     /* Transfer Complete flag */
639     mask_cpltlevel = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
640   }
641   else
642   {
643     /* Half Transfer Complete flag */
644     mask_cpltlevel = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
645   }
646 
647   regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
648   tmpisr = regs->ISR;
649 
650   while(((tmpisr & mask_cpltlevel) == RESET) && ((hdma->ErrorCode & HAL_DMA_ERROR_TE) == RESET))
651   {
652     /* Check for the Timeout (Not applicable in circular mode)*/
653     if(Timeout != HAL_MAX_DELAY)
654     {
655       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
656       {
657         /* Update error code */
658         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
659 
660         /* Change the DMA state */
661         hdma->State = HAL_DMA_STATE_READY;
662 
663         /* Process Unlocked */
664         __HAL_UNLOCK(hdma);
665 
666         return HAL_TIMEOUT;
667       }
668     }
669 
670     /* Get the ISR register value */
671     tmpisr = regs->ISR;
672 
673     if((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
674     {
675       /* Update error code */
676       hdma->ErrorCode |= HAL_DMA_ERROR_TE;
677 
678       /* Clear the transfer error flag */
679       regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
680     }
681 
682     if((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
683     {
684       /* Update error code */
685       hdma->ErrorCode |= HAL_DMA_ERROR_FE;
686 
687       /* Clear the FIFO error flag */
688       regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
689     }
690 
691     if((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
692     {
693       /* Update error code */
694       hdma->ErrorCode |= HAL_DMA_ERROR_DME;
695 
696       /* Clear the Direct Mode error flag */
697       regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
698     }
699   }
700 
701   if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
702   {
703     if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
704     {
705       HAL_DMA_Abort(hdma);
706 
707       /* Clear the half transfer and transfer complete flags */
708       regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
709 
710       /* Change the DMA state */
711       hdma->State= HAL_DMA_STATE_READY;
712 
713       /* Process Unlocked */
714       __HAL_UNLOCK(hdma);
715 
716       return HAL_ERROR;
717    }
718   }
719 
720   /* Get the level transfer complete flag */
721   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
722   {
723     /* Clear the half transfer and transfer complete flags */
724     regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
725 
726     hdma->State = HAL_DMA_STATE_READY;
727 
728     /* Process Unlocked */
729     __HAL_UNLOCK(hdma);
730   }
731   else
732   {
733     /* Clear the half transfer and transfer complete flags */
734     regs->IFCR = (DMA_FLAG_HTIF0_4) << hdma->StreamIndex;
735   }
736 
737   return status;
738 }
739 
740 /**
741   * @brief  Handles DMA interrupt request.
742   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
743   *               the configuration information for the specified DMA Stream.
744   * @retval None
745   */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * hdma)746 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
747 {
748   uint32_t tmpisr;
749   __IO uint32_t count = 0U;
750   uint32_t timeout = SystemCoreClock / 9600U;
751 
752   /* calculate DMA base and stream number */
753   DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
754 
755   tmpisr = regs->ISR;
756 
757   /* Transfer Error Interrupt management ***************************************/
758   if ((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
759   {
760     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
761     {
762       /* Disable the transfer error interrupt */
763       hdma->Instance->CR  &= ~(DMA_IT_TE);
764 
765       /* Clear the transfer error flag */
766       regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
767 
768       /* Update error code */
769       hdma->ErrorCode |= HAL_DMA_ERROR_TE;
770     }
771   }
772   /* FIFO Error Interrupt management ******************************************/
773   if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
774   {
775     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
776     {
777       /* Clear the FIFO error flag */
778       regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
779 
780       /* Update error code */
781       hdma->ErrorCode |= HAL_DMA_ERROR_FE;
782     }
783   }
784   /* Direct Mode Error Interrupt management ***********************************/
785   if ((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
786   {
787     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
788     {
789       /* Clear the direct mode error flag */
790       regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
791 
792       /* Update error code */
793       hdma->ErrorCode |= HAL_DMA_ERROR_DME;
794     }
795   }
796   /* Half Transfer Complete Interrupt management ******************************/
797   if ((tmpisr & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET)
798   {
799     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
800     {
801       /* Clear the half transfer complete flag */
802       regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
803 
804       /* Multi_Buffering mode enabled */
805       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
806       {
807         /* Current memory buffer used is Memory 0 */
808         if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
809         {
810           if(hdma->XferHalfCpltCallback != NULL)
811           {
812             /* Half transfer callback */
813             hdma->XferHalfCpltCallback(hdma);
814           }
815         }
816         /* Current memory buffer used is Memory 1 */
817         else
818         {
819           if(hdma->XferM1HalfCpltCallback != NULL)
820           {
821             /* Half transfer callback */
822             hdma->XferM1HalfCpltCallback(hdma);
823           }
824         }
825       }
826       else
827       {
828         /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
829         if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
830         {
831           /* Disable the half transfer interrupt */
832           hdma->Instance->CR  &= ~(DMA_IT_HT);
833         }
834 
835         if(hdma->XferHalfCpltCallback != NULL)
836         {
837           /* Half transfer callback */
838           hdma->XferHalfCpltCallback(hdma);
839         }
840       }
841     }
842   }
843   /* Transfer Complete Interrupt management ***********************************/
844   if ((tmpisr & (DMA_FLAG_TCIF0_4 << hdma->StreamIndex)) != RESET)
845   {
846     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
847     {
848       /* Clear the transfer complete flag */
849       regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
850 
851       if(HAL_DMA_STATE_ABORT == hdma->State)
852       {
853         /* Disable all the transfer interrupts */
854         hdma->Instance->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
855         hdma->Instance->FCR &= ~(DMA_IT_FE);
856 
857         if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
858         {
859           hdma->Instance->CR  &= ~(DMA_IT_HT);
860         }
861 
862         /* Clear all interrupt flags at correct offset within the register */
863         regs->IFCR = 0x3FU << hdma->StreamIndex;
864 
865         /* Change the DMA state */
866         hdma->State = HAL_DMA_STATE_READY;
867 
868         /* Process Unlocked */
869         __HAL_UNLOCK(hdma);
870 
871         if(hdma->XferAbortCallback != NULL)
872         {
873           hdma->XferAbortCallback(hdma);
874         }
875         return;
876       }
877 
878       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
879       {
880         /* Current memory buffer used is Memory 0 */
881         if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
882         {
883           if(hdma->XferM1CpltCallback != NULL)
884           {
885             /* Transfer complete Callback for memory1 */
886             hdma->XferM1CpltCallback(hdma);
887           }
888         }
889         /* Current memory buffer used is Memory 1 */
890         else
891         {
892           if(hdma->XferCpltCallback != NULL)
893           {
894             /* Transfer complete Callback for memory0 */
895             hdma->XferCpltCallback(hdma);
896           }
897         }
898       }
899       /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
900       else
901       {
902         if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
903         {
904           /* Disable the transfer complete interrupt */
905           hdma->Instance->CR  &= ~(DMA_IT_TC);
906 
907           /* Change the DMA state */
908           hdma->State = HAL_DMA_STATE_READY;
909 
910           /* Process Unlocked */
911           __HAL_UNLOCK(hdma);
912         }
913 
914         if(hdma->XferCpltCallback != NULL)
915         {
916           /* Transfer complete callback */
917           hdma->XferCpltCallback(hdma);
918         }
919       }
920     }
921   }
922 
923   /* manage error case */
924   if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
925   {
926     if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
927     {
928       hdma->State = HAL_DMA_STATE_ABORT;
929 
930       /* Disable the stream */
931       __HAL_DMA_DISABLE(hdma);
932 
933       do
934       {
935         if (++count > timeout)
936         {
937           break;
938         }
939       }
940       while((hdma->Instance->CR & DMA_SxCR_EN) != RESET);
941 
942       /* Change the DMA state */
943       hdma->State = HAL_DMA_STATE_READY;
944 
945       /* Process Unlocked */
946       __HAL_UNLOCK(hdma);
947     }
948 
949     if(hdma->XferErrorCallback != NULL)
950     {
951       /* Transfer error callback */
952       hdma->XferErrorCallback(hdma);
953     }
954   }
955 }
956 
957 /**
958   * @brief  Register callbacks
959   * @param  hdma                 pointer to a DMA_HandleTypeDef structure that contains
960   *                               the configuration information for the specified DMA Stream.
961   * @param  CallbackID           User Callback identifier
962   *                               a DMA_HandleTypeDef structure as parameter.
963   * @param  pCallback            pointer to private callback function which has pointer to
964   *                               a DMA_HandleTypeDef structure as parameter.
965   * @retval HAL status
966   */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* pCallback)(DMA_HandleTypeDef * _hdma))967 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
968 {
969 
970   HAL_StatusTypeDef status = HAL_OK;
971 
972   /* Process locked */
973   __HAL_LOCK(hdma);
974 
975   if(HAL_DMA_STATE_READY == hdma->State)
976   {
977     switch (CallbackID)
978     {
979     case  HAL_DMA_XFER_CPLT_CB_ID:
980       hdma->XferCpltCallback = pCallback;
981       break;
982 
983     case  HAL_DMA_XFER_HALFCPLT_CB_ID:
984       hdma->XferHalfCpltCallback = pCallback;
985       break;
986 
987     case  HAL_DMA_XFER_M1CPLT_CB_ID:
988       hdma->XferM1CpltCallback = pCallback;
989       break;
990 
991     case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
992       hdma->XferM1HalfCpltCallback = pCallback;
993       break;
994 
995     case  HAL_DMA_XFER_ERROR_CB_ID:
996       hdma->XferErrorCallback = pCallback;
997       break;
998 
999     case  HAL_DMA_XFER_ABORT_CB_ID:
1000       hdma->XferAbortCallback = pCallback;
1001       break;
1002 
1003     default:
1004       /* Return error status */
1005       status =  HAL_ERROR;
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 identifier
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