Skip to main content
Graduate
November 25, 2024
Solved

Strange issue with timer pwm in dma mode

  • November 25, 2024
  • 1 reply
  • 1386 views

Hello,

I'm facing a very strange issue with timer PWM in DMA mode.

I use the PWM channel to send step pulses to a stepping motor in order to free the mcu while the motor is moving, rather than using time consuming delays.

The issue raises when I change the motor speed by changing the PWM frequency.

Changing the PWM frequency breaks the DMA.

What I mean by breaks the DMA is that when I call the start function

 

if (HAL_TIM_PWM_Start_DMA(THIS->timer, THIS->channel, THIS->burst_buffer, THIS->steps_burst_size) == HAL_OK)
{
    osMessageQueueGet(THIS->sync, &_token, 0L, osWaitForever);
}

I always get HAL_OK, but the pulse finished callback is never called.

I change the PWM frequency in a rather rogue way, by writing a new value to the ARR register.

I'm sure that the issue is related to the frequency change, if I comment out the lines changing the frequency, all works well.

To check wether errors are are trigerred or not, I setup a HAL_TIM_ErrorCallback, but it never gets called.

 

    This topic has been closed for replies.
    Best answer by Sarra.S

    I think this has to do with the prescaler update being buffered and synchronized with the timer's update event, so, it avoids the immediate glitches that can occur when directly updating the ARR register.

    I still believe that the best way to deal with ARR is to enable the preload so that you can update the ARR register without immediately changing the active register. Then, creating an update event can make sure that the new value in the preload register is transferred to the active register at the right time.

     

    1 reply

    ST Employee
    November 25, 2024

    Hello @zeboss49

    Are you enabling the preload when updating to the ARR register? 

    zeboss49Author
    Graduate
    November 25, 2024

    Hello,

    No, I don't enable it.

    When it is enabled, DMA does not work properly.

    I've tried another solution, I change the prescaler, and surprise... all works well.

    I would prefer using ARR, but the workaround using the PSC is acceptable as a temporary solution.

    Sarra.SAnswer
    ST Employee
    November 26, 2024

    I think this has to do with the prescaler update being buffered and synchronized with the timer's update event, so, it avoids the immediate glitches that can occur when directly updating the ARR register.

    I still believe that the best way to deal with ARR is to enable the preload so that you can update the ARR register without immediately changing the active register. Then, creating an update event can make sure that the new value in the preload register is transferred to the active register at the right time.