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