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