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