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>© 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