Skip to main content
Associate
February 18, 2025
Solved

TIMER - Overflow event - Must reset CNT?

  • February 18, 2025
  • 5 replies
  • 979 views

Hi There,

I have setup TIMER4 on STM32G484 device for overflow event and enabled interrupt for events. 

Everything works fine and as expected with correct fire time if I RESET the CNT register in the ISR. However, if I do not, it seems to do some level of free-running.

I only inquire about this, as in all of the STM32 reference manual images, when an overflow event occurs and it's been enabled to detect this, the CNT resets in the peripheral (as long as not single shot mode). So I'm just wanting to confirm that this seems normal and is not a hint that I've misconfigured something. Here are my configuration calls and ISR, I verify the ISR timing on the scope with a GPIO toggling (not shown here).

 

 

 

 Register_t rcc_tim4_en = { .address = 0x40021058, .mask = 0x1, .bit_pos = 2 };
 Read_Then_Write_Masked(rcc_tim4_en, 0x1);

 Register_t tim4_cr_dir = { .address = k_tim4_addr + k_timx_cr1_offset, .mask = 0x1, .bit_pos = 4 };
 Read_Then_Write_Masked(tim4_cr_dir, 0); // Up counter

 Register_t tim4_smcr_sms = { .address = k_tim4_addr + k_timx_smcr_offset, .mask = 0x7, .bit_pos = 0 };
 Read_Then_Write_Masked(tim4_smcr_sms, 0); // Slave mode disabled, use internal clock for timer


 Read_Then_Write_Masked(k_tim4_arr, hal::Get_Timer_CLK_Hz() / k_timer_ISR_frequency_Hz); // No prescaler, overflow at this value

 // Trigger a software driven event update so new capture parameters are forced through
 Register_t tim4_egr_ug = { .address = k_tim4_addr + k_timx_egr_offset, .mask = 0x1, .bit_pos = 0 };
 Read_Then_Write_Masked(tim4_egr_ug, 1);

....
 Read_Then_Write_Masked(k_tim4_cr1_cen, 1);
 Read_Then_Write_Masked(k_tim4_dier_ue, 1);
....

void hal::timers::Factory::run_priority_tasks()
{
 // Make sure an overflow event is what got us here
 if (! Read_Masked_Shifted(k_tim4_sr_ue))
 {
 //FIXME error handling? This is kind of mission critical
 Abort();
 }

 Write_Masked(k_tim4_cnt, 0); // Unfortunately the peripheral does not reset this when overflowing
 Write_Masked(k_tim4_sr_ue, 0); // Reset it so can check on it again next ISR (this is purely a flag, not the interrupt clearing)

 hal::gpio::Factory::get_instance().toggle_debug_led(); 
}

 

 

 

 

 

This topic has been closed for replies.
Best answer by TDK

When a timer is in normal upcounting free-run mode, CNT resets to 0 after it reaches ARR. It does not need reset to 0, and in fact is already at 0 when the update event is handled.

TDK_0-1739852750794.png

 

5 replies

TDK
TDKBest answer
February 18, 2025

When a timer is in normal upcounting free-run mode, CNT resets to 0 after it reaches ARR. It does not need reset to 0, and in fact is already at 0 when the update event is handled.

TDK_0-1739852750794.png

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
SkeebAuthor
Associate
February 18, 2025

Thank you for confirming, any ideas with my configuration above why that is not happening? 

TDK
February 18, 2025

It probably is happening. The timer is a hardware state machine, if UIF gets set, an update event occurred, and CNT got set back to 0. It may tick a few times before you can handle it, depending on the timer tick speed. Probably you should recheck your assumptions which led you to believe it's not being set. Why do you think it's not happening?

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