TUKS MCU Introductory course / TUKS-COURSE-THERMOMETER

Fork of TUKS-COURSE-TIMER by TUKS MCU Introductory course

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_dma.c Source File

stm32l4xx_hal_dma.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_dma.c
00004   * @author  MCD Application Team
00005   * @version V1.5.1
00006   * @date    31-May-2016
00007   * @brief   DMA HAL module driver.
00008   *         This file provides firmware functions to manage the following
00009   *         functionalities of the Direct Memory Access (DMA) peripheral:
00010   *           + Initialization and de-initialization functions
00011   *           + IO operation functions
00012   *           + Peripheral State and errors functions
00013   @verbatim
00014   ==============================================================================
00015                         ##### How to use this driver #####
00016   ==============================================================================
00017   [..]
00018    (#) Enable and configure the peripheral to be connected to the DMA Channel
00019        (except for internal SRAM / FLASH memories: no initialization is 
00020        necessary). Please refer to the Reference manual for connection between peripherals
00021        and DMA requests.
00022 
00023    (#) For a given Channel, program the required configuration through the following parameters:
00024        Channel request, Transfer Direction, Source and Destination data formats,
00025        Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
00026        using HAL_DMA_Init() function.
00027 
00028    (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error 
00029        detection.
00030                     
00031    (#) Use HAL_DMA_Abort() function to abort the current transfer
00032                    
00033      -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.
00034      *** Polling mode IO operation ***
00035      =================================
00036     [..]
00037           (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
00038               address and destination address and the Length of data to be transferred
00039           (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
00040               case a fixed Timeout can be configured by User depending from his application.
00041 
00042      *** Interrupt mode IO operation ***
00043      ===================================
00044     [..]
00045           (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
00046           (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
00047           (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
00048               Source address and destination address and the Length of data to be transferred.
00049               In this case the DMA interrupt is configured
00050           (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
00051           (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
00052               add his own function by customization of function pointer XferCpltCallback and
00053               XferErrorCallback (i.e. a member of DMA handle structure).
00054 
00055      *** DMA HAL driver macros list ***
00056      ============================================= 
00057       [..]
00058        Below the list of most used macros in DMA HAL driver.
00059 
00060        (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
00061        (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
00062        (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
00063        (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
00064        (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
00065        (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
00066        (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not. 
00067 
00068      [..] 
00069       (@) You can refer to the DMA HAL driver header file for more useful macros  
00070 
00071   @endverbatim
00072   ******************************************************************************
00073   * @attention
00074   *
00075   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00076   *
00077   * Redistribution and use in source and binary forms, with or without modification,
00078   * are permitted provided that the following conditions are met:
00079   *   1. Redistributions of source code must retain the above copyright notice,
00080   *      this list of conditions and the following disclaimer.
00081   *   2. Redistributions in binary form must reproduce the above copyright notice,
00082   *      this list of conditions and the following disclaimer in the documentation
00083   *      and/or other materials provided with the distribution.
00084   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00085   *      may be used to endorse or promote products derived from this software
00086   *      without specific prior written permission.
00087   *
00088   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00089   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00090   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00091   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00092   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00093   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00094   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00095   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00096   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00097   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00098   *
00099   ******************************************************************************
00100   */
00101 
00102 /* Includes ------------------------------------------------------------------*/
00103 #include "stm32l4xx_hal.h"
00104 
00105 /** @addtogroup STM32L4xx_HAL_Driver
00106   * @{
00107   */
00108 
00109 /** @defgroup DMA DMA
00110   * @brief DMA HAL module driver
00111   * @{
00112   */
00113 
00114 #ifdef HAL_DMA_MODULE_ENABLED
00115 
00116 /* Private typedef -----------------------------------------------------------*/
00117 /* Private define ------------------------------------------------------------*/
00118 /* Private macro -------------------------------------------------------------*/
00119 /* Private variables ---------------------------------------------------------*/
00120 /* Private function prototypes -----------------------------------------------*/
00121 /** @defgroup DMA_Private_Functions DMA Private Functions
00122   * @{
00123   */
00124 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
00125 /**
00126   * @}
00127   */
00128 
00129 /* Exported functions ---------------------------------------------------------*/
00130 
00131 /** @defgroup DMA_Exported_Functions DMA Exported Functions
00132   * @{
00133   */
00134 
00135 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
00136  *  @brief   Initialization and de-initialization functions 
00137  *
00138 @verbatim
00139  ===============================================================================
00140              ##### Initialization and de-initialization functions  #####
00141  ===============================================================================
00142     [..]
00143     This section provides functions allowing to initialize the DMA Channel source
00144     and destination addresses, incrementation and data sizes, transfer direction, 
00145     circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
00146     [..]
00147     The HAL_DMA_Init() function follows the DMA configuration procedures as described in
00148     reference manual.  
00149 
00150 @endverbatim
00151   * @{
00152   */
00153 
00154 /**
00155   * @brief  Initialize the DMA according to the specified
00156   *         parameters in the DMA_InitTypeDef and initialize the associated handle.
00157   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
00158   *               the configuration information for the specified DMA Channel.
00159   * @retval HAL status
00160   */
00161 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
00162 {
00163   uint32_t tmp = 0;
00164   
00165   /* Check the DMA handle allocation */
00166   if(hdma == NULL)
00167   {
00168     return HAL_ERROR;
00169   }
00170 
00171   /* Check the parameters */
00172   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
00173   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
00174   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
00175   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
00176   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
00177   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
00178   assert_param(IS_DMA_MODE(hdma->Init.Mode));
00179   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
00180   if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
00181   {
00182     assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));
00183   }
00184   
00185   /* calculation of the channel index */
00186   if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
00187   {
00188     /* DMA1 */
00189     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
00190     hdma->DmaBaseAddress = DMA1;
00191   }
00192   else 
00193   {
00194     /* DMA2 */
00195     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
00196     hdma->DmaBaseAddress = DMA2;
00197   }
00198     
00199   /* Change DMA peripheral state */
00200   hdma->State = HAL_DMA_STATE_BUSY;
00201 
00202   /* Get the CR register value */
00203   tmp = hdma->Instance->CCR;
00204 
00205   /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */
00206   tmp &= ((uint32_t)~(DMA_CCR_PL    | DMA_CCR_MSIZE  | DMA_CCR_PSIZE  | \
00207                       DMA_CCR_MINC  | DMA_CCR_PINC   | DMA_CCR_CIRC   | \
00208                       DMA_CCR_DIR));
00209 
00210   /* Prepare the DMA Channel configuration */
00211   tmp |=  hdma->Init.Direction        |
00212           hdma->Init.PeriphInc           | hdma->Init.MemInc           |
00213           hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
00214           hdma->Init.Mode                | hdma->Init.Priority;
00215 
00216   /* Write to DMA Channel CR register */
00217   hdma->Instance->CCR = tmp;
00218 
00219   /* Set request selection */
00220   if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
00221   {
00222     /* Write to DMA channel selection register */
00223     if (DMA1 == hdma->DmaBaseAddress)
00224     {
00225       /* Reset request selection for DMA1 Channelx */
00226       DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << hdma->ChannelIndex);
00227 
00228       /* Configure request selection for DMA1 Channelx */
00229       DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex)); 
00230     }
00231     else /* DMA2 */
00232     {
00233       /* Reset request selection for DMA2 Channelx */
00234       DMA2_CSELR->CSELR &= ~(DMA_CSELR_C1S << hdma->ChannelIndex);
00235      
00236       /* Configure request selection for DMA2 Channelx */
00237       DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex)); 
00238     }
00239   }
00240 
00241   /* Clean callbacks */
00242   hdma->XferCpltCallback = NULL;
00243   hdma->XferHalfCpltCallback = NULL;
00244   hdma->XferErrorCallback = NULL;
00245   hdma->XferAbortCallback = NULL;
00246 
00247   /* Initialise the error code */
00248   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00249 
00250   /* Initialize the DMA state*/
00251   hdma->State  = HAL_DMA_STATE_READY;
00252 
00253   /* Allocate lock resource and initialize it */
00254   hdma->Lock = HAL_UNLOCKED;
00255   
00256   return HAL_OK;
00257 }
00258 
00259 /**
00260   * @brief  DeInitialize the DMA peripheral.
00261   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
00262   *               the configuration information for the specified DMA Channel.
00263   * @retval HAL status
00264   */
00265 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
00266 {
00267   /* Check the DMA handle allocation */
00268   if(hdma == NULL)
00269   {
00270     return HAL_ERROR;
00271   }
00272   
00273   /* Check the parameters */
00274   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
00275 
00276   /* Disable the selected DMA Channelx */
00277   __HAL_DMA_DISABLE(hdma);
00278 
00279   /* Reset DMA Channel control register */
00280   hdma->Instance->CCR  = 0;
00281 
00282   /* Calculation of the channel index */
00283   if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
00284   {
00285     /* DMA1 */
00286     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
00287     hdma->DmaBaseAddress = DMA1;
00288   }
00289   else 
00290   {
00291     /* DMA2 */
00292     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
00293     hdma->DmaBaseAddress = DMA2;
00294   }
00295 
00296 
00297   /* Clear all flags */
00298   hdma->DmaBaseAddress->IFCR |= ((DMA_ISR_GIF1) << (hdma->ChannelIndex));
00299   
00300   /* Reset DMA channel selection register */
00301   if (DMA1 == hdma->DmaBaseAddress)
00302   {
00303     /* DMA1 */
00304     DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex)); 
00305   }
00306   else  
00307   {
00308     /* DMA2 */
00309     DMA2_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex)); 
00310   }
00311 
00312   /* Initialize the error code */
00313   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00314 
00315   /* Initialize the DMA state */
00316   hdma->State = HAL_DMA_STATE_RESET;
00317 
00318   /* Release Lock */
00319   __HAL_UNLOCK(hdma);
00320 
00321   return HAL_OK;
00322 }
00323 
00324 /**
00325   * @}
00326   */
00327 
00328 /** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
00329  *  @brief   Input and Output operation functions
00330  *
00331 @verbatim
00332  ===============================================================================
00333                       #####  IO operation functions  #####
00334  ===============================================================================
00335     [..]  This section provides functions allowing to:
00336       (+) Configure the source, destination address and data length and Start DMA transfer
00337       (+) Configure the source, destination address and data length and
00338           Start DMA transfer with interrupt
00339       (+) Abort DMA transfer
00340       (+) Poll for transfer complete
00341       (+) Handle DMA interrupt request
00342 
00343 @endverbatim
00344   * @{
00345   */
00346 
00347 /**
00348   * @brief  Start the DMA Transfer.
00349   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
00350   *               the configuration information for the specified DMA Channel.
00351   * @param  SrcAddress: The source memory Buffer address
00352   * @param  DstAddress: The destination memory Buffer address
00353   * @param  DataLength: The length of data to be transferred from source to destination
00354   * @retval HAL status
00355   */
00356 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
00357 {
00358   HAL_StatusTypeDef status = HAL_OK;
00359 
00360   /* Check the parameters */
00361   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00362 
00363   /* Process locked */
00364   __HAL_LOCK(hdma);
00365 
00366   if(HAL_DMA_STATE_READY == hdma->State)
00367   {
00368     /* Change DMA peripheral state */
00369     hdma->State = HAL_DMA_STATE_BUSY;
00370     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00371             
00372     /* Disable the peripheral */
00373     __HAL_DMA_DISABLE(hdma);
00374     
00375     /* Configure the source, destination address and the data length & clear flags*/
00376     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
00377     
00378     /* Enable the Peripheral */
00379     __HAL_DMA_ENABLE(hdma);
00380   }
00381   else
00382   {
00383    /* Process Unlocked */
00384    __HAL_UNLOCK(hdma);  
00385    status = HAL_BUSY;
00386   }  
00387   return status;
00388 }
00389 
00390 /**
00391   * @brief  Start the DMA Transfer with interrupt enabled.
00392   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
00393   *               the configuration information for the specified DMA Channel.
00394   * @param  SrcAddress: The source memory Buffer address
00395   * @param  DstAddress: The destination memory Buffer address
00396   * @param  DataLength: The length of data to be transferred from source to destination
00397   * @retval HAL status
00398   */
00399 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
00400 {
00401   HAL_StatusTypeDef status = HAL_OK;
00402 
00403   /* Check the parameters */
00404   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00405 
00406   /* Process locked */
00407   __HAL_LOCK(hdma);
00408   
00409   if(HAL_DMA_STATE_READY == hdma->State)
00410   {
00411     /* Change DMA peripheral state */
00412     hdma->State = HAL_DMA_STATE_BUSY;
00413     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00414     
00415     /* Disable the peripheral */
00416     __HAL_DMA_DISABLE(hdma);
00417     
00418     /* Configure the source, destination address and the data length & clear flags*/
00419     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
00420     
00421     /* Enable the transfer complete interrupt */
00422     /* Enable the transfer Error interrupt */
00423     if(NULL != hdma->XferHalfCpltCallback )
00424     {
00425       /* Enable the Half transfer complete interrupt as well */
00426       __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
00427     }
00428     else
00429     {
00430       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
00431       __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
00432     }
00433     /* Enable the Peripheral */
00434     __HAL_DMA_ENABLE(hdma);
00435   }
00436   else
00437   {      
00438     /* Process Unlocked */
00439     __HAL_UNLOCK(hdma); 
00440 
00441     /* Remain BUSY */
00442     status = HAL_BUSY;
00443   }    
00444   return status;
00445 }
00446 
00447 /**
00448   * @brief  Abort the DMA Transfer.
00449   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
00450   *               the configuration information for the specified DMA Channel.
00451     * @retval HAL status
00452   */
00453 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
00454 {
00455   HAL_StatusTypeDef status = HAL_OK;
00456   
00457   if(HAL_DMA_STATE_BUSY != hdma->State)
00458   {
00459     /* no transfer ongoing */
00460     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
00461         
00462     status = HAL_ERROR;
00463   }
00464   else
00465   {
00466     /* Disable DMA IT */
00467     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
00468     
00469     /* Disable the channel */
00470     __HAL_DMA_DISABLE(hdma);
00471     
00472     /* Clear all flags */
00473     hdma->DmaBaseAddress->IFCR = ((DMA_ISR_GIF1) << (hdma->ChannelIndex));
00474 
00475     /* Change the DMA state */
00476     hdma->State = HAL_DMA_STATE_READY;
00477 
00478     /* Process Unlocked */
00479     __HAL_UNLOCK(hdma);      
00480   }
00481   return status; 
00482 }
00483 
00484 /**
00485   * @brief  Aborts the DMA Transfer in Interrupt mode.
00486   * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
00487   *                 the configuration information for the specified DMA Stream.
00488   * @retval HAL status
00489   */
00490 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
00491 {  
00492   HAL_StatusTypeDef status = HAL_OK;
00493   
00494   if(HAL_DMA_STATE_BUSY != hdma->State)
00495   {
00496     /* no transfer ongoing */
00497     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
00498         
00499     status = HAL_ERROR;
00500   }
00501   else
00502   { 
00503     /* Disable DMA IT */
00504     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
00505     
00506     /* Disable the channel */
00507     __HAL_DMA_DISABLE(hdma);
00508     
00509     /* Clear all flags */
00510     hdma->DmaBaseAddress->IFCR |= ((DMA_ISR_GIF1) << (hdma->ChannelIndex));
00511     
00512     /* Change the DMA state */
00513     hdma->State = HAL_DMA_STATE_READY;
00514 
00515     /* Process Unlocked */
00516     __HAL_UNLOCK(hdma);
00517     
00518     /* Call User Abort callback */ 
00519     if(hdma->XferAbortCallback != NULL)
00520     {
00521       hdma->XferAbortCallback(hdma);
00522     } 
00523   }
00524   return status;
00525 }
00526 
00527 /**
00528   * @brief  Polling for transfer complete.
00529   * @param  hdma:    pointer to a DMA_HandleTypeDef structure that contains
00530   *                  the configuration information for the specified DMA Channel.
00531   * @param  CompleteLevel: Specifies the DMA level complete.
00532   * @param  Timeout:       Timeout duration.
00533   * @retval HAL status
00534   */
00535 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
00536 {
00537   uint32_t temp;
00538   uint32_t tickstart = 0;
00539 
00540   if(HAL_DMA_STATE_BUSY != hdma->State)
00541   {
00542     /* no transfer ongoing */
00543     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
00544 
00545     return HAL_ERROR;
00546   }
00547 
00548   /* Polling mode not supported in circular mode */
00549   if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
00550   {
00551     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
00552     return HAL_ERROR;
00553   }
00554   
00555   /* Get the level transfer complete flag */
00556   if (HAL_DMA_FULL_TRANSFER == CompleteLevel)
00557   {
00558     /* Transfer Complete flag */
00559     temp = DMA_FLAG_TC1 << hdma->ChannelIndex;
00560   }
00561   else
00562   {
00563     /* Half Transfer Complete flag */
00564     temp = DMA_FLAG_HT1 << hdma->ChannelIndex;
00565   }
00566 
00567   /* Get tick */
00568   tickstart = HAL_GetTick();
00569 
00570   while(RESET == (hdma->DmaBaseAddress->ISR & temp))     
00571   {
00572     if((RESET != (hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << hdma->ChannelIndex))))    
00573     {
00574       /* When a DMA transfer error occurs */
00575       /* A hardware clear of its EN bits is performed */
00576       /* Clear all flags */
00577       hdma->DmaBaseAddress->IFCR |= ((DMA_ISR_GIF1) << (hdma->ChannelIndex));
00578 
00579       /* Update error code */
00580       hdma->ErrorCode = HAL_DMA_ERROR_TE;
00581 
00582       /* Change the DMA state */
00583       hdma->State= HAL_DMA_STATE_READY;
00584 
00585       /* Process Unlocked */
00586       __HAL_UNLOCK(hdma);
00587 
00588       return HAL_ERROR;
00589     }
00590     /* Check for the Timeout */
00591     if(Timeout != HAL_MAX_DELAY)
00592     {
00593       if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
00594       {
00595         /* Update error code */
00596         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
00597 
00598         /* Change the DMA state */
00599         hdma->State = HAL_DMA_STATE_READY;
00600         
00601         /* Process Unlocked */
00602         __HAL_UNLOCK(hdma);
00603 
00604         return HAL_ERROR;
00605       }
00606     }
00607   }
00608 
00609   if(HAL_DMA_FULL_TRANSFER == CompleteLevel)
00610   {
00611     /* Clear the transfer complete flag */
00612     hdma->DmaBaseAddress->IFCR  |= (DMA_FLAG_TC1 << hdma->ChannelIndex);
00613 
00614     /* The selected Channelx EN bit is cleared (DMA is disabled and
00615     all transfers are complete) */
00616     hdma->State = HAL_DMA_STATE_READY;
00617   }
00618   else
00619   {
00620     /* Clear the half transfer complete flag */
00621     hdma->DmaBaseAddress->IFCR |= (DMA_FLAG_HT1 << hdma->ChannelIndex);
00622   }
00623   
00624   /* Process unlocked */
00625   __HAL_UNLOCK(hdma);  
00626 
00627   return HAL_OK;
00628 }
00629 
00630 /**
00631   * @brief  Handle DMA interrupt request.
00632   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
00633   *               the configuration information for the specified DMA Channel.
00634   * @retval None
00635   */
00636 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
00637 {
00638   uint32_t flag_it = hdma->DmaBaseAddress->ISR;
00639   uint32_t source_it = hdma->Instance->CCR;
00640   
00641   /* Half Transfer Complete Interrupt management ******************************/
00642   if ((RESET != (flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_HT)))
00643   {
00644       /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
00645       if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
00646       {
00647         /* Disable the half transfer interrupt */
00648         __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
00649       }
00650       /* Clear the half transfer complete flag */
00651       hdma->DmaBaseAddress->IFCR  |= (DMA_ISR_HTIF1 << hdma->ChannelIndex);
00652 
00653       /* DMA peripheral state is not updated in Half Transfer */
00654       /* but in Transfer Complete case */
00655 
00656      if(hdma->XferHalfCpltCallback != NULL)
00657       {
00658         /* Half transfer callback */
00659         hdma->XferHalfCpltCallback(hdma);
00660       }
00661   }
00662   
00663   /* Transfer Complete Interrupt management ***********************************/
00664   else if ((RESET != (flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TC)))
00665   {
00666     if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
00667     {
00668       /* Disable the transfer complete and error interrupt */
00669       __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
00670 
00671       /* Change the DMA state */
00672       hdma->State = HAL_DMA_STATE_READY;
00673     }
00674     /* Clear the transfer complete flag */
00675     hdma->DmaBaseAddress->IFCR |= (DMA_ISR_TCIF1 << hdma->ChannelIndex);
00676 
00677     /* Process Unlocked */
00678     __HAL_UNLOCK(hdma);
00679 
00680     if(hdma->XferCpltCallback != NULL)
00681     {
00682       /* Transfer complete callback */
00683       hdma->XferCpltCallback(hdma);
00684     }
00685   }
00686 
00687   /* Transfer Error Interrupt management **************************************/
00688   else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
00689   {
00690     /* When a DMA transfer error occurs */
00691     /* A hardware clear of its EN bits is performed */
00692     /* Disable ALL DMA IT */
00693     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
00694 
00695     /* Clear all flags */
00696     hdma->DmaBaseAddress->IFCR  |= (DMA_ISR_GIF1 << hdma->ChannelIndex);
00697 
00698     /* Update error code */
00699     hdma->ErrorCode = HAL_DMA_ERROR_TE;
00700 
00701     /* Change the DMA state */
00702     hdma->State = HAL_DMA_STATE_READY;
00703 
00704     /* Process Unlocked */
00705     __HAL_UNLOCK(hdma);
00706 
00707     if (hdma->XferErrorCallback != NULL)
00708     {
00709       /* Transfer error callback */
00710       hdma->XferErrorCallback(hdma);
00711     }
00712   }
00713   return;
00714 }
00715 
00716 /**
00717   * @brief  Register callbacks
00718   * @param  hdma:                 pointer to a DMA_HandleTypeDef structure that contains
00719   *                               the configuration information for the specified DMA Stream.
00720   * @param  CallbackID:           User Callback identifer
00721   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
00722   * @param  pCallback:            pointer to private callbacsk function which has pointer to 
00723   *                               a DMA_HandleTypeDef structure as parameter.
00724   * @retval HAL status
00725   */                          
00726 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
00727 {
00728   HAL_StatusTypeDef status = HAL_OK;
00729   
00730   /* Process locked */
00731   __HAL_LOCK(hdma);
00732   
00733   if(HAL_DMA_STATE_READY == hdma->State)
00734   {
00735     switch (CallbackID)
00736     {
00737      case  HAL_DMA_XFER_CPLT_CB_ID:
00738            hdma->XferCpltCallback = pCallback;
00739            break;
00740        
00741      case  HAL_DMA_XFER_HALFCPLT_CB_ID:
00742            hdma->XferHalfCpltCallback = pCallback;
00743            break;         
00744 
00745      case  HAL_DMA_XFER_ERROR_CB_ID:
00746            hdma->XferErrorCallback = pCallback;
00747            break;         
00748            
00749      case  HAL_DMA_XFER_ABORT_CB_ID:
00750            hdma->XferAbortCallback = pCallback;
00751            break; 
00752            
00753      default:
00754            status = HAL_ERROR;
00755            break;
00756     }
00757   }
00758   else
00759   {
00760     status = HAL_ERROR;
00761   } 
00762   
00763   /* Release Lock */
00764   __HAL_UNLOCK(hdma);
00765   
00766   return status;
00767 }
00768 
00769 /**
00770   * @brief  UnRegister callbacks
00771   * @param  hdma:                 pointer to a DMA_HandleTypeDef structure that contains
00772   *                               the configuration information for the specified DMA Stream.
00773   * @param  CallbackID:           User Callback identifer
00774   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
00775   * @retval HAL status
00776   */              
00777 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
00778 {
00779   HAL_StatusTypeDef status = HAL_OK;
00780 
00781     /* Process locked */
00782   __HAL_LOCK(hdma);
00783   
00784   if(HAL_DMA_STATE_READY == hdma->State)
00785   {
00786     switch (CallbackID)
00787     {
00788      case  HAL_DMA_XFER_CPLT_CB_ID:
00789            hdma->XferCpltCallback = NULL;
00790            break;
00791        
00792      case  HAL_DMA_XFER_HALFCPLT_CB_ID:
00793            hdma->XferHalfCpltCallback = NULL;
00794            break;         
00795 
00796      case  HAL_DMA_XFER_ERROR_CB_ID:
00797            hdma->XferErrorCallback = NULL;
00798            break;         
00799            
00800      case  HAL_DMA_XFER_ABORT_CB_ID:
00801            hdma->XferAbortCallback = NULL;
00802            break; 
00803      
00804     case   HAL_DMA_XFER_ALL_CB_ID:
00805            hdma->XferCpltCallback = NULL;
00806            hdma->XferHalfCpltCallback = NULL;
00807            hdma->XferErrorCallback = NULL;
00808            hdma->XferAbortCallback = NULL;
00809            break; 
00810      
00811     default:
00812            status = HAL_ERROR;
00813            break;
00814     }
00815   }
00816   else
00817   {
00818     status = HAL_ERROR;
00819   } 
00820   
00821   /* Release Lock */
00822   __HAL_UNLOCK(hdma);
00823   
00824   return status;
00825 }
00826 
00827 /**
00828   * @}
00829   */
00830 
00831 
00832 
00833 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
00834  *  @brief    Peripheral State and Errors functions
00835  *
00836 @verbatim
00837  ===============================================================================
00838             ##### Peripheral State and Errors functions #####
00839  ===============================================================================  
00840     [..]
00841     This subsection provides functions allowing to
00842       (+) Check the DMA state
00843       (+) Get error code
00844 
00845 @endverbatim
00846   * @{
00847   */
00848 
00849 /**
00850   * @brief  Return the DMA hande state.
00851   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
00852   *               the configuration information for the specified DMA Channel.
00853   * @retval HAL state
00854   */
00855 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
00856 {
00857   /* Return DMA handle state */
00858   return hdma->State;
00859 }
00860 
00861 /**
00862   * @brief  Return the DMA error code.
00863   * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains
00864   *              the configuration information for the specified DMA Channel.
00865   * @retval DMA Error Code
00866   */
00867 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
00868 {
00869   return hdma->ErrorCode;
00870 }
00871 
00872 /**
00873   * @}
00874   */
00875 
00876 /**
00877   * @}
00878   */
00879 
00880 /** @addtogroup DMA_Private_Functions
00881   * @{
00882   */
00883 
00884 /**
00885   * @brief  Sets the DMA Transfer parameter.
00886   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
00887   *                     the configuration information for the specified DMA Channel.
00888   * @param  SrcAddress: The source memory Buffer address
00889   * @param  DstAddress: The destination memory Buffer address
00890   * @param  DataLength: The length of data to be transferred from source to destination
00891   * @retval HAL status
00892   */
00893 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
00894 {
00895   /* Clear all flags */
00896   hdma->DmaBaseAddress->IFCR  |= (DMA_ISR_GIF1 << hdma->ChannelIndex);
00897   
00898   /* Configure DMA Channel data length */
00899   hdma->Instance->CNDTR = DataLength;
00900 
00901   /* Peripheral to Memory */
00902   if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
00903   {
00904     /* Configure DMA Channel destination address */
00905     hdma->Instance->CPAR = DstAddress;
00906 
00907     /* Configure DMA Channel source address */
00908     hdma->Instance->CMAR = SrcAddress;
00909   }
00910   /* Memory to Peripheral */
00911   else
00912   {
00913     /* Configure DMA Channel source address */
00914     hdma->Instance->CPAR = SrcAddress;
00915 
00916     /* Configure DMA Channel destination address */
00917     hdma->Instance->CMAR = DstAddress;
00918   }
00919 }
00920 
00921 /**
00922   * @}
00923   */
00924 
00925 /**
00926   * @}
00927   */
00928 
00929 #endif /* HAL_DMA_MODULE_ENABLED */
00930 /**
00931   * @}
00932   */
00933 
00934 /**
00935   * @}
00936   */
00937 
00938 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/