Resolution of GPTimers

Flaubert
Posts: 2
Joined: Mon Sep 25, 2023 12:40 pm

Resolution of GPTimers

Postby Flaubert » Mon Sep 25, 2023 1:14 pm

Hello,
I'm trying to port some code form v4.4.2 to v5.5.1, in this case about using the new GPTimer (Timer Group Before). Here is a simple code to blink red led at a WROVER-KIT at 1Hz (change LED every 500ms).

Code: Select all

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <stddef.h>
#include "driver/gptimer.h"
#include "driver/gpio.h"
#include "esp_log.h"

#define LED_GPIO 0
#define PERIOD_MS 500
static const char *TAG = "example";

static bool IRAM_ATTR timer_gpt0_isr(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
{
	static int io_state = 0;
	io_state ^= 1;					    
	gpio_set_level(LED_GPIO, io_state); 
    return (true);
}

void timer_gpt0_initialise (int timer_period_ms)
{
    gptimer_handle_t gptimer = NULL;
    gptimer_config_t timer_config = {
        .clk_src = GPTIMER_CLK_SRC_DEFAULT,
        .direction = GPTIMER_COUNT_UP,
        .resolution_hz = 1000000, // 1MHz, 1 tick=1us //
    };
    ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));

    gptimer_event_callbacks_t cbs = { // ISR/callback del timer
        .on_alarm = timer_gpt0_isr,
    };


    gptimer_alarm_config_t alarm_config = {
        .reload_count = 0, // counter will reload with 0 on alarm event
        .alarm_count = timer_period_ms, // period = 500mss @resolution 1MHz
        .flags.auto_reload_on_alarm = true, // enable auto-reload
    };

    ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));
    ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, NULL));
    ESP_LOGI(TAG, "Enable timer");
    ESP_ERROR_CHECK(gptimer_enable(gptimer));
    ESP_LOGI(TAG, "Start timer");
    ESP_ERROR_CHECK(gptimer_start(gptimer));
}

void app_main(void){

	gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);

	timer_gpt0_initialise(PERIOD_MS*1000); 
	while(1) { 
		vTaskDelay(0.010* configTICK_RATE_HZ); 
	}
}
It works, but if I change timer resolution from 1us to 1ms:

Code: Select all

        .resolution_hz = 1000, // 1KHz, 1 tick=1ms //
...application crashes with a "assert failed: timer_ll_set_clock_prescale /IDF/components/hal/esp32/include/hal/timer_ll.h:84 (divider >= 2 && divider <= 65536)" message.
I would like to now whether is a minimum resolution for GPTimers and why.
Thanks in advance.

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Resolution of GPTimers

Postby ESP_Sprite » Tue Sep 26, 2023 12:12 am

There is. According to to the trm, the timer prescaler is 16 bit and it normally gets fed from the 80MHz APB clock. That means that the minimum resolution is (80MHz/65535=)1221Hz.

On the other side of the coin, the timer itself is 64 bit (56 bit on later ESP32-Cx/ESP32-Sx) which gives you 7 thousand years (28 years) of counting, even at 80MHz, so there really isn't a need to set such a high divider.

Flaubert
Posts: 2
Joined: Mon Sep 25, 2023 12:40 pm

Re: Resolution of GPTimers

Postby Flaubert » Tue Sep 26, 2023 7:08 am

ESP_Sprite wrote:
Tue Sep 26, 2023 12:12 am
There is. According to to the trm, the timer prescaler is 16 bit and it normally gets fed from the 80MHz APB clock. That means that the minimum resolution is (80MHz/65535=)1221Hz.

On the other side of the coin, the timer itself is 64 bit (56 bit on later ESP32-Cx/ESP32-Sx) which gives you 7 thousand years (28 years) of counting, even at 80MHz, so there really isn't a need to set such a high divider.
Thanks!! Perhaps some of this info should be documented. I understand that, for ms rates, is better to go with FreeRTOS timer SW. But what I cannot understand is why doing a high level function in which you lose that control/information. Old timer functions allowed you more control -though they were a little more difficult to program-

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Resolution of GPTimers

Postby ESP_Sprite » Wed Sep 27, 2023 1:33 am

Flaubert wrote:
Tue Sep 26, 2023 7:08 am
Thanks!! Perhaps some of this info should be documented. I understand that, for ms rates, is better to go with FreeRTOS timer SW. But what I cannot understand is why doing a high level function in which you lose that control/information. Old timer functions allowed you more control -though they were a little more difficult to program-
It's because newer chips have multiple clock sources in them as well as some peculiarities where it may be good to switch clock sources during the lifetime of a program (e.g. more precise clock when the device is awake while using a different clock source when asleep so we can power down the PLL). Having the user figure all that out gets progressively harder, so simply setting a target frequency allows us to handle all that in the driver.

Who is online

Users browsing this forum: No registered users and 93 guests