tdse-tp0_03-hw_sw_test

FIUBA - Electrónica - Taller de Sistemas Embebidos - Trabajo Práctico N°: 0 - Proyecto N°: 03
Index Commits Files Refs README
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