STM32F479xx HAL User Manual
stm32f4xx_hal_dma.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_dma.c
00004   * @author  MCD Application Team
00005   * @brief   DMA HAL module driver.
00006   *    
00007   *          This file provides firmware functions to manage the following 
00008   *          functionalities of the Direct Memory Access (DMA) peripheral:
00009   *           + Initialization and de-initialization functions
00010   *           + IO operation functions
00011   *           + Peripheral State and errors functions
00012   @verbatim     
00013   ==============================================================================
00014                         ##### How to use this driver #####
00015   ==============================================================================
00016   [..]
00017    (#) Enable and configure the peripheral to be connected to the DMA Stream
00018        (except for internal SRAM/FLASH memories: no initialization is 
00019        necessary) please refer to Reference manual for connection between peripherals
00020        and DMA requests.
00021 
00022    (#) For a given Stream, program the required configuration through the following parameters:
00023        Transfer Direction, Source and Destination data formats, 
00024        Circular, Normal or peripheral flow control mode, Stream Priority level, 
00025        Source and Destination Increment mode, FIFO mode and its Threshold (if needed), 
00026        Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.
00027 
00028    -@-   Prior to HAL_DMA_Init() the clock must be enabled for DMA through the following macros:
00029          __HAL_RCC_DMA1_CLK_ENABLE() or __HAL_RCC_DMA2_CLK_ENABLE().
00030 
00031      *** Polling mode IO operation ***
00032      =================================
00033     [..]
00034           (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source 
00035               address and destination address and the Length of data to be transferred.
00036           (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this  
00037               case a fixed Timeout can be configured by User depending from his application.
00038           (+) Use HAL_DMA_Abort() function to abort the current transfer.
00039 
00040      *** Interrupt mode IO operation ***
00041      ===================================
00042     [..]
00043           (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
00044           (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() 
00045           (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of  
00046               Source address and destination address and the Length of data to be transferred. In this 
00047               case the DMA interrupt is configured 
00048           (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
00049           (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can 
00050               add his own function by customization of function pointer XferCpltCallback and 
00051               XferErrorCallback (i.e a member of DMA handle structure).
00052     [..]
00053      (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error 
00054          detection.
00055 
00056      (#) Use HAL_DMA_Abort_IT() function to abort the current transfer
00057 
00058      -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.
00059 
00060      -@-   The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
00061            possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
00062            Half-Word data size for the peripheral to access its data register and set Word data size
00063            for the Memory to gain in access time. Each two half words will be packed and written in
00064            a single access to a Word in the Memory).
00065 
00066      -@-   When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
00067            and Destination. In this case the Peripheral Data Size will be applied to both Source
00068            and Destination.
00069 
00070      *** DMA HAL driver macros list ***
00071      =============================================
00072      [..]
00073        Below the list of most used macros in DMA HAL driver.
00074        
00075       (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.
00076       (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.
00077       (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not. 
00078 
00079      [..]
00080       (@) You can refer to the DMA HAL driver header file for more useful macros
00081 
00082   @endverbatim
00083   ******************************************************************************
00084   * @attention
00085   *
00086   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
00087   * All rights reserved.</center></h2>
00088   *
00089   * This software component is licensed by ST under BSD 3-Clause license,
00090   * the "License"; You may not use this file except in compliance with the
00091   * License. You may obtain a copy of the License at:
00092   *                        opensource.org/licenses/BSD-3-Clause
00093   *
00094   ******************************************************************************
00095   */ 
00096 
00097 /* Includes ------------------------------------------------------------------*/
00098 #include "stm32f4xx_hal.h"
00099 
00100 /** @addtogroup STM32F4xx_HAL_Driver
00101   * @{
00102   */
00103 
00104 /** @defgroup DMA DMA
00105   * @brief DMA HAL module driver
00106   * @{
00107   */
00108 
00109 #ifdef HAL_DMA_MODULE_ENABLED
00110 
00111 /* Private types -------------------------------------------------------------*/
00112 typedef struct
00113 {
00114   __IO uint32_t ISR;   /*!< DMA interrupt status register */
00115   __IO uint32_t Reserved0;
00116   __IO uint32_t IFCR;  /*!< DMA interrupt flag clear register */
00117 } DMA_Base_Registers;
00118 
00119 /* Private variables ---------------------------------------------------------*/
00120 /* Private constants ---------------------------------------------------------*/
00121 /** @addtogroup DMA_Private_Constants
00122  * @{
00123  */
00124  #define HAL_TIMEOUT_DMA_ABORT    5U  /* 5 ms */
00125 /**
00126   * @}
00127   */
00128 /* Private macros ------------------------------------------------------------*/
00129 /* Private functions ---------------------------------------------------------*/
00130 /** @addtogroup DMA_Private_Functions
00131   * @{
00132   */
00133 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
00134 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
00135 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma);
00136 
00137 /**
00138   * @}
00139   */  
00140 
00141 /* Exported functions ---------------------------------------------------------*/
00142 /** @addtogroup DMA_Exported_Functions
00143   * @{
00144   */
00145 
00146 /** @addtogroup DMA_Exported_Functions_Group1
00147   *
00148 @verbatim
00149  ===============================================================================
00150              ##### Initialization and de-initialization functions  #####
00151  ===============================================================================
00152     [..]
00153     This section provides functions allowing to initialize the DMA Stream source
00154     and destination addresses, incrementation and data sizes, transfer direction, 
00155     circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
00156     [..]
00157     The HAL_DMA_Init() function follows the DMA configuration procedures as described in
00158     reference manual.
00159 
00160 @endverbatim
00161   * @{
00162   */
00163   
00164 /**
00165   * @brief  Initialize the DMA according to the specified
00166   *         parameters in the DMA_InitTypeDef and create the associated handle.
00167   * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
00168   *               the configuration information for the specified DMA Stream.  
00169   * @retval HAL status
00170   */
00171 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
00172 {
00173   uint32_t tmp = 0U;
00174   uint32_t tickstart = HAL_GetTick();
00175   DMA_Base_Registers *regs;
00176 
00177   /* Check the DMA peripheral state */
00178   if(hdma == NULL)
00179   {
00180     return HAL_ERROR;
00181   }
00182 
00183   /* Check the parameters */
00184   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
00185   assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));
00186   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
00187   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
00188   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
00189   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
00190   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
00191   assert_param(IS_DMA_MODE(hdma->Init.Mode));
00192   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
00193   assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
00194   /* Check the memory burst, peripheral burst and FIFO threshold parameters only
00195      when FIFO mode is enabled */
00196   if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
00197   {
00198     assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
00199     assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
00200     assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
00201   }
00202 
00203   /* Change DMA peripheral state */
00204   hdma->State = HAL_DMA_STATE_BUSY;
00205 
00206   /* Allocate lock resource */
00207   __HAL_UNLOCK(hdma);
00208   
00209   /* Disable the peripheral */
00210   __HAL_DMA_DISABLE(hdma);
00211   
00212   /* Check if the DMA Stream is effectively disabled */
00213   while((hdma->Instance->CR & DMA_SxCR_EN) != RESET)
00214   {
00215     /* Check for the Timeout */
00216     if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
00217     {
00218       /* Update error code */
00219       hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
00220       
00221       /* Change the DMA state */
00222       hdma->State = HAL_DMA_STATE_TIMEOUT;
00223       
00224       return HAL_TIMEOUT;
00225     }
00226   }
00227   
00228   /* Get the CR register value */
00229   tmp = hdma->Instance->CR;
00230 
00231   /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
00232   tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
00233                       DMA_SxCR_PL    | DMA_SxCR_MSIZE  | DMA_SxCR_PSIZE  | \
00234                       DMA_SxCR_MINC  | DMA_SxCR_PINC   | DMA_SxCR_CIRC   | \
00235                       DMA_SxCR_DIR   | DMA_SxCR_CT     | DMA_SxCR_DBM));
00236 
00237   /* Prepare the DMA Stream configuration */
00238   tmp |=  hdma->Init.Channel             | hdma->Init.Direction        |
00239           hdma->Init.PeriphInc           | hdma->Init.MemInc           |
00240           hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
00241           hdma->Init.Mode                | hdma->Init.Priority;
00242 
00243   /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
00244   if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
00245   {
00246     /* Get memory burst and peripheral burst */
00247     tmp |=  hdma->Init.MemBurst | hdma->Init.PeriphBurst;
00248   }
00249   
00250   /* Write to DMA Stream CR register */
00251   hdma->Instance->CR = tmp;  
00252 
00253   /* Get the FCR register value */
00254   tmp = hdma->Instance->FCR;
00255 
00256   /* Clear Direct mode and FIFO threshold bits */
00257   tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
00258 
00259   /* Prepare the DMA Stream FIFO configuration */
00260   tmp |= hdma->Init.FIFOMode;
00261 
00262   /* The FIFO threshold is not used when the FIFO mode is disabled */
00263   if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
00264   {
00265     /* Get the FIFO threshold */
00266     tmp |= hdma->Init.FIFOThreshold;
00267     
00268     /* Check compatibility between FIFO threshold level and size of the memory burst */
00269     /* for INCR4, INCR8, INCR16 bursts */
00270     if (hdma->Init.MemBurst != DMA_MBURST_SINGLE)
00271     {
00272       if (DMA_CheckFifoParam(hdma) != HAL_OK)
00273       {
00274         /* Update error code */
00275         hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
00276         
00277         /* Change the DMA state */
00278         hdma->State = HAL_DMA_STATE_READY;
00279         
00280         return HAL_ERROR; 
00281       }
00282     }
00283   }
00284   
00285   /* Write to DMA Stream FCR */
00286   hdma->Instance->FCR = tmp;
00287 
00288   /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
00289      DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
00290   regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
00291   
00292   /* Clear all interrupt flags */
00293   regs->IFCR = 0x3FU << hdma->StreamIndex;
00294 
00295   /* Initialize the error code */
00296   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00297                                                                                      
00298   /* Initialize the DMA state */
00299   hdma->State = HAL_DMA_STATE_READY;
00300 
00301   return HAL_OK;
00302 }
00303 
00304 /**
00305   * @brief  DeInitializes the DMA peripheral 
00306   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
00307   *               the configuration information for the specified DMA Stream.  
00308   * @retval HAL status
00309   */
00310 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
00311 {
00312   DMA_Base_Registers *regs;
00313 
00314   /* Check the DMA peripheral state */
00315   if(hdma == NULL)
00316   {
00317     return HAL_ERROR;
00318   }
00319   
00320   /* Check the DMA peripheral state */
00321   if(hdma->State == HAL_DMA_STATE_BUSY)
00322   {
00323     /* Return error status */
00324     return HAL_BUSY;
00325   }
00326 
00327   /* Check the parameters */
00328   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
00329 
00330   /* Disable the selected DMA Streamx */
00331   __HAL_DMA_DISABLE(hdma);
00332 
00333   /* Reset DMA Streamx control register */
00334   hdma->Instance->CR   = 0U;
00335 
00336   /* Reset DMA Streamx number of data to transfer register */
00337   hdma->Instance->NDTR = 0U;
00338 
00339   /* Reset DMA Streamx peripheral address register */
00340   hdma->Instance->PAR  = 0U;
00341 
00342   /* Reset DMA Streamx memory 0 address register */
00343   hdma->Instance->M0AR = 0U;
00344   
00345   /* Reset DMA Streamx memory 1 address register */
00346   hdma->Instance->M1AR = 0U;
00347   
00348   /* Reset DMA Streamx FIFO control register */
00349   hdma->Instance->FCR  = 0x00000021U;
00350   
00351   /* Get DMA steam Base Address */  
00352   regs = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
00353   
00354   /* Clean all callbacks */
00355   hdma->XferCpltCallback = NULL;
00356   hdma->XferHalfCpltCallback = NULL;
00357   hdma->XferM1CpltCallback = NULL;
00358   hdma->XferM1HalfCpltCallback = NULL;
00359   hdma->XferErrorCallback = NULL;
00360   hdma->XferAbortCallback = NULL;
00361 
00362   /* Clear all interrupt flags at correct offset within the register */
00363   regs->IFCR = 0x3FU << hdma->StreamIndex;
00364 
00365   /* Reset the error code */
00366   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00367 
00368   /* Reset the DMA state */
00369   hdma->State = HAL_DMA_STATE_RESET;
00370 
00371   /* Release Lock */
00372   __HAL_UNLOCK(hdma);
00373 
00374   return HAL_OK;
00375 }
00376 
00377 /**
00378   * @}
00379   */
00380 
00381 /** @addtogroup DMA_Exported_Functions_Group2
00382   *
00383 @verbatim   
00384  ===============================================================================
00385                       #####  IO operation functions  #####
00386  ===============================================================================
00387     [..]  This section provides functions allowing to:
00388       (+) Configure the source, destination address and data length and Start DMA transfer
00389       (+) Configure the source, destination address and data length and 
00390           Start DMA transfer with interrupt
00391       (+) Abort DMA transfer
00392       (+) Poll for transfer complete
00393       (+) Handle DMA interrupt request  
00394 
00395 @endverbatim
00396   * @{
00397   */
00398 
00399 /**
00400   * @brief  Starts the DMA Transfer.
00401   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00402   *                     the configuration information for the specified DMA Stream.
00403   * @param  SrcAddress The source memory Buffer address
00404   * @param  DstAddress The destination memory Buffer address
00405   * @param  DataLength The length of data to be transferred from source to destination
00406   * @retval HAL status
00407   */
00408 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
00409 {
00410   HAL_StatusTypeDef status = HAL_OK;
00411   
00412   /* Check the parameters */
00413   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00414 
00415   /* Process locked */
00416   __HAL_LOCK(hdma);
00417 
00418   if(HAL_DMA_STATE_READY == hdma->State)
00419   {
00420     /* Change DMA peripheral state */
00421     hdma->State = HAL_DMA_STATE_BUSY;
00422     
00423     /* Initialize the error code */
00424     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00425     
00426     /* Configure the source, destination address and the data length */
00427     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
00428 
00429     /* Enable the Peripheral */
00430     __HAL_DMA_ENABLE(hdma);
00431   }
00432   else
00433   {
00434     /* Process unlocked */
00435     __HAL_UNLOCK(hdma);
00436     
00437     /* Return error status */
00438     status = HAL_BUSY;
00439   } 
00440   return status; 
00441 }
00442 
00443 /**
00444   * @brief  Start the DMA Transfer with interrupt enabled.
00445   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00446   *                     the configuration information for the specified DMA Stream.  
00447   * @param  SrcAddress The source memory Buffer address
00448   * @param  DstAddress The destination memory Buffer address
00449   * @param  DataLength The length of data to be transferred from source to destination
00450   * @retval HAL status
00451   */
00452 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
00453 {
00454   HAL_StatusTypeDef status = HAL_OK;
00455 
00456   /* calculate DMA base and stream number */
00457   DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
00458   
00459   /* Check the parameters */
00460   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00461  
00462   /* Process locked */
00463   __HAL_LOCK(hdma);
00464   
00465   if(HAL_DMA_STATE_READY == hdma->State)
00466   {
00467     /* Change DMA peripheral state */
00468     hdma->State = HAL_DMA_STATE_BUSY;
00469     
00470     /* Initialize the error code */
00471     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00472     
00473     /* Configure the source, destination address and the data length */
00474     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
00475     
00476     /* Clear all interrupt flags at correct offset within the register */
00477     regs->IFCR = 0x3FU << hdma->StreamIndex;
00478     
00479     /* Enable Common interrupts*/
00480     hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
00481     
00482     if(hdma->XferHalfCpltCallback != NULL)
00483     {
00484       hdma->Instance->CR  |= DMA_IT_HT;
00485     }
00486     
00487     /* Enable the Peripheral */
00488     __HAL_DMA_ENABLE(hdma);
00489   }
00490   else
00491   {
00492     /* Process unlocked */
00493     __HAL_UNLOCK(hdma);   
00494     
00495     /* Return error status */
00496     status = HAL_BUSY;
00497   }
00498   
00499   return status;
00500 }
00501 
00502 /**
00503   * @brief  Aborts the DMA Transfer.
00504   * @param  hdma   pointer to a DMA_HandleTypeDef structure that contains
00505   *                 the configuration information for the specified DMA Stream.
00506   *                   
00507   * @note  After disabling a DMA Stream, a check for wait until the DMA Stream is 
00508   *        effectively disabled is added. If a Stream is disabled 
00509   *        while a data transfer is ongoing, the current data will be transferred
00510   *        and the Stream will be effectively disabled only after the transfer of
00511   *        this single data is finished.  
00512   * @retval HAL status
00513   */
00514 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
00515 {
00516   /* calculate DMA base and stream number */
00517   DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
00518   
00519   uint32_t tickstart = HAL_GetTick();
00520   
00521   if(hdma->State != HAL_DMA_STATE_BUSY)
00522   {
00523     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
00524     
00525     /* Process Unlocked */
00526     __HAL_UNLOCK(hdma);
00527     
00528     return HAL_ERROR;
00529   }
00530   else
00531   {
00532     /* Disable all the transfer interrupts */
00533     hdma->Instance->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
00534     hdma->Instance->FCR &= ~(DMA_IT_FE);
00535     
00536     if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
00537     {
00538       hdma->Instance->CR  &= ~(DMA_IT_HT);
00539     }
00540     
00541     /* Disable the stream */
00542     __HAL_DMA_DISABLE(hdma);
00543     
00544     /* Check if the DMA Stream is effectively disabled */
00545     while((hdma->Instance->CR & DMA_SxCR_EN) != RESET)
00546     {
00547       /* Check for the Timeout */
00548       if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
00549       {
00550         /* Update error code */
00551         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
00552         
00553         /* Change the DMA state */
00554         hdma->State = HAL_DMA_STATE_TIMEOUT;
00555         
00556         /* Process Unlocked */
00557         __HAL_UNLOCK(hdma);
00558         
00559         return HAL_TIMEOUT;
00560       }
00561     }
00562     
00563     /* Clear all interrupt flags at correct offset within the register */
00564     regs->IFCR = 0x3FU << hdma->StreamIndex;
00565     
00566     /* Change the DMA state*/
00567     hdma->State = HAL_DMA_STATE_READY;
00568     
00569     /* Process Unlocked */
00570     __HAL_UNLOCK(hdma);
00571   }
00572   return HAL_OK;
00573 }
00574 
00575 /**
00576   * @brief  Aborts the DMA Transfer in Interrupt mode.
00577   * @param  hdma   pointer to a DMA_HandleTypeDef structure that contains
00578   *                 the configuration information for the specified DMA Stream.
00579   * @retval HAL status
00580   */
00581 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
00582 {
00583   if(hdma->State != HAL_DMA_STATE_BUSY)
00584   {
00585     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
00586     return HAL_ERROR;
00587   }
00588   else
00589   {
00590     /* Set Abort State  */
00591     hdma->State = HAL_DMA_STATE_ABORT;
00592     
00593     /* Disable the stream */
00594     __HAL_DMA_DISABLE(hdma);
00595   }
00596 
00597   return HAL_OK;
00598 }
00599 
00600 /**
00601   * @brief  Polling for transfer complete.
00602   * @param  hdma          pointer to a DMA_HandleTypeDef structure that contains
00603   *                        the configuration information for the specified DMA Stream.
00604   * @param  CompleteLevel Specifies the DMA level complete.
00605   * @note   The polling mode is kept in this version for legacy. it is recommanded to use the IT model instead.
00606   *         This model could be used for debug purpose.
00607   * @note   The HAL_DMA_PollForTransfer API cannot be used in circular and double buffering mode (automatic circular mode). 
00608   * @param  Timeout       Timeout duration.
00609   * @retval HAL status
00610   */
00611 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
00612 {
00613   HAL_StatusTypeDef status = HAL_OK; 
00614   uint32_t mask_cpltlevel;
00615   uint32_t tickstart = HAL_GetTick(); 
00616   uint32_t tmpisr;
00617   
00618   /* calculate DMA base and stream number */
00619   DMA_Base_Registers *regs;
00620 
00621   if(HAL_DMA_STATE_BUSY != hdma->State)
00622   {
00623     /* No transfer ongoing */
00624     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
00625     __HAL_UNLOCK(hdma);
00626     return HAL_ERROR;
00627   }
00628 
00629   /* Polling mode not supported in circular mode and double buffering mode */
00630   if ((hdma->Instance->CR & DMA_SxCR_CIRC) != RESET)
00631   {
00632     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
00633     return HAL_ERROR;
00634   }
00635   
00636   /* Get the level transfer complete flag */
00637   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
00638   {
00639     /* Transfer Complete flag */
00640     mask_cpltlevel = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
00641   }
00642   else
00643   {
00644     /* Half Transfer Complete flag */
00645     mask_cpltlevel = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
00646   }
00647   
00648   regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
00649   tmpisr = regs->ISR;
00650   
00651   while(((tmpisr & mask_cpltlevel) == RESET) && ((hdma->ErrorCode & HAL_DMA_ERROR_TE) == RESET))
00652   {
00653     /* Check for the Timeout (Not applicable in circular mode)*/
00654     if(Timeout != HAL_MAX_DELAY)
00655     {
00656       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00657       {
00658         /* Update error code */
00659         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
00660         
00661         /* Change the DMA state */
00662         hdma->State = HAL_DMA_STATE_READY;
00663         
00664         /* Process Unlocked */
00665         __HAL_UNLOCK(hdma);
00666         
00667         return HAL_TIMEOUT;
00668       }
00669     }
00670 
00671     /* Get the ISR register value */
00672     tmpisr = regs->ISR;
00673 
00674     if((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
00675     {
00676       /* Update error code */
00677       hdma->ErrorCode |= HAL_DMA_ERROR_TE;
00678       
00679       /* Clear the transfer error flag */
00680       regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
00681     }
00682     
00683     if((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
00684     {
00685       /* Update error code */
00686       hdma->ErrorCode |= HAL_DMA_ERROR_FE;
00687       
00688       /* Clear the FIFO error flag */
00689       regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
00690     }
00691     
00692     if((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
00693     {
00694       /* Update error code */
00695       hdma->ErrorCode |= HAL_DMA_ERROR_DME;
00696       
00697       /* Clear the Direct Mode error flag */
00698       regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
00699     }
00700   }
00701   
00702   if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
00703   {
00704     if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
00705     {
00706       HAL_DMA_Abort(hdma);
00707     
00708       /* Clear the half transfer and transfer complete flags */
00709       regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
00710     
00711       /* Change the DMA state */
00712       hdma->State= HAL_DMA_STATE_READY;
00713 
00714       /* Process Unlocked */
00715       __HAL_UNLOCK(hdma);
00716 
00717       return HAL_ERROR;
00718    }
00719   }
00720   
00721   /* Get the level transfer complete flag */
00722   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
00723   {
00724     /* Clear the half transfer and transfer complete flags */
00725     regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
00726     
00727     hdma->State = HAL_DMA_STATE_READY;
00728     
00729     /* Process Unlocked */
00730     __HAL_UNLOCK(hdma);
00731   }
00732   else
00733   {
00734     /* Clear the half transfer and transfer complete flags */
00735     regs->IFCR = (DMA_FLAG_HTIF0_4) << hdma->StreamIndex;
00736   }
00737   
00738   return status;
00739 }
00740 
00741 /**
00742   * @brief  Handles DMA interrupt request.
00743   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
00744   *               the configuration information for the specified DMA Stream.  
00745   * @retval None
00746   */
00747 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
00748 {
00749   uint32_t tmpisr;
00750   __IO uint32_t count = 0U;
00751   uint32_t timeout = SystemCoreClock / 9600U;
00752 
00753   /* calculate DMA base and stream number */
00754   DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
00755 
00756   tmpisr = regs->ISR;
00757 
00758   /* Transfer Error Interrupt management ***************************************/
00759   if ((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
00760   {
00761     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
00762     {
00763       /* Disable the transfer error interrupt */
00764       hdma->Instance->CR  &= ~(DMA_IT_TE);
00765       
00766       /* Clear the transfer error flag */
00767       regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
00768       
00769       /* Update error code */
00770       hdma->ErrorCode |= HAL_DMA_ERROR_TE;
00771     }
00772   }
00773   /* FIFO Error Interrupt management ******************************************/
00774   if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
00775   {
00776     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
00777     {
00778       /* Clear the FIFO error flag */
00779       regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
00780 
00781       /* Update error code */
00782       hdma->ErrorCode |= HAL_DMA_ERROR_FE;
00783     }
00784   }
00785   /* Direct Mode Error Interrupt management ***********************************/
00786   if ((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
00787   {
00788     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
00789     {
00790       /* Clear the direct mode error flag */
00791       regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
00792 
00793       /* Update error code */
00794       hdma->ErrorCode |= HAL_DMA_ERROR_DME;
00795     }
00796   }
00797   /* Half Transfer Complete Interrupt management ******************************/
00798   if ((tmpisr & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET)
00799   {
00800     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
00801     {
00802       /* Clear the half transfer complete flag */
00803       regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
00804       
00805       /* Multi_Buffering mode enabled */
00806       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
00807       {
00808         /* Current memory buffer used is Memory 0 */
00809         if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
00810         {
00811           if(hdma->XferHalfCpltCallback != NULL)
00812           {
00813             /* Half transfer callback */
00814             hdma->XferHalfCpltCallback(hdma);
00815           }
00816         }
00817         /* Current memory buffer used is Memory 1 */
00818         else
00819         {
00820           if(hdma->XferM1HalfCpltCallback != NULL)
00821           {
00822             /* Half transfer callback */
00823             hdma->XferM1HalfCpltCallback(hdma);
00824           }
00825         }
00826       }
00827       else
00828       {
00829         /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
00830         if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
00831         {
00832           /* Disable the half transfer interrupt */
00833           hdma->Instance->CR  &= ~(DMA_IT_HT);
00834         }
00835         
00836         if(hdma->XferHalfCpltCallback != NULL)
00837         {
00838           /* Half transfer callback */
00839           hdma->XferHalfCpltCallback(hdma);
00840         }
00841       }
00842     }
00843   }
00844   /* Transfer Complete Interrupt management ***********************************/
00845   if ((tmpisr & (DMA_FLAG_TCIF0_4 << hdma->StreamIndex)) != RESET)
00846   {
00847     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
00848     {
00849       /* Clear the transfer complete flag */
00850       regs->IFCR = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
00851       
00852       if(HAL_DMA_STATE_ABORT == hdma->State)
00853       {
00854         /* Disable all the transfer interrupts */
00855         hdma->Instance->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
00856         hdma->Instance->FCR &= ~(DMA_IT_FE);
00857         
00858         if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
00859         {
00860           hdma->Instance->CR  &= ~(DMA_IT_HT);
00861         }
00862 
00863         /* Clear all interrupt flags at correct offset within the register */
00864         regs->IFCR = 0x3FU << hdma->StreamIndex;
00865 
00866         /* Change the DMA state */
00867         hdma->State = HAL_DMA_STATE_READY;
00868 
00869         /* Process Unlocked */
00870         __HAL_UNLOCK(hdma);
00871 
00872         if(hdma->XferAbortCallback != NULL)
00873         {
00874           hdma->XferAbortCallback(hdma);
00875         }
00876         return;
00877       }
00878 
00879       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != RESET)
00880       {
00881         /* Current memory buffer used is Memory 0 */
00882         if((hdma->Instance->CR & DMA_SxCR_CT) == RESET)
00883         {
00884           if(hdma->XferM1CpltCallback != NULL)
00885           {
00886             /* Transfer complete Callback for memory1 */
00887             hdma->XferM1CpltCallback(hdma);
00888           }
00889         }
00890         /* Current memory buffer used is Memory 1 */
00891         else
00892         {
00893           if(hdma->XferCpltCallback != NULL)
00894           {
00895             /* Transfer complete Callback for memory0 */
00896             hdma->XferCpltCallback(hdma);
00897           }
00898         }
00899       }
00900       /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
00901       else
00902       {
00903         if((hdma->Instance->CR & DMA_SxCR_CIRC) == RESET)
00904         {
00905           /* Disable the transfer complete interrupt */
00906           hdma->Instance->CR  &= ~(DMA_IT_TC);
00907 
00908           /* Change the DMA state */
00909           hdma->State = HAL_DMA_STATE_READY;
00910 
00911           /* Process Unlocked */
00912           __HAL_UNLOCK(hdma);
00913         }
00914 
00915         if(hdma->XferCpltCallback != NULL)
00916         {
00917           /* Transfer complete callback */
00918           hdma->XferCpltCallback(hdma);
00919         }
00920       }
00921     }
00922   }
00923   
00924   /* manage error case */
00925   if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
00926   {
00927     if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
00928     {
00929       hdma->State = HAL_DMA_STATE_ABORT;
00930 
00931       /* Disable the stream */
00932       __HAL_DMA_DISABLE(hdma);
00933 
00934       do
00935       {
00936         if (++count > timeout)
00937         {
00938           break;
00939         }
00940       }
00941       while((hdma->Instance->CR & DMA_SxCR_EN) != RESET);
00942 
00943       /* Change the DMA state */
00944       hdma->State = HAL_DMA_STATE_READY;
00945 
00946       /* Process Unlocked */
00947       __HAL_UNLOCK(hdma);
00948     }
00949 
00950     if(hdma->XferErrorCallback != NULL)
00951     {
00952       /* Transfer error callback */
00953       hdma->XferErrorCallback(hdma);
00954     }
00955   }
00956 }
00957 
00958 /**
00959   * @brief  Register callbacks
00960   * @param  hdma                 pointer to a DMA_HandleTypeDef structure that contains
00961   *                               the configuration information for the specified DMA Stream.
00962   * @param  CallbackID           User Callback identifer
00963   *                               a DMA_HandleTypeDef structure as parameter.
00964   * @param  pCallback            pointer to private callbacsk function which has pointer to 
00965   *                               a DMA_HandleTypeDef structure as parameter.
00966   * @retval HAL status
00967   */                      
00968 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
00969 {
00970 
00971   HAL_StatusTypeDef status = HAL_OK;
00972 
00973   /* Process locked */
00974   __HAL_LOCK(hdma);
00975 
00976   if(HAL_DMA_STATE_READY == hdma->State)
00977   {
00978     switch (CallbackID)
00979     {
00980     case  HAL_DMA_XFER_CPLT_CB_ID:
00981       hdma->XferCpltCallback = pCallback;
00982       break;
00983 
00984     case  HAL_DMA_XFER_HALFCPLT_CB_ID:
00985       hdma->XferHalfCpltCallback = pCallback;
00986       break;
00987 
00988     case  HAL_DMA_XFER_M1CPLT_CB_ID:
00989       hdma->XferM1CpltCallback = pCallback;
00990       break;
00991 
00992     case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
00993       hdma->XferM1HalfCpltCallback = pCallback;
00994       break;
00995 
00996     case  HAL_DMA_XFER_ERROR_CB_ID:
00997       hdma->XferErrorCallback = pCallback;
00998       break;
00999 
01000     case  HAL_DMA_XFER_ABORT_CB_ID:
01001       hdma->XferAbortCallback = pCallback;
01002       break;
01003 
01004     default:
01005       break;
01006     }
01007   }
01008   else
01009   {
01010     /* Return error status */
01011     status =  HAL_ERROR;
01012   }
01013 
01014   /* Release Lock */
01015   __HAL_UNLOCK(hdma);
01016   
01017   return status;
01018 }
01019 
01020 /**
01021   * @brief  UnRegister callbacks
01022   * @param  hdma                 pointer to a DMA_HandleTypeDef structure that contains
01023   *                               the configuration information for the specified DMA Stream.
01024   * @param  CallbackID           User Callback identifer
01025   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
01026   * @retval HAL status
01027   */              
01028 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
01029 {
01030   HAL_StatusTypeDef status = HAL_OK;
01031   
01032   /* Process locked */
01033   __HAL_LOCK(hdma);
01034   
01035   if(HAL_DMA_STATE_READY == hdma->State)
01036   {
01037     switch (CallbackID)
01038     {
01039     case  HAL_DMA_XFER_CPLT_CB_ID:
01040       hdma->XferCpltCallback = NULL;
01041       break;
01042       
01043     case  HAL_DMA_XFER_HALFCPLT_CB_ID:
01044       hdma->XferHalfCpltCallback = NULL;
01045       break;
01046       
01047     case  HAL_DMA_XFER_M1CPLT_CB_ID:
01048       hdma->XferM1CpltCallback = NULL;
01049       break;
01050       
01051     case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
01052       hdma->XferM1HalfCpltCallback = NULL;
01053       break;
01054       
01055     case  HAL_DMA_XFER_ERROR_CB_ID:
01056       hdma->XferErrorCallback = NULL;
01057       break;
01058       
01059     case  HAL_DMA_XFER_ABORT_CB_ID:
01060       hdma->XferAbortCallback = NULL;
01061       break; 
01062       
01063     case   HAL_DMA_XFER_ALL_CB_ID:
01064       hdma->XferCpltCallback = NULL;
01065       hdma->XferHalfCpltCallback = NULL;
01066       hdma->XferM1CpltCallback = NULL;
01067       hdma->XferM1HalfCpltCallback = NULL;
01068       hdma->XferErrorCallback = NULL;
01069       hdma->XferAbortCallback = NULL;
01070       break; 
01071       
01072     default:
01073       status = HAL_ERROR;
01074       break;
01075     }
01076   }
01077   else
01078   {
01079     status = HAL_ERROR;
01080   }
01081   
01082   /* Release Lock */
01083   __HAL_UNLOCK(hdma);
01084   
01085   return status;
01086 }
01087 
01088 /**
01089   * @}
01090   */
01091 
01092 /** @addtogroup DMA_Exported_Functions_Group3
01093   *
01094 @verbatim
01095  ===============================================================================
01096                     ##### State and Errors functions #####
01097  ===============================================================================
01098     [..]
01099     This subsection provides functions allowing to
01100       (+) Check the DMA state
01101       (+) Get error code
01102 
01103 @endverbatim
01104   * @{
01105   */
01106 
01107 /**
01108   * @brief  Returns the DMA state.
01109   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
01110   *               the configuration information for the specified DMA Stream.
01111   * @retval HAL state
01112   */
01113 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
01114 {
01115   return hdma->State;
01116 }
01117 
01118 /**
01119   * @brief  Return the DMA error code
01120   * @param  hdma  pointer to a DMA_HandleTypeDef structure that contains
01121   *              the configuration information for the specified DMA Stream.
01122   * @retval DMA Error Code
01123   */
01124 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
01125 {
01126   return hdma->ErrorCode;
01127 }
01128 
01129 /**
01130   * @}
01131   */
01132 
01133 /**
01134   * @}
01135   */
01136 
01137 /** @addtogroup DMA_Private_Functions
01138   * @{
01139   */
01140 
01141 /**
01142   * @brief  Sets the DMA Transfer parameter.
01143   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
01144   *                     the configuration information for the specified DMA Stream.
01145   * @param  SrcAddress The source memory Buffer address
01146   * @param  DstAddress The destination memory Buffer address
01147   * @param  DataLength The length of data to be transferred from source to destination
01148   * @retval HAL status
01149   */
01150 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
01151 {
01152   /* Clear DBM bit */
01153   hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
01154 
01155   /* Configure DMA Stream data length */
01156   hdma->Instance->NDTR = DataLength;
01157 
01158   /* Memory to Peripheral */
01159   if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
01160   {
01161     /* Configure DMA Stream destination address */
01162     hdma->Instance->PAR = DstAddress;
01163 
01164     /* Configure DMA Stream source address */
01165     hdma->Instance->M0AR = SrcAddress;
01166   }
01167   /* Peripheral to Memory */
01168   else
01169   {
01170     /* Configure DMA Stream source address */
01171     hdma->Instance->PAR = SrcAddress;
01172 
01173     /* Configure DMA Stream destination address */
01174     hdma->Instance->M0AR = DstAddress;
01175   }
01176 }
01177 
01178 /**
01179   * @brief  Returns the DMA Stream base address depending on stream number
01180   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
01181   *                     the configuration information for the specified DMA Stream. 
01182   * @retval Stream base address
01183   */
01184 static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
01185 {
01186   uint32_t stream_number = (((uint32_t)hdma->Instance & 0xFFU) - 16U) / 24U;
01187   
01188   /* lookup table for necessary bitshift of flags within status registers */
01189   static const uint8_t flagBitshiftOffset[8U] = {0U, 6U, 16U, 22U, 0U, 6U, 16U, 22U};
01190   hdma->StreamIndex = flagBitshiftOffset[stream_number];
01191   
01192   if (stream_number > 3U)
01193   {
01194     /* return pointer to HISR and HIFCR */
01195     hdma->StreamBaseAddress = (((uint32_t)hdma->Instance & (uint32_t)(~0x3FFU)) + 4U);
01196   }
01197   else
01198   {
01199     /* return pointer to LISR and LIFCR */
01200     hdma->StreamBaseAddress = ((uint32_t)hdma->Instance & (uint32_t)(~0x3FFU));
01201   }
01202   
01203   return hdma->StreamBaseAddress;
01204 }
01205 
01206 /**
01207   * @brief  Check compatibility between FIFO threshold level and size of the memory burst
01208   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
01209   *                     the configuration information for the specified DMA Stream. 
01210   * @retval HAL status
01211   */
01212 static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma)
01213 {
01214   HAL_StatusTypeDef status = HAL_OK;
01215   uint32_t tmp = hdma->Init.FIFOThreshold;
01216   
01217   /* Memory Data size equal to Byte */
01218   if(hdma->Init.MemDataAlignment == DMA_MDATAALIGN_BYTE)
01219   {
01220     switch (tmp)
01221     {
01222     case DMA_FIFO_THRESHOLD_1QUARTERFULL:
01223     case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
01224       if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
01225       {
01226         status = HAL_ERROR;
01227       }
01228       break;
01229     case DMA_FIFO_THRESHOLD_HALFFULL:
01230       if (hdma->Init.MemBurst == DMA_MBURST_INC16)
01231       {
01232         status = HAL_ERROR;
01233       }
01234       break;
01235     case DMA_FIFO_THRESHOLD_FULL:
01236       break;
01237     default:
01238       break;
01239     }
01240   }
01241   
01242   /* Memory Data size equal to Half-Word */
01243   else if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
01244   {
01245     switch (tmp)
01246     {
01247     case DMA_FIFO_THRESHOLD_1QUARTERFULL:
01248     case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
01249       status = HAL_ERROR;
01250       break;
01251     case DMA_FIFO_THRESHOLD_HALFFULL:
01252       if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
01253       {
01254         status = HAL_ERROR;
01255       }
01256       break;
01257     case DMA_FIFO_THRESHOLD_FULL:
01258       if (hdma->Init.MemBurst == DMA_MBURST_INC16)
01259       {
01260         status = HAL_ERROR;
01261       }
01262       break;   
01263     default:
01264       break;
01265     }
01266   }
01267   
01268   /* Memory Data size equal to Word */
01269   else
01270   {
01271     switch (tmp)
01272     {
01273     case DMA_FIFO_THRESHOLD_1QUARTERFULL:
01274     case DMA_FIFO_THRESHOLD_HALFFULL:
01275     case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
01276       status = HAL_ERROR;
01277       break;
01278     case DMA_FIFO_THRESHOLD_FULL:
01279       if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
01280       {
01281         status = HAL_ERROR;
01282       }
01283       break;
01284     default:
01285       break;
01286     }
01287   } 
01288   
01289   return status; 
01290 }
01291 
01292 /**
01293   * @}
01294   */
01295 
01296 #endif /* HAL_DMA_MODULE_ENABLED */
01297 /**
01298   * @}
01299   */
01300 
01301 /**
01302   * @}
01303   */
01304 
01305 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/