#include "boot_button.h" #include "board_config.h" #include "driver/gpio.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/task.h" static const char *TAG = "boot_btn"; #define BOOT_DEBOUNCE_MS 50 static boot_button_cb_t s_on_press; static QueueHandle_t s_gpio_evt_queue; static void IRAM_ATTR gpio_isr_handler(void *arg) { uint32_t gpio_num = (uint32_t)arg; xQueueSendFromISR(s_gpio_evt_queue, &gpio_num, NULL); } static void boot_button_task(void *arg) { (void)arg; uint32_t io_num; while (1) { if (xQueueReceive(s_gpio_evt_queue, &io_num, portMAX_DELAY) != pdTRUE) { continue; } vTaskDelay(pdMS_TO_TICKS(BOOT_DEBOUNCE_MS)); if (gpio_get_level(BOARD_PIN_BOOT) != 0) { continue; } while (gpio_get_level(BOARD_PIN_BOOT) == 0) { vTaskDelay(pdMS_TO_TICKS(10)); } if (s_on_press != NULL) { s_on_press(); } } } void boot_button_init(boot_button_cb_t on_press) { s_on_press = on_press; gpio_config_t io_conf = { .pin_bit_mask = 1ULL << BOARD_PIN_BOOT, .mode = GPIO_MODE_INPUT, .pull_up_en = GPIO_PULLUP_ENABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_NEGEDGE, }; ESP_ERROR_CHECK(gpio_config(&io_conf)); s_gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t)); esp_err_t err = gpio_install_isr_service(0); if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { ESP_ERROR_CHECK(err); } ESP_ERROR_CHECK(gpio_isr_handler_add(BOARD_PIN_BOOT, gpio_isr_handler, (void *)BOARD_PIN_BOOT)); xTaskCreate(boot_button_task, "boot_btn", 2048, NULL, 5, NULL); ESP_LOGI(TAG, "BOOT button ready on GPIO%d", BOARD_PIN_BOOT); }