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