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