STM32F439xx HAL User Manual
|
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>© 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****/