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