diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 166045d..192eb15 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -12,4 +12,6 @@ idf_component_register( ble_scanner mqtt_publisher led_indicator + driver + esp_driver_gpio ) diff --git a/main/Kconfig b/main/Kconfig new file mode 100644 index 0000000..a731e5d --- /dev/null +++ b/main/Kconfig @@ -0,0 +1,20 @@ +menu "Sensor Configuration" + + config SENSOR_RESET_GPIO + int "Factory reset button GPIO number" + default 0 + help + GPIO connected to the factory reset button. The pin is configured + with the internal pull-up enabled; connect the button between this + pin and GND (active-low). GPIO 0 is the BOOT button on standard + ESP32 DevKit boards and requires no extra hardware. + + config SENSOR_RESET_HOLD_MS + int "Factory reset hold duration (ms)" + default 5000 + range 1000 30000 + help + How long the factory reset button must be held continuously before + a factory reset is triggered. Shorter presses are ignored. + +endmenu diff --git a/main/main.c b/main/main.c index 307b4f7..2771fa6 100644 --- a/main/main.c +++ b/main/main.c @@ -9,10 +9,12 @@ #include "esp_netif.h" #include "esp_log.h" #include "mdns.h" +#include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "freertos/task.h" -#include +#include "driver/gpio.h" +#include #include #define TAG "main" @@ -25,6 +27,37 @@ static EventGroupHandle_t s_evt; +static void reset_button_task(void *arg) +{ + gpio_config_t io_conf = { + .pin_bit_mask = 1ULL << CONFIG_SENSOR_RESET_GPIO, + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&io_conf); + + TickType_t held_since = 0; + const TickType_t threshold = pdMS_TO_TICKS(CONFIG_SENSOR_RESET_HOLD_MS); + + for (;;) { + if (gpio_get_level(CONFIG_SENSOR_RESET_GPIO) == 0) { + if (held_since == 0) held_since = xTaskGetTickCount(); + if ((xTaskGetTickCount() - held_since) >= threshold) { + ESP_LOGI(TAG, "Reset button held %d ms — factory resetting", CONFIG_SENSOR_RESET_HOLD_MS); + led_indicator_set(LED_ERROR); + vTaskDelay(pdMS_TO_TICKS(500)); + config_store_erase(); + esp_restart(); + } + } else { + held_since = 0; + } + vTaskDelay(pdMS_TO_TICKS(50)); + } +} + static void wifi_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data) { @@ -103,6 +136,8 @@ void app_main(void) led_indicator_init(); led_indicator_set(LED_CONNECTING); + xTaskCreate(reset_button_task, "reset_btn", 4096, NULL, 1, NULL); + ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default());