Skip to content

hw_timer_t can't be retriggered from inside an interrupt in 2.0.2+ #6693

@sweetlilmre

Description

@sweetlilmre
Contributor

Board

ESP32 Dev Module

Device Description

https://www.banggood.com/ESP32-WiFi-+-bluetooth-Development-Board-Ultra-Low-Power-Consumption-Dual-Core-ESP-32-ESP-32S-Similar-ESP8266-Geekcreit-for-Arduino-products-that-work-with-official-Arduino-boards-p-1175488.html

Hardware Configuration

16x2 LCD connected via I2C
SD card connected via SDMMC pins
Rotary encoder connected to general IO

Version

v2.0.2

IDE Name

Platformio 4.2.0 Visual Studio Code

Operating System

Windows 10 x64

Flash frequency

80 MHz

PSRAM enabled

no

Upload speed

921600

Description

The code below works in framework-arduinoespressif32 3.20001.0 (2.0.1) and below, but not 2.0.2 and above, including https://github.com/espressif/arduino-esp32.git#142fceb8563cd1795d619829e0a103770a344e1a (which I believe is 2.0.3 as based on the info from this issue: #6689 )

In 2.0.1 or below the serial output shows an increasing value for 'tick', but in any framework version greater than 2.0.1, 'tick' stays at 1 indicating that the interrupt is not retriggered by the timer code inside of it.

Using the PIO Arduino support 4.1.0 (2.0.1) <- Works, tick increments
Using the PIO Arduino support 4.2.0 (2.0.2) <- Does not work, tick is 1 (interrupt fired once)
Using the PIO Arduino support 4.2.0 (2.0.3 from the git hash mentioned above) <- Does not work, tick is 1 (interrupt fired once)

Sketch

#include <Arduino.h>

hw_timer_t *signalTimer;
#define IDLE_TIMER_EXECUTE 1000
volatile uint32_t tick = 0;

void IRAM_ATTR signalTimerFunc()
{
  tick++;
  timerWrite(signalTimer, 0);
  // IDLE_TIMER_EXECUTE is used here for simplicity. The actual next interval would be calculated in the ISR
  timerAlarmWrite(signalTimer, IDLE_TIMER_EXECUTE, false);
  timerAlarmEnable(signalTimer);
}

void startTimer()
{
  signalTimer = timerBegin(0, 40, true);
  timerAttachInterrupt(signalTimer, &signalTimerFunc, true);
  timerWrite(signalTimer, 0);
  timerAlarmWrite(signalTimer, IDLE_TIMER_EXECUTE, false);
  timerAlarmEnable(signalTimer);
}

void stopTimer()
{
  timerAlarmDisable(signalTimer);
  timerDetachInterrupt(signalTimer);
  timerEnd(signalTimer);
  signalTimer = NULL;
}

void setup()
{
  Serial.begin(115200);
  Serial.println("Starting timer");
  startTimer();
}

void loop()
{
  delay(10);
  Serial.printf("tick: %d\n", tick);
}

Debug Message

No debug, just the serial output as described.

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Activity

VojtechBartoska

VojtechBartoska commented on May 5, 2022

@VojtechBartoska
Contributor

Hello, are you please able to retest this with newly release 2.0.3 stable version please?

sweetlilmre

sweetlilmre commented on May 5, 2022

@sweetlilmre
ContributorAuthor

Hi I will retest, just need confirmation on how I would set this up with Platformio. I am assuming that I can do something like this in my platformio.ini file:

platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.3

I'll try this and get back to you.

Edit: I am specifying this to be clear:

platform = https://github.com/platformio/platform-espressif32.git#v4.2.0

platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.3

sweetlilmre

sweetlilmre commented on May 5, 2022

@sweetlilmre
ContributorAuthor

Just tested with the configuration below and the issue still persists:

Edit: doing further testing from a completely clean platformio installation.

CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32dev.html
PLATFORM: Espressif 32 (4.2.0+sha.6f9e45a) > Espressif ESP32 Dev Module
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
- framework-arduinoespressif32 2.0.3+sha.142fceb
- tool-esptoolpy 1.30300.0 (3.3.0)
- tool-mkfatfs 2.0.1
- tool-mklittlefs 1.203.210628 (2.3)
- tool-mkspiffs 2.230.0 (2.30)
- toolchain-xtensa-esp32 8.4.0+2021r2-patch3
sweetlilmre

