#include "status_led.h" #include #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "driver/gpio.h" enum led_states_t { STATUS_OFF, STATUS_SLOW_BLINK, STATUS_FAST_BLINK, STATUS_ON }; static const char* TAG = "status_led"; SemaphoreHandle_t status_sem = NULL; static const uint8_t status_led_pin = 15; static enum led_states_t current_state = STATUS_OFF; static bool led_on = false; void set_status_connecting() { xSemaphoreTake(status_sem, portMAX_DELAY); current_state = STATUS_FAST_BLINK; xSemaphoreGive(status_sem); ESP_LOGI(TAG, "status connecting"); } void set_status_joined() { xSemaphoreTake(status_sem, portMAX_DELAY); current_state = STATUS_ON; xSemaphoreGive(status_sem); ESP_LOGI(TAG, "status joined"); } void set_status_error_or_resetting() { xSemaphoreTake(status_sem, portMAX_DELAY); current_state = STATUS_SLOW_BLINK; xSemaphoreGive(status_sem); ESP_LOGI(TAG, "status error or resetting"); } static void set_led_on(void) { led_on = true; gpio_set_level(status_led_pin, false); } static void set_led_off(void) { led_on = false; gpio_set_level(status_led_pin, true); } static void set_led_toggle(void) { led_on = !led_on; gpio_set_level(status_led_pin, !led_on); } static enum led_states_t get_state(void) { xSemaphoreTake(status_sem, portMAX_DELAY); const enum led_states_t s = current_state; xSemaphoreGive(status_sem); return s; } void status_led_task(void *pvParameter) { const gpio_config_t io_conf = { .pin_bit_mask = (1ULL << status_led_pin), .mode = GPIO_MODE_OUTPUT, .pull_up_en = GPIO_PULLUP_ENABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE, }; gpio_config(&io_conf); set_led_off(); status_sem = xSemaphoreCreateMutex(); xSemaphoreGive(status_sem); ESP_LOGI(TAG, "status LED inited"); enum led_states_t prev_state = STATUS_OFF; while (true) { // NOLINT const enum led_states_t state = get_state(); if (state != prev_state) { prev_state = state; switch (state) { case STATUS_OFF: set_led_off(); break; case STATUS_SLOW_BLINK: set_led_toggle(); vTaskDelay(pdMS_TO_TICKS(500)); break; case STATUS_FAST_BLINK: set_led_toggle(); vTaskDelay(pdMS_TO_TICKS(100)); break; case STATUS_ON: set_led_on(); break; } } vTaskDelay(pdMS_TO_TICKS(15)); } }