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