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