Subversion Repositories EngineBay2

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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