199 lines
5.2 KiB
C
199 lines
5.2 KiB
C
/**
|
|
* @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 "soc/gpio_num.h"
|
|
#include "mbedtls/sha256.h"
|
|
|
|
#include <string.h>
|
|
|
|
static const char *TAG = "CONFIG";
|
|
|
|
#define NVS_NAMESPACE "led_ctrl"
|
|
|
|
#define HARDCODED_CONFIG
|
|
#ifdef HARDCODED_CONFIG
|
|
#define HARDCODED_CONFIG_LED_STRIP_A_PIN 3U
|
|
#define HARDCODED_CONFIG_LED_STRIP_B_PIN 2U
|
|
#define HARDCODED_CONFIG_LED_STRIP_A_COUNT 10U
|
|
#define HARDCODED_CONFIG_LED_STRIP_B_COUNT 10U
|
|
#define HARDCODED_CONFIG_PWM_PIN 1U
|
|
|
|
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
|
#define HARDCODED_CONFIG_LOCALBTN_PIN 9
|
|
#elif defined(CONFIG_IDF_TARGET_ESP32)
|
|
#define HARDCODED_CONFIG_LOCALBTN_PIN 0
|
|
#else
|
|
#error "Unsupported target: BOOT button GPIO not defined"
|
|
#endif
|
|
|
|
#endif
|
|
|
|
// 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,
|
|
.localBtn_pin = -1};
|
|
|
|
static void calculate_config_hash(const config_t *cfg, uint8_t *out_hash);
|
|
|
|
// NVS Functions
|
|
static esp_err_t load_config_from_nvs(void)
|
|
{
|
|
nvs_handle_t nvs_handle;
|
|
size_t size = sizeof(config_t);
|
|
config_t tmp;
|
|
|
|
for (uint8_t i = 0; i < 2U; i++)
|
|
{
|
|
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs_handle);
|
|
if (err != ESP_OK)
|
|
{
|
|
ESP_LOGW(TAG, "NVS not found, using defaults");
|
|
config_reset_config();
|
|
continue;
|
|
}
|
|
|
|
err = nvs_get_blob(nvs_handle, "config", &tmp, &size);
|
|
nvs_close(nvs_handle);
|
|
|
|
uint8_t calc_hash[CONFIG_HASH_LEN];
|
|
calculate_config_hash(&tmp, calc_hash);
|
|
|
|
if (memcmp(calc_hash, tmp.hash, CONFIG_HASH_LEN) != 0)
|
|
{
|
|
ESP_LOGW(TAG, "Invalid config in NVS, using defaults");
|
|
config_reset_config();
|
|
continue;
|
|
}
|
|
|
|
// We found a valid config
|
|
break;
|
|
}
|
|
|
|
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, " Strip A LED count: %d", current_config.led_count_strip_a);
|
|
ESP_LOGI(TAG, " Strip B LED count: %d", current_config.led_count_strip_b);
|
|
ESP_LOGI(TAG, " PWM Pin: GPIO%d", current_config.pwm_pin);
|
|
ESP_LOGI(TAG, " Local btn Pin: GPIO%d", current_config.localBtn_pin);
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t save_config_to_nvs(void)
|
|
{
|
|
calculate_config_hash(¤t_config, current_config.hash);
|
|
|
|
nvs_handle_t nvs_handle;
|
|
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs_handle);
|
|
if (err != ESP_OK)
|
|
{
|
|
return err;
|
|
}
|
|
|
|
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.localBtn_pin = -1;
|
|
|
|
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;
|
|
cnf->localBtn_pin = current_config.localBtn_pin;
|
|
}
|
|
|
|
esp_err_t config_init(void)
|
|
{
|
|
esp_err_t ret;
|
|
|
|
ESP_LOGI(TAG, "Initializing Config...");
|
|
|
|
// 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(config_reset_config());
|
|
}
|
|
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.localBtn_pin = HARDCODED_CONFIG_LOCALBTN_PIN;
|
|
|
|
save_config_to_nvs();
|
|
#endif
|
|
|
|
// Load configuration
|
|
load_config_from_nvs();
|
|
|
|
ESP_LOGI(TAG, "Config initialized successfully");
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
static void calculate_config_hash(const config_t *cfg, uint8_t *out_hash)
|
|
{
|
|
mbedtls_sha256_context ctx;
|
|
|
|
mbedtls_sha256_init(&ctx);
|
|
mbedtls_sha256_starts(&ctx, 0); // 0 = SHA-256, 1 = SHA-224
|
|
|
|
mbedtls_sha256_update(
|
|
&ctx,
|
|
(const unsigned char *)cfg,
|
|
offsetof(config_t, hash));
|
|
|
|
mbedtls_sha256_finish(&ctx, out_hash);
|
|
mbedtls_sha256_free(&ctx);
|
|
} |