Esp32 timer question

Hi,

I have a problem understanding the timer example found in the ESP32 arduino core 2.0.14.

The code doesn't say which timer is being used as far as I can see. Here's the code:

/*
 Repeat timer example

 This example shows how to use hardware timer in ESP32. The timer calls onTimer
 function every second. The timer can be stopped with button attached to PIN 0
 (IO0).

 This example code is in the public domain.
 */

// Stop button is attached to PIN 0 (IO0)
#define BTN_STOP_ALARM    0

hw_timer_t * timer = NULL;
volatile SemaphoreHandle_t timerSemaphore;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

volatile uint32_t isrCounter = 0;
volatile uint32_t lastIsrAt = 0;

void ARDUINO_ISR_ATTR onTimer(){
  // Increment the counter and set the time of ISR
  portENTER_CRITICAL_ISR(&timerMux);
  isrCounter = isrCounter + 1;
  lastIsrAt = millis();
  portEXIT_CRITICAL_ISR(&timerMux);
  // Give a semaphore that we can check in the loop
  xSemaphoreGiveFromISR(timerSemaphore, NULL);
  // It is safe to use digitalRead/Write here if you want to toggle an output
}

void setup() {
  Serial.begin(115200);

  // Set BTN_STOP_ALARM to input mode
  pinMode(BTN_STOP_ALARM, INPUT);

  // Create semaphore to inform us when the timer has fired
  timerSemaphore = xSemaphoreCreateBinary();

  // Set timer frequency to 1Mhz
  timer = timerBegin(1000000);

  // Attach onTimer function to our timer.
  timerAttachInterrupt(timer, &onTimer);

  // Set alarm to call onTimer function every second (value in microseconds).
  // Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter).
  timerAlarm(timer, 1000000, true, 0);
}

void loop() {
  // If Timer has fired
  if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE){
    uint32_t isrCount = 0, isrTime = 0;
    // Read the interrupt count and time
    portENTER_CRITICAL(&timerMux);
    isrCount = isrCounter;
    isrTime = lastIsrAt;
    portEXIT_CRITICAL(&timerMux);
    // Print it
    Serial.print("onTimer no. ");
    Serial.print(isrCount);
    Serial.print(" at ");
    Serial.print(isrTime);
    Serial.println(" ms");
  }
  // If button is pressed
  if (digitalRead(BTN_STOP_ALARM) == LOW) {
    // If timer is still running
    if (timer) {
      // Stop and free timer
      timerEnd(timer);
      timer = NULL;
    }
  }
}

Am I missing something?

Also. Seems that the timer = timerBegin(1000000); is using frequency, whereas in my code for the older v1.0.8 core I have which timer is being used, the divider, and finally count up or down.

I've looked through the core. Mostly it's above my knowledge level, but can someone please explain.

Main reason for asking is that I have code that compiles and runs on the 1.0.8 core but just keeps resetting on the 2.0.14 core.

For the record I'm using 1.8.16 ide I think.

Any help appreciated

Cheers

Matt

See if this link helps:
https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/timer.html
(At the end there is a copy of the code you are using).

@ruilviana
Thanks. However, I still can't see which timer is being used.

The API doesn't tell you. It just errors-out if there are none available. Why do you need to know?

@gfvalvo

I don't really 'need' to know, I was just wondering why a specific timer is not declared.

Does it just choose one itself?

Cheers,

Matt

Apparently, take a look at the source code for 'timerBegin()' in esp32-hal-timer.c. You'll see that it eventually calls This API.

1 Like

Yes, the key words in the linked Timer API

A GPTimer instance is represented by gptimer_handle_t. The driver behind will manage all available hardware resources in a pool, so that you do not need to care about which timer and which group it belongs to.

Thanks for all your help guys.

Cheers

Matt

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.