Subversion Repositories DashDisplay

Rev

Rev 50 | Details | Compare with Previous | Last modification | View Log | RSS feed

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