Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c (27727B)
1 /** 2 ****************************************************************************** 3 * @file stm32f1xx_hal_dma.c 4 * @author MCD Application Team 5 * @brief DMA HAL module driver. 6 * This file provides firmware functions to manage the following 7 * functionalities of the Direct Memory Access (DMA) peripheral: 8 * + Initialization and de-initialization functions 9 * + IO operation functions 10 * + Peripheral State and errors functions 11 @verbatim 12 ============================================================================== 13 ##### How to use this driver ##### 14 ============================================================================== 15 [..] 16 (#) Enable and configure the peripheral to be connected to the DMA Channel 17 (except for internal SRAM / FLASH memories: no initialization is 18 necessary). Please refer to the Reference manual for connection between peripherals 19 and DMA requests. 20 21 (#) For a given Channel, program the required configuration through the following parameters: 22 Channel request, Transfer Direction, Source and Destination data formats, 23 Circular or Normal mode, Channel Priority level, Source and Destination Increment mode 24 using HAL_DMA_Init() function. 25 26 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error 27 detection. 28 29 (#) Use HAL_DMA_Abort() function to abort the current transfer 30 31 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed. 32 *** Polling mode IO operation *** 33 ================================= 34 [..] 35 (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source 36 address and destination address and the Length of data to be transferred 37 (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this 38 case a fixed Timeout can be configured by User depending from his application. 39 40 *** Interrupt mode IO operation *** 41 =================================== 42 [..] 43 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority() 44 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() 45 (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of 46 Source address and destination address and the Length of data to be transferred. 47 In this case the DMA interrupt is configured 48 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine 49 (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can 50 add his own function by customization of function pointer XferCpltCallback and 51 XferErrorCallback (i.e. a member of DMA handle structure). 52 53 *** DMA HAL driver macros list *** 54 ============================================= 55 [..] 56 Below the list of most used macros in DMA HAL driver. 57 58 (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel. 59 (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel. 60 (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags. 61 (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags. 62 (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts. 63 (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts. 64 (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not. 65 66 [..] 67 (@) You can refer to the DMA HAL driver header file for more useful macros 68 69 @endverbatim 70 ****************************************************************************** 71 * @attention 72 * 73 * Copyright (c) 2016 STMicroelectronics. 74 * All rights reserved. 75 * 76 * This software is licensed under terms that can be found in the LICENSE file in 77 * the root directory of this software component. 78 * If no LICENSE file comes with this software, it is provided AS-IS. 79 * 80 ****************************************************************************** 81 */ 82 83 /* Includes ------------------------------------------------------------------*/ 84 #include "stm32f1xx_hal.h" 85 86 /** @addtogroup STM32F1xx_HAL_Driver 87 * @{ 88 */ 89 90 /** @defgroup DMA DMA 91 * @brief DMA HAL module driver 92 * @{ 93 */ 94 95 #ifdef HAL_DMA_MODULE_ENABLED 96 97 /* Private typedef -----------------------------------------------------------*/ 98 /* Private define ------------------------------------------------------------*/ 99 /* Private macro -------------------------------------------------------------*/ 100 /* Private variables ---------------------------------------------------------*/ 101 /* Private function prototypes -----------------------------------------------*/ 102 /** @defgroup DMA_Private_Functions DMA Private Functions 103 * @{ 104 */ 105 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, 106 uint32_t DstAddress, uint32_t DataLength); 107 /** 108 * @} 109 */ 110 111 /* Exported functions ---------------------------------------------------------*/ 112 113 /** @defgroup DMA_Exported_Functions DMA Exported Functions 114 * @{ 115 */ 116 117 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions 118 * @brief Initialization and de-initialization functions 119 * 120 @verbatim 121 =============================================================================== 122 ##### Initialization and de-initialization functions ##### 123 =============================================================================== 124 [..] 125 This section provides functions allowing to initialize the DMA Channel source 126 and destination addresses, incrementation and data sizes, transfer direction, 127 circular/normal mode selection, memory-to-memory mode selection and Channel priority value. 128 [..] 129 The HAL_DMA_Init() function follows the DMA configuration procedures as described in 130 reference manual. 131 132 @endverbatim 133 * @{ 134 */ 135 136 /** 137 * @brief Initialize the DMA according to the specified 138 * parameters in the DMA_InitTypeDef and initialize the associated handle. 139 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 140 * the configuration information for the specified DMA Channel. 141 * @retval HAL status 142 */ 143 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) 144 { 145 uint32_t tmp = 0U; 146 147 /* Check the DMA handle allocation */ 148 if (hdma == NULL) { 149 return HAL_ERROR; 150 } 151 152 /* Check the parameters */ 153 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); 154 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); 155 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc)); 156 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc)); 157 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment)); 158 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment)); 159 assert_param(IS_DMA_MODE(hdma->Init.Mode)); 160 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); 161 162 #if defined (DMA2) 163 /* calculation of the channel index */ 164 if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1)) 165 { 166 /* DMA1 */ 167 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2; 168 hdma->DmaBaseAddress = DMA1; 169 } 170 else 171 { 172 /* DMA2 */ 173 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2; 174 hdma->DmaBaseAddress = DMA2; 175 } 176 #else 177 /* DMA1 */ 178 hdma->ChannelIndex = (((uint32_t) hdma->Instance - (uint32_t) DMA1_Channel1) 179 / ((uint32_t) DMA1_Channel2 - (uint32_t) DMA1_Channel1)) << 2; 180 hdma->DmaBaseAddress = DMA1; 181 #endif /* DMA2 */ 182 183 /* Change DMA peripheral state */ 184 hdma->State = HAL_DMA_STATE_BUSY; 185 186 /* Get the CR register value */ 187 tmp = hdma->Instance->CCR; 188 189 /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ 190 tmp &= ((uint32_t) ~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | 191 DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | 192 DMA_CCR_DIR)); 193 194 /* Prepare the DMA Channel configuration */ 195 tmp |= hdma->Init.Direction | hdma->Init.PeriphInc | hdma->Init.MemInc 196 | hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment 197 | hdma->Init.Mode | hdma->Init.Priority; 198 199 /* Write to DMA Channel CR register */ 200 hdma->Instance->CCR = tmp; 201 202 /* Initialise the error code */ 203 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 204 205 /* Initialize the DMA state*/ 206 hdma->State = HAL_DMA_STATE_READY; 207 /* Allocate lock resource and initialize it */ 208 hdma->Lock = HAL_UNLOCKED; 209 210 return HAL_OK; 211 } 212 213 /** 214 * @brief DeInitialize the DMA peripheral. 215 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 216 * the configuration information for the specified DMA Channel. 217 * @retval HAL status 218 */ 219 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) 220 { 221 /* Check the DMA handle allocation */ 222 if (hdma == NULL) { 223 return HAL_ERROR; 224 } 225 226 /* Check the parameters */ 227 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); 228 229 /* Disable the selected DMA Channelx */ 230 __HAL_DMA_DISABLE(hdma); 231 232 /* Reset DMA Channel control register */ 233 hdma->Instance->CCR = 0U; 234 235 /* Reset DMA Channel Number of Data to Transfer register */ 236 hdma->Instance->CNDTR = 0U; 237 238 /* Reset DMA Channel peripheral address register */ 239 hdma->Instance->CPAR = 0U; 240 241 /* Reset DMA Channel memory address register */ 242 hdma->Instance->CMAR = 0U; 243 244 #if defined (DMA2) 245 /* calculation of the channel index */ 246 if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1)) 247 { 248 /* DMA1 */ 249 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2; 250 hdma->DmaBaseAddress = DMA1; 251 } 252 else 253 { 254 /* DMA2 */ 255 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2; 256 hdma->DmaBaseAddress = DMA2; 257 } 258 #else 259 /* DMA1 */ 260 hdma->ChannelIndex = (((uint32_t) hdma->Instance - (uint32_t) DMA1_Channel1) 261 / ((uint32_t) DMA1_Channel2 - (uint32_t) DMA1_Channel1)) << 2; 262 hdma->DmaBaseAddress = DMA1; 263 #endif /* DMA2 */ 264 265 /* Clear all flags */ 266 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex)); 267 268 /* Clean all callbacks */ 269 hdma->XferCpltCallback = NULL; 270 hdma->XferHalfCpltCallback = NULL; 271 hdma->XferErrorCallback = NULL; 272 hdma->XferAbortCallback = NULL; 273 274 /* Reset the error code */ 275 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 276 277 /* Reset the DMA state */ 278 hdma->State = HAL_DMA_STATE_RESET; 279 280 /* Release Lock */ 281 __HAL_UNLOCK(hdma); 282 283 return HAL_OK; 284 } 285 286 /** 287 * @} 288 */ 289 290 /** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions 291 * @brief Input and Output operation functions 292 * 293 @verbatim 294 =============================================================================== 295 ##### IO operation functions ##### 296 =============================================================================== 297 [..] This section provides functions allowing to: 298 (+) Configure the source, destination address and data length and Start DMA transfer 299 (+) Configure the source, destination address and data length and 300 Start DMA transfer with interrupt 301 (+) Abort DMA transfer 302 (+) Poll for transfer complete 303 (+) Handle DMA interrupt request 304 305 @endverbatim 306 * @{ 307 */ 308 309 /** 310 * @brief Start the DMA Transfer. 311 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 312 * the configuration information for the specified DMA Channel. 313 * @param SrcAddress: The source memory Buffer address 314 * @param DstAddress: The destination memory Buffer address 315 * @param DataLength: The length of data to be transferred from source to destination 316 * @retval HAL status 317 */ 318 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, 319 uint32_t DstAddress, uint32_t DataLength) 320 { 321 HAL_StatusTypeDef status = HAL_OK; 322 323 /* Check the parameters */ 324 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 325 326 /* Process locked */ 327 __HAL_LOCK(hdma); 328 329 if (HAL_DMA_STATE_READY == hdma->State) { 330 /* Change DMA peripheral state */ 331 hdma->State = HAL_DMA_STATE_BUSY; 332 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 333 334 /* Disable the peripheral */ 335 __HAL_DMA_DISABLE(hdma); 336 337 /* Configure the source, destination address and the data length & clear flags*/ 338 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); 339 340 /* Enable the Peripheral */ 341 __HAL_DMA_ENABLE(hdma); 342 } else { 343 /* Process Unlocked */ 344 __HAL_UNLOCK(hdma); 345 status = HAL_BUSY; 346 } 347 return status; 348 } 349 350 /** 351 * @brief Start the DMA Transfer with interrupt enabled. 352 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 353 * the configuration information for the specified DMA Channel. 354 * @param SrcAddress: The source memory Buffer address 355 * @param DstAddress: The destination memory Buffer address 356 * @param DataLength: The length of data to be transferred from source to destination 357 * @retval HAL status 358 */ 359 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, 360 uint32_t DstAddress, uint32_t DataLength) 361 { 362 HAL_StatusTypeDef status = HAL_OK; 363 364 /* Check the parameters */ 365 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 366 367 /* Process locked */ 368 __HAL_LOCK(hdma); 369 370 if (HAL_DMA_STATE_READY == hdma->State) { 371 /* Change DMA peripheral state */ 372 hdma->State = HAL_DMA_STATE_BUSY; 373 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 374 375 /* Disable the peripheral */ 376 __HAL_DMA_DISABLE(hdma); 377 378 /* Configure the source, destination address and the data length & clear flags*/ 379 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); 380 381 /* Enable the transfer complete interrupt */ 382 /* Enable the transfer Error interrupt */ 383 if (NULL != hdma->XferHalfCpltCallback) { 384 /* Enable the Half transfer complete interrupt as well */ 385 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 386 } else { 387 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); 388 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE)); 389 } 390 /* Enable the Peripheral */ 391 __HAL_DMA_ENABLE(hdma); 392 } else { 393 /* Process Unlocked */ 394 __HAL_UNLOCK(hdma); 395 396 /* Remain BUSY */ 397 status = HAL_BUSY; 398 } 399 return status; 400 } 401 402 /** 403 * @brief Abort the DMA Transfer. 404 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 405 * the configuration information for the specified DMA Channel. 406 * @retval HAL status 407 */ 408 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) 409 { 410 HAL_StatusTypeDef status = HAL_OK; 411 412 if (hdma->State != HAL_DMA_STATE_BUSY) { 413 /* no transfer ongoing */ 414 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 415 416 /* Process Unlocked */ 417 __HAL_UNLOCK(hdma); 418 419 return HAL_ERROR; 420 } else 421 422 { 423 /* Disable DMA IT */ 424 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 425 426 /* Disable the channel */ 427 __HAL_DMA_DISABLE(hdma); 428 429 /* Clear all flags */ 430 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); 431 } 432 /* Change the DMA state */ 433 hdma->State = HAL_DMA_STATE_READY; 434 435 /* Process Unlocked */ 436 __HAL_UNLOCK(hdma); 437 438 return status; 439 } 440 441 /** 442 * @brief Aborts the DMA Transfer in Interrupt mode. 443 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains 444 * the configuration information for the specified DMA Channel. 445 * @retval HAL status 446 */ 447 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma) 448 { 449 HAL_StatusTypeDef status = HAL_OK; 450 451 if (HAL_DMA_STATE_BUSY != hdma->State) { 452 /* no transfer ongoing */ 453 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 454 455 status = HAL_ERROR; 456 } else { 457 /* Disable DMA IT */ 458 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 459 460 /* Disable the channel */ 461 __HAL_DMA_DISABLE(hdma); 462 463 /* Clear all flags */ 464 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma)); 465 466 /* Change the DMA state */ 467 hdma->State = HAL_DMA_STATE_READY; 468 469 /* Process Unlocked */ 470 __HAL_UNLOCK(hdma); 471 472 /* Call User Abort callback */ 473 if (hdma->XferAbortCallback != NULL) { 474 hdma->XferAbortCallback(hdma); 475 } 476 } 477 return status; 478 } 479 480 /** 481 * @brief Polling for transfer complete. 482 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 483 * the configuration information for the specified DMA Channel. 484 * @param CompleteLevel: Specifies the DMA level complete. 485 * @param Timeout: Timeout duration. 486 * @retval HAL status 487 */ 488 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, 489 uint32_t CompleteLevel, uint32_t Timeout) 490 { 491 uint32_t temp; 492 uint32_t tickstart = 0U; 493 494 if (HAL_DMA_STATE_BUSY != hdma->State) { 495 /* no transfer ongoing */ 496 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 497 __HAL_UNLOCK(hdma); 498 return HAL_ERROR; 499 } 500 501 /* Polling mode not supported in circular mode */ 502 if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC)) { 503 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; 504 return HAL_ERROR; 505 } 506 507 /* Get the level transfer complete flag */ 508 if (CompleteLevel == HAL_DMA_FULL_TRANSFER) { 509 /* Transfer Complete flag */ 510 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma); 511 } else { 512 /* Half Transfer Complete flag */ 513 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma); 514 } 515 516 /* Get tick */ 517 tickstart = HAL_GetTick(); 518 519 while (__HAL_DMA_GET_FLAG(hdma, temp) == RESET) { 520 if ((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) 521 != RESET)) { 522 /* When a DMA transfer error occurs */ 523 /* A hardware clear of its EN bits is performed */ 524 /* Clear all flags */ 525 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); 526 527 /* Update error code */ 528 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE); 529 530 /* Change the DMA state */ 531 hdma->State = HAL_DMA_STATE_READY; 532 533 /* Process Unlocked */ 534 __HAL_UNLOCK(hdma); 535 536 return HAL_ERROR; 537 } 538 /* Check for the Timeout */ 539 if (Timeout != HAL_MAX_DELAY) { 540 if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) { 541 /* Update error code */ 542 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT); 543 544 /* Change the DMA state */ 545 hdma->State = HAL_DMA_STATE_READY; 546 547 /* Process Unlocked */ 548 __HAL_UNLOCK(hdma); 549 550 return HAL_ERROR; 551 } 552 } 553 } 554 555 if (CompleteLevel == HAL_DMA_FULL_TRANSFER) { 556 /* Clear the transfer complete flag */ 557 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 558 559 /* The selected Channelx EN bit is cleared (DMA is disabled and 560 all transfers are complete) */ 561 hdma->State = HAL_DMA_STATE_READY; 562 } else { 563 /* Clear the half transfer complete flag */ 564 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); 565 } 566 567 /* Process unlocked */ 568 __HAL_UNLOCK(hdma); 569 570 return HAL_OK; 571 } 572 573 /** 574 * @brief Handles DMA interrupt request. 575 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 576 * the configuration information for the specified DMA Channel. 577 * @retval None 578 */ 579 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) 580 { 581 uint32_t flag_it = hdma->DmaBaseAddress->ISR; 582 uint32_t source_it = hdma->Instance->CCR; 583 584 /* Half Transfer Complete Interrupt management ******************************/ 585 if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) 586 && ((source_it & DMA_IT_HT) != RESET)) { 587 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ 588 if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) { 589 /* Disable the half transfer interrupt */ 590 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); 591 } 592 /* Clear the half transfer complete flag */ 593 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); 594 595 /* DMA peripheral state is not updated in Half Transfer */ 596 /* but in Transfer Complete case */ 597 598 if (hdma->XferHalfCpltCallback != NULL) { 599 /* Half transfer callback */ 600 hdma->XferHalfCpltCallback(hdma); 601 } 602 } 603 604 /* Transfer Complete Interrupt management ***********************************/ 605 else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) 606 && ((source_it & DMA_IT_TC) != RESET)) { 607 if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) { 608 /* Disable the transfer complete and error interrupt */ 609 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC); 610 611 /* Change the DMA state */ 612 hdma->State = HAL_DMA_STATE_READY; 613 } 614 /* Clear the transfer complete flag */ 615 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 616 617 /* Process Unlocked */ 618 __HAL_UNLOCK(hdma); 619 620 if (hdma->XferCpltCallback != NULL) { 621 /* Transfer complete callback */ 622 hdma->XferCpltCallback(hdma); 623 } 624 } 625 626 /* Transfer Error Interrupt management **************************************/ 627 else if ((RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) 628 && (RESET != (source_it & DMA_IT_TE))) { 629 /* When a DMA transfer error occurs */ 630 /* A hardware clear of its EN bits is performed */ 631 /* Disable ALL DMA IT */ 632 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 633 634 /* Clear all flags */ 635 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); 636 637 /* Update error code */ 638 hdma->ErrorCode = HAL_DMA_ERROR_TE; 639 640 /* Change the DMA state */ 641 hdma->State = HAL_DMA_STATE_READY; 642 643 /* Process Unlocked */ 644 __HAL_UNLOCK(hdma); 645 646 if (hdma->XferErrorCallback != NULL) { 647 /* Transfer error callback */ 648 hdma->XferErrorCallback(hdma); 649 } 650 } 651 return; 652 } 653 654 /** 655 * @brief Register callbacks 656 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 657 * the configuration information for the specified DMA Channel. 658 * @param CallbackID: User Callback identifier 659 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. 660 * @param pCallback: pointer to private callback function which has pointer to 661 * a DMA_HandleTypeDef structure as parameter. 662 * @retval HAL status 663 */ 664 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, 665 HAL_DMA_CallbackIDTypeDef CallbackID, 666 void (*pCallback)(DMA_HandleTypeDef *_hdma)) 667 { 668 HAL_StatusTypeDef status = HAL_OK; 669 670 /* Process locked */ 671 __HAL_LOCK(hdma); 672 673 if (HAL_DMA_STATE_READY == hdma->State) { 674 switch (CallbackID) { 675 case HAL_DMA_XFER_CPLT_CB_ID: 676 hdma->XferCpltCallback = pCallback; 677 break; 678 679 case HAL_DMA_XFER_HALFCPLT_CB_ID: 680 hdma->XferHalfCpltCallback = pCallback; 681 break; 682 683 case HAL_DMA_XFER_ERROR_CB_ID: 684 hdma->XferErrorCallback = pCallback; 685 break; 686 687 case HAL_DMA_XFER_ABORT_CB_ID: 688 hdma->XferAbortCallback = pCallback; 689 break; 690 691 default: 692 status = HAL_ERROR; 693 break; 694 } 695 } else { 696 status = HAL_ERROR; 697 } 698 699 /* Release Lock */ 700 __HAL_UNLOCK(hdma); 701 702 return status; 703 } 704 705 /** 706 * @brief UnRegister callbacks 707 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 708 * the configuration information for the specified DMA Channel. 709 * @param CallbackID: User Callback identifier 710 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. 711 * @retval HAL status 712 */ 713 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, 714 HAL_DMA_CallbackIDTypeDef CallbackID) 715 { 716 HAL_StatusTypeDef status = HAL_OK; 717 718 /* Process locked */ 719 __HAL_LOCK(hdma); 720 721 if (HAL_DMA_STATE_READY == hdma->State) { 722 switch (CallbackID) { 723 case HAL_DMA_XFER_CPLT_CB_ID: 724 hdma->XferCpltCallback = NULL; 725 break; 726 727 case HAL_DMA_XFER_HALFCPLT_CB_ID: 728 hdma->XferHalfCpltCallback = NULL; 729 break; 730 731 case HAL_DMA_XFER_ERROR_CB_ID: 732 hdma->XferErrorCallback = NULL; 733 break; 734 735 case HAL_DMA_XFER_ABORT_CB_ID: 736 hdma->XferAbortCallback = NULL; 737 break; 738 739 case HAL_DMA_XFER_ALL_CB_ID: 740 hdma->XferCpltCallback = NULL; 741 hdma->XferHalfCpltCallback = NULL; 742 hdma->XferErrorCallback = NULL; 743 hdma->XferAbortCallback = NULL; 744 break; 745 746 default: 747 status = HAL_ERROR; 748 break; 749 } 750 } else { 751 status = HAL_ERROR; 752 } 753 754 /* Release Lock */ 755 __HAL_UNLOCK(hdma); 756 757 return status; 758 } 759 760 /** 761 * @} 762 */ 763 764 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions 765 * @brief Peripheral State and Errors functions 766 * 767 @verbatim 768 =============================================================================== 769 ##### Peripheral State and Errors functions ##### 770 =============================================================================== 771 [..] 772 This subsection provides functions allowing to 773 (+) Check the DMA state 774 (+) Get error code 775 776 @endverbatim 777 * @{ 778 */ 779 780 /** 781 * @brief Return the DMA handle state. 782 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 783 * the configuration information for the specified DMA Channel. 784 * @retval HAL state 785 */ 786 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma) 787 { 788 /* Return DMA handle state */ 789 return hdma->State; 790 } 791 792 /** 793 * @brief Return the DMA error code. 794 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains 795 * the configuration information for the specified DMA Channel. 796 * @retval DMA Error Code 797 */ 798 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma) 799 { 800 return hdma->ErrorCode; 801 } 802 803 /** 804 * @} 805 */ 806 807 /** 808 * @} 809 */ 810 811 /** @addtogroup DMA_Private_Functions 812 * @{ 813 */ 814 815 /** 816 * @brief Sets the DMA Transfer parameter. 817 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 818 * the configuration information for the specified DMA Channel. 819 * @param SrcAddress: The source memory Buffer address 820 * @param DstAddress: The destination memory Buffer address 821 * @param DataLength: The length of data to be transferred from source to destination 822 * @retval HAL status 823 */ 824 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, 825 uint32_t DstAddress, uint32_t DataLength) 826 { 827 /* Clear all flags */ 828 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); 829 830 /* Configure DMA Channel data length */ 831 hdma->Instance->CNDTR = DataLength; 832 833 /* Memory to Peripheral */ 834 if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) { 835 /* Configure DMA Channel destination address */ 836 hdma->Instance->CPAR = DstAddress; 837 838 /* Configure DMA Channel source address */ 839 hdma->Instance->CMAR = SrcAddress; 840 } 841 /* Peripheral to Memory */ 842 else { 843 /* Configure DMA Channel source address */ 844 hdma->Instance->CPAR = SrcAddress; 845 846 /* Configure DMA Channel destination address */ 847 hdma->Instance->CMAR = DstAddress; 848 } 849 } 850 851 /** 852 * @} 853 */ 854 855 #endif /* HAL_DMA_MODULE_ENABLED */ 856 /** 857 * @} 858 */ 859 860 /** 861 * @} 862 */ 863
