STM32F479xx HAL User Manual
stm32f4xx_hal_dma_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_dma_ex.c
00004   * @author  MCD Application Team
00005   * @brief   DMA Extension HAL module driver
00006   *         This file provides firmware functions to manage the following 
00007   *         functionalities of the DMA Extension peripheral:
00008   *           + Extended features functions
00009   *
00010   @verbatim
00011   ==============================================================================
00012                         ##### How to use this driver #####
00013   ==============================================================================
00014   [..]
00015   The DMA Extension HAL driver can be used as follows:
00016    (#) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function
00017        for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode.
00018                    
00019      -@-  In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.
00020      -@-  When Multi (Double) Buffer mode is enabled the, transfer is circular by default.
00021      -@-  In Multi (Double) buffer mode, it is possible to update the base address for 
00022           the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled. 
00023   
00024   @endverbatim
00025   ******************************************************************************
00026   * @attention
00027   *
00028   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
00029   * All rights reserved.</center></h2>
00030   *
00031   * This software component is licensed by ST under BSD 3-Clause license,
00032   * the "License"; You may not use this file except in compliance with the
00033   * License. You may obtain a copy of the License at:
00034   *                        opensource.org/licenses/BSD-3-Clause
00035   *
00036   ******************************************************************************
00037   */
00038 
00039 /* Includes ------------------------------------------------------------------*/
00040 #include "stm32f4xx_hal.h"
00041 
00042 /** @addtogroup STM32F4xx_HAL_Driver
00043   * @{
00044   */
00045 
00046 /** @defgroup DMAEx DMAEx
00047   * @brief DMA Extended HAL module driver
00048   * @{
00049   */
00050 
00051 #ifdef HAL_DMA_MODULE_ENABLED
00052 
00053 /* Private types -------------------------------------------------------------*/
00054 /* Private variables ---------------------------------------------------------*/
00055 /* Private Constants ---------------------------------------------------------*/
00056 /* Private macros ------------------------------------------------------------*/
00057 /* Private functions ---------------------------------------------------------*/
00058 /** @addtogroup DMAEx_Private_Functions
00059   * @{
00060   */
00061 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
00062 /**
00063   * @}
00064   */
00065 
00066 /* Exported functions ---------------------------------------------------------*/
00067 
00068 /** @addtogroup DMAEx_Exported_Functions
00069   * @{
00070   */
00071 
00072 
00073 /** @addtogroup DMAEx_Exported_Functions_Group1
00074   *
00075 @verbatim   
00076  ===============================================================================
00077                 #####  Extended features functions  #####
00078  ===============================================================================  
00079     [..]  This section provides functions allowing to:
00080       (+) Configure the source, destination address and data length and 
00081           Start MultiBuffer DMA transfer
00082       (+) Configure the source, destination address and data length and 
00083           Start MultiBuffer DMA transfer with interrupt
00084       (+) Change on the fly the memory0 or memory1 address.
00085       
00086 @endverbatim
00087   * @{
00088   */
00089 
00090 
00091 /**
00092   * @brief  Starts the multi_buffer DMA Transfer.
00093   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00094   *                     the configuration information for the specified DMA Stream.  
00095   * @param  SrcAddress The source memory Buffer address
00096   * @param  DstAddress The destination memory Buffer address
00097   * @param  SecondMemAddress The second memory Buffer address in case of multi buffer Transfer  
00098   * @param  DataLength The length of data to be transferred from source to destination
00099   * @retval HAL status
00100   */
00101 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
00102 {
00103   HAL_StatusTypeDef status = HAL_OK;
00104   
00105   /* Check the parameters */
00106   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00107   
00108   /* Memory-to-memory transfer not supported in double buffering mode */
00109   if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
00110   {
00111     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
00112     status = HAL_ERROR;
00113   }
00114   else
00115   {
00116     /* Process Locked */
00117     __HAL_LOCK(hdma);
00118     
00119     if(HAL_DMA_STATE_READY == hdma->State)
00120     {
00121       /* Change DMA peripheral state */
00122       hdma->State = HAL_DMA_STATE_BUSY; 
00123       
00124       /* Enable the double buffer mode */
00125       hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;
00126       
00127       /* Configure DMA Stream destination address */
00128       hdma->Instance->M1AR = SecondMemAddress;
00129       
00130       /* Configure the source, destination address and the data length */
00131       DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
00132       
00133       /* Enable the peripheral */
00134       __HAL_DMA_ENABLE(hdma);
00135     }
00136     else
00137     {
00138       /* Return error status */
00139       status = HAL_BUSY;
00140     }
00141   }
00142   return status;
00143 }
00144 
00145 /**
00146   * @brief  Starts the multi_buffer DMA Transfer with interrupt enabled.
00147   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00148   *                     the configuration information for the specified DMA Stream.  
00149   * @param  SrcAddress The source memory Buffer address
00150   * @param  DstAddress The destination memory Buffer address
00151   * @param  SecondMemAddress The second memory Buffer address in case of multi buffer Transfer  
00152   * @param  DataLength The length of data to be transferred from source to destination
00153   * @retval HAL status
00154   */
00155 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
00156 {
00157   HAL_StatusTypeDef status = HAL_OK;
00158   
00159   /* Check the parameters */
00160   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00161   
00162   /* Memory-to-memory transfer not supported in double buffering mode */
00163   if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
00164   {
00165     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
00166     return HAL_ERROR;
00167   }
00168   
00169   /* Check callback functions */
00170   if ((NULL == hdma->XferCpltCallback) || (NULL == hdma->XferM1CpltCallback) || (NULL == hdma->XferErrorCallback))
00171   {
00172     hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
00173     return HAL_ERROR;
00174   }
00175   
00176   /* Process locked */
00177   __HAL_LOCK(hdma);
00178   
00179   if(HAL_DMA_STATE_READY == hdma->State)
00180   {
00181     /* Change DMA peripheral state */
00182     hdma->State = HAL_DMA_STATE_BUSY;
00183     
00184     /* Initialize the error code */
00185     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00186     
00187     /* Enable the Double buffer mode */
00188     hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;
00189     
00190     /* Configure DMA Stream destination address */
00191     hdma->Instance->M1AR = SecondMemAddress;
00192     
00193     /* Configure the source, destination address and the data length */
00194     DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); 
00195     
00196     /* Clear all flags */
00197     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
00198     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
00199     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
00200     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
00201     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
00202 
00203     /* Enable Common interrupts*/
00204     hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
00205     hdma->Instance->FCR |= DMA_IT_FE;
00206     
00207     if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
00208     {
00209       hdma->Instance->CR  |= DMA_IT_HT;
00210     }
00211     
00212     /* Enable the peripheral */
00213     __HAL_DMA_ENABLE(hdma); 
00214   }
00215   else
00216   {     
00217     /* Process unlocked */
00218     __HAL_UNLOCK(hdma);   
00219     
00220     /* Return error status */
00221     status = HAL_BUSY;
00222   }  
00223   return status; 
00224 }
00225 
00226 /**
00227   * @brief  Change the memory0 or memory1 address on the fly.
00228   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00229   *                     the configuration information for the specified DMA Stream.  
00230   * @param  Address    The new address
00231   * @param  memory     the memory to be changed, This parameter can be one of 
00232   *                     the following values:
00233   *                      MEMORY0 /
00234   *                      MEMORY1
00235   * @note   The MEMORY0 address can be changed only when the current transfer use
00236   *         MEMORY1 and the MEMORY1 address can be changed only when the current 
00237   *         transfer use MEMORY0.
00238   * @retval HAL status
00239   */
00240 HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory)
00241 {
00242   if(memory == MEMORY0)
00243   {
00244     /* change the memory0 address */
00245     hdma->Instance->M0AR = Address;
00246   }
00247   else
00248   {
00249     /* change the memory1 address */
00250     hdma->Instance->M1AR = Address;
00251   }
00252 
00253   return HAL_OK;
00254 }
00255 
00256 /**
00257   * @}
00258   */
00259 
00260 /**
00261   * @}
00262   */
00263 
00264 /** @addtogroup DMAEx_Private_Functions
00265   * @{
00266   */
00267 
00268 /**
00269   * @brief  Set the DMA Transfer parameter.
00270   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00271   *                     the configuration information for the specified DMA Stream.  
00272   * @param  SrcAddress The source memory Buffer address
00273   * @param  DstAddress The destination memory Buffer address
00274   * @param  DataLength The length of data to be transferred from source to destination
00275   * @retval HAL status
00276   */
00277 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
00278 {  
00279   /* Configure DMA Stream data length */
00280   hdma->Instance->NDTR = DataLength;
00281   
00282   /* Peripheral to Memory */
00283   if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
00284   {   
00285     /* Configure DMA Stream destination address */
00286     hdma->Instance->PAR = DstAddress;
00287     
00288     /* Configure DMA Stream source address */
00289     hdma->Instance->M0AR = SrcAddress;
00290   }
00291   /* Memory to Peripheral */
00292   else
00293   {
00294     /* Configure DMA Stream source address */
00295     hdma->Instance->PAR = SrcAddress;
00296     
00297     /* Configure DMA Stream destination address */
00298     hdma->Instance->M0AR = DstAddress;
00299   }
00300 }
00301 
00302 /**
00303   * @}
00304   */
00305 
00306 #endif /* HAL_DMA_MODULE_ENABLED */
00307 /**
00308   * @}
00309   */
00310 
00311 /**
00312   * @}
00313   */
00314 
00315 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/