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