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 if(hdma->State != HAL_DMA_STATE_BUSY)
386 {
387 /* no transfer ongoing */
388 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
389
390 /* Process Unlocked */
391 __HAL_UNLOCK(hdma);
392
393 return HAL_ERROR;
394 }
395 else
396 {
397 /* Disable DMA IT */
398 hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE);
399
400 /* Disable the channel */
401 hdma->Instance->CCR &= ~DMA_CCR_EN;
402
403 /* Clear all flags */
404 hdma->DmaBaseAddress->IFCR = (DMA_FLAG_GL1 << hdma->ChannelIndex);
405 }
406 /* Change the DMA state*/
407 hdma->State = HAL_DMA_STATE_READY;
408
409 /* Process Unlocked */
410 __HAL_UNLOCK(hdma);
411
412 return HAL_OK;
413 }
414
415 /**
416 * @brief Abort the DMA Transfer in Interrupt mode.
417 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
418 * the configuration information for the specified DMA Stream.
419 * @retval HAL status
420 */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * hdma)421 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
422 {
423 HAL_StatusTypeDef status = HAL_OK;
424
425 if(HAL_DMA_STATE_BUSY != hdma->State)
426 {
427 /* no transfer ongoing */
428 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
429
430 status = HAL_ERROR;
431 }
432 else
433 {
434
435 /* Disable DMA IT */
436 hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE);
437
438 /* Disable the channel */
439 hdma->Instance->CCR &= ~DMA_CCR_EN;
440
441 /* Clear all flags */
442 hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex;
443
444 /* Change the DMA state */
445 hdma->State = HAL_DMA_STATE_READY;
446
447 /* Process Unlocked */
448 __HAL_UNLOCK(hdma);
449
450 /* Call User Abort callback */
451 if(hdma->XferAbortCallback != NULL)
452 {
453 hdma->XferAbortCallback(hdma);
454 }
455 }
456 return status;
457 }
458
459 /**
460 * @brief Polling for transfer complete.
461 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
462 * the configuration information for the specified DMA Channel.
463 * @param CompleteLevel Specifies the DMA level complete.
464 * @param Timeout Timeout duration.
465 * @retval HAL status
466 */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * hdma,uint32_t CompleteLevel,uint32_t Timeout)467 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
468 {
469 uint32_t temp;
470 uint32_t tickstart = 0U;
471
472 if(HAL_DMA_STATE_BUSY != hdma->State)
473 {
474 /* no transfer ongoing */
475 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
476 __HAL_UNLOCK(hdma);
477 return HAL_ERROR;
478 }
479
480 /* Polling mode not supported in circular mode */
481 if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
482 {
483 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
484 return HAL_ERROR;
485 }
486
487 /* Get the level transfer complete flag */
488 if(HAL_DMA_FULL_TRANSFER == CompleteLevel)
489 {
490 /* Transfer Complete flag */
491 temp = DMA_FLAG_TC1 << hdma->ChannelIndex;
492 }
493 else
494 {
495 /* Half Transfer Complete flag */
496 temp = DMA_FLAG_HT1 << hdma->ChannelIndex;
497 }
498
499 /* Get tick */
500 tickstart = HAL_GetTick();
501
502 while(RESET == (hdma->DmaBaseAddress->ISR & temp))
503 {
504 if(RESET != (hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << hdma->ChannelIndex)))
505 {
506 /* When a DMA transfer error occurs */
507 /* A hardware clear of its EN bits is performed */
508 /* Clear all flags */
509 hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex;
510
511 /* Update error code */
512 hdma->ErrorCode = HAL_DMA_ERROR_TE;
513
514 /* Change the DMA state */
515 hdma->State= HAL_DMA_STATE_READY;
516
517 /* Process Unlocked */
518 __HAL_UNLOCK(hdma);
519
520 return HAL_ERROR;
521 }
522 /* Check for the Timeout */
523 if(Timeout != HAL_MAX_DELAY)
524 {
525 if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
526 {
527 /* Update error code */
528 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
529
530 /* Change the DMA state */
531 hdma->State = HAL_DMA_STATE_READY;
532
533 /* Process Unlocked */
534 __HAL_UNLOCK(hdma);
535
536 return HAL_ERROR;
537 }
538 }
539 }
540
541 if(HAL_DMA_FULL_TRANSFER == CompleteLevel)
542 {
543 /* Clear the transfer complete flag */
544 hdma->DmaBaseAddress->IFCR = DMA_FLAG_TC1 << hdma->ChannelIndex;
545
546 /* The selected Channelx EN bit is cleared (DMA is disabled and
547 all transfers are complete) */
548 hdma->State = HAL_DMA_STATE_READY;
549 }
550 else
551 {
552 /* Clear the half transfer complete flag */
553 hdma->DmaBaseAddress->IFCR = DMA_FLAG_HT1 << hdma->ChannelIndex;
554 }
555
556 /* Process unlocked */
557 __HAL_UNLOCK(hdma);
558
559 return HAL_OK;
560 }
561
562 /**
563 * @brief Handle DMA interrupt request.
564 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
565 * the configuration information for the specified DMA Channel.
566 * @retval None
567 */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * hdma)568 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
569 {
570 uint32_t flag_it = hdma->DmaBaseAddress->ISR;
571 uint32_t source_it = hdma->Instance->CCR;
572
573 /* Half Transfer Complete Interrupt management ******************************/
574 if ((RESET != (flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_HT)))
575 {
576 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
577 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
578 {
579 /* Disable the half transfer interrupt */
580 hdma->Instance->CCR &= ~DMA_IT_HT;
581 }
582
583 /* Clear the half transfer complete flag */
584 hdma->DmaBaseAddress->IFCR = DMA_FLAG_HT1 << hdma->ChannelIndex;
585
586 /* DMA peripheral state is not updated in Half Transfer */
587 /* State is updated only in Transfer Complete case */
588
589 if(hdma->XferHalfCpltCallback != NULL)
590 {
591 /* Half transfer callback */
592 hdma->XferHalfCpltCallback(hdma);
593 }
594 }
595
596 /* Transfer Complete Interrupt management ***********************************/
597 else if ((RESET != (flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TC)))
598 {
599 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
600 {
601 /* Disable the transfer complete & transfer error interrupts */
602 /* if the DMA mode is not CIRCULAR */
603 hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_TE);
604
605 /* Change the DMA state */
606 hdma->State = HAL_DMA_STATE_READY;
607 }
608
609 /* Clear the transfer complete flag */
610 hdma->DmaBaseAddress->IFCR = DMA_FLAG_TC1 << hdma->ChannelIndex;
611
612 /* Process Unlocked */
613 __HAL_UNLOCK(hdma);
614
615 if(hdma->XferCpltCallback != NULL)
616 {
617 /* Transfer complete callback */
618 hdma->XferCpltCallback(hdma);
619 }
620 }
621
622 /* Transfer Error Interrupt management ***************************************/
623 else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
624 {
625 /* When a DMA transfer error occurs */
626 /* A hardware clear of its EN bits is performed */
627 /* Then, disable all DMA interrupts */
628 hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE);
629
630 /* Clear all flags */
631 hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex;
632
633 /* Update error code */
634 hdma->ErrorCode = HAL_DMA_ERROR_TE;
635
636 /* Change the DMA state */
637 hdma->State = HAL_DMA_STATE_READY;
638
639 /* Process Unlocked */
640 __HAL_UNLOCK(hdma);
641
642 if(hdma->XferErrorCallback != NULL)
643 {
644 /* Transfer error callback */
645 hdma->XferErrorCallback(hdma);
646 }
647 }
648 }
649
650 /**
651 * @brief Register callbacks
652 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
653 * the configuration information for the specified DMA Stream.
654 * @param CallbackID User Callback identifier
655 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
656 * @param pCallback pointer to private callback function which has pointer to
657 * a DMA_HandleTypeDef structure as parameter.
658 * @retval HAL status
659 */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* pCallback)(DMA_HandleTypeDef * _hdma))660 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
661 {
662 HAL_StatusTypeDef status = HAL_OK;
663
664 /* Process locked */
665 __HAL_LOCK(hdma);
666
667 if(HAL_DMA_STATE_READY == hdma->State)
668 {
669 switch (CallbackID)
670 {
671 case HAL_DMA_XFER_CPLT_CB_ID:
672 hdma->XferCpltCallback = pCallback;
673 break;
674
675 case HAL_DMA_XFER_HALFCPLT_CB_ID:
676 hdma->XferHalfCpltCallback = pCallback;
677 break;
678
679 case HAL_DMA_XFER_ERROR_CB_ID:
680 hdma->XferErrorCallback = pCallback;
681 break;
682
683 case HAL_DMA_XFER_ABORT_CB_ID:
684 hdma->XferAbortCallback = pCallback;
685 break;
686
687 default:
688 status = HAL_ERROR;
689 break;
690 }
691 }
692 else
693 {
694 status = HAL_ERROR;
695 }
696
697 /* Release Lock */
698 __HAL_UNLOCK(hdma);
699
700 return status;
701 }
702
703 /**
704 * @brief UnRegister callbacks
705 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
706 * the configuration information for the specified DMA Stream.
707 * @param CallbackID User Callback identifier
708 * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
709 * @retval HAL status
710 */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID)711 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
712 {
713 HAL_StatusTypeDef status = HAL_OK;
714
715 /* Process locked */
716 __HAL_LOCK(hdma);
717
718 if(HAL_DMA_STATE_READY == hdma->State)
719 {
720 switch (CallbackID)
721 {
722 case HAL_DMA_XFER_CPLT_CB_ID:
723 hdma->XferCpltCallback = NULL;
724 break;
725
726 case HAL_DMA_XFER_HALFCPLT_CB_ID:
727 hdma->XferHalfCpltCallback = NULL;
728 break;
729
730 case HAL_DMA_XFER_ERROR_CB_ID:
731 hdma->XferErrorCallback = NULL;
732 break;
733
734 case HAL_DMA_XFER_ABORT_CB_ID:
735 hdma->XferAbortCallback = NULL;
736 break;
737
738 case HAL_DMA_XFER_ALL_CB_ID:
739 hdma->XferCpltCallback = NULL;
740 hdma->XferHalfCpltCallback = NULL;
741 hdma->XferErrorCallback = NULL;
742 hdma->XferAbortCallback = NULL;
743 break;
744
745 default:
746 status = HAL_ERROR;
747 break;
748 }
749 }
750 else
751 {
752 status = HAL_ERROR;
753 }
754
755 /* Release Lock */
756 __HAL_UNLOCK(hdma);
757
758 return status;
759 }
760
761 /**
762 * @}
763 */
764
765 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State functions
766 * @brief Peripheral State functions
767 *
768 @verbatim
769 ===============================================================================
770 ##### State and Errors functions #####
771 ===============================================================================
772 [..]
773 This subsection provides functions allowing to
774 (+) Check the DMA state
775 (+) Get error code
776
777 @endverbatim
778 * @{
779 */
780
781 /**
782 * @brief Returns the DMA state.
783 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
784 * the configuration information for the specified DMA Channel.
785 * @retval HAL state
786 */
HAL_DMA_GetState(DMA_HandleTypeDef * hdma)787 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
788 {
789 return hdma->State;
790 }
791
792 /**
793 * @brief Return the DMA error code
794 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
795 * the configuration information for the specified DMA Channel.
796 * @retval DMA Error Code
797 */
HAL_DMA_GetError(DMA_HandleTypeDef * hdma)798 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
799 {
800 return hdma->ErrorCode;
801 }
802
803 /**
804 * @}
805 */
806
807 /**
808 * @}
809 */
810
811 /** @addtogroup DMA_Private_Functions
812 * @{
813 */
814
815 /**
816 * @brief Set the DMA Transfer parameters.
817 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
818 * the configuration information for the specified DMA Channel.
819 * @param SrcAddress The source memory Buffer address
820 * @param DstAddress The destination memory Buffer address
821 * @param DataLength The length of data to be transferred from source to destination
822 * @retval HAL status
823 */
DMA_SetConfig(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)824 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
825 {
826 /* Clear all flags */
827 hdma->DmaBaseAddress->IFCR = (DMA_FLAG_GL1 << hdma->ChannelIndex);
828
829 /* Configure DMA Channel data length */
830 hdma->Instance->CNDTR = DataLength;
831
832 /* Peripheral to Memory */
833 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
834 {
835 /* Configure DMA Channel destination address */
836 hdma->Instance->CPAR = DstAddress;
837
838 /* Configure DMA Channel source address */
839 hdma->Instance->CMAR = SrcAddress;
840 }
841 /* Memory to Peripheral */
842 else
843 {
844 /* Configure DMA Channel source address */
845 hdma->Instance->CPAR = SrcAddress;
846
847 /* Configure DMA Channel destination address */
848 hdma->Instance->CMAR = DstAddress;
849 }
850 }
851
852 /**
853 * @brief Set the DMA base address and channel index depending on DMA instance
854 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
855 * the configuration information for the specified DMA Stream.
856 * @retval None
857 */
DMA_CalcBaseAndBitshift(DMA_HandleTypeDef * hdma)858 static void DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
859 {
860 #if defined (DMA2)
861 /* calculation of the channel index */
862 if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
863 {
864 /* DMA1 */
865 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
866 hdma->DmaBaseAddress = DMA1;
867 }
868 else
869 {
870 /* DMA2 */
871 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
872 hdma->DmaBaseAddress = DMA2;
873 }
874 #else
875 /* calculation of the channel index */
876 /* DMA1 */
877 hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
878 hdma->DmaBaseAddress = DMA1;
879 #endif
880 }
881
882 /**
883 * @}
884 */
885
886 /**
887 * @}
888 */
889 #endif /* HAL_DMA_MODULE_ENABLED */
890
891 /**
892 * @}
893 */
894
895 /**
896 * @}
897 */
898
899