Page 1 of 3

The exact frequency of the timer

Posted: Wed Aug 30, 2023 12:22 pm
by mikl604
Hello everybody!
How do I get the exact interrupt frequency from the hardware timer? I need 115200 Hz. I can't find the coefficients. How do I calculate frequencies correctly using all the possibilities?

Re: The exact frequency of the timer

Posted: Fri Sep 01, 2023 8:57 am
by MicroController
What coefficients/what hardware timer are you referring to?

Are we talking about the "General Purpose Timer"?

Re: The exact frequency of the timer

Posted: Fri Sep 01, 2023 12:30 pm
by mikl604
Yes. Here in this timer setting, how to choose the right coefficients in X, Y and Z to get an interrupt of 115200 Hz:

timer_config_t config_period =
{
.divider = X,
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.auto_reload = TIMER_AUTORELOAD_EN,
};
timer_set_counter_value(TIMER_GROUP_0, TIMER_0, Y);
timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, Z);

Re: The exact frequency of the timer

Posted: Fri Sep 01, 2023 7:52 pm
by MicroController
Ok.
One factor is missing: The timer's "source clock".
The way the timer works is:
1. You select a source clock, which by its frequency defines the "source" frequency for the timer.
2. You select a "divider" (>=2). The timer "ticks" at a rate of (source frequency / divider).
3. You select an "alarm value" (Z) to specify when the timer's interrupt is to trigger.
Normally, the timer counts, at the rate determined by 1. and 2., from 0 up to the alarm count value and then triggers an interrupt. An "auto reload" timer automatically resets to (typically) 0 when the alarm count is reached and keeps counting up, repeating the process and giving a fixed rate of interrupts of ((source frequency / divider) / alarm value).
In most cases you won't care about setting a specific counter value but just let it run from 0.

The relation is thus: F[alarm] = F[src] / (divider * alarm value), or F[src] / F[alarm] = divider * alarm value

For 115200Hz, you could do:
1. source clock = GPTIMER_CLK_SRC_APB (which is 80 MHz)
2. 80'000'000Hz/115200Hz = 694.4444..., which should equal (divider * alarm value)
3. select any combination of divider (>=2 and <= 65536) and alarm value (>0) which (closest) satisfies (divider * alarm value) = 694.4444...; for example divider := 2 -> alarm value = ((80Mhz/2)/115200Hz) ~ 347, giving an interrupt frequency of 80MHz/(2*347) ~ 115273Hz.

If the frequency attainable by the hardware is not accurate enough, you can implement a form of dithering by varying the alarm value for the next interrupt by 0 or 1 in the ISR to "succesively approximate" the average interrupt frequency to the exact required frequency.

Re: The exact frequency of the timer

Posted: Sat Sep 02, 2023 1:29 pm
by mikl604
Thanks I got it. Does the clock speed of the timer equal the clock speed of the processor? If the processor frequency is set to 240 MHz, will the timer also work on it?

Re: The exact frequency of the timer

Posted: Sat Sep 02, 2023 3:14 pm
by ghost07
115200 Hz it is interrupt every 8.6 microseconds.
Context switch takes 12 microseconds with CPU clock at 240 MHz (15 microseconds at 160 MHz). Interrupt handler written in "high-level" language (in C instead of assembler) will be probably called from isr0 or isr1 task which requires context switch, and after ISR handler returns it will probably try to yield to Idle which means another context switch.

What are you trying to achieve? Maybe some peripheral (dedicated HW) could help here. For example UART, PWM, SPI etc..

Re: The exact frequency of the timer

Posted: Sat Sep 02, 2023 3:16 pm
by MicroController
Thanks I got it. Does the clock speed of the timer equal the clock speed of the processor? If the processor frequency is set to 240 MHz, will the timer also work on it?
No. The timer is clocked by its "source clock". The ESP32 supports only one source clock, the APB clock, which runs at 80MHz max.

Re: The exact frequency of the timer

Posted: Sat Sep 02, 2023 3:34 pm
by MicroController
ghost07 wrote:
Sat Sep 02, 2023 3:14 pm
115200 Hz it is interrupt every 8.6 microseconds.
I.o.w., about 2000 CPU clock cycles per interrupt. Should be possible.
Context switch takes 12 microseconds with CPU clock at 240 MHz (15 microseconds at 160 MHz).
Fortunately, running an ISR per se doesn't require a context switch between tasks.

Re: The exact frequency of the timer

Posted: Sat Sep 02, 2023 5:49 pm
by mikl604
ghost07 wrote:
Sat Sep 02, 2023 3:14 pm
What are you trying to achieve? Maybe some peripheral (dedicated HW) could help here. For example UART, PWM, SPI etc..
I need to read data strictly simultaneously from 8 sensors via UART. Hardware UART is not suitable for this, so I'm writing my own.

Re: The exact frequency of the timer

Posted: Sat Sep 02, 2023 5:58 pm
by mikl604
And another question, how do I get the timer to start working with an interrupt? In a normal setting, the timer starts counting from 0 and takes some time before an interruption occurs. And it is necessary that when the timer starts, an interruption immediately occurs, then a count, another interruption, etc.