WIP: feature/esp32-ng-basic #1
@ -6,5 +6,6 @@ idf_component_register(
|
|||||||
"rcsignal.c"
|
"rcsignal.c"
|
||||||
"animation.c"
|
"animation.c"
|
||||||
"localbtn.c"
|
"localbtn.c"
|
||||||
|
"config.c"
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
)
|
)
|
||||||
|
|||||||
177
main/config.c
Normal file
177
main/config.c
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/**
|
||||||
|
* @file config.c
|
||||||
|
* @brief Config module implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "nvs.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static const char *TAG = "CONFIG";
|
||||||
|
|
||||||
|
#define NVS_NAMESPACE "led_ctrl"
|
||||||
|
#define CONFIG_MAGIC 0xDEADBEEF
|
||||||
|
|
||||||
|
#define HARDCODED_CONFIG
|
||||||
|
#define HARDCODED_CONFIG_LED_STRIP_A_PIN 12U
|
||||||
|
#define HARDCODED_CONFIG_LED_STRIP_B_PIN 14U
|
||||||
|
#define HARDCODED_CONFIG_LED_STRIP_A_COUNT 7U
|
||||||
|
#define HARDCODED_CONFIG_LED_STRIP_B_COUNT 7U
|
||||||
|
#define HARDCODED_CONFIG_PWM_PIN 13U
|
||||||
|
|
||||||
|
// Global state
|
||||||
|
static config_t current_config = {
|
||||||
|
.led_pin_strip_a = -1,
|
||||||
|
.led_pin_strip_b = -1,
|
||||||
|
.led_count_strip_a = -1,
|
||||||
|
.led_count_strip_b = -1,
|
||||||
|
.pwm_pin = -1,
|
||||||
|
.magic = CONFIG_MAGIC};
|
||||||
|
|
||||||
|
// NVS Functions
|
||||||
|
static esp_err_t load_config_from_nvs(void)
|
||||||
|
{
|
||||||
|
nvs_handle_t nvs_handle;
|
||||||
|
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs_handle);
|
||||||
|
if (err != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "NVS not found, using defaults");
|
||||||
|
return ESP_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t required_size = sizeof(config_t);
|
||||||
|
err = nvs_get_blob(nvs_handle, "config", ¤t_config, &required_size);
|
||||||
|
nvs_close(nvs_handle);
|
||||||
|
|
||||||
|
if (err != ESP_OK || current_config.magic != CONFIG_MAGIC)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Invalid config in NVS, using defaults");
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Loaded config from NVS");
|
||||||
|
ESP_LOGI(TAG, " Strip A: GPIO%d", current_config.led_pin_strip_a);
|
||||||
|
ESP_LOGI(TAG, " Strip B: GPIO%d", current_config.led_pin_strip_b);
|
||||||
|
ESP_LOGI(TAG, " PWM Pin: GPIO%d", current_config.pwm_pin);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t save_config_to_nvs(void)
|
||||||
|
{
|
||||||
|
nvs_handle_t nvs_handle;
|
||||||
|
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs_handle);
|
||||||
|
if (err != ESP_OK)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_config.magic = CONFIG_MAGIC;
|
||||||
|
err = nvs_set_blob(nvs_handle, "config", ¤t_config, sizeof(config_t));
|
||||||
|
if (err == ESP_OK)
|
||||||
|
{
|
||||||
|
err = nvs_commit(nvs_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
nvs_close(nvs_handle);
|
||||||
|
|
||||||
|
if (err == ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Config saved to NVS");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Failed to save config: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t config_reset_config(void)
|
||||||
|
{
|
||||||
|
current_config.led_pin_strip_a = -1;
|
||||||
|
current_config.led_pin_strip_b = -1;
|
||||||
|
current_config.led_count_strip_a = -1;
|
||||||
|
current_config.led_count_strip_b = -1;
|
||||||
|
current_config.pwm_pin = -1;
|
||||||
|
current_config.magic = CONFIG_MAGIC;
|
||||||
|
|
||||||
|
return save_config_to_nvs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_get_config(config_t *const cnf)
|
||||||
|
{
|
||||||
|
cnf->led_pin_strip_a = current_config.led_pin_strip_a;
|
||||||
|
cnf->led_pin_strip_b = current_config.led_pin_strip_b;
|
||||||
|
cnf->led_count_strip_a = current_config.led_count_strip_a;
|
||||||
|
cnf->led_count_strip_b = current_config.led_count_strip_b;
|
||||||
|
cnf->pwm_pin = current_config.pwm_pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t config_update_config(const config_t *config)
|
||||||
|
{
|
||||||
|
if (!config)
|
||||||
|
{
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reinitialize if pins changed
|
||||||
|
bool pins_changed = (current_config.led_pin_strip_a != config->led_pin_strip_a) ||
|
||||||
|
(current_config.led_pin_strip_b != config->led_pin_strip_b) ||
|
||||||
|
(current_config.pwm_pin != config->pwm_pin);
|
||||||
|
|
||||||
|
memcpy(¤t_config, config, sizeof(config_t));
|
||||||
|
esp_err_t err = save_config_to_nvs();
|
||||||
|
|
||||||
|
if (err == ESP_OK && pins_changed)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Restarting to apply new pin configuration...");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main initialization
|
||||||
|
esp_err_t config_init(void)
|
||||||
|
{
|
||||||
|
esp_err_t ret;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Initializing Config Controller...");
|
||||||
|
|
||||||
|
// Initialize NVS
|
||||||
|
ret = nvs_flash_init();
|
||||||
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
ret = nvs_flash_init();
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
#ifdef HARDCODED_CONFIG
|
||||||
|
current_config.led_pin_strip_a = HARDCODED_CONFIG_LED_STRIP_A_PIN;
|
||||||
|
current_config.led_pin_strip_b = HARDCODED_CONFIG_LED_STRIP_B_PIN;
|
||||||
|
current_config.led_count_strip_a = HARDCODED_CONFIG_LED_STRIP_A_COUNT;
|
||||||
|
current_config.led_count_strip_b = HARDCODED_CONFIG_LED_STRIP_B_COUNT;
|
||||||
|
current_config.pwm_pin = HARDCODED_CONFIG_PWM_PIN;
|
||||||
|
current_config.magic = CONFIG_MAGIC;
|
||||||
|
|
||||||
|
save_config_to_nvs();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Load configuration
|
||||||
|
load_config_from_nvs();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Config system initialized successfully");
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
52
main/config.h
Normal file
52
main/config.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* @file config.h
|
||||||
|
* @brief Config module for LED controller - handles read and store of persistent data
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration structure stored in NVS
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int8_t led_pin_strip_a; // GPIO pin for LED strip A (-1 = not configured)
|
||||||
|
int8_t led_pin_strip_b; // GPIO pin for LED strip B (-1 = not configured)
|
||||||
|
int8_t led_count_strip_a; // LED count for LED strip A (-1 = not configured)
|
||||||
|
int8_t led_count_strip_b; // LED count for LED strip B (-1 = not configured)
|
||||||
|
int8_t pwm_pin; // GPIO pin for PWM input (-1 = not configured)
|
||||||
|
uint32_t magic; // Magic number to validate config (0xDEADBEEF) //TODO: use sha256
|
||||||
|
} config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the config system
|
||||||
|
* Loads configuration from NVS and initializes subsystems
|
||||||
|
* @return ESP_OK on success
|
||||||
|
*/
|
||||||
|
esp_err_t config_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current configuration
|
||||||
|
* @param Pointer to current configuration (read-only)
|
||||||
|
*/
|
||||||
|
void config_get_config(config_t *const cnf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update configuration and save to NVS
|
||||||
|
* @param config New configuration
|
||||||
|
* @return ESP_OK on success
|
||||||
|
*/
|
||||||
|
esp_err_t config_update_config(const config_t *config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset configuration to defaults
|
||||||
|
* @return ESP_OK on success
|
||||||
|
*/
|
||||||
|
esp_err_t config_reset_config(void);
|
||||||
|
|
||||||
|
#endif // CONFIG_H
|
||||||
131
main/control.c
131
main/control.c
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
#include "config.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "rcsignal.h"
|
#include "rcsignal.h"
|
||||||
#include "localbtn.h"
|
#include "localbtn.h"
|
||||||
@ -13,130 +14,17 @@
|
|||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "nvs_flash.h"
|
|
||||||
#include "nvs.h"
|
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static const char *TAG = "CONTROL";
|
static const char *TAG = "CONTROL";
|
||||||
|
|
||||||
#define NVS_NAMESPACE "led_ctrl"
|
|
||||||
#define CONFIG_MAGIC 0xDEADBEEF
|
|
||||||
#define DEFAULT_NUM_LEDS_A 7
|
|
||||||
#define DEFAULT_NUM_LEDS_B 7
|
|
||||||
|
|
||||||
// Global state
|
|
||||||
static controller_config_t current_config = {
|
|
||||||
.led_pin_strip_a = -1,
|
|
||||||
.led_pin_strip_b = -1,
|
|
||||||
.pwm_pin = -1,
|
|
||||||
.magic = CONFIG_MAGIC};
|
|
||||||
|
|
||||||
static uint8_t current_animation_mode = 0;
|
static uint8_t current_animation_mode = 0;
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
static void on_mode_change(uint8_t new_mode);
|
static void on_mode_change(uint8_t new_mode);
|
||||||
|
|
||||||
// NVS Functions
|
|
||||||
static esp_err_t load_config_from_nvs(void)
|
|
||||||
{
|
|
||||||
nvs_handle_t nvs_handle;
|
|
||||||
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs_handle);
|
|
||||||
if (err != ESP_OK)
|
|
||||||
{
|
|
||||||
ESP_LOGW(TAG, "NVS not found, using defaults");
|
|
||||||
return ESP_ERR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t required_size = sizeof(controller_config_t);
|
|
||||||
err = nvs_get_blob(nvs_handle, "config", ¤t_config, &required_size);
|
|
||||||
nvs_close(nvs_handle);
|
|
||||||
|
|
||||||
if (err != ESP_OK || current_config.magic != CONFIG_MAGIC)
|
|
||||||
{
|
|
||||||
ESP_LOGW(TAG, "Invalid config in NVS, using defaults");
|
|
||||||
return ESP_ERR_INVALID_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Loaded config from NVS");
|
|
||||||
ESP_LOGI(TAG, " Strip A: GPIO%d", current_config.led_pin_strip_a);
|
|
||||||
ESP_LOGI(TAG, " Strip B: GPIO%d", current_config.led_pin_strip_b);
|
|
||||||
ESP_LOGI(TAG, " PWM Pin: GPIO%d", current_config.pwm_pin);
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t save_config_to_nvs(void)
|
|
||||||
{
|
|
||||||
nvs_handle_t nvs_handle;
|
|
||||||
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs_handle);
|
|
||||||
if (err != ESP_OK)
|
|
||||||
{
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_config.magic = CONFIG_MAGIC;
|
|
||||||
err = nvs_set_blob(nvs_handle, "config", ¤t_config, sizeof(controller_config_t));
|
|
||||||
if (err == ESP_OK)
|
|
||||||
{
|
|
||||||
err = nvs_commit(nvs_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
nvs_close(nvs_handle);
|
|
||||||
|
|
||||||
if (err == ESP_OK)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Config saved to NVS");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "Failed to save config: %s", esp_err_to_name(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t control_reset_config(void)
|
|
||||||
{
|
|
||||||
current_config.led_pin_strip_a = 12;
|
|
||||||
current_config.led_pin_strip_b = 14;
|
|
||||||
current_config.pwm_pin = 13;
|
|
||||||
current_config.magic = CONFIG_MAGIC;
|
|
||||||
|
|
||||||
return save_config_to_nvs();
|
|
||||||
}
|
|
||||||
|
|
||||||
const controller_config_t *control_get_config(void)
|
|
||||||
{
|
|
||||||
return ¤t_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t control_update_config(const controller_config_t *config)
|
|
||||||
{
|
|
||||||
if (!config)
|
|
||||||
{
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reinitialize if pins changed
|
|
||||||
bool pins_changed = (current_config.led_pin_strip_a != config->led_pin_strip_a) ||
|
|
||||||
(current_config.led_pin_strip_b != config->led_pin_strip_b) ||
|
|
||||||
(current_config.pwm_pin != config->pwm_pin);
|
|
||||||
|
|
||||||
memcpy(¤t_config, config, sizeof(controller_config_t));
|
|
||||||
esp_err_t err = save_config_to_nvs();
|
|
||||||
|
|
||||||
if (err == ESP_OK && pins_changed)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Restarting to apply new pin configuration...");
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
esp_restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animation mode change callback
|
// Animation mode change callback
|
||||||
static void on_mode_change(uint8_t new_mode)
|
static void on_mode_change(uint8_t new_mode)
|
||||||
{
|
{
|
||||||
@ -170,21 +58,20 @@ esp_err_t control_init(void)
|
|||||||
|
|
||||||
ESP_LOGI(TAG, "Initializing LED Controller...");
|
ESP_LOGI(TAG, "Initializing LED Controller...");
|
||||||
|
|
||||||
// Initialize NVS
|
// Initialize config
|
||||||
ret = nvs_flash_init();
|
ret = config_init();
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
|
if (ret != ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
ESP_LOGE(TAG, "Config init failed: %s", esp_err_to_name(ret));
|
||||||
ret = nvs_flash_init();
|
return ret;
|
||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(ret);
|
|
||||||
|
|
||||||
// Load configuration
|
config_t current_config;
|
||||||
load_config_from_nvs();
|
config_get_config(¤t_config);
|
||||||
|
|
||||||
// Initialize LED strips
|
// Initialize LED strips
|
||||||
ret = led_init(current_config.led_pin_strip_a, current_config.led_pin_strip_b,
|
ret = led_init(current_config.led_pin_strip_a, current_config.led_pin_strip_b,
|
||||||
DEFAULT_NUM_LEDS_A, DEFAULT_NUM_LEDS_B);
|
current_config.led_count_strip_a, current_config.led_count_strip_a);
|
||||||
if (ret != ESP_OK)
|
if (ret != ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "LED init failed: %s", esp_err_to_name(ret));
|
ESP_LOGE(TAG, "LED init failed: %s", esp_err_to_name(ret));
|
||||||
|
|||||||
@ -10,17 +10,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configuration structure stored in NVS
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int8_t led_pin_strip_a; // GPIO pin for LED strip A (-1 = not configured)
|
|
||||||
int8_t led_pin_strip_b; // GPIO pin for LED strip B (-1 = not configured)
|
|
||||||
int8_t pwm_pin; // GPIO pin for PWM input (-1 = not configured)
|
|
||||||
uint32_t magic; // Magic number to validate config (0xDEADBEEF)
|
|
||||||
} controller_config_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the control system
|
* @brief Initialize the control system
|
||||||
* Loads configuration from NVS and initializes subsystems
|
* Loads configuration from NVS and initializes subsystems
|
||||||
@ -28,25 +17,6 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
esp_err_t control_init(void);
|
esp_err_t control_init(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get current configuration
|
|
||||||
* @return Pointer to current configuration (read-only)
|
|
||||||
*/
|
|
||||||
const controller_config_t *control_get_config(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update configuration and save to NVS
|
|
||||||
* @param config New configuration
|
|
||||||
* @return ESP_OK on success
|
|
||||||
*/
|
|
||||||
esp_err_t control_update_config(const controller_config_t *config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reset configuration to defaults
|
|
||||||
* @return ESP_OK on success
|
|
||||||
*/
|
|
||||||
esp_err_t control_reset_config(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set animation mode manually
|
* @brief Set animation mode manually
|
||||||
* @param mode Animation mode (0-13)
|
* @param mode Animation mode (0-13)
|
||||||
|
|||||||
@ -56,8 +56,6 @@ void app_main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
control_reset_config();
|
|
||||||
|
|
||||||
// Create animation update task
|
// Create animation update task
|
||||||
BaseType_t task_ret = xTaskCreate(
|
BaseType_t task_ret = xTaskCreate(
|
||||||
animation_task,
|
animation_task,
|
||||||
|
|||||||
Reference in New Issue
Block a user