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