96 lines
2.3 KiB
C
96 lines
2.3 KiB
C
#include "led_indicator.h"
|
|
#include "driver/gpio.h"
|
|
#include "esp_timer.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include <stdint.h>
|
|
|
|
#define LED_GPIO GPIO_NUM_2
|
|
|
|
static esp_timer_handle_t s_timer;
|
|
static led_state_t s_state = LED_OFF;
|
|
static int s_phase = 0; /* generic phase counter for multi-step patterns */
|
|
|
|
static void set_level(int lvl) { gpio_set_level(LED_GPIO, lvl); }
|
|
|
|
static void IRAM_ATTR timer_cb(void *arg)
|
|
{
|
|
switch (s_state) {
|
|
case LED_OFF:
|
|
set_level(0);
|
|
break;
|
|
|
|
case LED_PROVISIONING:
|
|
set_level(s_phase ^= 1);
|
|
esp_timer_start_once(s_timer, 200 * 1000);
|
|
break;
|
|
|
|
case LED_CONNECTING:
|
|
set_level(s_phase ^= 1);
|
|
esp_timer_start_once(s_timer, 1000 * 1000);
|
|
break;
|
|
|
|
case LED_SCANNING:
|
|
set_level(1);
|
|
break;
|
|
|
|
case LED_CALIBRATING:
|
|
set_level(s_phase ^= 1);
|
|
esp_timer_start_once(s_timer, 500 * 1000);
|
|
break;
|
|
|
|
case LED_SELECTED: {
|
|
/* Triple flash: on/off/on/off/on/off, then 1s dark. s_phase 0-5 = flashes, 6 = pause */
|
|
static const uint64_t us[] = {100000,100000,100000,100000,100000,100000,1000000};
|
|
if (s_phase < 6) {
|
|
set_level(s_phase % 2 == 0 ? 1 : 0);
|
|
} else {
|
|
set_level(0);
|
|
}
|
|
uint64_t delay = us[s_phase];
|
|
s_phase = (s_phase + 1) % 7;
|
|
esp_timer_start_once(s_timer, delay);
|
|
break;
|
|
}
|
|
|
|
case LED_ERROR:
|
|
set_level(s_phase ^= 1);
|
|
esp_timer_start_once(s_timer, 50 * 1000);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void led_indicator_init(void)
|
|
{
|
|
gpio_config_t io = {
|
|
.pin_bit_mask = (1ULL << LED_GPIO),
|
|
.mode = GPIO_MODE_OUTPUT,
|
|
.pull_up_en = GPIO_PULLUP_DISABLE,
|
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
|
.intr_type = GPIO_INTR_DISABLE,
|
|
};
|
|
gpio_config(&io);
|
|
|
|
esp_timer_create_args_t args = {
|
|
.callback = timer_cb,
|
|
.name = "led",
|
|
};
|
|
esp_timer_create(&args, &s_timer);
|
|
}
|
|
|
|
void led_indicator_set(led_state_t state)
|
|
{
|
|
esp_timer_stop(s_timer);
|
|
s_state = state;
|
|
s_phase = 0;
|
|
|
|
if (state == LED_SCANNING) {
|
|
set_level(1);
|
|
} else if (state == LED_OFF) {
|
|
set_level(0);
|
|
} else {
|
|
/* Kick off the timer-driven pattern immediately */
|
|
esp_timer_start_once(s_timer, 0);
|
|
}
|
|
}
|