2025-04-24 4:56 AM
I am porting code from G473 to U575 because I need more flash and ram.
Then I meet some issues on gpdma transmission size.
For G473, I use dma to transfer data to timer ARR likes:
uint16_t buf[65536] = { ..... };
HAL_TIM_Base_Start_DMA(&htim1, (uint32_t *)buf, 65536);
For U575, the code doesn't work because the size have to be 65536 * sizeof(uint16_t), not the number of buf.
Is there any way to figure it out?
2025-04-24 6:07 AM
The code presented cannot work, either at 65536 or at 65536 * sizeof(uint16_t).
The CNDT register field is 16 bits and accept a maximum value of 65535.
The HAL_TIM_Base_Start_DMA also accept a max value of 65535.
/**
* @brief Starts the TIM Base generation in DMA mode.
* @PAram htim TIM Base handle
* @PAram pData The source Buffer address.
* @PAram Length The length of data to be transferred from memory to peripheral.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, const uint32_t *pData, uint16_t Length)
{
2025-04-24 6:53 AM
Yes, you are right.
Currently, I only use 16384 in G473. But I want to port code to U575 and use more buf in DMA.
And I found the definition is different between G4 and U5 in DMA size.
2025-04-24 6:56 AM
> And I found the definition is different between G4 and U5 in DMA size.
No it's not.
2025-04-24 7:08 AM
In G473, the code below is ok.
uint16_t buf[4] = { ..... };
HAL_TIM_Base_Start_DMA(&htim1, (uint32_t *)buf, 4);
I tried this in U575, buf[2] and buf[3] will not be transfered,unless I set the size = 4 * sizeof(uint16_t).
2025-04-24 9:14 AM
Hmm, the code seems consistent, but maybe there's a bug in there I'm not spotting.
It doesn't seem like my answer provided a solution. You can unmark it as a solution.
2025-04-24 7:54 PM - edited 2025-04-24 8:14 PM
New question: How to configure linked list DMA to update TIM->ARR each time when Update Event generated?
/**
* @brief DMA Linked-list xFreqList configuration
* None
* @retval None
*/
HAL_StatusTypeDef MX_xFreqList_Config(void)
{
HAL_StatusTypeDef ret = HAL_OK;
/* DMA node configuration declaration */
DMA_NodeConfTypeDef pNodeConfig;
/* Set node configuration ################################################*/
pNodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
pNodeConfig.Init.Request = GPDMA1_REQUEST_TIM15_UP;
pNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
pNodeConfig.Init.Direction = DMA_MEMORY_TO_PERIPH;
pNodeConfig.Init.SrcInc = DMA_SINC_INCREMENTED;
pNodeConfig.Init.DestInc = DMA_DINC_FIXED;
pNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD;
pNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD;
pNodeConfig.Init.SrcBurstLength = 1;
pNodeConfig.Init.DestBurstLength = 1;
pNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
pNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
pNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
pNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
pNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
pNodeConfig.SrcAddress = (uint32_t)TimerTable;
pNodeConfig.DstAddress = (uint32_t)&(TIM15->ARR);
pNodeConfig.DataSize = 4*2;
/* Build FreqTimerTable1 Node */
ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &FreqTimerTable1);
/* Insert FreqTimerTable1 to Queue */
ret |= HAL_DMAEx_List_InsertNode_Tail(&xFreqList, &FreqTimerTable1);
ret |= HAL_DMAEx_List_SetCircularMode(&xFreqList);
return ret;
}
MX_xFreqList_Config();
HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &xFreqList);
HAL_DMAEx_List_Start(&handle_GPDMA1_Channel0);
HAL_TIM_Base_Start(&htim15);
2025-04-24 9:13 PM
Follow this ST video as a guide: https://youtu.be/jKOhRfb3gvk?si=xX4p7RoMXyTvPXEC
2025-04-24 10:04 PM - edited 2025-04-24 10:09 PM
I tried the code in the video. It works on ADC but not on Timer.
Also I tried standard request mode dma with HAL_TIM_Base_Start_DMA. ARR was being updated.
I am confused why it does not work with linked-list mode dma.
2025-04-24 11:15 PM
uint16_t StartTable = 1;
MX_xFreqQ_Config();
HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &xFreqList);
HAL_DMAEx_List_Start(&handle_GPDMA1_Channel0);
HAL_TIM_Base_Start_DMA(&htim15, (uint32_t *)&StartTable, 2);
Things are weird.
I opened an other standard request mode dma for the same timer, and ran HAL_TIM_Base_Start_DMA.
Then the linked-list dma started working.
I think maybe I need to set bit TIMx_EGR.UG to force ARR update, but it's not the key.
Why? very confused.