firmware-nucleo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c (27418B)
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, uint32_t DstAddress, uint32_t DataLength); 106 /** 107 * @} 108 */ 109 110 /* Exported functions ---------------------------------------------------------*/ 111 112 /** @defgroup DMA_Exported_Functions DMA Exported Functions 113 * @{ 114 */ 115 116 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions 117 * @brief Initialization and de-initialization functions 118 * 119 @verbatim 120 =============================================================================== 121 ##### Initialization and de-initialization functions ##### 122 =============================================================================== 123 [..] 124 This section provides functions allowing to initialize the DMA Channel source 125 and destination addresses, incrementation and data sizes, transfer direction, 126 circular/normal mode selection, memory-to-memory mode selection and Channel priority value. 127 [..] 128 The HAL_DMA_Init() function follows the DMA configuration procedures as described in 129 reference manual. 130 131 @endverbatim 132 * @{ 133 */ 134 135 /** 136 * @brief Initialize the DMA according to the specified 137 * parameters in the DMA_InitTypeDef and initialize the associated handle. 138 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 139 * the configuration information for the specified DMA Channel. 140 * @retval HAL status 141 */ 142 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) 143 { 144 uint32_t tmp = 0U; 145 146 /* Check the DMA handle allocation */ 147 if(hdma == NULL) 148 { 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) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2; 179 hdma->DmaBaseAddress = DMA1; 180 #endif /* DMA2 */ 181 182 /* Change DMA peripheral state */ 183 hdma->State = HAL_DMA_STATE_BUSY; 184 185 /* Get the CR register value */ 186 tmp = hdma->Instance->CCR; 187 188 /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ 189 tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \ 190 DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \ 191 DMA_CCR_DIR)); 192 193 /* Prepare the DMA Channel configuration */ 194 tmp |= hdma->Init.Direction | 195 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 { 224 return HAL_ERROR; 225 } 226 227 /* Check the parameters */ 228 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); 229 230 /* Disable the selected DMA Channelx */ 231 __HAL_DMA_DISABLE(hdma); 232 233 /* Reset DMA Channel control register */ 234 hdma->Instance->CCR = 0U; 235 236 /* Reset DMA Channel Number of Data to Transfer register */ 237 hdma->Instance->CNDTR = 0U; 238 239 /* Reset DMA Channel peripheral address register */ 240 hdma->Instance->CPAR = 0U; 241 242 /* Reset DMA Channel memory address register */ 243 hdma->Instance->CMAR = 0U; 244 245 #if defined (DMA2) 246 /* calculation of the channel index */ 247 if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1)) 248 { 249 /* DMA1 */ 250 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2; 251 hdma->DmaBaseAddress = DMA1; 252 } 253 else 254 { 255 /* DMA2 */ 256 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2; 257 hdma->DmaBaseAddress = DMA2; 258 } 259 #else 260 /* DMA1 */ 261 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((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, uint32_t DstAddress, uint32_t DataLength) 319 { 320 HAL_StatusTypeDef status = HAL_OK; 321 322 /* Check the parameters */ 323 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 324 325 /* Process locked */ 326 __HAL_LOCK(hdma); 327 328 if(HAL_DMA_STATE_READY == hdma->State) 329 { 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 } 343 else 344 { 345 /* Process Unlocked */ 346 __HAL_UNLOCK(hdma); 347 status = HAL_BUSY; 348 } 349 return status; 350 } 351 352 /** 353 * @brief Start the DMA Transfer with interrupt enabled. 354 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 355 * the configuration information for the specified DMA Channel. 356 * @param SrcAddress: The source memory Buffer address 357 * @param DstAddress: The destination memory Buffer address 358 * @param DataLength: The length of data to be transferred from source to destination 359 * @retval HAL status 360 */ 361 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 362 { 363 HAL_StatusTypeDef status = HAL_OK; 364 365 /* Check the parameters */ 366 assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 367 368 /* Process locked */ 369 __HAL_LOCK(hdma); 370 371 if(HAL_DMA_STATE_READY == hdma->State) 372 { 373 /* Change DMA peripheral state */ 374 hdma->State = HAL_DMA_STATE_BUSY; 375 hdma->ErrorCode = HAL_DMA_ERROR_NONE; 376 377 /* Disable the peripheral */ 378 __HAL_DMA_DISABLE(hdma); 379 380 /* Configure the source, destination address and the data length & clear flags*/ 381 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); 382 383 /* Enable the transfer complete interrupt */ 384 /* Enable the transfer Error interrupt */ 385 if(NULL != hdma->XferHalfCpltCallback) 386 { 387 /* Enable the Half transfer complete interrupt as well */ 388 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 389 } 390 else 391 { 392 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); 393 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE)); 394 } 395 /* Enable the Peripheral */ 396 __HAL_DMA_ENABLE(hdma); 397 } 398 else 399 { 400 /* Process Unlocked */ 401 __HAL_UNLOCK(hdma); 402 403 /* Remain BUSY */ 404 status = HAL_BUSY; 405 } 406 return status; 407 } 408 409 /** 410 * @brief Abort the DMA Transfer. 411 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 412 * the configuration information for the specified DMA Channel. 413 * @retval HAL status 414 */ 415 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) 416 { 417 HAL_StatusTypeDef status = HAL_OK; 418 419 if(hdma->State != HAL_DMA_STATE_BUSY) 420 { 421 /* no transfer ongoing */ 422 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 423 424 /* Process Unlocked */ 425 __HAL_UNLOCK(hdma); 426 427 return HAL_ERROR; 428 } 429 else 430 431 { 432 /* Disable DMA IT */ 433 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 434 435 /* Disable the channel */ 436 __HAL_DMA_DISABLE(hdma); 437 438 /* Clear all flags */ 439 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); 440 } 441 /* Change the DMA state */ 442 hdma->State = HAL_DMA_STATE_READY; 443 444 /* Process Unlocked */ 445 __HAL_UNLOCK(hdma); 446 447 return status; 448 } 449 450 /** 451 * @brief Aborts the DMA Transfer in Interrupt mode. 452 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains 453 * the configuration information for the specified DMA Channel. 454 * @retval HAL status 455 */ 456 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma) 457 { 458 HAL_StatusTypeDef status = HAL_OK; 459 460 if(HAL_DMA_STATE_BUSY != hdma->State) 461 { 462 /* no transfer ongoing */ 463 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 464 465 status = HAL_ERROR; 466 } 467 else 468 { 469 /* Disable DMA IT */ 470 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 471 472 /* Disable the channel */ 473 __HAL_DMA_DISABLE(hdma); 474 475 /* Clear all flags */ 476 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma)); 477 478 /* Change the DMA state */ 479 hdma->State = HAL_DMA_STATE_READY; 480 481 /* Process Unlocked */ 482 __HAL_UNLOCK(hdma); 483 484 /* Call User Abort callback */ 485 if(hdma->XferAbortCallback != NULL) 486 { 487 hdma->XferAbortCallback(hdma); 488 } 489 } 490 return status; 491 } 492 493 /** 494 * @brief Polling for transfer complete. 495 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 496 * the configuration information for the specified DMA Channel. 497 * @param CompleteLevel: Specifies the DMA level complete. 498 * @param Timeout: Timeout duration. 499 * @retval HAL status 500 */ 501 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) 502 { 503 uint32_t temp; 504 uint32_t tickstart = 0U; 505 506 if(HAL_DMA_STATE_BUSY != hdma->State) 507 { 508 /* no transfer ongoing */ 509 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; 510 __HAL_UNLOCK(hdma); 511 return HAL_ERROR; 512 } 513 514 /* Polling mode not supported in circular mode */ 515 if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC)) 516 { 517 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; 518 return HAL_ERROR; 519 } 520 521 /* Get the level transfer complete flag */ 522 if(CompleteLevel == HAL_DMA_FULL_TRANSFER) 523 { 524 /* Transfer Complete flag */ 525 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma); 526 } 527 else 528 { 529 /* Half Transfer Complete flag */ 530 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma); 531 } 532 533 /* Get tick */ 534 tickstart = HAL_GetTick(); 535 536 while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET) 537 { 538 if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)) 539 { 540 /* When a DMA transfer error occurs */ 541 /* A hardware clear of its EN bits is performed */ 542 /* Clear all flags */ 543 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); 544 545 /* Update error code */ 546 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE); 547 548 /* Change the DMA state */ 549 hdma->State= HAL_DMA_STATE_READY; 550 551 /* Process Unlocked */ 552 __HAL_UNLOCK(hdma); 553 554 return HAL_ERROR; 555 } 556 /* Check for the Timeout */ 557 if(Timeout != HAL_MAX_DELAY) 558 { 559 if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) 560 { 561 /* Update error code */ 562 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT); 563 564 /* Change the DMA state */ 565 hdma->State = HAL_DMA_STATE_READY; 566 567 /* Process Unlocked */ 568 __HAL_UNLOCK(hdma); 569 570 return HAL_ERROR; 571 } 572 } 573 } 574 575 if(CompleteLevel == HAL_DMA_FULL_TRANSFER) 576 { 577 /* Clear the transfer complete flag */ 578 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 579 580 /* The selected Channelx EN bit is cleared (DMA is disabled and 581 all transfers are complete) */ 582 hdma->State = HAL_DMA_STATE_READY; 583 } 584 else 585 { 586 /* Clear the half transfer complete flag */ 587 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); 588 } 589 590 /* Process unlocked */ 591 __HAL_UNLOCK(hdma); 592 593 return HAL_OK; 594 } 595 596 /** 597 * @brief Handles DMA interrupt request. 598 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 599 * the configuration information for the specified DMA Channel. 600 * @retval None 601 */ 602 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) 603 { 604 uint32_t flag_it = hdma->DmaBaseAddress->ISR; 605 uint32_t source_it = hdma->Instance->CCR; 606 607 /* Half Transfer Complete Interrupt management ******************************/ 608 if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET)) 609 { 610 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ 611 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) 612 { 613 /* Disable the half transfer interrupt */ 614 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); 615 } 616 /* Clear the half transfer complete flag */ 617 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); 618 619 /* DMA peripheral state is not updated in Half Transfer */ 620 /* but in Transfer Complete case */ 621 622 if(hdma->XferHalfCpltCallback != NULL) 623 { 624 /* Half transfer callback */ 625 hdma->XferHalfCpltCallback(hdma); 626 } 627 } 628 629 /* Transfer Complete Interrupt management ***********************************/ 630 else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET)) 631 { 632 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) 633 { 634 /* Disable the transfer complete and error interrupt */ 635 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC); 636 637 /* Change the DMA state */ 638 hdma->State = HAL_DMA_STATE_READY; 639 } 640 /* Clear the transfer complete flag */ 641 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 642 643 /* Process Unlocked */ 644 __HAL_UNLOCK(hdma); 645 646 if(hdma->XferCpltCallback != NULL) 647 { 648 /* Transfer complete callback */ 649 hdma->XferCpltCallback(hdma); 650 } 651 } 652 653 /* Transfer Error Interrupt management **************************************/ 654 else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE))) 655 { 656 /* When a DMA transfer error occurs */ 657 /* A hardware clear of its EN bits is performed */ 658 /* Disable ALL DMA IT */ 659 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 660 661 /* Clear all flags */ 662 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); 663 664 /* Update error code */ 665 hdma->ErrorCode = HAL_DMA_ERROR_TE; 666 667 /* Change the DMA state */ 668 hdma->State = HAL_DMA_STATE_READY; 669 670 /* Process Unlocked */ 671 __HAL_UNLOCK(hdma); 672 673 if (hdma->XferErrorCallback != NULL) 674 { 675 /* Transfer error callback */ 676 hdma->XferErrorCallback(hdma); 677 } 678 } 679 return; 680 } 681 682 /** 683 * @brief Register callbacks 684 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 685 * the configuration information for the specified DMA Channel. 686 * @param CallbackID: User Callback identifier 687 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. 688 * @param pCallback: pointer to private callback function which has pointer to 689 * a DMA_HandleTypeDef structure as parameter. 690 * @retval HAL status 691 */ 692 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma)) 693 { 694 HAL_StatusTypeDef status = HAL_OK; 695 696 /* Process locked */ 697 __HAL_LOCK(hdma); 698 699 if(HAL_DMA_STATE_READY == hdma->State) 700 { 701 switch (CallbackID) 702 { 703 case HAL_DMA_XFER_CPLT_CB_ID: 704 hdma->XferCpltCallback = pCallback; 705 break; 706 707 case HAL_DMA_XFER_HALFCPLT_CB_ID: 708 hdma->XferHalfCpltCallback = pCallback; 709 break; 710 711 case HAL_DMA_XFER_ERROR_CB_ID: 712 hdma->XferErrorCallback = pCallback; 713 break; 714 715 case HAL_DMA_XFER_ABORT_CB_ID: 716 hdma->XferAbortCallback = pCallback; 717 break; 718 719 default: 720 status = HAL_ERROR; 721 break; 722 } 723 } 724 else 725 { 726 status = HAL_ERROR; 727 } 728 729 /* Release Lock */ 730 __HAL_UNLOCK(hdma); 731 732 return status; 733 } 734 735 /** 736 * @brief UnRegister callbacks 737 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 738 * the configuration information for the specified DMA Channel. 739 * @param CallbackID: User Callback identifier 740 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. 741 * @retval HAL status 742 */ 743 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID) 744 { 745 HAL_StatusTypeDef status = HAL_OK; 746 747 /* Process locked */ 748 __HAL_LOCK(hdma); 749 750 if(HAL_DMA_STATE_READY == hdma->State) 751 { 752 switch (CallbackID) 753 { 754 case HAL_DMA_XFER_CPLT_CB_ID: 755 hdma->XferCpltCallback = NULL; 756 break; 757 758 case HAL_DMA_XFER_HALFCPLT_CB_ID: 759 hdma->XferHalfCpltCallback = NULL; 760 break; 761 762 case HAL_DMA_XFER_ERROR_CB_ID: 763 hdma->XferErrorCallback = NULL; 764 break; 765 766 case HAL_DMA_XFER_ABORT_CB_ID: 767 hdma->XferAbortCallback = NULL; 768 break; 769 770 case HAL_DMA_XFER_ALL_CB_ID: 771 hdma->XferCpltCallback = NULL; 772 hdma->XferHalfCpltCallback = NULL; 773 hdma->XferErrorCallback = NULL; 774 hdma->XferAbortCallback = NULL; 775 break; 776 777 default: 778 status = HAL_ERROR; 779 break; 780 } 781 } 782 else 783 { 784 status = HAL_ERROR; 785 } 786 787 /* Release Lock */ 788 __HAL_UNLOCK(hdma); 789 790 return status; 791 } 792 793 /** 794 * @} 795 */ 796 797 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions 798 * @brief Peripheral State and Errors functions 799 * 800 @verbatim 801 =============================================================================== 802 ##### Peripheral State and Errors functions ##### 803 =============================================================================== 804 [..] 805 This subsection provides functions allowing to 806 (+) Check the DMA state 807 (+) Get error code 808 809 @endverbatim 810 * @{ 811 */ 812 813 /** 814 * @brief Return the DMA handle state. 815 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 816 * the configuration information for the specified DMA Channel. 817 * @retval HAL state 818 */ 819 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma) 820 { 821 /* Return DMA handle state */ 822 return hdma->State; 823 } 824 825 /** 826 * @brief Return the DMA error code. 827 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains 828 * the configuration information for the specified DMA Channel. 829 * @retval DMA Error Code 830 */ 831 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma) 832 { 833 return hdma->ErrorCode; 834 } 835 836 /** 837 * @} 838 */ 839 840 /** 841 * @} 842 */ 843 844 /** @addtogroup DMA_Private_Functions 845 * @{ 846 */ 847 848 /** 849 * @brief Sets the DMA Transfer parameter. 850 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 851 * the configuration information for the specified DMA Channel. 852 * @param SrcAddress: The source memory Buffer address 853 * @param DstAddress: The destination memory Buffer address 854 * @param DataLength: The length of data to be transferred from source to destination 855 * @retval HAL status 856 */ 857 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 858 { 859 /* Clear all flags */ 860 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); 861 862 /* Configure DMA Channel data length */ 863 hdma->Instance->CNDTR = DataLength; 864 865 /* Memory to Peripheral */ 866 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) 867 { 868 /* Configure DMA Channel destination address */ 869 hdma->Instance->CPAR = DstAddress; 870 871 /* Configure DMA Channel source address */ 872 hdma->Instance->CMAR = SrcAddress; 873 } 874 /* Peripheral to Memory */ 875 else 876 { 877 /* Configure DMA Channel source address */ 878 hdma->Instance->CPAR = SrcAddress; 879 880 /* Configure DMA Channel destination address */ 881 hdma->Instance->CMAR = DstAddress; 882 } 883 } 884 885 /** 886 * @} 887 */ 888 889 #endif /* HAL_DMA_MODULE_ENABLED */ 890 /** 891 * @} 892 */ 893 894 /** 895 * @} 896 */ 897
