new release
This commit is contained in:
163
main/main.c
163
main/main.c
@@ -33,10 +33,41 @@
|
||||
#include "led.h"
|
||||
#include "scheduler.h"
|
||||
#include "storage_service.h"
|
||||
#include "time_service.h"
|
||||
|
||||
#define AP_CONNECTION_TIMEOUT 120000
|
||||
#define RESET_HOLD_TIME 30000 // ms
|
||||
#define DEBOUNCE_TIME_MS 50
|
||||
/*
|
||||
* Modos de controlo do AP:
|
||||
*
|
||||
* APP_AP_CONTROL_BUTTON:
|
||||
* - Usa botão físico.
|
||||
* - Pressão curta: inicia AP.
|
||||
* - Pressão longa: apaga NVS e reinicia.
|
||||
*
|
||||
* APP_AP_CONTROL_BOOT_WINDOW:
|
||||
* - Não usa botão físico.
|
||||
* - Inicia AP automaticamente no arranque.
|
||||
* - Mantém AP ativo durante os primeiros 3 minutos.
|
||||
* - Depois desliga AP e volta ao modo STA.
|
||||
*/
|
||||
#define APP_AP_CONTROL_BUTTON 0
|
||||
#define APP_AP_CONTROL_BOOT_WINDOW 1
|
||||
|
||||
/*
|
||||
* Escolher aqui o modo pretendido:
|
||||
*
|
||||
* Para placa COM botão:
|
||||
* #define APP_AP_CONTROL_MODE APP_AP_CONTROL_BUTTON
|
||||
*
|
||||
* Para placa SEM botão:
|
||||
* #define APP_AP_CONTROL_MODE APP_AP_CONTROL_BOOT_WINDOW
|
||||
*/
|
||||
#define APP_AP_CONTROL_MODE APP_AP_CONTROL_BOOT_WINDOW
|
||||
|
||||
#define AP_BOOT_WINDOW_MS 180000UL // 3 minutos
|
||||
#define AP_CONNECTION_TIMEOUT AP_BOOT_WINDOW_MS
|
||||
|
||||
#define RESET_HOLD_TIME 30000UL // ms
|
||||
#define DEBOUNCE_TIME_MS 50UL
|
||||
|
||||
#define PRESS_BIT BIT0
|
||||
#define RELEASED_BIT BIT1
|
||||
@@ -98,6 +129,7 @@ static void wifi_event_task_func(void *param)
|
||||
{
|
||||
(void)param;
|
||||
EventBits_t mode_bits;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
mode_bits = xEventGroupWaitBits(
|
||||
@@ -130,7 +162,8 @@ static void wifi_event_task_func(void *param)
|
||||
if (xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT)
|
||||
{
|
||||
// Timeout sem cliente ligado
|
||||
// wifi_ap_stop();
|
||||
// O desligar do AP no modo sem botão é feito pela boot_ap_task_func().
|
||||
// No modo com botão, mantemos o comportamento antigo.
|
||||
ESP_LOGW(TAG, "AP timeout sem conexões");
|
||||
}
|
||||
}
|
||||
@@ -165,9 +198,15 @@ static void handle_button_press(void)
|
||||
ESP_LOGI(TAG, "Starting Wi-Fi AP mode (short press)");
|
||||
wifi_ap_start();
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Wi-Fi AP mode já está ativo");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Task para lidar com notificações de botão (PRESS / RELEASE)
|
||||
//
|
||||
static void user_input_task_func(void *param)
|
||||
{
|
||||
(void)param;
|
||||
@@ -186,12 +225,13 @@ static void user_input_task_func(void *param)
|
||||
press_tick = xTaskGetTickCount();
|
||||
pressed = true;
|
||||
ESP_LOGI(TAG, "Button Pressed");
|
||||
// Decisão (short/long) é feita na soltura
|
||||
// Decisão short/long é feita na soltura
|
||||
}
|
||||
|
||||
if ((notification & RELEASED_BIT) && pressed)
|
||||
{
|
||||
pressed = false;
|
||||
|
||||
TickType_t held_ticks = xTaskGetTickCount() - press_tick;
|
||||
uint32_t held_ms = pdTICKS_TO_MS(held_ticks);
|
||||
|
||||
@@ -200,7 +240,13 @@ static void user_input_task_func(void *param)
|
||||
if (held_ms >= RESET_HOLD_TIME)
|
||||
{
|
||||
ESP_LOGW(TAG, "Long press: erasing NVS + reboot");
|
||||
nvs_flash_erase();
|
||||
|
||||
esp_err_t ret = nvs_flash_erase();
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Erro ao apagar NVS: %s", esp_err_to_name(ret));
|
||||
}
|
||||
|
||||
esp_restart();
|
||||
}
|
||||
else
|
||||
@@ -213,7 +259,9 @@ static void user_input_task_func(void *param)
|
||||
}
|
||||
}
|
||||
|
||||
// ISR para GPIO do botão (ativo em nível baixo)
|
||||
//
|
||||
// ISR para GPIO do botão ativo em nível baixo
|
||||
//
|
||||
static void IRAM_ATTR button_isr_handler(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
@@ -221,11 +269,13 @@ static void IRAM_ATTR button_isr_handler(void *arg)
|
||||
TickType_t now = xTaskGetTickCountFromISR();
|
||||
|
||||
portENTER_CRITICAL_ISR(&button_spinlock);
|
||||
|
||||
if (now - last_interrupt_tick < pdMS_TO_TICKS(DEBOUNCE_TIME_MS))
|
||||
{
|
||||
portEXIT_CRITICAL_ISR(&button_spinlock);
|
||||
return;
|
||||
}
|
||||
|
||||
last_interrupt_tick = now;
|
||||
|
||||
if (user_input_task == NULL)
|
||||
@@ -265,11 +315,45 @@ static void button_init(void)
|
||||
}
|
||||
|
||||
//
|
||||
// Inicialização dos módulos do sistema (SEM botão)
|
||||
// AP automático no arranque para placas sem botão
|
||||
//
|
||||
static void boot_ap_task_func(void *param)
|
||||
{
|
||||
(void)param;
|
||||
|
||||
if (wifi_event_group == NULL)
|
||||
{
|
||||
ESP_LOGW(TAG, "Wi-Fi ainda não inicializado, não é possível iniciar AP");
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Modo sem botão: iniciar AP automaticamente durante 3 minutos");
|
||||
|
||||
wifi_ap_start();
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(AP_BOOT_WINDOW_MS));
|
||||
|
||||
EventBits_t bits = xEventGroupGetBits(wifi_event_group);
|
||||
|
||||
if (bits & WIFI_AP_MODE_BIT)
|
||||
{
|
||||
ESP_LOGI(TAG, "Modo sem botão: janela de AP terminou, a desligar AP");
|
||||
wifi_ap_stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Modo sem botão: AP já não estava ativo");
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
//
|
||||
// Inicialização dos módulos do sistema
|
||||
//
|
||||
static void init_modules(void)
|
||||
{
|
||||
|
||||
ESP_ERROR_CHECK(storage_service_init());
|
||||
|
||||
peripherals_init();
|
||||
@@ -284,6 +368,7 @@ static void init_modules(void)
|
||||
meter_manager_init();
|
||||
meter_manager_start();
|
||||
ocpp_start();
|
||||
time_service_init();
|
||||
scheduler_init();
|
||||
protocols_init();
|
||||
loadbalancer_init();
|
||||
@@ -295,7 +380,6 @@ static void init_modules(void)
|
||||
//
|
||||
void app_main(void)
|
||||
{
|
||||
|
||||
esp_reset_reason_t reason = esp_reset_reason();
|
||||
ESP_LOGI(TAG, "Reset reason: %d", reason);
|
||||
|
||||
@@ -309,25 +393,74 @@ void app_main(void)
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
fs_init();
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
ESP_ERROR_CHECK(gpio_install_isr_service(0));
|
||||
|
||||
board_config_load();
|
||||
|
||||
// 1) Inicia todos os módulos (inclui Wi-Fi, EVSE, etc.)
|
||||
/*
|
||||
* O serviço GPIO ISR tem de estar instalado antes de qualquer módulo
|
||||
* chamar gpio_isr_handler_add().
|
||||
*
|
||||
* O RFID/Wiegand usa interrupções GPIO durante auth_init(),
|
||||
* que é chamado dentro de init_modules().
|
||||
*/
|
||||
esp_err_t gpio_isr_ret = gpio_install_isr_service(0);
|
||||
if (gpio_isr_ret != ESP_OK && gpio_isr_ret != ESP_ERR_INVALID_STATE)
|
||||
{
|
||||
ESP_ERROR_CHECK(gpio_isr_ret);
|
||||
}
|
||||
|
||||
|
||||
// 1) Inicia todos os módulos, incluindo Wi-Fi, EVSE, etc.
|
||||
init_modules();
|
||||
|
||||
// 2) Cria a task que recebe notificações do botão
|
||||
BaseType_t rc;
|
||||
rc = xTaskCreate(user_input_task_func, "user_input_task", 4 * 1024, NULL, 3, &user_input_task);
|
||||
|
||||
#if APP_AP_CONTROL_MODE == APP_AP_CONTROL_BUTTON
|
||||
|
||||
ESP_LOGI(TAG, "Modo AP por botão ativo");
|
||||
|
||||
// 2) Cria a task que recebe notificações do botão
|
||||
rc = xTaskCreate(
|
||||
user_input_task_func,
|
||||
"user_input_task",
|
||||
4 * 1024,
|
||||
NULL,
|
||||
3,
|
||||
&user_input_task);
|
||||
configASSERT(rc == pdPASS);
|
||||
|
||||
// 3) Agora é seguro registrar ISR do botão
|
||||
button_init();
|
||||
|
||||
#elif APP_AP_CONTROL_MODE == APP_AP_CONTROL_BOOT_WINDOW
|
||||
|
||||
ESP_LOGI(TAG, "Modo AP automático no arranque ativo");
|
||||
|
||||
// 2) Inicia AP automaticamente durante os primeiros 3 minutos
|
||||
rc = xTaskCreate(
|
||||
boot_ap_task_func,
|
||||
"boot_ap_task",
|
||||
4 * 1024,
|
||||
NULL,
|
||||
3,
|
||||
NULL);
|
||||
configASSERT(rc == pdPASS);
|
||||
|
||||
#else
|
||||
#error "APP_AP_CONTROL_MODE inválido"
|
||||
#endif
|
||||
|
||||
// 4) Task auxiliar para eventos Wi-Fi
|
||||
rc = xTaskCreate(wifi_event_task_func, "wifi_event_task", 8 * 1024, NULL, 3, NULL);
|
||||
rc = xTaskCreate(
|
||||
wifi_event_task_func,
|
||||
"wifi_event_task",
|
||||
8 * 1024,
|
||||
NULL,
|
||||
3,
|
||||
NULL);
|
||||
configASSERT(rc == pdPASS);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user