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