Open juantxorena opened 10 months ago
The second parameter of gpio_isr_handler_add() is an ISR handler function, not a task entry function.
ISR handler function cannot be launched as a task.
Ok, I don't know what does have to do. In the code example that I pasted the second parameter of gpio_isr_handler_add() is a ISR handler function, not a task.
Learn using this official sample.
https://github.com/espressif/esp-idf/tree/master/examples/peripherals/gpio/generic_gpio
I used the official example. As I said in the description, the whole things works perfectly, as long as the switch connected to the GPIO is closed.
Hi @juantxorena, this is probably because the interrupt starts to get triggered before the ISR handler is added. Please try with configure as GPIO_INTR_DISABLE
first in the gpio_config
. And use gpio_set_intr_type(TEST_GPIO_INPUT_OUTPUT_IO1, GPIO_INTR_HIGH_LEVEL)
after gpio_isr_handler_add
is called.
Hi @songruo, sorry for the delay, I haven't got a lot of time for testing this. Thanks for the suggestion, unfortunately it doesn't help, same exception. Here's the code, maybe I implemented something wrong:
water_level_event_group = xEventGroupCreate();
gpio_config_t io_conf;
//io_conf.intr_type = GPIO_INTR_HIGH_LEVEL;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = (1ULL << GPIO_WATER_LEVEL_GPIO);
io_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
gpio_wakeup_enable(GPIO_WATER_LEVEL_GPIO, GPIO_INTR_HIGH_LEVEL);
int switch_state = gpio_get_level(GPIO_WATER_LEVEL_GPIO);
ESP_LOGE(TAG, "Switch state: %d", switch_state);
water_tank_empty = switch_state;
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_WATER_LEVEL_GPIO, water_level_switch_isr_handler, (void *)water_level_event_group);
gpio_intr_enable(GPIO_WATER_LEVEL_GPIO);
gpio_set_intr_type(GPIO_WATER_LEVEL_GPIO, GPIO_INTR_HIGH_LEVEL);
xTaskCreate(&water_level_switch_handler, "water_level_switch_handler_task", 3072, NULL, configMAX_PRIORITIES-1, NULL);
xTaskCreate(&restart_water_level, "restart_water_level", 3072, NULL, configMAX_PRIORITIES-2, NULL);
@juantxorena The problem of your latest code is due to the line of gpio_intr_enable
after the gpio_isr_handler_add
being called. Indeed, the interrupt has been enabled internally inside the gpio_isr_handler_add
function. The interrupt is triggered as soon as the interrupt is enabled, and goes into your ISR, where you disable the interrupt. After it returns from the interrupt, the program starts to do the next line, which is gpio_intr_enable
. The interrupt is enabled again, this is undesired, because your ISR only disables interrupt based on the interrupt_executed
variable. Now the interrupt gets triggered again and again, and eventually triggers task watchdog.
Overall, you don't need to call an extra gpio_intr_enable
after the gpio_isr_handler_add
.
@songruo sorry for the delay, I was on holidays and I didn't have access to the hardware.
Your suggestion doesn't solve it. I removed the gpio_intr_enable line, and it has the same problem.
Answers checklist.
IDF version.
v5.1.2
Espressif SoC revision.
ESP32-C6FH4 (QFN32) (revision v0.0)
Operating System used.
Linux
How did you build your project?
VS Code IDE
If you are using Windows, please specify command line type.
None
Development Kit.
esp32-c6-devkitm-1
Power Supply used.
USB
What is the expected behavior?
I want to initialize a interrupt for GPIO, no matter its initial value.
What is the actual behavior?
I have a switch connected to GPIO 14 and ground with an interrupt and a handler. If the switch is closed when booting, everything it works as expected. If it's open (so GPIO will be connected to ground), the watchdog gets triggered.
Steps to reproduce.
Here's the relevant code:
The line gpio_install_isr_service(0); fails. I put a log after it, and it never logs.
Debug Logs.
More Information.
Edit Sorry, I put the description wrong, the error happens when the switch is open, so not at ground, not the other way around.