Subversion Repositories EngineBay2

Rev

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

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