This commit is contained in:
2025-08-24 11:17:48 +01:00
parent 0d0dc5b129
commit 96b2ab1f57
31 changed files with 2883 additions and 4054 deletions

View File

@@ -18,7 +18,7 @@
#include "network.h"
#include "board_config.h"
#include "logger.h"
#include "rest_main.h"
#include "rest_main.h"
#include "peripherals.h"
#include "protocols.h"
@@ -29,15 +29,15 @@
#include "meter_manager.h"
#include "buzzer.h"
#include "evse_link.h"
#include "ocpp.h"
#define EVSE_MANAGER_TICK_PERIOD_MS 1000
#define AP_CONNECTION_TIMEOUT 120000
#define RESET_HOLD_TIME 10000
#define DEBOUNCE_TIME_MS 50
#define AP_CONNECTION_TIMEOUT 120000
#define RESET_HOLD_TIME 30000
#define DEBOUNCE_TIME_MS 50
#define PRESS_BIT BIT0
#define RELEASED_BIT BIT1
#define PRESS_BIT BIT0
#define RELEASED_BIT BIT1
static const char *TAG = "app_main";
@@ -46,11 +46,11 @@ static TickType_t press_tick = 0;
static TickType_t last_interrupt_tick = 0;
static bool pressed = false;
//
// File system (SPIFFS) init and info
//
static void fs_info(esp_vfs_spiffs_conf_t *conf) {
static void fs_info(esp_vfs_spiffs_conf_t *conf)
{
size_t total = 0, used = 0;
esp_err_t ret = esp_spiffs_info(conf->partition_label, &total, &used);
if (ret == ESP_OK)
@@ -59,20 +59,19 @@ static void fs_info(esp_vfs_spiffs_conf_t *conf) {
ESP_LOGE(TAG, "Failed to get SPIFFS info: %s", esp_err_to_name(ret));
}
static void fs_init(void) {
static void fs_init(void)
{
esp_vfs_spiffs_conf_t cfg_conf = {
.base_path = "/cfg",
.partition_label = "cfg",
.max_files = 1,
.format_if_mount_failed = false
};
.format_if_mount_failed = false};
esp_vfs_spiffs_conf_t data_conf = {
.base_path = "/data",
.partition_label = "data",
.max_files = 5,
.format_if_mount_failed = true
};
.format_if_mount_failed = true};
ESP_ERROR_CHECK(esp_vfs_spiffs_register(&cfg_conf));
ESP_ERROR_CHECK(esp_vfs_spiffs_register(&data_conf));
@@ -83,116 +82,139 @@ static void fs_init(void) {
//
// Wi-Fi event monitoring task
//
static void wifi_event_task_func(void *param) {
static void wifi_event_task_func(void *param)
{
EventBits_t mode_bits;
for (;;) {
for (;;)
{
// Wait indefinitely until either AP or STA mode is entered
mode_bits = xEventGroupWaitBits(
wifi_event_group,
WIFI_AP_MODE_BIT | WIFI_STA_MODE_BIT,
pdFALSE, // do not clear bits on exit
pdFALSE, // wait for any bit
portMAX_DELAY
);
pdFALSE, // do not clear bits on exit
pdFALSE, // wait for any bit
portMAX_DELAY);
if (mode_bits & WIFI_AP_MODE_BIT) {
if (mode_bits & WIFI_AP_MODE_BIT)
{
// We're in AP mode: wait for a client to connect within the timeout
if (xEventGroupWaitBits(
wifi_event_group,
WIFI_AP_CONNECTED_BIT,
pdFALSE,
pdFALSE,
pdMS_TO_TICKS(AP_CONNECTION_TIMEOUT)
) & WIFI_AP_CONNECTED_BIT) {
pdMS_TO_TICKS(AP_CONNECTION_TIMEOUT)) &
WIFI_AP_CONNECTED_BIT)
{
// Once connected, block until the client disconnects
xEventGroupWaitBits(
wifi_event_group,
WIFI_AP_DISCONNECTED_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY
);
} else {
portMAX_DELAY);
}
else
{
// Timeout expired with no client—optionally stop the AP
if (xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT) {
if (xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT)
{
// wifi_ap_stop();
}
}
} else if (mode_bits & WIFI_STA_MODE_BIT) {
}
else if (mode_bits & WIFI_STA_MODE_BIT)
{
// We're in STA mode: block until disconnected from the AP
xEventGroupWaitBits(
wifi_event_group,
WIFI_STA_DISCONNECTED_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY
);
portMAX_DELAY);
}
// Prevent this task from hogging the CPU when idle
//vTaskDelay(pdMS_TO_TICKS(10));
// vTaskDelay(pdMS_TO_TICKS(10));
}
}
//
// Button press handler
//
static void handle_button_press(void) {
static void handle_button_press(void)
{
// If not already in AP mode, start it
if (!(xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT)) {
if (!(xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT))
{
ESP_LOGI(TAG, "Starting Wi-Fi AP mode");
wifi_ap_start();
}
}
// Task to handle button press/release notifications
static void user_input_task_func(void *param) {
static void user_input_task_func(void *param)
{
uint32_t notification;
for (;;) {
for (;;)
{
// Wait for notification bits from ISR
if (xTaskNotifyWait(
0, // do not clear any bits on entry
UINT32_MAX, // clear all bits on exit
0, // do not clear any bits on entry
UINT32_MAX, // clear all bits on exit
&notification,
portMAX_DELAY)) {
portMAX_DELAY))
{
// Handle button press event
if (notification & PRESS_BIT) {
if (notification & PRESS_BIT)
{
press_tick = xTaskGetTickCount();
pressed = true;
ESP_LOGI(TAG, "Button Pressed");
handle_button_press();
handle_button_press(); // só aqui
}
// Handle button release event (only if previously pressed)
if ((notification & RELEASED_BIT) && pressed) {
if ((notification & RELEASED_BIT) && pressed)
{
pressed = false;
ESP_LOGI(TAG, "Button Released");
handle_button_press();
TickType_t held = xTaskGetTickCount() - press_tick;
ESP_LOGI(TAG, "Button Released (held %u ms)", (unsigned)pdTICKS_TO_MS(held));
if (held >= pdMS_TO_TICKS(RESET_HOLD_TIME))
{
ESP_LOGW(TAG, "Long press: erasing NVS + reboot");
nvs_flash_erase();
esp_restart();
}
}
}
}
}
// ISR for button GPIO interrupt (active-low)
static void IRAM_ATTR button_isr_handler(void *arg) {
static void IRAM_ATTR button_isr_handler(void *arg)
{
BaseType_t higher_task_woken = pdFALSE;
TickType_t now = xTaskGetTickCountFromISR();
// Debounce: ignore interrupts occurring too close together
if (now - last_interrupt_tick < pdMS_TO_TICKS(DEBOUNCE_TIME_MS)) {
if (now - last_interrupt_tick < pdMS_TO_TICKS(DEBOUNCE_TIME_MS))
{
return;
}
last_interrupt_tick = now;
// Read GPIO level: 0 = button pressed, 1 = button released
int level = gpio_get_level(board_config.button_wifi_gpio);
if (level == 0) {
if (level == 0)
{
// Notify task: button pressed
xTaskNotifyFromISR(
user_input_task,
PRESS_BIT,
eSetBits,
&higher_task_woken);
} else {
}
else
{
// Notify task: button released
xTaskNotifyFromISR(
user_input_task,
@@ -202,20 +224,20 @@ static void IRAM_ATTR button_isr_handler(void *arg) {
}
// Yield to higher priority task if unblocked
if (higher_task_woken) {
if (higher_task_woken)
{
portYIELD_FROM_ISR();
}
}
static void button_init(void) {
static void button_init(void)
{
gpio_config_t conf = {
.pin_bit_mask = BIT64(board_config.button_wifi_gpio),
.mode = GPIO_MODE_INPUT,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pull_up_en = GPIO_PULLUP_ENABLE,
.intr_type = GPIO_INTR_ANYEDGE
};
.intr_type = GPIO_INTR_ANYEDGE};
ESP_ERROR_CHECK(gpio_config(&conf));
ESP_ERROR_CHECK(gpio_isr_handler_add(board_config.button_wifi_gpio, button_isr_handler, NULL));
}
@@ -223,20 +245,23 @@ static void button_init(void) {
//
// Inicialização dos módulos do sistema
//
static void init_modules(void) {
static void init_modules(void)
{
peripherals_init();
//api_init();
wifi_ini();
// api_init();
buzzer_init();
ESP_ERROR_CHECK(rest_server_init("/data"));
protocols_init();
evse_manager_init();
evse_init(); // Cria a task para FSM
evse_init(); // Cria a task para FSM
button_init();
auth_init();
loadbalancer_init();
meter_manager_init();
meter_manager_start();
meter_manager_start();
evse_link_init();
ocpp_start();
// wifi_ap_start();
// Outros módulos (descomente conforme necessário)
@@ -253,7 +278,8 @@ static void init_modules(void) {
//
// Função principal do firmware
//
void app_main(void) {
void app_main(void)
{
logger_init();
esp_log_set_vprintf(logger_vprintf);
@@ -261,7 +287,8 @@ void app_main(void) {
ESP_LOGI(TAG, "Reset reason: %d", reason);
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_LOGW(TAG, "Erasing NVS flash");
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
@@ -274,8 +301,6 @@ void app_main(void) {
ESP_ERROR_CHECK(gpio_install_isr_service(0));
board_config_load();
wifi_ini();
//wifi_ap_start();
init_modules();
xTaskCreate(wifi_event_task_func, "wifi_event_task", 8 * 1024, NULL, 3, NULL);