source: rtems/c/src/lib/libbsp/arm/stm32f7x/hal/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.c @ c20847a5

5
Last change on this file since c20847a5 was c20847a5, checked in by Isaac Gutekunst <isaac.gutekunst@…>, on 09/16/15 at 13:16:02

Add STM32F7 HAL Files

These files originated as:

+ STC32CubeF7 V1.1.0 from http://www.st.com/web/en/catalog/tools/PF261909

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