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