cancel
Showing results for 
Search instead for 
Did you mean: 

How to set addresses and length for linked list DMA based transfers

LVan .31
Associate III

I am using linked list based DMA with an STM32U5 and everything works as expected, great. I do however have a question what is the best way to set the source address, destination address and length for a linked list node.

CubeMX allows these parameters to fill but I don't like to add names of variables or other expressions in CubeMX. Entering these expressions in CubeMX requires the variables to be globally accessible. Especially since I am working in C++ I just don't like this. Adding expressions from user code in CubeMX creates a fuzzy dependency and what I would like is to fill the applicable fields runtime.

What I do now is leave the fields empty in CubeMX in which case the generated code fills the fields with zero's, as shown below.

 

pNodeConfig.Init.DestBurstLength = 1;

pNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;

pNodeConfig.Init.TransferEventMode = DMA_TCEM_LAST_LL_ITEM_TRANSFER;

pNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;

pNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;

pNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;

pNodeConfig.SrcAddress = 0;

pNodeConfig.DstAddress = 0;

pNodeConfig.DataSize = 0;

 

Now in my code before calling HAL_DMAEx_List_LinkQ and HAL_DMAEx_List_Start, I fill the applicable fields by accessing the global variable declared in the CubeMX generated code like....

 

extern DMA_NodeTypeDef MainCtrPrimaryNode;

HAL_StatusTypeDef MX_MainCtrPrimaryQueue_Config();

 

if (MX_MainCtrPrimaryQueue_Config() != HAL_OK){Error_Handler(); }

 

MainCtrPrimaryNode.LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = sizeof(mainCtrPrimaryData);

MainCtrPrimaryNode.LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = &mainCtrPrimaryData[0];

MainCtrPrimaryNode.LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = &htim5.Instance->CCR3;

if (HAL_DMAEx_List_LinkQ (&handle_GPDMA1_Channel0, &MainCtrPrimaryQueue) != HAL_OK){Error_Handler(); }

if (HAL_DMAEx_List_Start (&handle_GPDMA1_Channel0) != HAL_OK){Error_Handler(); }

 

 

This works for me but I am wondering if this is the best way to change node parameters dynamically?

1 ACCEPTED SOLUTION

Accepted Solutions
CMYL
ST Employee

Hello @LVan .31 ,

There will be no issue in your case since the modification is performed before enabling the DMA (GPDMA_CxCR.EN=1 by calling HAL_DMAEx_List_Start ). We can't neither consider that the reconfiguration you did is dynamic for the same reason (DMA still not started). 

 

Dynamic reconfiguration of DMA is possible in STM32U5 (see figure below from RM0456) when the DMA Enable bit is dis-asserted (GPDMA_CxCR.EN=0). This bit is automatically disasserted after transfer complete or transfer error,  so that reconfiguration can be done after each transfer.

CMYL_0-1718838113034.png

best regards,

View solution in original post

1 REPLY 1
CMYL
ST Employee

Hello @LVan .31 ,

There will be no issue in your case since the modification is performed before enabling the DMA (GPDMA_CxCR.EN=1 by calling HAL_DMAEx_List_Start ). We can't neither consider that the reconfiguration you did is dynamic for the same reason (DMA still not started). 

 

Dynamic reconfiguration of DMA is possible in STM32U5 (see figure below from RM0456) when the DMA Enable bit is dis-asserted (GPDMA_CxCR.EN=0). This bit is automatically disasserted after transfer complete or transfer error,  so that reconfiguration can be done after each transfer.

CMYL_0-1718838113034.png

best regards,