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