Subversion Repositories FuelGauge

Rev

Details | Last modification | View Log | RSS feed

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