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