Skip to main content
Associate
October 3, 2023
Solved

STM32H5: PWM generation with DMA (classic approach)

  • October 3, 2023
  • 3 replies
  • 2572 views

Hello,
Finally I managed to produce a three-phase PWM in classic DMA mode with the pure HAL-Lib. (Hardware: NUCLEO-H563ZI)

However, within the cube produced routine, file: tim.c:
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)

This wrong call appears:

__HAL_LINKDMA(tim_ocHandle, hdma[TIM_DMA_ID_CC4], handle_GPDMA1_Channel3);

It should be :
__HAL_LINKDMA(tim_pwmHandle, hdma[TIM_DMA_ID_CC4], handle_GPDMA1_Channel3);

To get rid of this error when re-generating the code from the Cube MX, I added

/* USER CODE BEGIN TIM1_MspInit 0 */

#define tim_ocHandle tim_pwmHandle

/* USER CODE END TIM1_MspInit 0 */

Did I something wrong or can this be fixed in the future?
Thanks a lot,
Andreas

Code generated by CubeMx:

 
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
DMA_NodeConfTypeDef NodeConfig= {0};
if(tim_pwmHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspInit 0 */
#define tim_ocHandle tim_pwmHandle
/* USER CODE END TIM1_MspInit 0 */
/* TIM1 clock enable */

__HAL_RCC_TIM1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();

/**TIM1 GPIO Configuration
PB12 ------> TIM1_BKIN
*/
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* TIM1 DMA Init */
/* GPDMA1_REQUEST_TIM1_CH4 Init */
NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
NodeConfig.Init.Request = GPDMA1_REQUEST_TIM1_CH4;
NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
NodeConfig.Init.Direction = DMA_MEMORY_TO_PERIPH;
NodeConfig.Init.SrcInc = DMA_SINC_INCREMENTED;
NodeConfig.Init.DestInc = DMA_DINC_FIXED;
NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
NodeConfig.Init.SrcBurstLength = 1;
NodeConfig.Init.DestBurstLength = 1;
NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
NodeConfig.Init.Mode = DMA_NORMAL;
NodeConfig.TriggerConfig.TriggerMode = DMA_TRIGM_SINGLE_BURST_TRANSFER;
NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_RISING;
NodeConfig.TriggerConfig.TriggerSelection = GPDMA1_TRIGGER_TIM2_TRGO;
NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
if (HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel3) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel3, NULL, &Node_GPDMA1_Channel3) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel3) != HAL_OK)
{
Error_Handler();
}
handle_GPDMA1_Channel3.Instance = GPDMA1_Channel3;
handle_GPDMA1_Channel3.InitLinkedList.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
handle_GPDMA1_Channel3.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
handle_GPDMA1_Channel3.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT0;
handle_GPDMA1_Channel3.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel3.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel3) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel3, &List_GPDMA1_Channel3) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(tim_ocHandle, hdma[TIM_DMA_ID_CC4], handle_GPDMA1_Channel3);

if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel3, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}

 

 

This topic has been closed for replies.
Best answer by Semer CHERNI

Hello @AGerth 

Thanks for sharing the configuration file. With it I was able to reproduce the issue.

This problem is raised internally to be reviewed. I'll keep you posted with the updates.
Internal ticket number: 164588 (This is an internal tracking number and is not accessible or usable by customers).

As a temporary solution, either you make the modification to the generated code which you have mentioned.
Or you can change all timer handler to tim_Handle instead of tim_pwmHandle and tim_ocHandle.

KR,

Semer.

3 replies

waclawek.jan
Super User
October 3, 2023

> However, within the cube[MX] produced routine, file: tim.c [...] This wrong call appears:

So, this is a CubeMX bug, supposedly?

@Foued_KH, can you please move it to the appropriate sub-forum?

JW

Foued_KH
ST Employee
October 4, 2023

Thank you @waclawek.jan 

Foued

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.
Semer CHERNI
ST Employee
October 9, 2023

Hello @AGerth 

First let me thank you for posting.
Could you provide the *.ioc file with the configuration you made.

KR,
Semer.

AGerthAuthor
Associate
October 22, 2023

Hello,
Attached the file you are requested. Hope this can be fixed somehow.
Thank you,
Andreas

Semer CHERNI
Semer CHERNIBest answer
ST Employee
October 23, 2023

Hello @AGerth 

Thanks for sharing the configuration file. With it I was able to reproduce the issue.

This problem is raised internally to be reviewed. I'll keep you posted with the updates.
Internal ticket number: 164588 (This is an internal tracking number and is not accessible or usable by customers).

As a temporary solution, either you make the modification to the generated code which you have mentioned.
Or you can change all timer handler to tim_Handle instead of tim_pwmHandle and tim_ocHandle.

KR,

Semer.