Subversion Repositories dashGPS

Rev

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