spaxel/firmware/main/led.c
jedarden d7c1adc260 Fix ESP-IDF 5.x firmware compilation for ESP32-S3 build
Port firmware/main to ESP-IDF 5.2 API:
- Add idf_component.yml with mdns and esp_websocket_client managed deps
- Rename esp_ota → app_update, esp_wifi_csi_info_t → wifi_csi_info_t
- Fix freertos/semphr.h include path rename
- Add missing headers: esp_mac.h, esp_netif.h, driver/temperature_sensor.h, string.h, math.h
- Add led.c to SRCS, fix xTaskCreate arg count (7→6)
- Use IDF 5.x temperature_sensor API in place of stub
- Fix mdns_query_ptr signature (add max_results arg)
- Fix url_decode isxdigit unsigned char cast
- Add flash size config (16MB) to sdkconfig.defaults
- Pin managed component versions in dependencies.lock
- Add sdkconfig (generated) to .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 15:35:03 -04:00

129 lines
3.3 KiB
C

#include "led.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "esp_rom_sys.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/gpio_num.h"
static const char *TAG = "led";
// LED GPIO configuration (can be overridden via sdkconfig)
#ifndef CONFIG_SPAXEL_LED_GPIO
#define CONFIG_SPAXEL_LED_GPIO 8 // Default GPIO8 for ESP32-S3-DevKitC
#endif
#define LED_GPIO ((gpio_num_t)CONFIG_SPAXEL_LED_GPIO)
// Blink state
static struct {
bool initialized;
bool blinking;
uint32_t duration_ms;
TaskHandle_t task_handle;
} s_led_state = {
.initialized = false,
.blinking = false,
.task_handle = NULL,
};
// LED blink task
static void led_blink_task(void *arg) {
uint32_t duration_ms = (uint32_t)(uintptr_t)arg;
ESP_LOGI(TAG, "LED blink task started for %lu ms", duration_ms);
const TickType_t blink_on = pdMS_TO_TICKS(100); // 100ms on
const TickType_t blink_off = pdMS_TO_TICKS(100); // 100ms off
const TickType_t total_ticks = pdMS_TO_TICKS(duration_ms);
TickType_t elapsed = 0;
while (s_led_state.blinking && elapsed < total_ticks) {
// Turn LED on
gpio_set_level(LED_GPIO, 1);
vTaskDelay(blink_on);
elapsed += blink_on;
if (!s_led_state.blinking || elapsed >= total_ticks) break;
// Turn LED off
gpio_set_level(LED_GPIO, 0);
vTaskDelay(blink_off);
elapsed += blink_off;
}
// Ensure LED is off before exiting
gpio_set_level(LED_GPIO, 0);
ESP_LOGI(TAG, "LED blink task finished");
s_led_state.blinking = false;
s_led_state.task_handle = NULL;
vTaskDelete(NULL);
}
esp_err_t led_init(void) {
if (s_led_state.initialized) {
return ESP_OK;
}
// Configure LED GPIO as output
gpio_reset_pin(LED_GPIO);
gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(LED_GPIO, 0); // Start with LED off
ESP_LOGI(TAG, "LED initialized on GPIO %d", LED_GPIO);
s_led_state.initialized = true;
return ESP_OK;
}
esp_err_t led_blink_identify(uint32_t duration_ms) {
if (!s_led_state.initialized) {
ESP_LOGW(TAG, "LED not initialized");
return ESP_ERR_INVALID_STATE;
}
// Limit duration to 60 seconds
if (duration_ms > 60000) {
duration_ms = 60000;
}
// Cancel any running blink
led_stop_blink();
// Start new blink task
s_led_state.blinking = true;
s_led_state.duration_ms = duration_ms;
BaseType_t ret = xTaskCreate(
led_blink_task,
"led_blink",
2048,
(void *)(uintptr_t)duration_ms,
5, // Priority
&s_led_state.task_handle
);
if (ret != pdPASS) {
ESP_LOGE(TAG, "Failed to create LED blink task");
s_led_state.blinking = false;
return ESP_ERR_NO_MEM;
}
ESP_LOGI(TAG, "LED identify blink started for %lu ms", duration_ms);
return ESP_OK;
}
void led_stop_blink(void) {
if (s_led_state.blinking && s_led_state.task_handle != NULL) {
ESP_LOGD(TAG, "Stopping LED blink");
s_led_state.blinking = false;
// Task will delete itself
vTaskDelay(pdMS_TO_TICKS(50)); // Give task time to exit
}
// Ensure LED is off
gpio_set_level(LED_GPIO, 0);
}
bool led_is_blinking(void) {
return s_led_state.blinking;
}