blackmagic-esp32-s2/main/factory-reset-service.c

120 lines
2.9 KiB
C

#include "driver/gpio.h"
#include <string.h>
#include <esp_log.h>
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
#include "led.h"
#include "nvs.h"
#define BOOT_PIN (0)
#define ESP_INTR_FLAG_DEFAULT 0
#define RESET_TIMER_TICK 250
#define RESET_TIMER_TICKS_TO_RESET 40
// static timer
static StaticTimer_t reset_timer_data;
static TimerHandle_t reset_timer;
static size_t reset_counter = 0;
static void start_reset_timer() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if(xPortInIsrContext()) {
xTimerStartFromISR(reset_timer, &xHigherPriorityTaskWoken);
} else {
xTimerStart(reset_timer, portMAX_DELAY);
}
if(xHigherPriorityTaskWoken != pdFALSE) {
portYIELD_FROM_ISR(pdTRUE);
}
}
static void stop_reset_timer() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if(xPortInIsrContext()) {
xTimerStopFromISR(reset_timer, &xHigherPriorityTaskWoken);
} else {
xTimerStop(reset_timer, portMAX_DELAY);
}
reset_counter = 0;
led_set(0, 0, 0);
if(xHigherPriorityTaskWoken != pdFALSE) {
portYIELD_FROM_ISR(pdTRUE);
}
}
static void IRAM_ATTR boot_button_isr_handler(void* arg) {
if(gpio_get_level(BOOT_PIN) == 0) {
start_reset_timer();
} else {
stop_reset_timer();
}
}
static void reset_timer_cb(TimerHandle_t xTimer) {
(void)xTimer;
if(gpio_get_level(BOOT_PIN) == 1) {
stop_reset_timer();
} else {
reset_counter++;
uint8_t led_color = 0;
if(reset_counter < (RESET_TIMER_TICKS_TO_RESET / 2)) {
// slow blink
if(reset_counter % 4 < 2) {
led_color = 0xFF;
}
} else {
// fast blink
if(reset_counter % 2 != 0) {
led_color = 0xFF;
}
}
if(reset_counter > RESET_TIMER_TICKS_TO_RESET) {
stop_reset_timer();
led_set(255, 0, 0);
// waiting for button release
while(gpio_get_level(BOOT_PIN) == 0) {
}
led_set(0, 255, 0);
nvs_erase();
led_set(0, 0, 255);
esp_restart();
} else {
led_set(led_color, led_color, led_color);
}
}
}
void factory_reset_service_init(void) {
gpio_config_t io_conf;
memset(&io_conf, 0, sizeof(gpio_config_t));
io_conf.intr_type = GPIO_INTR_ANYEDGE;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = ((1 << BOOT_PIN));
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&io_conf);
// install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
// attach interrupt
gpio_isr_handler_add(BOOT_PIN, boot_button_isr_handler, (void*)BOOT_PIN);
// soft timers
reset_timer = xTimerCreateStatic(
NULL, pdMS_TO_TICKS(RESET_TIMER_TICK), true, NULL, reset_timer_cb, &reset_timer_data);
}