Stopping esp timer generates exception

hetal.panara82
Posts: 16
Joined: Wed Jun 26, 2019 7:11 am

Stopping esp timer generates exception

Postby hetal.panara82 » Mon Aug 19, 2019 4:26 pm

I am working with ESP32 Dev kit V1.
As I load example program, esp_timer from package it works fine and I see one shot timer and periodic timer working fine as expected.

However if I create a task and initialize timer (copy paste from example), I see timer is started as expected (based on the logs it prints). I have assigned a callback which,
1. printf a log statement
2. stop timer by calling, (code snippet attached)
ESP_ERROR_CHECK(esp_timer_stop(periodic_timer_handle));

Here, as soon as it calls stop timer, it generates exception and reboots. Any clue? It seems to be the same example code which I have added as part of my new task which I am calling from app_main routine.
After initializing the gpio and timer, task is there in while loop so as not to end it

Code: Select all

/* GPIO Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"

/**
 * Brief:
 * This test code shows how to configure gpio and how to use gpio interrupt.
 *
 * GPIO status:
 * GPIO18: output
 * GPIO19: output
 * GPIO4:  input, pulled up, interrupt from rising edge and falling edge
 * GPIO5:  input, pulled up, interrupt from rising edge.
 *
 * Test:
 * Connect GPIO18 with GPIO4
 * Connect GPIO19 with GPIO5
 * Generate pulses on GPIO18/19, that triggers interrupt on GPIO4/5
 *
 */

#define GPIO_INPUT_IO_0     23
#define GPIO_INPUT_PIN_SEL  (1ULL<<GPIO_INPUT_IO_0)
#define ESP_INTR_FLAG_DEFAULT 0

static gpio_num_t switch_gpio_num;

static xQueueHandle gpio_evt_queue = NULL;

    
//static esp_timer_handle_t oneshot_timer;
static void oneshot_timer_callback(void* arg);

    
static esp_timer_create_args_t oneshot_timer_args;

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);

}

static void gpio_switch_task(void* arg)
{
    printf("SP_DEBUG: starting gpio switch task\n");
    for(;;) {
        if(xQueueReceive(gpio_evt_queue, &switch_gpio_num, portMAX_DELAY)) {
            printf("GPIO[%d] intr, val: %d\n", switch_gpio_num, gpio_get_level(switch_gpio_num));
    
    
	    //ESP_ERROR_CHECK(esp_timer_stop(oneshot_timer));
	    //ESP_ERROR_CHECK(esp_timer_start_once(oneshot_timer, 1000000));
        
	}else {
	    printf("SP_DEBUG: nothing received from GPIO\n");
	}
    }
}

void switch_scan_task(void *pvParameters)
{
    esp_timer_handle_t oneshot_timer;
    
    switch_gpio_num = GPIO_INPUT_IO_0;
    gpio_config_t io_conf;
    
    //disable pull-down mode
    //io_conf.pull_down_en = 0;
    
    //disable pull-up mode
    //io_conf.pull_up_en = 0;

    //interrupt of rising edge
    io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
    //bit mask of the pins, use GPIO4/5 here
    io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
    //set as input mode    
    io_conf.mode = GPIO_MODE_INPUT;
    //enable pull-up mode
    //io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

    //change gpio intrrupt type for one pin
    gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_POSEDGE/*GPIO_INTR_ANYEDGE*/);

    //create a queue to handle gpio event from isr
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
    //start gpio task
    xTaskCreate(gpio_switch_task, "gpio_switch_task", 2048, NULL, 10, NULL);

    //install gpio isr service
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    //hook isr handler for specific gpio pin
    gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);

    //remove isr handler for gpio number.
    gpio_isr_handler_remove(GPIO_INPUT_IO_0);
    //hook isr handler for specific gpio pin again
    gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);

    //One shot timer for switch glitch filtering
    //const esp_timer_create_args_t oneshot_timer_args = {
    oneshot_timer_args.callback = &oneshot_timer_callback;
       /* argument specified here will be passed to timer callback function */
       oneshot_timer_args.arg = (void*) oneshot_timer;
       oneshot_timer_args.name = "one-shot";

    ESP_ERROR_CHECK(esp_timer_create(&oneshot_timer_args, &oneshot_timer));
	    
    ESP_ERROR_CHECK(esp_timer_start_periodic(oneshot_timer, 1000000));

#if 1
    int cnt = 0;
    while(1) {
        printf("cnt: %d\n", cnt++);
        vTaskDelay(1000 / portTICK_RATE_MS);
        //gpio_set_level(GPIO_OUTPUT_IO_0, cnt % 2);
        //gpio_set_level(GPIO_OUTPUT_IO_1, cnt % 2);
    }
#endif
}

static void oneshot_timer_callback(void* arg)
{
    //int64_t time_since_boot = esp_timer_get_time();
    //ESP_LOGI(TAG, "One-shot timer called, time since boot: %lld us", time_since_boot);
            
    printf("SP_DEBUG: oneshot timer : GPIO[%d] intr, val: %d\n", switch_gpio_num, gpio_get_level(switch_gpio_num));
    esp_timer_handle_t periodic_timer_handle = (esp_timer_handle_t) arg;
    /* To start the timer which is running, need to stop it first */
    ESP_ERROR_CHECK(esp_timer_stop(periodic_timer_handle));
    //ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer_handle, 1000000));
    //time_since_boot = esp_timer_get_time();
    //ESP_LOGI(TAG, "Restarted periodic timer with 1s period, time since boot: %lld us",
    //        time_since_boot);
}


Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot] and 328 guests