I'm having a little suprise with timer interrupt on update event. I thought that if timer is configured to count up, update event will occure just after the overflow, i.e. when CNT will become equal to zero. According to figures 103-105 from reference manual.
But that doesn't seem to be the case for some reason. I tested it with this simple code:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// tick frequency in Hz
const uint32_t tickFreq = 1000*1000;
const uint16_t timPrescaler = SystemCoreClock / (tickFreq ) - 1;
TIM_TimeBaseInitTypeDef timBaseStruct;
timBaseStruct.TIM_Prescaler = timPrescaler;
timBaseStruct.TIM_ClockDivision = 0;
timBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
timBaseStruct.TIM_Period = 5;
TIM_TimeBaseInit(TIM2, &timBaseStruct);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE );
NVIC_EnableIRQ(TIM2_IRQn);
Then in the irq handler:
void TIM2_IRQHandler(void)
{
if(TIM2->CNT != 0)
{
TIM2->CNT = 1; // <----------- and I put a breakpoint on this line
}
TIM2->SR = ( uint16_t ) ~TIM_IT_Update;
}
I don't have anything else enabled, no critical sections, just an empty while loop.
I also have an .ini file for debugger, so when I stop the execution, all timers are also stopped.
Now the interesting bit.
When I debug in the Keil Simulator - execution doesn't stop on the breakpoint. But when I debug on the board - execution stops on the breakpoint and I can see that TIM2->CNT is equal to 1!
It does appear to be connected with tick frequency, if I make it a thousand times less, breakpoint doesn't stop the execution. But what the hell, it's just 1 MHz; CPU is clocked on 72 MHz!
Now I wonder - is it a bug in the simulator or in the hardware? Or I have simply misread something and timer is not initialized properly?