The exact frequency of the timer
The exact frequency of the timer
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?
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?
-
- Posts: 1725
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: The exact frequency of the timer
What coefficients/what hardware timer are you referring to?
Are we talking about the "General Purpose Timer"?
Are we talking about the "General Purpose Timer"?
Re: The exact frequency of the timer
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);
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);
-
- Posts: 1725
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: The exact frequency of the timer
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.
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
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
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..
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..
Last edited by ghost07 on Sat Sep 02, 2023 3:25 pm, edited 1 time in total.
-
- Posts: 1725
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: The exact frequency of the timer
No. The timer is clocked by its "source clock". The ESP32 supports only one source clock, the APB clock, which runs at 80MHz max.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?
-
- Posts: 1725
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: The exact frequency of the timer
I.o.w., about 2000 CPU clock cycles per interrupt. Should be possible.
Fortunately, running an ISR per se doesn't require a context switch between tasks.Context switch takes 12 microseconds with CPU clock at 240 MHz (15 microseconds at 160 MHz).
Re: The exact frequency of the timer
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.
Who is online
Users browsing this forum: No registered users and 437 guests