Skip to main content
peterdonchev
Senior
October 26, 2025
Solved

STM32CubeMX 6.15: Incorrect LL code generation for Circular DMA on STM32H523

  • October 26, 2025
  • 2 replies
  • 305 views

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

Best answer by Ghofrane GSOURI

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

2 replies

Ghofrane GSOURI
Technical Moderator
October 27, 2025

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 

GhofraneGSOURI_0-1761560456786.png

 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.

GhofraneGSOURI_1-1761560641557.png

GhofraneGSOURI_3-1761560778837.png

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.
peterdonchev
Senior
October 27, 2025

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.
 peterdonchev_0-1761582499010.png
Can I send you my .ioc file privately?

Edit: I’m using the following option, which causes the difference:

peterdonchev_1-1761583458895.png

 

 

Regards,
Peter

 

 

 

Ghofrane GSOURI
Ghofrane GSOURIBest answer
Technical Moderator
October 28, 2025

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.
peterdonchev
Senior
October 28, 2025

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