TIMER - Overflow event - Must reset CNT?
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();
}

