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