Subversion Repositories AFRtranscoder

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 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