]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_dma.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F4 / stm32f4xx_hal_dma.c
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_dma.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    19-June-2014
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) 2014 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 "stm32f4xx_hal.h"
118
119 /** @addtogroup STM32F4xx_HAL_Driver
120   * @{
121   */
122
123 /** @defgroup DMA 
124   * @brief DMA HAL module driver
125   * @{
126   */
127
128 #ifdef HAL_DMA_MODULE_ENABLED
129
130 /* Private typedef -----------------------------------------------------------*/
131 /* Private define ------------------------------------------------------------*/
132 #define HAL_TIMEOUT_DMA_ABORT    ((uint32_t)1000)  /* 1s  */
133 /* Private macro -------------------------------------------------------------*/
134 /* Private variables ---------------------------------------------------------*/
135 /* Private function prototypes -----------------------------------------------*/
136 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
137
138 /* Private functions ---------------------------------------------------------*/
139
140 /** @defgroup DMA_Private_Functions
141   * @{
142   */
143
144 /** @defgroup DMA_Group1 Initialization and de-initialization functions 
145  *  @brief   Initialization and de-initialization functions 
146  *
147 @verbatim   
148  ===============================================================================
149              ##### Initialization and de-initialization functions  #####
150  ===============================================================================  
151     [..]
152     This section provides functions allowing to initialize the DMA Stream source
153     and destination addresses, incrementation and data sizes, transfer direction, 
154     circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
155     [..]
156     The HAL_DMA_Init() function follows the DMA configuration procedures as described in
157     reference manual.  
158
159 @endverbatim
160   * @{
161   */
162   
163 /**
164   * @brief  Initializes the DMA according to the specified
165   *         parameters in the DMA_InitTypeDef and create the associated handle.
166   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
167   *               the configuration information for the specified DMA Stream.  
168   * @retval HAL status
169   */
170 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
171
172   uint32_t tmp = 0;
173   
174   /* Check the DMA peripheral state */
175   if(hdma == HAL_NULL)
176   {
177     return HAL_ERROR;
178   }
179
180   /* Check the parameters */
181   assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
182   assert_param(IS_DMA_CHANNEL(hdma->Init.Channel));
183   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
184   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
185   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
186   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
187   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
188   assert_param(IS_DMA_MODE(hdma->Init.Mode));
189   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
190   assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
191   /* Check the memory burst, peripheral burst and FIFO threshold parameters only
192      when FIFO mode is enabled */
193   if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
194   {
195     assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
196     assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
197     assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
198   }
199
200   /* Change DMA peripheral state */
201   hdma->State = HAL_DMA_STATE_BUSY;
202
203   /* Get the CR register value */
204   tmp = hdma->Instance->CR;
205
206   /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR and CT bits */
207   tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
208                       DMA_SxCR_PL    | DMA_SxCR_MSIZE  | DMA_SxCR_PSIZE  | \
209                       DMA_SxCR_MINC  | DMA_SxCR_PINC   | DMA_SxCR_CIRC   | \
210                       DMA_SxCR_DIR   | DMA_SxCR_CT  ));
211
212   /* Prepare the DMA Stream configuration */
213   tmp |=  hdma->Init.Channel             | hdma->Init.Direction        |
214           hdma->Init.PeriphInc           | hdma->Init.MemInc           |
215           hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
216           hdma->Init.Mode                | hdma->Init.Priority;
217
218   /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
219   if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
220   {
221     /* Get memory burst and peripheral burst */
222     tmp |=  hdma->Init.MemBurst | hdma->Init.PeriphBurst;
223   }
224   
225   /* Write to DMA Stream CR register */
226   hdma->Instance->CR = tmp;  
227
228   /* Get the FCR register value */
229   tmp = hdma->Instance->FCR;
230
231   /* Clear Direct mode and FIFO threshold bits */
232   tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
233
234   /* Prepare the DMA Stream FIFO configuration */
235   tmp |= hdma->Init.FIFOMode;
236
237   /* the FIFO threshold is not used when the FIFO mode is disabled */
238   if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
239   {
240     /* Get the FIFO threshold */
241     tmp |= hdma->Init.FIFOThreshold;
242   }
243   
244   /* Write to DMA Stream FCR */
245   hdma->Instance->FCR = tmp;
246
247   /* Initialise the error code */
248   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
249
250   /* Initialize the DMA state */
251   hdma->State = HAL_DMA_STATE_READY;
252
253   return HAL_OK;
254 }
255
256 /**
257   * @brief  DeInitializes the DMA peripheral 
258   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
259   *               the configuration information for the specified DMA Stream.  
260   * @retval HAL status
261   */
262 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
263 {
264   /* Check the DMA peripheral state */
265   if(hdma == HAL_NULL)
266   {
267     return HAL_ERROR;
268   }
269   
270   /* Check the DMA peripheral state */
271   if(hdma->State == HAL_DMA_STATE_BUSY)
272   {
273      return HAL_ERROR;
274   }
275
276   /* Disable the selected DMA Streamx */
277   __HAL_DMA_DISABLE(hdma);
278
279   /* Reset DMA Streamx control register */
280   hdma->Instance->CR   = 0;
281
282   /* Reset DMA Streamx number of data to transfer register */
283   hdma->Instance->NDTR = 0;
284
285   /* Reset DMA Streamx peripheral address register */
286   hdma->Instance->PAR  = 0;
287
288   /* Reset DMA Streamx memory 0 address register */
289   hdma->Instance->M0AR = 0;
290
291   /* Reset DMA Streamx memory 1 address register */
292   hdma->Instance->M1AR = 0;
293
294   /* Reset DMA Streamx FIFO control register */
295   hdma->Instance->FCR  = (uint32_t)0x00000021;
296
297   /* Clear all flags */
298   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
299   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
300   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
301   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
302   __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
303
304   /* Initialise the error code */
305   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
306
307   /* Initialize the DMA state */
308   hdma->State = HAL_DMA_STATE_RESET;
309
310   /* Release Lock */
311   __HAL_UNLOCK(hdma);
312
313   return HAL_OK;
314 }
315
316 /**
317   * @}
318   */
319
320 /** @defgroup DMA_Group2 I/O operation functions 
321  *  @brief   I/O operation functions  
322  *
323 @verbatim   
324  ===============================================================================
325                       #####  IO operation functions  #####
326  ===============================================================================  
327     [..]  This section provides functions allowing to:
328       (+) Configure the source, destination address and data length and Start DMA transfer
329       (+) Configure the source, destination address and data length and 
330           Start DMA transfer with interrupt
331       (+) Abort DMA transfer
332       (+) Poll for transfer complete
333       (+) Handle DMA interrupt request  
334
335 @endverbatim
336   * @{
337   */
338
339 /**
340   * @brief  Starts the DMA Transfer.
341   * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains
342   *                     the configuration information for the specified DMA Stream.  
343   * @param  SrcAddress: The source memory Buffer address
344   * @param  DstAddress: The destination memory Buffer address
345   * @param  DataLength: The length of data to be transferred from source to destination
346   * @retval HAL status
347   */
348 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
349 {
350   /* Process locked */
351   __HAL_LOCK(hdma);
352
353   /* Change DMA peripheral state */
354   hdma->State = HAL_DMA_STATE_BUSY;
355
356    /* Check the parameters */
357   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
358
359   /* Disable the peripheral */
360   __HAL_DMA_DISABLE(hdma);
361
362   /* Configure the source, destination address and the data length */
363   DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
364
365   /* Enable the Peripheral */
366   __HAL_DMA_ENABLE(hdma);
367
368   return HAL_OK; 
369 }
370
371 /**
372   * @brief  Start the DMA Transfer with interrupt enabled.
373   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
374   *                     the configuration information for the specified DMA Stream.  
375   * @param  SrcAddress: The source memory Buffer address
376   * @param  DstAddress: The destination memory Buffer address
377   * @param  DataLength: The length of data to be transferred from source to destination
378   * @retval HAL status
379   */
380 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
381 {
382   /* Process locked */
383   __HAL_LOCK(hdma);
384
385   /* Change DMA peripheral state */
386   hdma->State = HAL_DMA_STATE_BUSY;
387
388    /* Check the parameters */
389   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
390
391   /* Disable the peripheral */
392   __HAL_DMA_DISABLE(hdma);
393
394   /* Configure the source, destination address and the data length */
395   DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
396
397   /* Enable the transfer complete interrupt */
398   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
399
400   /* Enable the Half transfer complete interrupt */
401   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);  
402
403   /* Enable the transfer Error interrupt */
404   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
405
406   /* Enable the FIFO Error interrupt */
407   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE);
408
409   /* Enable the direct mode Error interrupt */
410   __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME);
411
412    /* Enable the Peripheral */
413   __HAL_DMA_ENABLE(hdma);
414
415   return HAL_OK;
416
417
418 /**
419   * @brief  Aborts the DMA Transfer.
420   * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
421   *                 the configuration information for the specified DMA Stream.
422   *                   
423   * @note  After disabling a DMA Stream, a check for wait until the DMA Stream is 
424   *        effectively disabled is added. If a Stream is disabled 
425   *        while a data transfer is ongoing, the current data will be transferred
426   *        and the Stream will be effectively disabled only after the transfer of
427   *        this single data is finished.  
428   * @retval HAL status
429   */
430 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
431 {
432   uint32_t tickstart = 0;
433
434   /* Disable the stream */
435   __HAL_DMA_DISABLE(hdma);
436
437   /* Get tick */
438   tickstart = HAL_GetTick();
439
440   /* Check if the DMA Stream is effectively disabled */
441   while((hdma->Instance->CR & DMA_SxCR_EN) != 0)
442   {
443     /* Check for the Timeout */
444     if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
445     {
446       /* Update error code */
447       hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
448       
449       /* Process Unlocked */
450       __HAL_UNLOCK(hdma);
451       
452       /* Change the DMA state */
453       hdma->State = HAL_DMA_STATE_TIMEOUT;
454       
455       return HAL_TIMEOUT;
456     }
457   }
458   /* Process Unlocked */
459   __HAL_UNLOCK(hdma);
460
461   /* Change the DMA state*/
462   hdma->State = HAL_DMA_STATE_READY;
463
464   return HAL_OK;
465 }
466
467 /**
468   * @brief  Polling for transfer complete.
469   * @param  hdma:          pointer to a DMA_HandleTypeDef structure that contains
470   *                        the configuration information for the specified DMA Stream.
471   * @param  CompleteLevel: Specifies the DMA level complete.  
472   * @param  Timeout:       Timeout duration.
473   * @retval HAL status
474   */
475 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
476 {
477   uint32_t temp, tmp, tmp1, tmp2;
478   uint32_t tickstart = 0; 
479
480   /* Get the level transfer complete flag */
481   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
482   {
483     /* Transfer Complete flag */
484     temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
485   }
486   else
487   {
488     /* Half Transfer Complete flag */
489     temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
490   }
491
492   /* Get tick */
493   tickstart = HAL_GetTick();
494
495   while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
496   {
497     tmp  = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
498     tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
499     tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
500     if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET))
501     {
502       if(tmp != RESET)
503       {
504         /* Update error code */
505         hdma->ErrorCode |= HAL_DMA_ERROR_TE;
506
507         /* Clear the transfer error flag */
508         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
509       }
510       if(tmp1 != RESET)
511       {
512         /* Update error code */
513         hdma->ErrorCode |= HAL_DMA_ERROR_FE;
514  
515         /* Clear the FIFO error flag */
516         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
517       }
518       if(tmp2 != RESET)
519       {
520         /* Update error code */
521         hdma->ErrorCode |= HAL_DMA_ERROR_DME;
522
523         /* Clear the Direct Mode error flag */
524         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
525       }
526       /* Change the DMA state */
527       hdma->State= HAL_DMA_STATE_ERROR;
528       
529       /* Process Unlocked */
530       __HAL_UNLOCK(hdma);
531
532       return HAL_ERROR;
533     }  
534     /* Check for the Timeout */
535     if(Timeout != HAL_MAX_DELAY)
536     {
537       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
538       {
539         /* Update error code */
540         hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
541
542         /* Change the DMA state */
543         hdma->State = HAL_DMA_STATE_TIMEOUT;
544
545         /* Process Unlocked */
546         __HAL_UNLOCK(hdma);
547         
548         return HAL_TIMEOUT;
549       }
550     }
551   }
552
553   if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
554   {
555     /* Multi_Buffering mode enabled */
556     if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
557     {
558       /* Clear the half transfer complete flag */
559       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
560       /* Clear the transfer complete flag */
561       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
562
563       /* Current memory buffer used is Memory 0 */
564       if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
565       {
566         /* Change DMA peripheral state */
567         hdma->State = HAL_DMA_STATE_READY_MEM0;
568       }
569       /* Current memory buffer used is Memory 1 */
570       else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
571       {
572         /* Change DMA peripheral state */
573         hdma->State = HAL_DMA_STATE_READY_MEM1;
574       }
575     }
576     else
577     {
578       /* Clear the half transfer complete flag */
579       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
580       /* Clear the transfer complete flag */
581       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 
582
583       /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers
584          are complete) */
585       hdma->State = HAL_DMA_STATE_READY_MEM0;
586     }
587     /* Process Unlocked */
588     __HAL_UNLOCK(hdma);
589   }
590   else
591   { 
592     /* Multi_Buffering mode enabled */
593     if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
594     {
595       /* Clear the half transfer complete flag */
596       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
597
598       /* Current memory buffer used is Memory 0 */
599       if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
600       {
601         /* Change DMA peripheral state */
602         hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
603       }
604       /* Current memory buffer used is Memory 1 */
605       else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
606       {
607         /* Change DMA peripheral state */
608         hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
609       }
610     }
611     else
612     {
613       /* Clear the half transfer complete flag */
614       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
615
616       /* Change DMA peripheral state */
617       hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
618     }
619   }
620   return HAL_OK;
621 }
622
623 /**
624   * @brief  Handles DMA interrupt request.
625   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
626   *               the configuration information for the specified DMA Stream.  
627   * @retval None
628   */
629 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
630 {
631   /* Transfer Error Interrupt management ***************************************/
632   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
633   {
634     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
635     {
636       /* Disable the transfer error interrupt */
637       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
638
639       /* Clear the transfer error flag */
640       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
641
642       /* Update error code */
643       hdma->ErrorCode |= HAL_DMA_ERROR_TE;
644
645       /* Change the DMA state */
646       hdma->State = HAL_DMA_STATE_ERROR;
647
648       /* Process Unlocked */
649       __HAL_UNLOCK(hdma); 
650
651       if(hdma->XferErrorCallback != HAL_NULL)
652       {
653         /* Transfer error callback */
654         hdma->XferErrorCallback(hdma);
655       }
656     }
657   }
658   /* FIFO Error Interrupt management ******************************************/
659   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)
660   {
661     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
662     {
663       /* Disable the FIFO Error interrupt */
664       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);
665
666       /* Clear the FIFO error flag */
667       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
668
669       /* Update error code */
670       hdma->ErrorCode |= HAL_DMA_ERROR_FE;
671
672       /* Change the DMA state */
673       hdma->State = HAL_DMA_STATE_ERROR;
674
675       /* Process Unlocked */
676       __HAL_UNLOCK(hdma);
677
678       if(hdma->XferErrorCallback != HAL_NULL)
679       {
680         /* Transfer error callback */
681         hdma->XferErrorCallback(hdma);
682       }
683     }
684   }
685   /* Direct Mode Error Interrupt management ***********************************/
686   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)
687   {
688     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
689     {
690       /* Disable the direct mode Error interrupt */
691       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);
692
693       /* Clear the direct mode error flag */
694       __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
695
696       /* Update error code */
697       hdma->ErrorCode |= HAL_DMA_ERROR_DME;
698
699       /* Change the DMA state */
700       hdma->State = HAL_DMA_STATE_ERROR;
701
702       /* Process Unlocked */
703       __HAL_UNLOCK(hdma);
704
705       if(hdma->XferErrorCallback != HAL_NULL)
706       {
707         /* Transfer error callback */
708         hdma->XferErrorCallback(hdma);
709       }
710     }
711   }
712   /* Half Transfer Complete Interrupt management ******************************/
713   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
714   {
715     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
716     { 
717       /* Multi_Buffering mode enabled */
718       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
719       {
720         /* Clear the half transfer complete flag */
721         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
722
723         /* Current memory buffer used is Memory 0 */
724         if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
725         {
726           /* Change DMA peripheral state */
727           hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
728         }
729         /* Current memory buffer used is Memory 1 */
730         else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
731         {
732           /* Change DMA peripheral state */
733           hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
734         }
735       }
736       else
737       {
738         /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
739         if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
740         {
741           /* Disable the half transfer interrupt */
742           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
743         }
744         /* Clear the half transfer complete flag */
745         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
746
747         /* Change DMA peripheral state */
748         hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
749       }
750
751       if(hdma->XferHalfCpltCallback != HAL_NULL)
752       {
753         /* Half transfer callback */
754         hdma->XferHalfCpltCallback(hdma);
755       }
756     }
757   }
758   /* Transfer Complete Interrupt management ***********************************/
759   if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
760   {
761     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
762     {
763       if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
764       {
765         /* Clear the transfer complete flag */
766         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
767
768         /* Current memory buffer used is Memory 1 */
769         if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
770         {
771           if(hdma->XferM1CpltCallback != HAL_NULL)
772           {
773             /* Transfer complete Callback for memory1 */
774             hdma->XferM1CpltCallback(hdma);
775           }
776         }
777         /* Current memory buffer used is Memory 0 */
778         else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) 
779         {
780           if(hdma->XferCpltCallback != HAL_NULL)
781           {
782             /* Transfer complete Callback for memory0 */
783             hdma->XferCpltCallback(hdma);
784           }
785         }
786       }
787       /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
788       else
789       {
790         if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
791         {
792           /* Disable the transfer complete interrupt */
793           __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
794         }
795         /* Clear the transfer complete flag */
796         __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
797
798         /* Update error code */
799         hdma->ErrorCode |= HAL_DMA_ERROR_NONE;
800
801         /* Change the DMA state */
802         hdma->State = HAL_DMA_STATE_READY_MEM0;
803
804         /* Process Unlocked */
805         __HAL_UNLOCK(hdma);      
806
807         if(hdma->XferCpltCallback != HAL_NULL)
808         {
809           /* Transfer complete callback */
810           hdma->XferCpltCallback(hdma);
811         }
812       }
813     }
814   }
815 }
816
817 /**
818   * @}
819   */
820
821 /** @defgroup DMA_Group3 Peripheral State functions
822  *  @brief    Peripheral State functions 
823  *
824 @verbatim
825  ===============================================================================
826                     ##### State and Errors functions #####
827  ===============================================================================
828     [..]
829     This subsection provides functions allowing to
830       (+) Check the DMA state
831       (+) Get error code
832
833 @endverbatim
834   * @{
835   */
836
837 /**
838   * @brief  Returns the DMA state.
839   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
840   *               the configuration information for the specified DMA Stream.
841   * @retval HAL state
842   */
843 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
844 {
845   return hdma->State;
846 }
847
848 /**
849   * @brief  Return the DMA error code
850   * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains
851   *              the configuration information for the specified DMA Stream.
852   * @retval DMA Error Code
853   */
854 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
855 {
856   return hdma->ErrorCode;
857 }
858
859 /**
860   * @}
861   */
862
863 /**
864   * @brief  Sets the DMA Transfer parameter.
865   * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
866   *                     the configuration information for the specified DMA Stream.
867   * @param  SrcAddress: The source memory Buffer address
868   * @param  DstAddress: The destination memory Buffer address
869   * @param  DataLength: The length of data to be transferred from source to destination
870   * @retval HAL status
871   */
872 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
873 {
874   /* Configure DMA Stream data length */
875   hdma->Instance->NDTR = DataLength;
876
877   /* Peripheral to Memory */
878   if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
879   {
880     /* Configure DMA Stream destination address */
881     hdma->Instance->PAR = DstAddress;
882
883     /* Configure DMA Stream source address */
884     hdma->Instance->M0AR = SrcAddress;
885   }
886   /* Memory to Peripheral */
887   else
888   {
889     /* Configure DMA Stream source address */
890     hdma->Instance->PAR = SrcAddress;
891     
892     /* Configure DMA Stream destination address */
893     hdma->Instance->M0AR = DstAddress;
894   }
895 }
896
897 /**
898   * @}
899   */
900
901 #endif /* HAL_DMA_MODULE_ENABLED */
902 /**
903   * @}
904   */
905
906 /**
907   * @}
908   */
909
910 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/