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