2025-10-26 1:53 PM
Hi,
When configuring a DMA channel in Circular mode with the LL code generator for STM32H523, the generated initialization code is incorrect.
It creates a DMA Link Node (LL_DMA_LinkNodeTypeDef) on the stack, which is invalid since the DMA continuously accesses this structure. The link node should be placed in persistent memory instead.
Additionally, the generated code does not set the source address, destination address, or block length when the link node is created, although these can be manually set later.
Regards,
Peter
Solved! Go to Solution.
2025-10-28 4:43 AM
Hello @peterdonchev
Regarding the first issue, “LL_DMA_LinkNodeTypeDef Node_GPDMA1_Channel0 = {0};” is declared locally within the MX_ADC1_Init() function, an internal ticket (Ticket 220610) has been raised to address and improve this behavior.
For the second point, when configuring DMA (such as for ADC), you do not specify the source address, destination address, or transfer size in the CubeMX GUI. Instead, you define the destination buffer and transfer size in your application code when starting the DMA transfer. The source address (peripheral data register) is automatically handled by the HAL/LL drivers. This approach keeps the CubeMX configuration simple, while giving you flexibility in your code to define how and where the data is stored.
THX
Ghofrane
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-10-27 12:22 AM - edited 2025-10-27 3:26 AM
Hello @peterdonchev
When configuring a DMA channel in Circular mode with the LL code generator for STM32H523, CubeMX generates code that correctly allocates the LL_DMA_LinkNodeTypeDef as a global variable as shown below
ensuring it remains in persistent memory and accessible to the DMA hardware throughout operation.
Regarding the source address, destination address, or block length for the link node ,CubeMX allows users to set these values in the GUI under "Runtime configuration," and if valid values are entered, the generated code will include them.
I will be waiting for your feedback.
THX
Ghofrane
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-10-27 9:32 AM - edited 2025-10-27 9:45 AM
Hi @Ghofrane GSOURI ,
Thank you for your reply.
Unfortunately, my experience differs. I’ve attached the generated adc.c file, where Node_GPDMA1_Channel0 is declared as a local variable.
Below is a snippet from the code.
#include "adc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* ADC1 init function */
void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
LL_ADC_InitTypeDef ADC_InitStruct = {0};
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_DMA_InitNodeTypeDef NodeConfig = {0};
LL_DMA_LinkNodeTypeDef Node_GPDMA1_Channel0 = {0};
LL_DMA_InitLinkedListTypeDef DMA_InitLinkedListStruct = {0};
LL_RCC_SetADCDACClockSource(LL_RCC_ADCDAC_CLKSOURCE_PLL2R);
Also, I don’t see the mentioned parameters in my project.
Can I send you my .ioc file privately?
Edit: I’m using the following option, which causes the difference:
Regards,
Peter
2025-10-28 4:43 AM
Hello @peterdonchev
Regarding the first issue, “LL_DMA_LinkNodeTypeDef Node_GPDMA1_Channel0 = {0};” is declared locally within the MX_ADC1_Init() function, an internal ticket (Ticket 220610) has been raised to address and improve this behavior.
For the second point, when configuring DMA (such as for ADC), you do not specify the source address, destination address, or transfer size in the CubeMX GUI. Instead, you define the destination buffer and transfer size in your application code when starting the DMA transfer. The source address (peripheral data register) is automatically handled by the HAL/LL drivers. This approach keeps the CubeMX configuration simple, while giving you flexibility in your code to define how and where the data is stored.
THX
Ghofrane
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-10-28 5:45 AM
Hello @Ghofrane GSOURI ,
Thank you for your reply. I noticed that the Source Address, Destination Address, and Data Size fields become visible when the Software Request option is selected. However, in the case of an ADC request, these values should ideally be set during the creation of the linked list to avoid having to fill them in manually later in the generated linked list node. It would be very helpful if a USER CODE section were added just before the LL_DMA_CreateLinkNode call.
NodeConfig.Request = LL_GPDMA1_REQUEST_ADC1;
NodeConfig.UpdateRegisters = (LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CTR3 | LL_DMA_UPDATE_CBR2 | LL_DMA_UPDATE_CLLR);
NodeConfig.NodeType = LL_DMA_GPDMA_LINEAR_NODE;
/* USER CODE BEGIN ADC1_Init 1 */
/* Add a new USER CODE section here to initialize:
* NodeConfig.SrcAddress =
* NodeConfig.DestAddress =
* NodeConfig.BlkDataLength =
*/
/* USER CODE END ADC1_Init 1 */
LL_DMA_CreateLinkNode(&NodeConfig, &Node_GPDMA1_Channel0);
LL_DMA_ConnectLinkNode(&Node_GPDMA1_Channel0, LL_DMA_CLLR_OFFSET5, &Node_GPDMA1_Channel0, LL_DMA_CLLR_OFFSET5);
Also, it’s not clear to me how the source address (the peripheral data register) is automatically managed by the LL drivers.
Regards,
Peter
2025-10-28 5:57 AM - edited 2025-10-28 6:12 AM
Hello @peterdonchev
When you use DMA to transfer data from a peripheral (like an ADC) to memory, the source address is the location in the microcontroller where the peripheral’s data is stored—this is called the peripheral data register (for example, ADC1->DR for ADC1).
You do not need to manually specify this address when using STM32’s HAL or LL drivers. Instead, when you call functions like HAL_ADC_Start_DMA(), the driver automatically knows which peripheral you are using and sets the correct source address for the DMA transfer behind the scenes.
THX
Ghofrane
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-10-28 6:24 AM
Hello @Ghofrane GSOURI .
Thank you for your prompt response. I'm familiar with the structure of the ADC peripheral; however, I wasn’t certain how the LL drivers automatically handle the peripheral address (data register). I understand that the HAL drivers provide this capability, but I’m not using them. Sorry for the confusion — I initially assumed that the LL drivers offered similar functionality based on your explanation, but I don’t see any corresponding implementation in their code.
Regards,
Petar