cancel
Showing results for 
Search instead for 
Did you mean: 

Using repetition count with PWM generates wrong number of events on STM32U5

jrhtech
Associate II

Hello,

   I am trying to use a timer 15 in PWM mode to drive the DMA of a DAC.   I need the PWM to generate N number of update events for M number of pulses.  For example, generated an update event 10 times every 200 pulses.   I'm just trying to get the PWM working before checking if the DAC is working.  

  The problem I'm having is generating the correct number of update events from the PWM.   At the moment, I'm not trying to count the number of update event's since it's not working.   I am setting the repetition counter to 10; however, I only get like 4(or 3) update events and then 20ms of none.  So for the events I do get, they are the correct number of pulse but I'm expecting to see the updates events running all the time, not blocks of 3-4.

 I'm using Cube for configuring the timer but I do some manual config so I can change things in the code instead of depending on the config generated by Cube.

 So in the timer init code I do the following in the user code section

 

 

  uint32_t ps = HAL_RCC_GetPCLK2Freq()/1000000;
  __HAL_TIM_SET_PRESCALER(&htim15, ps - 1);
  __HAL_TIM_SET_AUTORELOAD(&htim15, (HAL_RCC_GetPCLK2Freq()/(ps * 10000)) - 1);
  // enable interrupt, need so can count N update events
  HAL_TIM_PWM_MspInit(&htim15);

 

 

 

 

Then in my default FreeRTOS task I do this.  Note that the PWM does not enable the update event(which I need to drive DAC DMA) so I have to enable that manually.

 

 

	LL_TIM_SetRepetitionCounter(htim15.Instance, (sizeof(vdef)/sizeof(vdef[0])-1));
	// 50% for now
	__HAL_TIM_SET_COMPARE(&htim15, TIM_CHANNEL_1, __HAL_TIM_GET_AUTORELOAD(&htim15)/2);
	//HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, vdef, sizeof(vdef)/sizeof(vdef[0]), DAC_ALIGN_12B_R);
	// PWM does not enable update event
    __HAL_TIM_ENABLE_IT(&htim15, TIM_IT_UPDATE);
    // don't use Start_IT, we don't need CC events
	HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_1);

 

 

 

However,  as I said above, I'll get 3-4 update events and then nothing for 20ms, then get another 3-4 update events.   However, I just discovered this morning that if I change the PWM to generate at 1kHz instead of 10kHz the update events are generated continuously.  

  The PWM output looks fine for both 1kHz and 10kHz and I don't understand what is causing the issue with the update event when I change the period?

thanks

Jeff

8 REPLIES 8
TDK
Guru

>   The PWM output looks fine for both 1kHz and 10kHz and I don't understand what is causing the issue with the update event when I change the period?

It sounds like the cpu is busy in the interrupt or in another interrupt, which delays the next update interrupt from taking place.

Look at interrupt events in your code and ensure they finish quickly enough. Don't use blocking call. Give higher priority to interrupts that needs to be executed in a timely manner.

If you feel a post has answered your question, please click "Accept as Solution".

> I only get like 4(or 3) update events and then 20ms of none.

How do you know?

> It sounds like the cpu is busy in the interrupt or in another interrupt,

+1

Using the Cube/HAL interrupt "system" and inadequate compiler optimization setting makes things worse.

> FreeRTOS

Maybe this, too.

JW

I measured the timing on an analyzer.

It's not interrupts or lack of optimization.  This is bare bones test code with nothing more than gpio, PWM and DAC.

The timing interrupt callback is a bare metal gpio toggle, again no delays.  I've got infinity more complex code with multiple tasks and interrupts which is not compiled with optimization and it works fine.

 

Jeff

 

With nonzero TIMx_RCR, Update is generated only when the repetition counter reaches zero, i.e. once per TIMx_RCR+1 periods.

JW

Yes, but it should do that indefinitely.   Not generate 3-4 update events, do nothing for 20ms, then generate 3-4 again.   And as I mentioned, just changing the frequency from 10kHz to 1kHz changes the behavior, which is a clue, but I don't know what it points to.   

 

jeff

 

Try to reduce complexity.

As a minimum, remove the TIMx_RCR-dependancy - plain timer updates at the same rate should result in the same behaviour.

JW

TDK
Guru

Let's be objective here.

The interrupts within the STM32 are handled by the core. They are hardware state machines and are not prone to odd behavior and "missing" interrupts. Surely they are happening, so you need to look at your code to understand why they were unable to be processed, or why you could be mistaken in thinking they are not happening.

If you feel a post has answered your question, please click "Accept as Solution".
Roger SHIVELY
ST Employee

Hello @jrhtech 

This post has been escalated to the ST Online Support Team for additional assistance.  We'll contact you directly.

 

Regards,

Roger

ST Support