cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H5 - Issue with TIM update event generation forced by software (UG)

CTabo.1
Senior
Hello,
I have already seen some old post about this topic, but without a clear explanation and solution.
 
I have the following function, to configure and enable timer with the desired period.
 
void HW_TIMER_Enable(uint32_t period)
{
  LL_TIM_SetAutoReload(TIM6, period);
 
  // reset counter register and prescaler counter register
  LL_TIM_GenerateEvent_UPDATE(TIM6);
  LL_TIM_ClearFlag_UPDATE(TIM6);
 
  // enable timer and update event interrupt
  LL_TIM_EnableIT_UPDATE(TIM6);
  LL_TIM_EnableCounter(TIM6);
}
 
If I execute this function without optimizations (-O0), it works well.
But if I activate optimizations, that inlines the LL functions code in the caller, eliminating the LL functions call overhead, it doesn't work any longer.
In this last case, the IRQ is triggered immediately, and not at the end of the expected period.
 
The reason seems to be due to necessity to add a delay between the UG and the UIF clear commands.
Indeed, if I add a couple of __NOP() instructions after the UG command, before clearing the UIF, the function works again.
 
void HW_TIMER_Enable(uint32_t period)
{
  LL_TIM_SetAutoReload(TIM6, period);
 
  // reset counter register and prescaler counter register
  LL_TIM_GenerateEvent_UPDATE(TIM6);
  __NOP();
  __NOP();
 
  LL_TIM_ClearFlag_UPDATE(TIM6);
 
  // enable timer and update event interrupt
  LL_TIM_EnableIT_UPDATE(TIM6);
  LL_TIM_EnableCounter(TIM6);
}
 
Why I need to add a delay between UG and UIF clear commands?
How this delay must be dimensioned?
Is this pattern correct?
 
Regards,
Carlo

 

1 ACCEPTED SOLUTION

Accepted Solutions
Sarra.S
ST Employee

Hello @CTabo.1

When you set the update generation (UG) bit, it takes a few clock cycles for the update to be effective (~3 ck_tim cycles)

So, if two consecutive APB accesses are made (which last 2 cycles), the second one can pass before the update.

It is therefore necessary to add 1 delay cycle: in this case, the 2 actions will be simultaneous (update and forcing to writing counter), and writing takes priority.

 

>> if I add a couple of __NOP() instructions after the UG command, before clearing the UIF, the function works again.

however, it is not recommended to use NOPs as a delay (unpredictable results in duration, the processor may not execute the NOPs), instead, use Data Memory Barrier (DMB), Data Synchronization Barrier (DSB), and Instruction Synchronization Barrier (ISB) instructions.

Hopefully, this simplifies things slightly!

 

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.

View solution in original post

2 REPLIES 2
Sarra.S
ST Employee

Hello @CTabo.1

When you set the update generation (UG) bit, it takes a few clock cycles for the update to be effective (~3 ck_tim cycles)

So, if two consecutive APB accesses are made (which last 2 cycles), the second one can pass before the update.

It is therefore necessary to add 1 delay cycle: in this case, the 2 actions will be simultaneous (update and forcing to writing counter), and writing takes priority.

 

>> if I add a couple of __NOP() instructions after the UG command, before clearing the UIF, the function works again.

however, it is not recommended to use NOPs as a delay (unpredictable results in duration, the processor may not execute the NOPs), instead, use Data Memory Barrier (DMB), Data Synchronization Barrier (DSB), and Instruction Synchronization Barrier (ISB) instructions.

Hopefully, this simplifies things slightly!

 

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.

Thank you @Sarra.S 
for the clear and detailed explanation.

Regards,
Carlo