2024-12-16 07:12 AM
It is well-known that when configuring and starting a timer using HAL_TIM_Base_Init and HAL_TIM_Base_Start_IT, the interrupt and callback are triggered immediately. This is because configuring the reload-register & prescaler requires generating an update event (using EGR_UG) which then sets the interrupt flag.
The function TIM_Base_SetConfig even contains an attempt to solve this by manually clearing the UIF flag.
/* Generate an update event to reload the Prescaler
and the repetition counter (only for advanced timer) value immediately */
TIMx->EGR = TIM_EGR_UG;
/* Check if the update flag is set after the Update Generation, if so clear the UIF flag */
if (HAL_IS_BIT_SET(TIMx->SR, TIM_FLAG_UPDATE))
{
/* Clear the update flag */
CLEAR_BIT(TIMx->SR, TIM_FLAG_UPDATE);
}
However, this does not usually work, probably because the timer runs a little slower than the CPU, and the APB bus also needs a few cycles to transfer the access to EGR. Compiling without optimizations or adding a few "NOP"s after setting TIM_EGR_UG makes this "work", i.e. the first interrupt is skipped.
So I would propose to change this to:
/* Wait for the timer to set the update flag after the Update Generation, such that we can clear the UIF flag */
while (!HAL_IS_BIT_SET(TIMx->SR, TIM_FLAG_UPDATE));
/* Clear the update flag */
TIMx->SR = ~TIM_FLAG_UPDATE;
The timer hardware should always set the UIF after setting EGR_UG, so we can safely wait for this using "while", which will only take a few CPU cycles. After that we clear UIF such that the first interrupt is guaranteed to be blocked.
Alternatively, the entire check for the UIF should be removed, such that user code can manually clear the UIF. IMO the current implementation of that check is pointless, as it might only work occasionally (probably dependent on APB prescaler, program memory speed / flash latency, dynamic voltage scaling - anything that affects CPU speed relative to timer clock).
2024-12-16 08:20 AM
Hello @Erlkoenig,
Thank you for the constructive insights, This issue is already under investigation in an ongoing ticket (Internal ticket number: 160192)
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.