Hal Drivers for L4

Dependents:   BSP OneHopeOnePrayer FINAL_AUDIO_RECORD AudioDemo

Fork of STM32L4xx_HAL_Driver by Senior Design: Sound Monitor

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