/** * @file localbtn.c * @brief Local GPIO0 BTN reading implementation using edge capture */ #include "localbtn.h" #include "driver/gpio.h" #include "esp_timer.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include static const char *TAG = "LOCALBTN"; uint8_t current_mode; int8_t current_localBtnPin; bool initialized; TaskHandle_t localbtnTaskhandle; localbtn_mode_change_callback_t callback; static void localbtn_task(void *arg) { bool lastState = false; while (1) { vTaskDelay(pdMS_TO_TICKS(100)); // TODO:Get btn state via interrupt instead of polling bool currentState = (gpio_get_level(current_localBtnPin) == 0); if ((currentState) && (lastState != currentState)) { ESP_LOGI(TAG, "Local button pressed"); if (callback) { callback(current_mode); } } lastState = currentState; } } esp_err_t localbtn_init(int8_t pin_localbtn) { current_localBtnPin = pin_localbtn; gpio_config_t io_conf = { .pin_bit_mask = 1ULL << current_localBtnPin, .mode = GPIO_MODE_INPUT, .pull_up_en = GPIO_PULLUP_ENABLE, // safe even if external pull-up exists .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE}; ESP_ERROR_CHECK(gpio_config(&io_conf)); // Create monitor task BaseType_t ret = xTaskCreate(localbtn_task, "localbtn_task", 2048, NULL, 5, &localbtnTaskhandle); if (ret != pdPASS) { return ESP_FAIL; } initialized = true; ESP_LOGI(TAG, "local btn initialized on GPIO%d", current_localBtnPin); return ESP_OK; } void localbtn_deinit(void) { if (!initialized) { return; } if (localbtnTaskhandle) { vTaskDelete(localbtnTaskhandle); localbtnTaskhandle = NULL; } initialized = false; } void localbtn_register_callback(localbtn_mode_change_callback_t cb) { callback = cb; }