Skip to main content
Visitor II
February 18, 2025
Solved

TIMER - Overflow event - Must reset CNT?

  • February 18, 2025
  • 1 reply
  • 920 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

     

    1 reply

    TDKAnswer
    Super User
    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

     

    SkeebAuthor
    Visitor II
    February 18, 2025

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

    Super User
    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?