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