1 /**
2 **********************************************************************************************************************
3 * @file stm32wbaxx_hal_dma.c
4 * @author MCD Application Team
5 * @brief This file provides firmware functions to manage the following functionalities of the Direct Memory Access
6 * (DMA) peripheral:
7 * + Initialization/De-Initialization Functions
8 * + I/O Operation Functions
9 * + State and Errors Functions
10 * + DMA Attributes Functions
11 *
12 **********************************************************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2022 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 [..]
29 DMA transfer modes are divided to 2 major categories :
30 (+) Normal transfers (legacy)
31 (+) Linked-list transfers
32
33 [..]
34 Normal transfers mode is initialized via the standard module and linked-list mode is configured via the extended
35 module.
36
37 [..]
38 Additionally to linked-list capability, all advanced DMA features are managed and configured via the extended
39 module as extensions to normal mode.
40 Advanced features are :
41 (+) Repeated block feature.
42 (+) Trigger feature.
43 (+) Data handling feature.
44
45 [..]
46 DMA Legacy circular transfer, is replaced by circular linked-list configuration.
47
48
49 *** Initialization and De-Initialization ***
50 ============================================
51 [..]
52 For a given channel, enable and configure the peripheral to be connected to the DMA Channel (except for internal
53 SRAM/FLASH memories: no initialization is necessary) please refer to Reference manual for connection between
54 peripherals and DMA requests.
55
56 [..]
57 For a given channel, use HAL_DMA_Init function to program the required configuration for normal transfer through
58 the following parameters:
59
60 (+) Request : Specifies the DMA channel request
61 Request parameters :
62 (++) can be a value of DMA_Request_Selection
63
64 (+) BlkHWRequest : Specifies the Block hardware request mode for DMA channel
65 (++) can be a value of DMA_Block_Request
66
67 (+) Direction : Specifies the transfer direction for DMA channel
68 (++) can be a value of DMA_Transfer_Direction
69
70 (+) SrcInc : Specifies the source increment mode for the DMA channel
71 (++) can be a value of DMA_Source_Increment_Mode
72
73 (+) DestInc : Specifies the destination increment mode for the DMA channel
74 (++) can be a value of DMA_Destination_Increment_Mode
75
76 (+) SrcDataWidth : Specifies the source data width for the DMA channel
77 (++) can be a value of DMA_Source_Data_Width
78
79 (+) DestDataWidth : Specifies the destination data width for the DMA channel
80 (++) can be a value of DMA_Destination_Data_Width
81
82 (+) Priority : Specifies the priority for the DMA channel
83 (++) can be a value of DMA_Priority_Level
84
85 (+) SrcBurstLength : Specifies the source burst length (number of beats) for the DMA channel
86 (++) can be a value of between 1 and 64
87
88 (+) DestBurstLength : Specifies the destination burst length (number of beats) for the DMA channel
89 (++) can be a value of between 1 and 64
90
91 (+) TransferAllocatedPort : Specifies the source and destination allocated ports
92 (++) can be a value of DMA_Transfer_Allocated_Port
93
94 (+) TransferEventMode : Specifies the transfer event mode for the DMA channel
95 (++) can be a value of DMA_Transfer_Event_Mode
96
97 (+) Mode : Specifies the transfer mode for the DMA channel
98 (++) can be DMA_NORMAL
99
100 *** Polling mode IO operation ***
101 =================================
102 [..]
103 (+) Use HAL_DMA_Start() to start a DMA normal transfer after the configuration of source address, destination
104 address and the size of data to be transferred.
105
106 (+) Use HAL_DMA_PollForTransfer() to poll for selected transfer level. In this case a fixed Timeout can be
107 configured by User depending on his application.
108 Transfer level can be :
109 (++) HAL_DMA_HALF_TRANSFER
110 (++) HAL_DMA_FULL_TRANSFER
111 For circular transfer, this API returns an HAL_ERROR with HAL_DMA_ERROR_NOT_SUPPORTED error code.
112
113 (+) Use HAL_DMA_Abort() function to abort any ongoing DMA transfer in blocking mode.
114 This API returns HAL_ERROR when there is no ongoing transfer or timeout is reached when disabling the DMA
115 channel. (This API should not be called from an interrupt service routine)
116
117
118 *** Interrupt mode IO operation ***
119 ===================================
120 [..]
121 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
122
123 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
124
125 (+) Use HAL_DMA_RegisterCallback() function to register user callbacks from the following list :
126 (++) XferCpltCallback : transfer complete callback.
127 (++) XferHalfCpltCallback : half transfer complete callback.
128 (++) XferErrorCallback : transfer error callback.
129 (++) XferAbortCallback : transfer abort complete callback.
130 (++) XferSuspendCallback : transfer suspend complete callback.
131
132 (+) Use HAL_DMA_Start_IT() to start the DMA transfer after the enable of DMA interrupts and the configuration
133 of source address,destination address and the size of data to be transferred.
134
135 (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() interrupt subroutine to handle any DMA interrupt.
136
137 (+) Use HAL_DMA_Abort_IT() function to abort any on-going DMA transfer in non-blocking mode.
138 This API will suspend immediately the DMA channel execution. When the transfer is effectively suspended,
139 an interrupt is generated and HAL_DMA_IRQHandler() will reset the channel and execute the callback
140 XferAbortCallback. (This API could be called from an interrupt service routine)
141
142
143 *** State and errors ***
144 ========================
145 [..]
146 (+) Use HAL_DMA_GetState() function to get the DMA state.
147 (+) Use HAL_DMA_GetError() function to get the DMA error code.
148
149
150 *** Security and privilege attributes ***
151 =========================================
152 [..]
153 (+) Use HAL_DMA_ConfigChannelAttributes() function to configure DMA channel security and privilege attributes.
154 (++) Security : at channel level, at source level and at destination level.
155 (++) Privilege : at channel level.
156 (+) Use HAL_DMA_GetConfigChannelAttributes() function to get the DMA channel attributes.
157 (+) Use HAL_DMA_LockChannelAttributes() function to lock the DMA channel security and privilege attributes
158 configuration. This API can be called once after each system boot.
159 If called again, HAL_DMA_ConfigChannelAttributes() API has no effect.
160 Unlock is done either by a system boot or a by an RCC reset.
161 (+) Use HAL_DMA_GetLockChannelAttributes() function to get the attributes lock status.
162
163
164 *** DMA HAL driver macros list ***
165 ==================================
166 [..]
167 Below the list of most used macros in DMA HAL driver.
168
169 (+) __HAL_DMA_ENABLE : Enable the specified DMA Channel.
170 (+) __HAL_DMA_DISABLE : Disable the specified DMA Channel.
171 (+) __HAL_DMA_GET_FLAG : Get the DMA Channel pending flags.
172 (+) __HAL_DMA_CLEAR_FLAG : Clear the DMA Channel pending flags.
173 (+) __HAL_DMA_ENABLE_IT : Enable the specified DMA Channel interrupts.
174 (+) __HAL_DMA_DISABLE_IT : Disable the specified DMA Channel interrupts.
175 (+) __HAL_DMA_GET_IT_SOURCE : Check whether the specified DMA Channel interrupt has occurred or not.
176
177 [..]
178 (@) You can refer to the header file of the DMA HAL driver for more useful macros.
179
180 @endverbatim
181 **********************************************************************************************************************
182 */
183
184 /* Includes ----------------------------------------------------------------------------------------------------------*/
185 #include "stm32wbaxx_hal.h"
186
187 /** @addtogroup STM32WBAxx_HAL_Driver
188 * @{
189 */
190
191 /** @defgroup DMA DMA
192 * @brief DMA HAL module driver
193 * @{
194 */
195
196 #ifdef HAL_DMA_MODULE_ENABLED
197
198 /* Private typedef ---------------------------------------------------------------------------------------------------*/
199 /* Private constants -------------------------------------------------------------------------------------------------*/
200 /* Private macro -----------------------------------------------------------------------------------------------------*/
201 /* Private variables -------------------------------------------------------------------------------------------------*/
202 /* Private function prototypes ---------------------------------------------------------------------------------------*/
203 static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
204 uint32_t SrcAddress,
205 uint32_t DstAddress,
206 uint32_t SrcDataSize);
207 static void DMA_Init(DMA_HandleTypeDef const *const hdma);
208
209 /* Exported functions ------------------------------------------------------------------------------------------------*/
210
211 /** @addtogroup DMA_Exported_Functions DMA Exported Functions
212 * @{
213 */
214
215 /** @addtogroup DMA_Exported_Functions_Group1
216 *
217 @verbatim
218 ======================================================================================================================
219 ##### Initialization and de-initialization functions #####
220 ======================================================================================================================
221 [..]
222 This section provides functions allowing to initialize and de-initialize the DMA channel in normal mode.
223
224 [..]
225 (+) The HAL_DMA_Init() function follows the DMA channel configuration procedures as described in reference manual.
226 (+) The HAL_DMA_DeInit() function allows to de-initialize the DMA channel.
227
228 @endverbatim
229 * @{
230 */
231
232 /**
233 * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef and
234 * create the associated handle.
235 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
236 * specified DMA Channel.
237 * @retval HAL status.
238 */
HAL_DMA_Init(DMA_HandleTypeDef * const hdma)239 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *const hdma)
240 {
241
242 /* Get tick number */
243 uint32_t tickstart = HAL_GetTick();
244
245 /* Check the DMA peripheral handle parameter */
246 if (hdma == NULL)
247 {
248 return HAL_ERROR;
249 }
250
251 /* Check the parameters */
252 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
253 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
254 if (hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
255 {
256 assert_param(IS_DMA_REQUEST(hdma->Init.Request));
257 }
258 assert_param(IS_DMA_BLOCK_HW_REQUEST(hdma->Init.BlkHWRequest));
259 assert_param(IS_DMA_SOURCE_INC(hdma->Init.SrcInc));
260 assert_param(IS_DMA_DESTINATION_INC(hdma->Init.DestInc));
261 assert_param(IS_DMA_SOURCE_DATA_WIDTH(hdma->Init.SrcDataWidth));
262 assert_param(IS_DMA_DESTINATION_DATA_WIDTH(hdma->Init.DestDataWidth));
263 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
264 assert_param(IS_DMA_TCEM_EVENT_MODE(hdma->Init.TransferEventMode));
265 assert_param(IS_DMA_MODE(hdma->Init.Mode));
266 /* Check DMA channel instance */
267 if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
268 {
269 assert_param(IS_DMA_BURST_LENGTH(hdma->Init.SrcBurstLength));
270 assert_param(IS_DMA_BURST_LENGTH(hdma->Init.DestBurstLength));
271 assert_param(IS_DMA_TRANSFER_ALLOCATED_PORT(hdma->Init.TransferAllocatedPort));
272 }
273
274
275 /* Allocate lock resource */
276 __HAL_UNLOCK(hdma);
277
278 /* Update the DMA channel state */
279 hdma->State = HAL_DMA_STATE_BUSY;
280
281 /* Disable the DMA channel */
282 __HAL_DMA_DISABLE(hdma);
283
284 /* Check if the DMA channel is effectively disabled */
285 while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
286 {
287 /* Check for the Timeout */
288 if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
289 {
290 /* Update the DMA channel error code */
291 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
292
293 /* Update the DMA channel state */
294 hdma->State = HAL_DMA_STATE_ERROR;
295
296 return HAL_ERROR;
297 }
298 }
299
300 /* Initialize the DMA channel registers */
301 DMA_Init(hdma);
302
303 /* Update DMA channel operation mode */
304 hdma->Mode = hdma->Init.Mode;
305
306 /* Update the DMA channel error code */
307 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
308
309 /* Update the DMA channel state */
310 hdma->State = HAL_DMA_STATE_READY;
311
312 return HAL_OK;
313 }
314
315 /**
316 * @brief DeInitialize the DMA channel when it is configured in normal mode.
317 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
318 * specified DMA Channel.
319 * @retval HAL status.
320 */
HAL_DMA_DeInit(DMA_HandleTypeDef * const hdma)321 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *const hdma)
322 {
323 #if defined (DMA_PRIVCFGR_PRIV0)
324 DMA_TypeDef *p_dma_instance;
325 #endif /* DMA_PRIVCFGR_PRIV0 */
326 uint32_t tickstart = HAL_GetTick();
327
328 /* Check the DMA peripheral handle parameter */
329 if (hdma == NULL)
330 {
331 return HAL_ERROR;
332 }
333
334 /* Check the parameters */
335 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
336 #if defined (DMA_PRIVCFGR_PRIV0)
337 /* Get DMA instance */
338 p_dma_instance = GET_DMA_INSTANCE(hdma);
339 #endif /* DMA_PRIVCFGR_PRIV0 */
340 /* Disable the selected DMA Channel */
341 __HAL_DMA_DISABLE(hdma);
342
343 /* Check if the DMA channel is effectively disabled */
344 while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
345 {
346 /* Check for the Timeout */
347 if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
348 {
349 /* Update the DMA channel error code */
350 hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
351
352 /* Update the DMA channel state */
353 hdma->State = HAL_DMA_STATE_ERROR;
354
355 return HAL_ERROR;
356 }
357 }
358
359 /* Reset DMA Channel registers */
360 hdma->Instance->CLBAR = 0U;
361 hdma->Instance->CCR = 0U;
362 hdma->Instance->CTR1 = 0U;
363 hdma->Instance->CTR2 = 0U;
364 hdma->Instance->CBR1 = 0U;
365 hdma->Instance->CSAR = 0U;
366 hdma->Instance->CDAR = 0U;
367 hdma->Instance->CLLR = 0U;
368 #if defined (DMA_PRIVCFGR_PRIV0)
369 /* Clear privilege attribute */
370 CLEAR_BIT(p_dma_instance->PRIVCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU)));
371 #endif /* DMA_PRIVCFGR_PRIV0 */
372 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
373 /* Clear secure attribute */
374 CLEAR_BIT(p_dma_instance->SECCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU)));
375 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
376
377 /* Clear all flags */
378 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
379 DMA_FLAG_TO));
380
381 /* Clean all callbacks */
382 hdma->XferCpltCallback = NULL;
383 hdma->XferHalfCpltCallback = NULL;
384 hdma->XferErrorCallback = NULL;
385 hdma->XferAbortCallback = NULL;
386 hdma->XferSuspendCallback = NULL;
387
388 /* Clean DMA queue */
389 hdma->LinkedListQueue = NULL;
390
391 /* Clean DMA parent */
392 if (hdma->Parent != NULL)
393 {
394 hdma->Parent = NULL;
395 }
396
397 /* Update DMA channel operation mode */
398 hdma->Mode = DMA_NORMAL;
399
400 /* Update the DMA channel error code */
401 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
402
403 /* Update the DMA channel state */
404 hdma->State = HAL_DMA_STATE_RESET;
405
406 /* Release Lock */
407 __HAL_UNLOCK(hdma);
408
409 return HAL_OK;
410 }
411 /**
412 * @}
413 */
414
415 /** @addtogroup DMA_Exported_Functions_Group2
416 *
417 @verbatim
418 ======================================================================================================================
419 ##### IO operation functions #####
420 ======================================================================================================================
421 [..]
422 This section provides functions allowing to :
423 (+) Configure the source, destination address and data size and Start DMA transfer in normal mode
424 (+) Abort DMA transfer
425 (+) Poll for transfer complete
426 (+) Handle DMA interrupt request
427 (+) Register and Unregister DMA callbacks
428
429 [..]
430 (+) The HAL_DMA_Start() function allows to start the DMA channel transfer in normal mode (Blocking mode).
431 (+) The HAL_DMA_Start_IT() function allows to start the DMA channel transfer in normal mode (Non-blocking mode).
432 (+) The HAL_DMA_Abort() function allows to abort any on-going transfer (Blocking mode).
433 (+) The HAL_DMA_Abort_IT() function allows to abort any on-going transfer (Non-blocking mode).
434 (+) The HAL_DMA_PollForTransfer() function allows to poll on half transfer and transfer complete (Blocking mode).
435 This API cannot be used for circular transfers.
436 (+) The HAL_DMA_IRQHandler() function allows to handle any DMA channel interrupt (Non-blocking mode).
437 (+) The HAL_DMA_RegisterCallback() and HAL_DMA_UnRegisterCallback() functions allow respectively to register and
438 unregister user customized callbacks.
439 User callbacks are called under HAL_DMA_IRQHandler().
440
441 @endverbatim
442 * @{
443 */
444
445 /**
446 * @brief Start the DMA channel transfer in normal mode (Blocking mode).
447 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
448 * the specified DMA Channel.
449 * @param SrcAddress : The source data address.
450 * @param DstAddress : The destination data address.
451 * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
452 * @retval HAL status.
453 */
HAL_DMA_Start(DMA_HandleTypeDef * const hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SrcDataSize)454 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *const hdma,
455 uint32_t SrcAddress,
456 uint32_t DstAddress,
457 uint32_t SrcDataSize)
458 {
459 /* Check the DMA peripheral handle parameter */
460 if (hdma == NULL)
461 {
462 return HAL_ERROR;
463 }
464
465 /* Check the parameters */
466 assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
467
468 /* Process locked */
469 __HAL_LOCK(hdma);
470
471 /* Check DMA channel state */
472 if (hdma->State == HAL_DMA_STATE_READY)
473 {
474 /* Update the DMA channel state */
475 hdma->State = HAL_DMA_STATE_BUSY;
476
477 /* Update the DMA channel error code */
478 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
479
480 /* Configure the source address, destination address, the data size and clear flags */
481 DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize);
482
483 /* Enable DMA channel */
484 __HAL_DMA_ENABLE(hdma);
485 }
486 else
487 {
488 /* Update the DMA channel error code */
489 hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
490
491 /* Process unlocked */
492 __HAL_UNLOCK(hdma);
493
494 return HAL_ERROR;
495 }
496
497 return HAL_OK;
498 }
499
500 /**
501 * @brief Starts the DMA channel transfer in normal mode with interrupts enabled (Non-blocking mode).
502 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
503 * specified DMA Channel.
504 * @param SrcAddress : The source data address.
505 * @param DstAddress : The destination data address.
506 * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
507 * @retval HAL status.
508 */
HAL_DMA_Start_IT(DMA_HandleTypeDef * const hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SrcDataSize)509 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *const hdma,
510 uint32_t SrcAddress,
511 uint32_t DstAddress,
512 uint32_t SrcDataSize)
513 {
514 /* Check the DMA peripheral handle parameter */
515 if (hdma == NULL)
516 {
517 return HAL_ERROR;
518 }
519
520 /* Check the parameters */
521 assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
522
523 /* Process locked */
524 __HAL_LOCK(hdma);
525
526 /* Check DMA channel state */
527 if (hdma->State == HAL_DMA_STATE_READY)
528 {
529 /* Update the DMA channel state */
530 hdma->State = HAL_DMA_STATE_BUSY;
531
532 /* Update the DMA channel error code */
533 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
534
535 /* Configure the source address, destination address, the data size and clear flags */
536 DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize);
537
538 /* Enable common interrupts: Transfer Complete and Transfer Errors ITs */
539 __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_DTE | DMA_IT_ULE | DMA_IT_USE | DMA_IT_TO));
540
541 /* Check half transfer complete callback */
542 if (hdma->XferHalfCpltCallback != NULL)
543 {
544 /* If Half Transfer complete callback is set, enable the corresponding IT */
545 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
546 }
547
548 /* Check Half suspend callback */
549 if (hdma->XferSuspendCallback != NULL)
550 {
551 /* If Transfer suspend callback is set, enable the corresponding IT */
552 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_SUSP);
553 }
554
555 /* Enable DMA channel */
556 __HAL_DMA_ENABLE(hdma);
557 }
558 else
559 {
560 /* Update the DMA channel error code */
561 hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
562
563 /* Process unlocked */
564 __HAL_UNLOCK(hdma);
565
566 return HAL_ERROR;
567 }
568
569 return HAL_OK;
570 }
571
572 /**
573 * @brief Abort any on-going DMA channel transfer (Blocking mode).
574 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
575 * specified DMA Channel.
576 * @note After suspending a DMA channel, a wait until the DMA channel is effectively stopped is added. If a channel
577 * is suspended while a data transfer is on-going, the current data will be transferred and the channel will be
578 * effectively suspended only after the transfer of any on-going data is finished.
579 * @retval HAL status.
580 */
HAL_DMA_Abort(DMA_HandleTypeDef * const hdma)581 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *const hdma)
582 {
583 /* Get tick number */
584 uint32_t tickstart = HAL_GetTick();
585
586 /* Check the DMA peripheral handle parameter */
587 if (hdma == NULL)
588 {
589 return HAL_ERROR;
590 }
591
592 /* Check DMA channel state */
593 if (hdma->State != HAL_DMA_STATE_BUSY)
594 {
595 /* Update the DMA channel error code */
596 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
597
598 /* Process Unlocked */
599 __HAL_UNLOCK(hdma);
600
601 return HAL_ERROR;
602 }
603 else
604 {
605 /* Suspend the channel */
606 hdma->Instance->CCR |= DMA_CCR_SUSP;
607
608 /* Update the DMA channel state */
609 hdma->State = HAL_DMA_STATE_SUSPEND;
610
611 /* Check if the DMA Channel is suspended */
612 while ((hdma->Instance->CSR & DMA_CSR_SUSPF) == 0U)
613 {
614 /* Check for the Timeout */
615 if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
616 {
617 /* Update the DMA channel error code */
618 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
619
620 /* Update the DMA channel state */
621 hdma->State = HAL_DMA_STATE_ERROR;
622
623 /* Check DMA channel transfer mode */
624 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
625 {
626 /* Update the linked-list queue state */
627 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
628 }
629
630 /* Process Unlocked */
631 __HAL_UNLOCK(hdma);
632
633 return HAL_ERROR;
634 }
635 }
636
637 /* Reset the channel */
638 hdma->Instance->CCR |= DMA_CCR_RESET;
639
640 /* Update the DMA channel state */
641 hdma->State = HAL_DMA_STATE_ABORT;
642
643 /* Clear all status flags */
644 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
645 DMA_FLAG_TO));
646
647 /* Update the DMA channel state */
648 hdma->State = HAL_DMA_STATE_READY;
649
650 /* Check DMA channel transfer mode */
651 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
652 {
653 /* Update the linked-list queue state */
654 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
655
656 /* Clear remaining data size to ensure loading linked-list from memory next start */
657 hdma->Instance->CBR1 = 0U;
658 }
659
660 /* Process Unlocked */
661 __HAL_UNLOCK(hdma);
662 }
663
664 return HAL_OK;
665 }
666
667 /**
668 * @brief Abort any on-going DMA channel transfer in interrupt mode (Non-blocking mode).
669 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
670 * specified DMA Channel.
671 * @retval HAL status.
672 */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * const hdma)673 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *const hdma)
674 {
675 /* Check the DMA peripheral handle parameter */
676 if (hdma == NULL)
677 {
678 return HAL_ERROR;
679 }
680
681 /* Check DMA channel state */
682 if (hdma->State != HAL_DMA_STATE_BUSY)
683 {
684 /* Update the DMA channel error code */
685 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
686
687 return HAL_ERROR;
688 }
689 else
690 {
691 /* Update the DMA channel state */
692 hdma->State = HAL_DMA_STATE_ABORT;
693
694 /* Suspend the channel and activate suspend interrupt */
695 hdma->Instance->CCR |= (DMA_CCR_SUSP | DMA_CCR_SUSPIE);
696 }
697
698 return HAL_OK;
699 }
700
701 /**
702 * @brief Polling for transfer status (Blocking mode).
703 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
704 * specified DMA Channel.
705 * @param CompleteLevel : Specifies the DMA level complete.
706 * @param Timeout : Timeout duration.
707 * @retval HAL status
708 */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * const hdma,HAL_DMA_LevelCompleteTypeDef CompleteLevel,uint32_t Timeout)709 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *const hdma,
710 HAL_DMA_LevelCompleteTypeDef CompleteLevel,
711 uint32_t Timeout)
712 {
713 /* Get tick number */
714 uint32_t tickstart = HAL_GetTick();
715 uint32_t level_flag;
716 uint32_t tmp_csr;
717
718 /* Check the DMA peripheral handle parameter */
719 if (hdma == NULL)
720 {
721 return HAL_ERROR;
722 }
723
724 /* Check the parameters */
725 assert_param(IS_DMA_LEVEL_COMPLETE(CompleteLevel));
726
727 /* Check DMA channel state */
728 if (hdma->State != HAL_DMA_STATE_BUSY)
729 {
730 /* Update the DMA channel error code */
731 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
732
733 /* Process Unlocked */
734 __HAL_UNLOCK(hdma);
735
736 return HAL_ERROR;
737 }
738
739 /* Polling mode is not supported in circular mode */
740 if ((hdma->Mode & DMA_LINKEDLIST_CIRCULAR) == DMA_LINKEDLIST_CIRCULAR)
741 {
742 /* Update the DMA channel error code */
743 hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
744
745 return HAL_ERROR;
746 }
747
748 /* Get the level transfer complete flag */
749 level_flag = ((CompleteLevel == HAL_DMA_FULL_TRANSFER) ? DMA_FLAG_IDLE : DMA_FLAG_HT);
750
751 /* Get DMA channel status */
752 tmp_csr = hdma->Instance->CSR;
753
754 while ((tmp_csr & level_flag) == 0U)
755 {
756 /* Check for the timeout */
757 if (Timeout != HAL_MAX_DELAY)
758 {
759 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
760 {
761 /* Update the DMA channel error code */
762 hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
763
764 /*
765 If timeout, abort the current transfer.
766 Note that the Abort function will
767 - Clear all transfer flags.
768 - Unlock.
769 - Set the State.
770 */
771 (void)HAL_DMA_Abort(hdma);
772
773 return HAL_ERROR;
774 }
775 }
776
777 /* Get a newer CSR register value */
778 tmp_csr = hdma->Instance->CSR;
779 }
780
781 /* Check trigger overrun flag */
782 if ((tmp_csr & DMA_FLAG_TO) != 0U)
783 {
784 /* Update the DMA channel error code */
785 hdma->ErrorCode |= HAL_DMA_ERROR_TO;
786
787 /* Clear the error flag */
788 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
789 }
790
791 /* Check error flags */
792 if ((tmp_csr & (DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE)) != 0U)
793 {
794 /* Check the data transfer error flag */
795 if ((tmp_csr & DMA_FLAG_DTE) != 0U)
796 {
797 /* Update the DMA channel error code */
798 hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
799
800 /* Clear the error flag */
801 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
802 }
803
804 /* Check the update link error flag */
805 if ((tmp_csr & DMA_FLAG_ULE) != 0U)
806 {
807 /* Update the DMA channel error code */
808 hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
809
810 /* Clear the error flag */
811 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
812 }
813
814 /* Check the user setting error flag */
815 if ((tmp_csr & DMA_FLAG_USE) != 0U)
816 {
817 /* Update the DMA channel error code */
818 hdma->ErrorCode |= HAL_DMA_ERROR_USE;
819
820 /* Clear the error flag */
821 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
822 }
823
824 /* Reset the channel */
825 hdma->Instance->CCR |= DMA_CCR_RESET;
826
827 /* Update the DMA channel state */
828 hdma->State = HAL_DMA_STATE_READY;
829
830 /* Check DMA channel transfer mode */
831 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
832 {
833 /* Update the linked-list queue state */
834 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
835 }
836
837 /* Process Unlocked */
838 __HAL_UNLOCK(hdma);
839
840 return HAL_ERROR;
841 }
842
843 /* Clear the transfer level flag */
844 if (CompleteLevel == HAL_DMA_HALF_TRANSFER)
845 {
846 /* Clear the Half Transfer flag */
847 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
848 }
849 else if (CompleteLevel == HAL_DMA_FULL_TRANSFER)
850 {
851 /* Clear the transfer flags */
852 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
853
854 /* Update the DMA channel state */
855 hdma->State = HAL_DMA_STATE_READY;
856
857 /* Check DMA channel transfer mode */
858 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
859 {
860 /* Update the linked-list queue state */
861 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
862 }
863
864 /* Process unlocked */
865 __HAL_UNLOCK(hdma);
866 }
867 else
868 {
869 return HAL_ERROR;
870 }
871
872 return HAL_OK;
873 }
874
875 /**
876 * @brief Handle DMA interrupt request (Non-blocking mode).
877 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
878 * specified DMA Channel.
879 * @retval None.
880 */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * const hdma)881 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
882 {
883 const DMA_TypeDef *p_dma_instance = GET_DMA_INSTANCE(hdma);
884 uint32_t global_it_flag = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
885 uint32_t global_active_flag_ns = IS_DMA_GLOBAL_ACTIVE_FLAG_NS(p_dma_instance, global_it_flag);
886 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
887 uint32_t global_active_flag_s = IS_DMA_GLOBAL_ACTIVE_FLAG_S(p_dma_instance, global_it_flag);
888 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
889
890 /* Global Interrupt Flag management *********************************************************************************/
891 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
892 if ((global_active_flag_s == 0U) && (global_active_flag_ns == 0U))
893 #else
894 if (global_active_flag_ns == 0U)
895 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
896 {
897 return; /* the global interrupt flag for the current channel is down , nothing to do */
898 }
899
900 /* Data Transfer Error Interrupt management *************************************************************************/
901 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_DTE) != 0U))
902 {
903 /* Check if interrupt source is enabled */
904 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DTE) != 0U)
905 {
906 /* Clear the transfer error flag */
907 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
908
909 /* Update the DMA channel error code */
910 hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
911 }
912 }
913
914 /* Update Linked-list Error Interrupt management ********************************************************************/
915 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_ULE) != 0U))
916 {
917 /* Check if interrupt source is enabled */
918 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_ULE) != 0U)
919 {
920 /* Clear the update linked-list error flag */
921 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
922
923 /* Update the DMA channel error code */
924 hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
925 }
926 }
927
928 /* User Setting Error Interrupt management **************************************************************************/
929 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_USE) != 0U))
930 {
931 /* Check if interrupt source is enabled */
932 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_USE) != 0U)
933 {
934 /* Clear the user setting error flag */
935 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
936
937 /* Update the DMA channel error code */
938 hdma->ErrorCode |= HAL_DMA_ERROR_USE;
939 }
940 }
941
942 /* Trigger Overrun Interrupt management *****************************************************************************/
943 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TO) != 0U))
944 {
945 /* Check if interrupt source is enabled */
946 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TO) != 0U)
947 {
948 /* Clear the trigger overrun flag */
949 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
950
951 /* Update the DMA channel error code */
952 hdma->ErrorCode |= HAL_DMA_ERROR_TO;
953 }
954 }
955
956 /* Half Transfer Complete Interrupt management **********************************************************************/
957 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_HT) != 0U))
958 {
959 /* Check if interrupt source is enabled */
960 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
961 {
962 /* Clear the half transfer flag */
963 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
964
965 /* Check half transfer complete callback */
966 if (hdma->XferHalfCpltCallback != NULL)
967 {
968 /* Half transfer callback */
969 hdma->XferHalfCpltCallback(hdma);
970 }
971 }
972 }
973
974 /* Suspend Transfer Interrupt management ****************************************************************************/
975 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_SUSP) != 0U))
976 {
977 /* Check if interrupt source is enabled */
978 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_SUSP) != 0U)
979 {
980 /* Clear the block transfer complete flag */
981 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_SUSP);
982
983 /* Check DMA channel state */
984 if (hdma->State == HAL_DMA_STATE_ABORT)
985 {
986 /* Disable the suspend transfer interrupt */
987 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_SUSP);
988
989 /* Reset the channel internal state and reset the FIFO */
990 hdma->Instance->CCR |= DMA_CCR_RESET;
991
992 /* Update the DMA channel state */
993 hdma->State = HAL_DMA_STATE_READY;
994
995 /* Check DMA channel transfer mode */
996 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
997 {
998 /* Update the linked-list queue state */
999 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1000
1001 /* Clear remaining data size to ensure loading linked-list from memory next start */
1002 hdma->Instance->CBR1 = 0U;
1003 }
1004
1005 /* Process Unlocked */
1006 __HAL_UNLOCK(hdma);
1007
1008 /* Check transfer abort callback */
1009 if (hdma->XferAbortCallback != NULL)
1010 {
1011 /* Transfer abort callback */
1012 hdma->XferAbortCallback(hdma);
1013 }
1014
1015 return;
1016 }
1017 else
1018 {
1019 /* Update the DMA channel state */
1020 hdma->State = HAL_DMA_STATE_SUSPEND;
1021
1022 /* Check transfer suspend callback */
1023 if (hdma->XferSuspendCallback != NULL)
1024 {
1025 /* Transfer suspend callback */
1026 hdma->XferSuspendCallback(hdma);
1027 }
1028 }
1029 }
1030 }
1031
1032 /* Transfer Complete Interrupt management ***************************************************************************/
1033 if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U))
1034 {
1035 /* Check if interrupt source is enabled */
1036 if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
1037 {
1038 /* Check DMA channel transfer mode */
1039 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1040 {
1041 /* If linked-list transfer */
1042 if (hdma->Instance->CLLR == 0U)
1043 {
1044 if (hdma->Instance->CBR1 == 0U)
1045 {
1046 /* Update the DMA channel state */
1047 hdma->State = HAL_DMA_STATE_READY;
1048
1049 /* Update the linked-list queue state */
1050 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1051 }
1052 }
1053 }
1054 else
1055 {
1056 /* If normal transfer */
1057 if (hdma->Instance->CBR1 == 0U)
1058 {
1059 /* Update the DMA channel state */
1060 hdma->State = HAL_DMA_STATE_READY;
1061 }
1062 }
1063
1064 /* Clear TC and HT transfer flags */
1065 __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
1066
1067 /* Process Unlocked */
1068 __HAL_UNLOCK(hdma);
1069
1070 /* Check transfer complete callback */
1071 if (hdma->XferCpltCallback != NULL)
1072 {
1073 /* Channel Transfer Complete callback */
1074 hdma->XferCpltCallback(hdma);
1075 }
1076 }
1077 }
1078
1079 /* Manage error case ************************************************************************************************/
1080 if (hdma->ErrorCode != HAL_DMA_ERROR_NONE)
1081 {
1082 /* Reset the channel internal state and reset the FIFO */
1083 hdma->Instance->CCR |= DMA_CCR_RESET;
1084
1085 /* Update the DMA channel state */
1086 hdma->State = HAL_DMA_STATE_READY;
1087
1088 /* Check DMA channel transfer mode */
1089 if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1090 {
1091 /* Update the linked-list queue state */
1092 hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
1093 }
1094
1095 /* Process Unlocked */
1096 __HAL_UNLOCK(hdma);
1097
1098 /* Check transfer error callback */
1099 if (hdma->XferErrorCallback != NULL)
1100 {
1101 /* Transfer error callback */
1102 hdma->XferErrorCallback(hdma);
1103 }
1104 }
1105 }
1106
1107 /**
1108 * @brief Register callback according to specified ID.
1109 * @note The HAL_DMA_RegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
1110 * to register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
1111 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1112 * specified DMA Channel.
1113 * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enumeration.
1114 * @param pCallback : Pointer to private callback function.
1115 * @retval HAL status.
1116 */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * const hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* const pCallback)(DMA_HandleTypeDef * const _hdma))1117 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *const hdma,
1118 HAL_DMA_CallbackIDTypeDef CallbackID,
1119 void (*const pCallback)(DMA_HandleTypeDef *const _hdma))
1120 {
1121 HAL_StatusTypeDef status = HAL_OK;
1122
1123 /* Check the DMA peripheral handle parameter */
1124 if (hdma == NULL)
1125 {
1126 return HAL_ERROR;
1127 }
1128
1129 /* Check DMA channel state */
1130 if (hdma->State == HAL_DMA_STATE_READY)
1131 {
1132 /* Check callback ID */
1133 switch (CallbackID)
1134 {
1135 case HAL_DMA_XFER_CPLT_CB_ID:
1136 {
1137 /* Register transfer complete callback */
1138 hdma->XferCpltCallback = pCallback;
1139 break;
1140 }
1141
1142 case HAL_DMA_XFER_HALFCPLT_CB_ID:
1143 {
1144 /* Register half transfer callback */
1145 hdma->XferHalfCpltCallback = pCallback;
1146 break;
1147 }
1148
1149 case HAL_DMA_XFER_ERROR_CB_ID:
1150 {
1151 /* Register transfer error callback */
1152 hdma->XferErrorCallback = pCallback;
1153 break;
1154 }
1155
1156 case HAL_DMA_XFER_ABORT_CB_ID:
1157 {
1158 /* Register abort callback */
1159 hdma->XferAbortCallback = pCallback;
1160 break;
1161 }
1162
1163 case HAL_DMA_XFER_SUSPEND_CB_ID:
1164 {
1165 /* Register suspend callback */
1166 hdma->XferSuspendCallback = pCallback;
1167 break;
1168 }
1169
1170 default:
1171 {
1172 /* Update error status */
1173 status = HAL_ERROR;
1174 break;
1175 }
1176 }
1177 }
1178 else
1179 {
1180 /* Update error status */
1181 status = HAL_ERROR;
1182 }
1183
1184 return status;
1185 }
1186
1187 /**
1188 * @brief Unregister callback according to specified ID.
1189 * @note The HAL_DMA_UnRegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
1190 * to un-register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
1191 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1192 * specified DMA Channel.
1193 * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enum.
1194 * @retval HAL status.
1195 */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * const hdma,HAL_DMA_CallbackIDTypeDef CallbackID)1196 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *const hdma,
1197 HAL_DMA_CallbackIDTypeDef CallbackID)
1198 {
1199 HAL_StatusTypeDef status = HAL_OK;
1200
1201 /* Check the DMA peripheral handle parameter */
1202 if (hdma == NULL)
1203 {
1204 return HAL_ERROR;
1205 }
1206
1207 /* Check DMA channel state */
1208 if (hdma->State == HAL_DMA_STATE_READY)
1209 {
1210 /* Check callback ID */
1211 switch (CallbackID)
1212 {
1213 case HAL_DMA_XFER_CPLT_CB_ID:
1214 {
1215 /* UnRegister transfer complete callback */
1216 hdma->XferCpltCallback = NULL;
1217 break;
1218 }
1219
1220 case HAL_DMA_XFER_HALFCPLT_CB_ID:
1221 {
1222 /* UnRegister half transfer callback */
1223 hdma->XferHalfCpltCallback = NULL;
1224 break;
1225 }
1226
1227 case HAL_DMA_XFER_ERROR_CB_ID:
1228 {
1229 /* UnRegister transfer error callback */
1230 hdma->XferErrorCallback = NULL;
1231 break;
1232 }
1233
1234 case HAL_DMA_XFER_ABORT_CB_ID:
1235 {
1236 /* UnRegister abort callback */
1237 hdma->XferAbortCallback = NULL;
1238 break;
1239 }
1240
1241 case HAL_DMA_XFER_SUSPEND_CB_ID:
1242 {
1243 /* UnRegister suspend callback */
1244 hdma->XferSuspendCallback = NULL;
1245 break;
1246 }
1247
1248 case HAL_DMA_XFER_ALL_CB_ID:
1249 {
1250 /* UnRegister all available callbacks */
1251 hdma->XferCpltCallback = NULL;
1252 hdma->XferHalfCpltCallback = NULL;
1253 hdma->XferErrorCallback = NULL;
1254 hdma->XferAbortCallback = NULL;
1255 hdma->XferSuspendCallback = NULL;
1256 break;
1257 }
1258
1259 default:
1260 {
1261 /* Update error status */
1262 status = HAL_ERROR;
1263 break;
1264 }
1265 }
1266 }
1267 else
1268 {
1269 /* Update error status */
1270 status = HAL_ERROR;
1271 }
1272
1273 return status;
1274 }
1275 /**
1276 * @}
1277 */
1278
1279 /** @addtogroup DMA_Exported_Functions_Group3
1280 *
1281 @verbatim
1282 ======================================================================================================================
1283 ##### State and Errors functions #####
1284 ======================================================================================================================
1285 [..]
1286 This section provides functions allowing to :
1287 (+) Check the DMA state
1288 (+) Get error code
1289
1290 [..]
1291 (+) The HAL_DMA_GetState() function allows to get the DMA channel state.
1292 (+) The HAL_DMA_DeInit() function allows to get the DMA channel error code.
1293
1294 @endverbatim
1295 * @{
1296 */
1297
1298 /**
1299 * @brief Returns the DMA channel state.
1300 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1301 * specified DMA Channel.
1302 * @retval DMA state.
1303 */
HAL_DMA_GetState(DMA_HandleTypeDef const * const hdma)1304 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef const *const hdma)
1305 {
1306 /* Return the DMA channel state */
1307 return hdma->State;
1308 }
1309
1310 /**
1311 * @brief Return the DMA channel error code.
1312 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1313 * specified DMA Channel.
1314 * @retval DMA Error Code.
1315 */
HAL_DMA_GetError(DMA_HandleTypeDef const * const hdma)1316 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef const *const hdma)
1317 {
1318 /* Return the DMA channel error code */
1319 return hdma->ErrorCode;
1320 }
1321 /**
1322 * @}
1323 */
1324
1325 /** @addtogroup DMA_Exported_Functions_Group4
1326 *
1327 @verbatim
1328 ======================================================================================================================
1329 ##### DMA Attributes functions #####
1330 ======================================================================================================================
1331 [..]
1332 This section provides functions allowing to :
1333 (+) Configure DMA channel secure and privilege attributes.
1334 (+) Get DMA channel secure and privilege attributes.
1335 (+) Lock DMA channel secure and privilege attributes configuration.
1336 (+) Check whether DMA channel secure and privilege attributes configuration is locked or not.
1337
1338 [..]
1339 (+) The HAL_DMA_ConfigChannelAttributes() function allows to configure DMA channel security and privilege
1340 attributes.
1341 (+) The HAL_DMA_GetConfigChannelAttributes() function allows to get DMA channel security and privilege attributes
1342 configuration.
1343 (+) The HAL_DMA_LockChannelAttributes() function allows to lock the DMA channel security and privilege attributes.
1344 (+) The HAL_DMA_GetLockChannelAttributes() function allows to get the DMA channel security and privilege
1345 attributes lock status.
1346
1347 @endverbatim
1348 * @{
1349 */
1350 #if defined (DMA_PRIVCFGR_PRIV0)
1351 /**
1352 * @brief Configure the DMA channel security and privilege attribute(s).
1353 * @note These attributes cannot be modified when the corresponding lock state is enabled.
1354 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
1355 * the specified DMA Channel.
1356 * @param ChannelAttributes : Specifies the DMA channel secure/privilege attributes.
1357 * This parameter can be a one or a combination of @ref DMA_Channel_Attributes.
1358 * @retval HAL Status.
1359 */
HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef * const hdma,uint32_t ChannelAttributes)1360 HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *const hdma, uint32_t ChannelAttributes)
1361 {
1362 DMA_TypeDef *p_dma_instance;
1363 uint32_t channel_idx;
1364
1365 /* Check the DMA peripheral handle parameter */
1366 if (hdma == NULL)
1367 {
1368 return HAL_ERROR;
1369 }
1370
1371 /* Check the parameters */
1372 assert_param(IS_DMA_ATTRIBUTES(ChannelAttributes));
1373
1374 /* Get DMA instance */
1375 p_dma_instance = GET_DMA_INSTANCE(hdma);
1376
1377 /* Get channel index */
1378 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1379
1380 /* Check DMA channel privilege attribute management */
1381 if ((ChannelAttributes & DMA_CHANNEL_ATTR_PRIV_MASK) == DMA_CHANNEL_ATTR_PRIV_MASK)
1382 {
1383 /* Configure DMA channel privilege attribute */
1384 if ((ChannelAttributes & DMA_CHANNEL_PRIV) == DMA_CHANNEL_PRIV)
1385 {
1386 p_dma_instance->PRIVCFGR |= channel_idx;
1387 }
1388 else
1389 {
1390 p_dma_instance->PRIVCFGR &= (~channel_idx);
1391 }
1392 }
1393
1394 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1395 /* Check DMA channel security attribute management */
1396 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_MASK) == DMA_CHANNEL_ATTR_SEC_MASK)
1397 {
1398 /* Configure DMA channel security attribute */
1399 if ((ChannelAttributes & DMA_CHANNEL_SEC) == DMA_CHANNEL_SEC)
1400 {
1401 p_dma_instance->SECCFGR |= channel_idx;
1402 }
1403 else
1404 {
1405 p_dma_instance->SECCFGR &= (~channel_idx);
1406 }
1407 }
1408
1409 /* Channel source security attribute management */
1410 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_SRC_MASK) == DMA_CHANNEL_ATTR_SEC_SRC_MASK)
1411 {
1412 /* Configure DMA channel source security attribute */
1413 if ((ChannelAttributes & DMA_CHANNEL_SRC_SEC) == DMA_CHANNEL_SRC_SEC)
1414 {
1415 hdma->Instance->CTR1 |= DMA_CTR1_SSEC;
1416 }
1417 else
1418 {
1419 hdma->Instance->CTR1 &= (~DMA_CTR1_SSEC);
1420 }
1421 }
1422
1423 /* Channel destination security attribute management */
1424 if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_DEST_MASK) == DMA_CHANNEL_ATTR_SEC_DEST_MASK)
1425 {
1426 /* Configure DMA channel destination security attribute */
1427 if ((ChannelAttributes & DMA_CHANNEL_DEST_SEC) == DMA_CHANNEL_DEST_SEC)
1428 {
1429 hdma->Instance->CTR1 |= DMA_CTR1_DSEC;
1430 }
1431 else
1432 {
1433 hdma->Instance->CTR1 &= (~DMA_CTR1_DSEC);
1434 }
1435 }
1436 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
1437
1438 return HAL_OK;
1439 }
1440
1441 /**
1442 * @brief Get the DMA channel security and privilege attributes.
1443 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information
1444 * for the specified DMA Channel.
1445 * @param pChannelAttributes : Pointer to the returned attributes.
1446 * @retval HAL Status.
1447 */
HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const * const hdma,uint32_t * const pChannelAttributes)1448 HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const *const hdma,
1449 uint32_t *const pChannelAttributes)
1450 {
1451 const DMA_TypeDef *p_dma_instance;
1452 uint32_t attributes;
1453 uint32_t channel_idx;
1454
1455 /* Check the DMA peripheral handle and channel attributes parameters */
1456 if ((hdma == NULL) || (pChannelAttributes == NULL))
1457 {
1458 return HAL_ERROR;
1459 }
1460
1461 /* Get DMA instance */
1462 p_dma_instance = GET_DMA_INSTANCE(hdma);
1463
1464 /* Get channel index */
1465 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1466
1467 /* Get DMA channel privilege attribute */
1468 attributes = ((p_dma_instance->PRIVCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
1469
1470 #if defined (DMA_SECCFGR_SEC0)
1471 /* Get DMA channel security attribute */
1472 attributes |= ((p_dma_instance->SECCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC;
1473
1474 /* Get DMA channel source security attribute */
1475 attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_SSEC) == 0U) ? DMA_CHANNEL_SRC_NSEC : DMA_CHANNEL_SRC_SEC;
1476
1477 /* Get DMA channel destination security attribute */
1478 attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_DSEC) == 0U) ? DMA_CHANNEL_DEST_NSEC : DMA_CHANNEL_DEST_SEC;
1479 #endif /* DMA_SECCFGR_SEC0 */
1480
1481 /* return value */
1482 *pChannelAttributes = attributes;
1483
1484 return HAL_OK;
1485 }
1486 #endif /* DMA_PRIVCFGR_PRIV0 */
1487 #if defined (DMA_RCFGLOCKR_LOCK0)
1488 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1489 /**
1490 * @brief Lock the DMA channel security and privilege attribute(s).
1491 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1492 * specified DMA Channel.
1493 * @retval HAL Status.
1494 */
HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const * const hdma)1495 HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const hdma)
1496 {
1497 DMA_TypeDef *p_dma_instance;
1498 uint32_t channel_idx;
1499
1500 /* Check the DMA peripheral handle parameter */
1501 if (hdma == NULL)
1502 {
1503 return HAL_ERROR;
1504 }
1505
1506 /* Get DMA instance */
1507 p_dma_instance = GET_DMA_INSTANCE(hdma);
1508
1509 /* Get channel index */
1510 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1511
1512 /* Lock the DMA channel privilege and security attributes */
1513 p_dma_instance->RCFGLOCKR |= channel_idx;
1514
1515 return HAL_OK;
1516 }
1517 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
1518
1519 /**
1520 * @brief Get the security and privilege attribute lock state of a DMA channel.
1521 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1522 * specified DMA Channel.
1523 * @param pLockState : Pointer to lock state (returned value can be DMA_CHANNEL_ATTRIBUTE_UNLOCKED or
1524 * DMA_CHANNEL_ATTRIBUTE_LOCKED).
1525 * @retval HAL status.
1526 */
HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const * const hdma,uint32_t * const pLockState)1527 HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, uint32_t *const pLockState)
1528 {
1529 const DMA_TypeDef *p_dma_instance;
1530 uint32_t channel_idx;
1531
1532 /* Check the DMA peripheral handle and lock state parameters */
1533 if ((hdma == NULL) || (pLockState == NULL))
1534 {
1535 return HAL_ERROR;
1536 }
1537
1538 /* Get DMA instance */
1539 p_dma_instance = GET_DMA_INSTANCE(hdma);
1540
1541 /* Get channel index */
1542 channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
1543
1544 /* Get channel lock attribute state */
1545 *pLockState = ((p_dma_instance->RCFGLOCKR & channel_idx) == 0U) ? DMA_CHANNEL_ATTRIBUTE_UNLOCKED : \
1546 DMA_CHANNEL_ATTRIBUTE_LOCKED;
1547
1548 return HAL_OK;
1549 }
1550 #endif /* DMA_RCFGLOCKR_LOCK0 */
1551 /**
1552 * @}
1553 */
1554
1555 /**
1556 * @}
1557 */
1558
1559
1560 /* Private functions -------------------------------------------------------------------------------------------------*/
1561 /** @defgroup DMA_Private_Functions DMA Private Functions
1562 * @brief DMA Private Functions
1563 * @{
1564 */
1565
1566 /**
1567 * @brief Set the DMA channel normal transfer parameters.
1568 * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1569 * specified DMA Channel.
1570 * @param SrcAddress : The source data address.
1571 * @param DstAddress : The destination data address.
1572 * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
1573 * @retval None.
1574 */
DMA_SetConfig(DMA_HandleTypeDef const * const hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t SrcDataSize)1575 static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
1576 uint32_t SrcAddress,
1577 uint32_t DstAddress,
1578 uint32_t SrcDataSize)
1579 {
1580 /* Configure the DMA channel data size */
1581 MODIFY_REG(hdma->Instance->CBR1, DMA_CBR1_BNDT, (SrcDataSize & DMA_CBR1_BNDT));
1582
1583 /* Clear all interrupt flags */
1584 __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
1585 DMA_FLAG_TO);
1586
1587 /* Configure DMA channel source address */
1588 hdma->Instance->CSAR = SrcAddress;
1589
1590 /* Configure DMA channel destination address */
1591 hdma->Instance->CDAR = DstAddress;
1592 }
1593
1594 /**
1595 * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef.
1596 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
1597 * specified DMA Channel.
1598 * @retval None.
1599 */
DMA_Init(DMA_HandleTypeDef const * const hdma)1600 static void DMA_Init(DMA_HandleTypeDef const *const hdma)
1601 {
1602 uint32_t tmpreg;
1603
1604 /* Prepare DMA Channel Control Register (CCR) value *****************************************************************/
1605 tmpreg = hdma->Init.Priority;
1606
1607 /* Write DMA Channel Control Register (CCR) */
1608 MODIFY_REG(hdma->Instance->CCR, DMA_CCR_PRIO | DMA_CCR_LAP | DMA_CCR_LSM, tmpreg);
1609
1610 /* Prepare DMA Channel Transfer Register (CTR1) value ***************************************************************/
1611 tmpreg = hdma->Init.DestInc | hdma->Init.DestDataWidth | hdma->Init.SrcInc | hdma->Init.SrcDataWidth;
1612
1613 /* Add parameters specific to GPDMA */
1614 if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
1615 {
1616 tmpreg |= (hdma->Init.TransferAllocatedPort |
1617 (((hdma->Init.DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1) |
1618 (((hdma->Init.SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1));
1619 }
1620
1621 /* Write DMA Channel Transfer Register 1 (CTR1) */
1622 #if defined (DMA_CTR1_SSEC)
1623 MODIFY_REG(hdma->Instance->CTR1, ~(DMA_CTR1_SSEC | DMA_CTR1_DSEC), tmpreg);
1624 #else
1625 WRITE_REG(hdma->Instance->CTR1, tmpreg);
1626 #endif /* DMA_CTR1_SSEC */
1627
1628 /* Prepare DMA Channel Transfer Register 2 (CTR2) value *************************************************************/
1629 tmpreg = hdma->Init.BlkHWRequest | (hdma->Init.Request & DMA_CTR2_REQSEL) | hdma->Init.TransferEventMode;
1630
1631 /* Memory to Peripheral Transfer */
1632 if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1633 {
1634 if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
1635 {
1636 tmpreg |= DMA_CTR2_DREQ;
1637 }
1638 }
1639 /* Memory to Memory Transfer */
1640 else if ((hdma->Init.Direction) == DMA_MEMORY_TO_MEMORY)
1641 {
1642 tmpreg |= DMA_CTR2_SWREQ;
1643 }
1644 else
1645 {
1646 /* Nothing to do */
1647 }
1648
1649 /* Write DMA Channel Transfer Register 2 (CTR2) */
1650 MODIFY_REG(hdma->Instance->CTR2, (DMA_CTR2_TCEM | DMA_CTR2_TRIGPOL | DMA_CTR2_TRIGSEL | DMA_CTR2_TRIGM |
1651 DMA_CTR2_BREQ | DMA_CTR2_DREQ | DMA_CTR2_SWREQ | DMA_CTR2_REQSEL), tmpreg);
1652
1653 /* Write DMA Channel Block Register 1 (CBR1) ************************************************************************/
1654 WRITE_REG(hdma->Instance->CBR1, 0U);
1655
1656 /* Write DMA Channel linked-list address register (CLLR) ************************************************************/
1657 WRITE_REG(hdma->Instance->CLLR, 0U);
1658 }
1659 /**
1660 * @}
1661 */
1662
1663 #endif /* HAL_DMA_MODULE_ENABLED */
1664
1665 /**
1666 * @}
1667 */
1668
1669 /**
1670 * @}
1671 */
1672