sweetlilmre commented on May 5, 2022

@sweetlilmre
ContributorAuthor

Full clean platformio install with 2.0.3 and the issue persists:

Processing esp32dev (platform: platform = espressif32 @ 4.2.0; board: esp32dev; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Tool Manager: Installing platformio/tool-mkspiffs @ ~2.230.0
Downloading  [####################################]  100%
Unpacking  [####################################]  100%
Tool Manager: tool-mkspiffs @ 2.230.0 has been installed!     
Tool Manager: Installing platformio/tool-mklittlefs @ ~1.203.0
Downloading  [####################################]  100%
Unpacking  [####################################]  100%
Tool Manager: tool-mklittlefs @ 1.203.210628 has been installed!
Tool Manager: Installing platformio/tool-mkfatfs @ ~2.0.0       
Downloading  [####################################]  100%
Unpacking  [####################################]  100%
Tool Manager: tool-mkfatfs @ 2.0.1 has been installed!
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32dev.html
PLATFORM: Espressif 32 (4.2.0) > Espressif ESP32 Dev Module
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
 - framework-arduinoespressif32 2.0.3+sha.142fceb
 - tool-esptoolpy 1.30300.0 (3.3.0)
 - tool-mkfatfs 2.0.1
 - tool-mklittlefs 1.203.210628 (2.3)
 - tool-mkspiffs 2.230.0 (2.30)
 - toolchain-xtensa-esp32 8.4.0+2021r2-patch3
self-assigned this
on May 5, 2022
P-R-O-C-H-Y

P-R-O-C-H-Y commented on May 5, 2022

@P-R-O-C-H-Y
Member

Hi @sweetlilmre,
Your implementation is wrong. The functions timerAlarmWrite(signalTimer, IDLE_TIMER_EXECUTE, false); the last parameter is, if you want to repeat the alarm. Set it to TRUE and comment out timerAlarmWrite(signalTimer, IDLE_TIMER_EXECUTE, false); and timerAlarmEnable(signalTimer); from void IRAM_ATTR signalTimerFunc() :)

sweetlilmre

sweetlilmre commented on May 5, 2022

@sweetlilmre
ContributorAuthor

Hi @P-R-O-C-H-Y 

Thank you for your response. The sample I have provided is just the smallest possible example of the functionality I am using in a bigger project.

I do not want the timer to repeat as per your code above. In the actual project:

  • the next timer interval is calculated in the ISR
  • IO lines are set high / low
  • the timer is set to re-trigger at the next calculated interval.
  • effectively this is a data based signal generator

So my implementation is logically correct and works as stated for anything pre 2.0.2. If there is a change in the API that would require me to implement this functionality differently then that would be helpful to understand.

I have updated the example code to make the use-case explicit. Apologies for any confusion caused.

atanisoft

atanisoft commented on May 5, 2022

@atanisoft
Collaborator

@sweetlilmre remove the call to timerAlarmEnable from signalTimerFunc, it shouldn't be necessary and may actually be resetting your parameters!

Be warned however, using HW Timers to adjust GPIO pins WILL generate inconsistencies in your signal! I initially was using the timers in this code and moved to the RMT for accuracy/compliance purposes. You can see some externally captured timing here.

sweetlilmre

sweetlilmre commented on May 5, 2022

@sweetlilmre
ContributorAuthor

Hi @atanisoft I tried your suggestion. Unfortunately this does not solve the 2.0.3 issue and additionally stops the timer from re-firing in 2.0.1 so it seems to be necessary in this "repeating one-shot" context. 

Luckily signal inconsistency is not a huge issue in my application and it definitely works for use-case.

Thank you very much for the links, I've been meaning to look into the RMT stuff for a while but the complexity scared me off.

16 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @sweetlilmre@x29a@atanisoft@VojtechBartoska@P-R-O-C-H-Y

      Issue actions

        hw_timer_t can't be retriggered from inside an interrupt in 2.0.2+ · Issue #6693 · espressif/arduino-esp32