| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 | /**  ******************************************************************************  * @file    stm32f7xx_hal_dma_ex.c  * @author  MCD Application Team  * @brief   DMA Extension HAL module driver  *         This file provides firmware functions to manage the following   *         functionalities of the DMA Extension peripheral:  *           + Extended features functions  *  @verbatim  ==============================================================================                        ##### How to use this driver #####  ==============================================================================  [..]  The DMA Extension HAL driver can be used as follows:   (+) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function       for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode.     -@-  In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.     -@-  When Multi (Double) Buffer mode is enabled, the transfer is circular by default.     -@-  In Multi (Double) buffer mode, it is possible to update the base address for           the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled.    @endverbatim  ******************************************************************************  * @attention  *  * Copyright (c) 2017 STMicroelectronics.  * All rights reserved.  *  * This software is licensed under terms that can be found in the LICENSE file in  * the root directory of this software component.  * If no LICENSE file comes with this software, it is provided AS-IS.  *  ******************************************************************************  *//* Includes ------------------------------------------------------------------*/#include "stm32f7xx_hal.h"/** @addtogroup STM32F7xx_HAL_Driver  * @{  *//** @defgroup DMAEx DMAEx  * @brief DMA Extended HAL module driver  * @{  */#ifdef HAL_DMA_MODULE_ENABLED/* Private types -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private Constants ---------------------------------------------------------*//* Private macros ------------------------------------------------------------*//* Private functions ---------------------------------------------------------*//** @addtogroup DMAEx_Private_Functions  * @{  */static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);/**  * @}  *//* Exported functions ---------------------------------------------------------*//** @addtogroup DMAEx_Exported_Functions  * @{  *//** @addtogroup DMAEx_Exported_Functions_Group1  *@verbatim ===============================================================================                #####  Extended features functions  ##### ===============================================================================      [..]  This section provides functions allowing to:      (+) Configure the source, destination address and data length and           Start MultiBuffer DMA transfer      (+) Configure the source, destination address and data length and           Start MultiBuffer DMA transfer with interrupt      (+) Change on the fly the memory0 or memory1 address.      @endverbatim  * @{  *//**  * @brief  Starts the multi_buffer DMA Transfer.  * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains  *                     the configuration information for the specified DMA Stream.    * @param  SrcAddress The source memory Buffer address  * @param  DstAddress The destination memory Buffer address  * @param  SecondMemAddress The second memory Buffer address in case of multi buffer Transfer    * @param  DataLength The length of data to be transferred from source to destination  * @retval HAL status  */HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength){  HAL_StatusTypeDef status = HAL_OK;    /* Check the parameters */  assert_param(IS_DMA_BUFFER_SIZE(DataLength));    /* Memory-to-memory transfer not supported in double buffering mode */  if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)  {    hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;    status = HAL_ERROR;  }  else  {    /* Process Locked */    __HAL_LOCK(hdma);        if(HAL_DMA_STATE_READY == hdma->State)    {      /* Change DMA peripheral state */      hdma->State = HAL_DMA_STATE_BUSY;             /* Enable the double buffer mode */      hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;            /* Configure DMA Stream destination address */      hdma->Instance->M1AR = SecondMemAddress;            /* Configure the source, destination address and the data length */      DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);            /* Enable the peripheral */      __HAL_DMA_ENABLE(hdma);    }    else    {      /* Return error status */      status = HAL_BUSY;    }  }  return status;}/**  * @brief  Starts the multi_buffer DMA Transfer with interrupt enabled.  * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains  *                     the configuration information for the specified DMA Stream.    * @param  SrcAddress The source memory Buffer address  * @param  DstAddress The destination memory Buffer address  * @param  SecondMemAddress The second memory Buffer address in case of multi buffer Transfer    * @param  DataLength The length of data to be transferred from source to destination  * @retval HAL status  */HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength){  HAL_StatusTypeDef status = HAL_OK;    /* Check the parameters */  assert_param(IS_DMA_BUFFER_SIZE(DataLength));    /* Memory-to-memory transfer not supported in double buffering mode */  if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)  {    hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;    return HAL_ERROR;  }    /* Process locked */  __HAL_LOCK(hdma);    if(HAL_DMA_STATE_READY == hdma->State)  {    /* Change DMA peripheral state */    hdma->State = HAL_DMA_STATE_BUSY;        /* Initialize the error code */    hdma->ErrorCode = HAL_DMA_ERROR_NONE;        /* Enable the Double buffer mode */    hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;        /* Configure DMA Stream destination address */    hdma->Instance->M1AR = SecondMemAddress;        /* Configure the source, destination address and the data length */    DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);         /* Clear all flags */    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));        /* Enable Common interrupts*/    hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;    hdma->Instance->FCR |= DMA_IT_FE;        if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))    {      hdma->Instance->CR  |= DMA_IT_HT;    }        /* Enable the peripheral */    __HAL_DMA_ENABLE(hdma);   }  else  {         /* Process unlocked */    __HAL_UNLOCK(hdma);	          /* Return error status */    status = HAL_BUSY;  }    return status; }/**  * @brief  Change the memory0 or memory1 address on the fly.  * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains  *                     the configuration information for the specified DMA Stream.    * @param  Address    The new address  * @param  memory     the memory to be changed, This parameter can be one of   *                     the following values:  *                      MEMORY0 /  *                      MEMORY1  * @note   The MEMORY0 address can be changed only when the current transfer use  *         MEMORY1 and the MEMORY1 address can be changed only when the current   *         transfer use MEMORY0.  * @retval HAL status  */HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory){  if(memory == MEMORY0)  {    /* change the memory0 address */    hdma->Instance->M0AR = Address;  }  else  {    /* change the memory1 address */    hdma->Instance->M1AR = Address;  }    return HAL_OK;}/**  * @}  *//**  * @}  *//** @addtogroup DMAEx_Private_Functions  * @{  *//**  * @brief  Set the DMA Transfer parameter.  * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains  *                     the configuration information for the specified DMA Stream.    * @param  SrcAddress The source memory Buffer address  * @param  DstAddress The destination memory Buffer address  * @param  DataLength The length of data to be transferred from source to destination  * @retval HAL status  */static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength){  /* Configure DMA Stream data length */  hdma->Instance->NDTR = DataLength;    /* Peripheral to Memory */  if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)  {    /* Configure DMA Stream destination address */    hdma->Instance->PAR = DstAddress;        /* Configure DMA Stream source address */    hdma->Instance->M0AR = SrcAddress;  }  /* Memory to Peripheral */  else  {    /* Configure DMA Stream source address */    hdma->Instance->PAR = SrcAddress;        /* Configure DMA Stream destination address */    hdma->Instance->M0AR = DstAddress;  }}/**  * @}  */#endif /* HAL_DMA_MODULE_ENABLED *//**  * @}  *//**  * @}  */
 |