Skip to main content
Visitor II
August 5, 2024
Question

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

  • August 5, 2024
  • 6 replies
  • 1810 views

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

    This topic has been closed for replies.

    6 replies

    Super User
    August 5, 2024

    >   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.

    Super User
    August 5, 2024

    > 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

    jrhtechAuthor
    Visitor II
    August 6, 2024

    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

     

    Super User
    August 6, 2024

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

    JW

    jrhtechAuthor
    Visitor II
    August 6, 2024

    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

     

    Super User
    August 6, 2024

    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

    Super User
    August 6, 2024

    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.

    ST Employee
    August 12, 2024

    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