STM32F439xx 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</center></h2>
00029   *
00030   * Redistribution and use in source and binary forms, with or without modification,
00031   * are permitted provided that the following conditions are met:
00032   *   1. Redistributions of source code must retain the above copyright notice,
00033   *      this list of conditions and the following disclaimer.
00034   *   2. Redistributions in binary form must reproduce the above copyright notice,
00035   *      this list of conditions and the following disclaimer in the documentation
00036   *      and/or other materials provided with the distribution.
00037   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00038   *      may be used to endorse or promote products derived from this software
00039   *      without specific prior written permission.
00040   *
00041   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00042   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00043   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00044   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00045   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00046   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00047   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00048   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00049   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00050   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00051   *
00052   ******************************************************************************
00053   */
00054 
00055 /* Includes ------------------------------------------------------------------*/
00056 #include "stm32f4xx_hal.h"
00057 
00058 /** @addtogroup STM32F4xx_HAL_Driver
00059   * @{
00060   */
00061 
00062 /** @defgroup DMAEx DMAEx
00063   * @brief DMA Extended HAL module driver
00064   * @{
00065   */
00066 
00067 #ifdef HAL_DMA_MODULE_ENABLED
00068 
00069 /* Private types -------------------------------------------------------------*/
00070 /* Private variables ---------------------------------------------------------*/
00071 /* Private Constants ---------------------------------------------------------*/
00072 /* Private macros ------------------------------------------------------------*/
00073 /* Private functions ---------------------------------------------------------*/
00074 /** @addtogroup DMAEx_Private_Functions
00075   * @{
00076   */
00077 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
00078 /**
00079   * @}
00080   */
00081 
00082 /* Exported functions ---------------------------------------------------------*/
00083 
00084 /** @addtogroup DMAEx_Exported_Functions
00085   * @{
00086   */
00087 
00088 
00089 /** @addtogroup DMAEx_Exported_Functions_Group1
00090   *
00091 @verbatim   
00092  ===============================================================================
00093                 #####  Extended features functions  #####
00094  ===============================================================================  
00095     [..]  This section provides functions allowing to:
00096       (+) Configure the source, destination address and data length and 
00097           Start MultiBuffer DMA transfer
00098       (+) Configure the source, destination address and data length and 
00099           Start MultiBuffer DMA transfer with interrupt
00100       (+) Change on the fly the memory0 or memory1 address.
00101       
00102 @endverbatim
00103   * @{
00104   */
00105 
00106 
00107 /**
00108   * @brief  Starts the multi_buffer DMA Transfer.
00109   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00110   *                     the configuration information for the specified DMA Stream.  
00111   * @param  SrcAddress The source memory Buffer address
00112   * @param  DstAddress The destination memory Buffer address
00113   * @param  SecondMemAddress The second memory Buffer address in case of multi buffer Transfer  
00114   * @param  DataLength The length of data to be transferred from source to destination
00115   * @retval HAL status
00116   */
00117 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
00118 {
00119   HAL_StatusTypeDef status = HAL_OK;
00120   
00121   /* Check the parameters */
00122   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00123   
00124   /* Memory-to-memory transfer not supported in double buffering mode */
00125   if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
00126   {
00127     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
00128     status = HAL_ERROR;
00129   }
00130   else
00131   {
00132     /* Process Locked */
00133     __HAL_LOCK(hdma);
00134     
00135     if(HAL_DMA_STATE_READY == hdma->State)
00136     {
00137       /* Change DMA peripheral state */
00138       hdma->State = HAL_DMA_STATE_BUSY; 
00139       
00140       /* Enable the double buffer mode */
00141       hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;
00142       
00143       /* Configure DMA Stream destination address */
00144       hdma->Instance->M1AR = SecondMemAddress;
00145       
00146       /* Configure the source, destination address and the data length */
00147       DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
00148       
00149       /* Enable the peripheral */
00150       __HAL_DMA_ENABLE(hdma);
00151     }
00152     else
00153     {
00154       /* Return error status */
00155       status = HAL_BUSY;
00156     }
00157   }
00158   return status;
00159 }
00160 
00161 /**
00162   * @brief  Starts the multi_buffer DMA Transfer with interrupt enabled.
00163   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00164   *                     the configuration information for the specified DMA Stream.  
00165   * @param  SrcAddress The source memory Buffer address
00166   * @param  DstAddress The destination memory Buffer address
00167   * @param  SecondMemAddress The second memory Buffer address in case of multi buffer Transfer  
00168   * @param  DataLength The length of data to be transferred from source to destination
00169   * @retval HAL status
00170   */
00171 HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
00172 {
00173   HAL_StatusTypeDef status = HAL_OK;
00174   
00175   /* Check the parameters */
00176   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
00177   
00178   /* Memory-to-memory transfer not supported in double buffering mode */
00179   if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
00180   {
00181     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
00182     return HAL_ERROR;
00183   }
00184   
00185   /* Check callback functions */
00186   if ((NULL == hdma->XferCpltCallback) || (NULL == hdma->XferM1CpltCallback) || (NULL == hdma->XferErrorCallback))
00187   {
00188     hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
00189     return HAL_ERROR;
00190   }
00191   
00192   /* Process locked */
00193   __HAL_LOCK(hdma);
00194   
00195   if(HAL_DMA_STATE_READY == hdma->State)
00196   {
00197     /* Change DMA peripheral state */
00198     hdma->State = HAL_DMA_STATE_BUSY;
00199     
00200     /* Initialize the error code */
00201     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
00202     
00203     /* Enable the Double buffer mode */
00204     hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;
00205     
00206     /* Configure DMA Stream destination address */
00207     hdma->Instance->M1AR = SecondMemAddress;
00208     
00209     /* Configure the source, destination address and the data length */
00210     DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); 
00211     
00212     /* Clear all flags */
00213     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
00214     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
00215     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
00216     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
00217     __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
00218 
00219     /* Enable Common interrupts*/
00220     hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
00221     hdma->Instance->FCR |= DMA_IT_FE;
00222     
00223     if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
00224     {
00225       hdma->Instance->CR  |= DMA_IT_HT;
00226     }
00227     
00228     /* Enable the peripheral */
00229     __HAL_DMA_ENABLE(hdma); 
00230   }
00231   else
00232   {     
00233     /* Process unlocked */
00234     __HAL_UNLOCK(hdma);   
00235     
00236     /* Return error status */
00237     status = HAL_BUSY;
00238   }  
00239   return status; 
00240 }
00241 
00242 /**
00243   * @brief  Change the memory0 or memory1 address on the fly.
00244   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00245   *                     the configuration information for the specified DMA Stream.  
00246   * @param  Address    The new address
00247   * @param  memory     the memory to be changed, This parameter can be one of 
00248   *                     the following values:
00249   *                      MEMORY0 /
00250   *                      MEMORY1
00251   * @note   The MEMORY0 address can be changed only when the current transfer use
00252   *         MEMORY1 and the MEMORY1 address can be changed only when the current 
00253   *         transfer use MEMORY0.
00254   * @retval HAL status
00255   */
00256 HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory)
00257 {
00258   if(memory == MEMORY0)
00259   {
00260     /* change the memory0 address */
00261     hdma->Instance->M0AR = Address;
00262   }
00263   else
00264   {
00265     /* change the memory1 address */
00266     hdma->Instance->M1AR = Address;
00267   }
00268 
00269   return HAL_OK;
00270 }
00271 
00272 /**
00273   * @}
00274   */
00275 
00276 /**
00277   * @}
00278   */
00279 
00280 /** @addtogroup DMAEx_Private_Functions
00281   * @{
00282   */
00283 
00284 /**
00285   * @brief  Set the DMA Transfer parameter.
00286   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
00287   *                     the configuration information for the specified DMA Stream.  
00288   * @param  SrcAddress The source memory Buffer address
00289   * @param  DstAddress The destination memory Buffer address
00290   * @param  DataLength The length of data to be transferred from source to destination
00291   * @retval HAL status
00292   */
00293 static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
00294 {  
00295   /* Configure DMA Stream data length */
00296   hdma->Instance->NDTR = DataLength;
00297   
00298   /* Peripheral to Memory */
00299   if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
00300   {   
00301     /* Configure DMA Stream destination address */
00302     hdma->Instance->PAR = DstAddress;
00303     
00304     /* Configure DMA Stream source address */
00305     hdma->Instance->M0AR = SrcAddress;
00306   }
00307   /* Memory to Peripheral */
00308   else
00309   {
00310     /* Configure DMA Stream source address */
00311     hdma->Instance->PAR = SrcAddress;
00312     
00313     /* Configure DMA Stream destination address */
00314     hdma->Instance->M0AR = DstAddress;
00315   }
00316 }
00317 
00318 /**
00319   * @}
00320   */
00321 
00322 #endif /* HAL_DMA_MODULE_ENABLED */
00323 /**
00324   * @}
00325   */
00326 
00327 /**
00328   * @}
00329   */
00330 
00331 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/