cancel
Showing results for 
Search instead for 
Did you mean: 

How to configure GPDMA for PWM generation?

m4rk0401
Associate

Hi,

I'm using a Riverdi RVT50HQSFWN00 Screen with the STM32U5A9NJH6Q MCU. COnnected to pin PI0 is a WS2812 LED light strip. I already configured the timer 5 channel 4 for PWM generation and validated it with a scope at the pin. Right now I'm stuck at the GPDMA part. I'm able to start the PWM generation using: HAL_TIM_PWM_Start_DMA(&htim8, TIM_CHANNEL_1, (uint32_t *)pwmData, indx);

For the code I followed this tutorial: https://controllerstech.com/interface-ws2812-with-stm32/

This is my timer configuration (TIM5 global interrupt enabled):

m4rk0401_0-1736341234347.png

This is GPDMA configuration:

m4rk0401_1-1736341318843.png

Using a scope, I see that a PWM signal is generated but the HAL_TIM_PWM_PulseFinishedCallback() function is never called, which in the end, stops the DMA transfer.

Would really appreciate any help.

Best regards
Marko

2 REPLIES 2
Sarra.S
ST Employee

Hello @m4rk0401

In your GPDMA configuration, in the destination data setting, try enabling the destination address increment after transfer

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.

m4rk0401
Associate

Thanks @Sarra.S for your quick response. I tried your suggestion without success.

I tried some more debugging today and achieved following result:

Code (reduced to most important parts) - app_freertos.c: 

int datasentflag = 0;
extern TIM_HandleTypeDef htim5;

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	HAL_TIM_PWM_Stop_DMA(&htim5, TIM_CHANNEL_4);
	datasentflag=1;
}

uint16_t pwmData[24];
void test()
{
	for(int i=0; i<24; i++)
	{
		pwmData[i] = 50;
	}

	HAL_TIM_PWM_Start_DMA(&htim5, TIM_CHANNEL_4, (uint32_t *)pwmData, 24);
	/*
	while (!datasentflag){};
	datasentflag = 0;
	*/
}

void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN defaultTask */
  /* Infinite loop */
  for(;;)
  {
	  test();
	  osDelay(100);
  }
  /* USER CODE END defaultTask */
}


GPDMA configuration:

m4rk0401_0-1736433491609.png

Timer configuration is the same because basic PWM generations works.

Unfortunately is set 24 different duty cycles in my code and get following result using a oscilloscope:

IMG_8265 (2).png


Any idea why only 14 cycles are outputted?

Best regards
Marko