SuperHouse / esp-open-rtos

Open source FreeRTOS-based ESP8266 software framework
BSD 3-Clause "New" or "Revised" License
1.52k stars 491 forks source link

(Dis-)arming timer 100 times per second #736

Open mgoeller opened 4 years ago

mgoeller commented 4 years ago

I have an GPIO with a small circuit connected to power frequency and a button. E.g. the GPIO receives a rectangular waveform with HIGH/LOW with a period of 10ms if the button is pressed. If the button isn't pressed the GPIO is constant HIGH.

I want a counter variable to count up whenever the button is pressed and hold.

I initialise the functions, button and timer as follows.

 // define button as input
 gpio_enable(BTN_GPIO, GPIO_INPUT);
// set up interrupt listener
gpio_set_interrupt(BTN_GPIO, GPIO_INTTYPE_EDGE_POS, btn_intr_cb);
//define timer
static ETSTimer btn_timer;

And the interrupt callback function:

IRAM static void btn_intr_cb(uint8_t gpio) {
   sdk_os_timer_disarm(&btn_timer);
   counter++;
   sdk_os_timer_arm(&btn_timer, 10*AC_PERIOD, 0);
}

My ESP8266 constantly reboots after a few random button presses and holds (counter is in the range of 1k) if disarming and arming of the timer is done in the interrupt callback function. If I remove the timer stuff it works perfectly. Is the frequency too high and leads to an overflow?

Somehow it doesn't matter if set the INTTYPE_EDGE to ANY, POS or NEG. The button callback function is always executed with a 10ms period. Except when I put the "counter++" lign at first in the callback function, then it is only executed with a 20ms period.

Any ideas?

nonameplum commented 4 years ago

I'm not sure if arming timer in ISR interrupt is allowed or not but there is high chance that you might expect problems because of it. Even print in interrupt handler is not a good practice. I would suggest take a look at button example https://github.com/SuperHouse/esp-open-rtos/blob/master/examples/button/button.c and move the handling into task that is wakeup using queue.