Calling gptimer_start() from ISR crashes. Why?
Posted: Wed Sep 13, 2023 9:35 am
Hello,
I just spent 4 hrs trying to figure this out, but I don't know why my code crashes. Could someone please have a look?
I have a Pulsecounter running, reading pulses from GPIO21.
Also on GPIO21 is an Interrupt (positive edge).
The interrupt handler is supposed to start a timer.
However, I cannot start the timer.
It keeps crashing with error gptimer: gptimer_start(337): timer is not enabled yet
- I have created and enabled the timer.
- I enabled timer controls in IRAM and gptimer IRAM safe in menuconfig.
- I enabled gpio controls in IRAM and gpio IRAM safe in menuconfig.
Perhaps problem lies where I pass the timer handle to the interrupt handler: (LINE 12)
this is my interrupt handler:
All the code:
I just spent 4 hrs trying to figure this out, but I don't know why my code crashes. Could someone please have a look?
I have a Pulsecounter running, reading pulses from GPIO21.
Also on GPIO21 is an Interrupt (positive edge).
The interrupt handler is supposed to start a timer.
However, I cannot start the timer.
It keeps crashing with error gptimer: gptimer_start(337): timer is not enabled yet
- I have created and enabled the timer.
- I enabled timer controls in IRAM and gptimer IRAM safe in menuconfig.
- I enabled gpio controls in IRAM and gpio IRAM safe in menuconfig.
Perhaps problem lies where I pass the timer handle to the interrupt handler: (LINE 12)
- gpio_config_t io_conf = {};
- //interrupt of rising edge
- io_conf.intr_type = GPIO_INTR_POSEDGE;
- io_conf.pin_bit_mask = (1ULL<<GPIO_NUM_21);
- //set as input mode
- io_conf.mode = GPIO_MODE_INPUT;
- //enable pull-down mode
- io_conf.pull_down_en = 1;
- gpio_config(&io_conf);
- gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
- gpio_isr_handler_add(GPIO_NUM_21, gpio_isr_handler, &gpfiltertimer);
this is my interrupt handler:
- static void IRAM_ATTR gpio_isr_handler(void* arg)
- {
- gptimer_handle_t gpfiltertimer = (gptimer_handle_t) arg;
- gptimer_start(gpfiltertimer); /////// CRASH: gptimer: gptimer_start(337): timer is not enabled yet
- gpio_set_level(45, 1);
- }
All the code:
- #include <math.h>
- #include "esp_err.h"
- #include "esp_log.h"
- #include "esp_system.h"
- #include "esp_timer.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/semphr.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #include "lvgl.h"
- #include <stdio.h>
- #include "driver/gpio.h"
- #include "driver/pulse_cnt.h"
- #include "driver/gptimer.h"
- #include "ui.h"
- #include "generics.h"
- void rRpmCounter(void);
- void vStartRpmCounterTask(void);
- extern void init_rpm_counter();
- static const char *TAG = "pulse counter";
- TaskHandle_t xRpmCounterTaskHandle;
- static pcnt_unit_handle_t pcnt_unit = NULL;
- static pcnt_channel_handle_t pcnt_chan_a = NULL;
- static gptimer_handle_t gpfiltertimer = NULL;
- static bool IRAM_ATTR filter_timer_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
- {
- BaseType_t high_task_awoken = pdFALSE;
- gpio_set_level(45, 0);
- return (high_task_awoken == pdTRUE);
- }
- static void IRAM_ATTR gpio_isr_handler(void* arg)
- {
- gpfiltertimer = (gptimer_handle_t) arg;
- //ESP_ERROR_CHECK(gptimer_start(gpfiltertimer)); /////// CRASH: gptimer: gptimer_start(337): timer is not enabled yet
- gpio_set_level(45, 1);
- }
- void vRpmCounter() {
- vTaskDelay(pdMS_TO_TICKS(500));
- ESP_LOGI(TAG, "install pcnt unit");
- pcnt_unit_config_t unit_config = {
- .high_limit = 6000,
- .low_limit = -10,
- .flags.accum_count = 0,
- };
- ESP_ERROR_CHECK(pcnt_new_unit(&unit_config, &pcnt_unit));
- ESP_LOGI(TAG, "set glitch filter");
- pcnt_glitch_filter_config_t filter_config = {
- .max_glitch_ns = 10000,
- };
- ESP_ERROR_CHECK(pcnt_unit_set_glitch_filter(pcnt_unit, &filter_config));
- ESP_LOGI(TAG, "install pcnt channels");
- pcnt_chan_config_t chan_a_config = {
- .edge_gpio_num = 21,
- .level_gpio_num = 45,
- };
- ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_a_config, &pcnt_chan_a));
- ESP_LOGI(TAG, "set edge and level actions for pcnt channels");
- ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_a, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD));
- ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_a, PCNT_CHANNEL_LEVEL_ACTION_HOLD, PCNT_CHANNEL_LEVEL_ACTION_KEEP));
- ESP_LOGI(TAG, "enable pcnt unit");
- ESP_ERROR_CHECK(pcnt_unit_enable(pcnt_unit));
- ESP_LOGI(TAG, "clear pcnt unit");
- ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit));
- ESP_LOGI(TAG, "start pcnt unit");
- ESP_ERROR_CHECK(pcnt_unit_start(pcnt_unit));
- vTaskDelay(pdMS_TO_TICKS(500));
- ESP_LOGI(TAG, "Create RPM Filter timer handle");
- gptimer_config_t filter_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(&filter_timer_config, &gpfiltertimer));
- gptimer_event_callbacks_t filter_cbs = {
- .on_alarm = filter_timer_cb,
- };
- ESP_ERROR_CHECK(gptimer_register_event_callbacks(gpfiltertimer, &filter_cbs, NULL));
- ESP_ERROR_CHECK(gptimer_enable(gpfiltertimer));
- gptimer_alarm_config_t filter_alarm_config = {
- .alarm_count = 10000, //1000000 = 1s
- };
- ESP_ERROR_CHECK(gptimer_set_alarm_action(gpfiltertimer, &filter_alarm_config));
- vTaskDelay(pdMS_TO_TICKS(500));
- gpio_config_t io_conf = {};
- //interrupt of rising edge
- io_conf.intr_type = GPIO_INTR_POSEDGE;
- io_conf.pin_bit_mask = (1ULL<<GPIO_NUM_21);
- //set as input mode
- io_conf.mode = GPIO_MODE_INPUT;
- //enable pull-down mode
- io_conf.pull_down_en = 1;
- gpio_config(&io_conf);
- gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
- gpio_isr_handler_add(GPIO_NUM_21, gpio_isr_handler, &gpfiltertimer); ///// SETTING THE GPIO INTERRUPT
- uint32_t rpm;
- while (1) {
- if (xQueueReceive(queue, &ele, pdMS_TO_TICKS(1000))) {
- // This Queue is used by another timer which I have left out for brevity
- } else {
- //my_toba.rpm = 0;
- }
- }
- }
- void vStartRpmCounterTask(void) {
- xTaskCreate(vRpmCounter, "RPM", 4096, NULL, 1, &xRpmCounterTaskHandle);
- configASSERT(xRpmCounterTaskHandle);
- }