ESP32 simple timer setup

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

ESP32 simple timer setup

Postby zazas321 » Mon Sep 20, 2021 11:43 am

Hello. I am working on ESP32 and trying to setup the most simple timer example. I have found some timer_queue example code in the esp examples folder but this example is way too complicated and overwhelming. All I want is to setup a simple timer and trigger my callback function lets say every 20ms.

See my .c file

Code: Select all

#include "timer_custom.h"


static void IRAM_ATTR timer_group0_isr(void* arg) {

    printf("TIMER CALLBACK\n");
    //TIMERG0.int_clr_timers.t0 = 1;
    //TIMERG0.hw_timer[0].config.alarm_en = 1;
}


void TIMER_INIT(int timer_idx) {

    timer_config_t config = 
    {
  		  .alarm_en = true,
  		  .counter_en = false,
  		  .intr_type = TIMER_INTR_LEVEL,
  		  .counter_dir = TIMER_COUNT_UP,
  		  .auto_reload = true,
  		  .divider = 80
            
    };


  timer_init(TIMER_GROUP_0, timer_idx, &config);
  timer_set_counter_value(TIMER_GROUP_0, timer_idx, 0);
  timer_set_alarm_value(TIMER_GROUP_0, timer_idx, 10000);
  timer_enable_intr(TIMER_GROUP_0, timer_idx);
  timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr, (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
  timer_start(TIMER_GROUP_0, timer_idx);
  printf("timer initialzied!!!!\n");
}




my header file

Code: Select all

#ifndef TIMER_CUSTOM_H
#define TIMER_CUSTOM_H

#include "driver/timer.h"
#include "stdio.h"


void TIMER_INIT (int timer_idx);


#endif


As you can see in my TIMER_INIT function I have set the divider to 80 which means that the timer frequency should be 80mhz(apb frequency) / 80 = 1Mhz

I have set my counter value to 0 and my alarm value to 20000.

So from what I understand, the callback function is only going to trigger when the alarm value reaches 20000 so it is going to take 20000 timer ticks which results in 50hz frequency is that right? So I am expecting my timer callback function be executed at 50hz.

However, I cannot get my program to work, the cpu just constantly crashing:

Code: Select all

timer initialzied!!!!
abort() was called at PC 0x4008265f on core 0

My questions:

1. Can someone help me understand the example timer_queue code. Why would I need to use freertos queues for a simple timer application? I have tried to play with the esp-idf example by changing the intervals but just couldnt get my head around it. If I want to get a timer with a frequency of 1khz and in the callback function I want to increment counter, what do I need to modify in the example code?

2. In my own custom example. I use:

Code: Select all

timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr, (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
to register the callback function, but the example code uses

Code: Select all

timer_isr_callback_add(TIMER_GROUP_0, timer_idx, timer_group0_isr, NULL, 0);
I cant really seem to understand what exactly are the differences.

Please advise me how to develop timers for esp32

felmue
Posts: 69
Joined: Mon Nov 16, 2020 2:55 pm

Re: ESP32 simple timer setup

Postby felmue » Mon Sep 20, 2021 12:32 pm

Hello @zazas321

most likely the reason your code is crashing is the 'printf()' statement in the ISR callback function. As a rule all of the ISR code needs to be in RAM, but 'printf()' is not, hence the crash. (BTW: That is probably the reason the example you found is using a queue.)

Have you checked out this timer example? https://github.com/espressif/esp-idf/tr ... /esp_timer

Thanks
Felix

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

Re: ESP32 simple timer setup

Postby zazas321 » Tue Sep 21, 2021 4:19 am

Oh I see. I havent come across this particular example that you have just provided. Thank you I will look it up. I have managed to implement a simple software timer using xTimerStart(). However, this can go maximum at 100Hz because that is my FreeRTOS tick rate set at. I need a timer that is much faster than that, however, I am slightly concerned about FreeRTOS working together with timers,is that not an issue? For example, If I have multiple timers running at fast speeds, I will need my CPU to send some or process some information hence less time for other FreeRTOS Tasks

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

Re: ESP32 simple timer setup

Postby zazas321 » Tue Sep 21, 2021 5:46 am

I have been further learning about timers and experimenting with various example codes, it frustrates that I cannot get this most basic example to work:

As you have mentioned, I have ensured that I do not have any print statements in my timer callback function. All I want to do now, is setup a timer that would trigger every 1second and increment a variable.

Code: Select all

int count = 0;


static void IRAM_ATTR timer_callback(void* args) {
    count++;
}

void TIMER_INIT2(int timer_idx) {
    timer_config_t config = 
    {
  		  .alarm_en = true,
  		  .counter_en = false,
  		  .intr_type = TIMER_INTR_LEVEL,
  		  .counter_dir = TIMER_COUNT_UP,
  		  .auto_reload = true,
  		  .divider = 80
            
    };

    timer_init(TIMER_GROUP_0, timer_idx, &config);
    timer_set_counter_value(TIMER_GROUP_0, timer_idx, 0);
    timer_set_alarm_value(TIMER_GROUP_0, timer_idx, 1000000);
    timer_enable_intr(TIMER_GROUP_0, timer_idx);
    timer_isr_register(TIMER_GROUP_0, timer_idx, timer_callback, (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
    timer_start(TIMER_GROUP_0, timer_idx);
    printf("timer initialzied!!!!\n");
}
and in my main.c I call:

Code: Select all

TIMER_INIT2(TIMER_0) 
Since I have set my divider to 80 ( clocking at 1mhz since apb clock is 80mhz) and alarm value at 1000000, that means my callback should execute every 1s. When I start the program, the cpu crashes every 1 second ( when the alarm is triggered)

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

Re: ESP32 simple timer setup

Postby zazas321 » Tue Sep 21, 2021 6:04 am

I have found an issue what was causing the problem. I was initially using:

Code: Select all

timer_isr_register(TIMER_GROUP_0, timer_idx, timer_callback, (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
And this was causing the CPU to crash when alarm value is reached.

I have now replaced the function above with the:

Code: Select all

timer_isr_callback_add(TIMER_GROUP_0, timer_idx, timer_callback, NULL, 0);
And my everything seems to work fine. Could someone help me understand the differences between two? The example I was looking at suggested to use the non working function

Code: Select all

timer_isr_register(TIMER_GROUP_0, timer_idx, timer_callback, (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);

Who is online

Users browsing this forum: Phillip and 159 guests