Adicionar primeiro
This commit is contained in:
13
main/CMakeLists.txt
Executable file
13
main/CMakeLists.txt
Executable file
@@ -0,0 +1,13 @@
|
||||
set(COMPONENT_SRCS "main.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
register_component()
|
||||
|
||||
if(CONFIG_BOARD_CONFIG_DEPLOY)
|
||||
set(CFG_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../cfg/${CONFIG_BOARD_CONFIG}")
|
||||
if(EXISTS ${CFG_SRC_DIR}/board.cfg)
|
||||
spiffs_create_partition_image(cfg ${CFG_SRC_DIR} FLASH_IN_PROJECT)
|
||||
else()
|
||||
message(FATAL_ERROR "${CFG_SRC_DIR}/board.cfg doesn't exit")
|
||||
endif()
|
||||
endif()
|
||||
72
main/Kconfig.projbuild
Executable file
72
main/Kconfig.projbuild
Executable file
@@ -0,0 +1,72 @@
|
||||
menu "EVSE Configuration"
|
||||
|
||||
config BOARD_CONFIG_DEPLOY
|
||||
bool "Deploy board config to SPI Nor Flash"
|
||||
default y
|
||||
help
|
||||
Deploy board config to SPI Nor Flash.
|
||||
Choose this in production mode or once to copy config.
|
||||
|
||||
choice BOARD_CONFIG
|
||||
prompt "Board config file"
|
||||
default BOARD_CONFIG_ESP32DEVKITC
|
||||
help
|
||||
Board config file
|
||||
|
||||
config BOARD_CONFIG_ESP32DEVKITC
|
||||
bool "esp32devkitc"
|
||||
config BOARD_CONFIG_ESP32S2DA
|
||||
bool "esp32s2da"
|
||||
config BOARD_CONFIG_CUSTON
|
||||
bool "custom"
|
||||
endchoice
|
||||
|
||||
config BOARD_CONFIG
|
||||
string
|
||||
default "esp32devkitc" if BOARD_CONFIG_ESP32DEVKITC
|
||||
default "esp32s2da" if BOARD_CONFIG_ESP32S2DA
|
||||
default "custom" if BOARD_CONFIG_CUSTON
|
||||
|
||||
|
||||
config APP_ESPNOW_RETRY_NUM
|
||||
int "Packet retransmission count"
|
||||
default 5
|
||||
help
|
||||
Set the packet retransmission count. The more retransmission
|
||||
times, the lower the throughput rate.
|
||||
|
||||
config APP_ESPNOW_SESSION_POP
|
||||
string "Proof of Possession"
|
||||
default "espnow_pop"
|
||||
help
|
||||
Proof of Possession (PoP) string used to authorize session and derive shared key.
|
||||
|
||||
config APP_ESPNOW_SEC_OPTION
|
||||
bool "The payload data is ciphertext or plaintext when enable security"
|
||||
default y
|
||||
help
|
||||
Send ciphertext or plaintext when enable security.
|
||||
|
||||
choice APP_ESPNOW_SEC_MODE
|
||||
bool "ESP-NOW Mode"
|
||||
default APP_ESPNOW_SEC_INITIATOR
|
||||
help
|
||||
Select the ESP-NOW Mode.
|
||||
|
||||
config APP_ESPNOW_SEC_INITIATOR
|
||||
bool "Initiator Mode"
|
||||
help
|
||||
Select the ESP-NOW SEC initiator Mode.
|
||||
|
||||
config APP_ESPNOW_SEC_RESPONDER
|
||||
bool "Responder Mode"
|
||||
help
|
||||
Select the ESP-NOW SEC responder Mode.
|
||||
|
||||
endchoice
|
||||
|
||||
config APP_ESPNOW_SEC_MODE
|
||||
int
|
||||
default 0 if APP_ESPNOW_SEC_INITIATOR
|
||||
default 1 if APP_ESPNOW_SEC_RESPONDER
|
||||
endmenu
|
||||
5
main/component.mk
Executable file
5
main/component.mk
Executable file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
||||
18
main/idf_component.yml
Normal file
18
main/idf_component.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/mdns: "=*"
|
||||
espressif/ntc_driver: "^0.3.0"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=4.1.0"
|
||||
# # Put list of dependencies here
|
||||
# # For components maintained by Espressif:
|
||||
# component: "~1.0.0"
|
||||
# # For 3rd party components:
|
||||
# username/component: ">=1.0.0,<2.0.0"
|
||||
# username2/component2:
|
||||
# version: "~1.0.0"
|
||||
# # For transient dependencies `public` flag can be set.
|
||||
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||
# # All dependencies of `main` are public by default.
|
||||
# public: true
|
||||
285
main/main.c
Executable file
285
main/main.c
Executable file
@@ -0,0 +1,285 @@
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/param.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_spiffs.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#include "evse_api.h"
|
||||
#include "evse_manager.h"
|
||||
#include "peripherals.h"
|
||||
#include "led.h"
|
||||
#include "api.h"
|
||||
#include "protocols.h"
|
||||
#include "serial_mt.h"
|
||||
#include "board_config.h"
|
||||
#include "wifi.h"
|
||||
#include "logger.h"
|
||||
|
||||
#define EVSE_MANAGER_TICK_PERIOD_MS 1000 // 1 segundo
|
||||
#define AP_CONNECTION_TIMEOUT 60000 // 60sec
|
||||
#define RESET_HOLD_TIME 10000 // 10sec
|
||||
#define PRESS_BIT BIT0
|
||||
#define RELEASED_BIT BIT1
|
||||
|
||||
static const char *TAG = "app_main";
|
||||
static TaskHandle_t user_input_task;
|
||||
|
||||
static bool pressed = false; // Variável para verificar se o botão foi pressionado
|
||||
static TickType_t press_tick = 0; // Variável para armazenar o tempo de pressionamento do botão
|
||||
|
||||
|
||||
static void reset_and_reboot(void)
|
||||
{
|
||||
ESP_LOGW(TAG, "All settings will be erased...");
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
|
||||
ESP_LOGW(TAG, "Rebooting...");
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
static void wifi_event_task_func(void *param)
|
||||
{
|
||||
EventBits_t mode_bits;
|
||||
while (true)
|
||||
{
|
||||
mode_bits = xEventGroupWaitBits(wifi_event_group, WIFI_AP_MODE_BIT | WIFI_STA_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
|
||||
if (mode_bits & WIFI_AP_MODE_BIT)
|
||||
{
|
||||
if (xEventGroupWaitBits(wifi_event_group, WIFI_AP_CONNECTED_BIT | WIFI_STA_MODE_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(AP_CONNECTION_TIMEOUT)) & WIFI_AP_CONNECTED_BIT)
|
||||
{
|
||||
do
|
||||
{
|
||||
} while (!(xEventGroupWaitBits(wifi_event_group, WIFI_AP_DISCONNECTED_BIT | WIFI_STA_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY) & WIFI_AP_DISCONNECTED_BIT));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT)
|
||||
{
|
||||
wifi_ap_stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mode_bits & WIFI_STA_MODE_BIT)
|
||||
{
|
||||
if (xEventGroupWaitBits(wifi_event_group, WIFI_STA_CONNECTED_BIT | WIFI_AP_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY) & WIFI_STA_CONNECTED_BIT)
|
||||
{
|
||||
do
|
||||
{
|
||||
} while (!(xEventGroupWaitBits(wifi_event_group, WIFI_STA_DISCONNECTED_BIT | WIFI_AP_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY) & WIFI_STA_DISCONNECTED_BIT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void handle_button_press(void)
|
||||
{
|
||||
if (xTaskGetTickCount() - press_tick >= pdMS_TO_TICKS(RESET_HOLD_TIME)) {
|
||||
evse_set_available(false);
|
||||
reset_and_reboot();
|
||||
} else {
|
||||
if (!(xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT)) {
|
||||
wifi_ap_start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_button_release(void)
|
||||
{
|
||||
// Lógica quando o botão for liberado
|
||||
pressed = false;
|
||||
}
|
||||
|
||||
static void user_input_task_func(void *param)
|
||||
{
|
||||
uint32_t notification;
|
||||
while (true)
|
||||
{
|
||||
if (xTaskNotifyWait(0x00, 0xff, ¬ification, portMAX_DELAY))
|
||||
{
|
||||
if (notification & PRESS_BIT)
|
||||
{
|
||||
press_tick = xTaskGetTickCount();
|
||||
pressed = true;
|
||||
}
|
||||
if (notification & RELEASED_BIT)
|
||||
{
|
||||
if (pressed)
|
||||
{
|
||||
handle_button_press();
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_button_release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void IRAM_ATTR button_isr_handler(void *arg)
|
||||
{
|
||||
BaseType_t higher_task_woken = pdFALSE;
|
||||
|
||||
if (!gpio_get_level(board_config.button_wifi_gpio))
|
||||
{
|
||||
xTaskNotifyFromISR(user_input_task, RELEASED_BIT, eSetBits, &higher_task_woken);
|
||||
}
|
||||
else
|
||||
{
|
||||
xTaskNotifyFromISR(user_input_task, PRESS_BIT, eSetBits, &higher_task_woken);
|
||||
}
|
||||
|
||||
if (higher_task_woken)
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
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};
|
||||
ESP_ERROR_CHECK(gpio_config(&conf));
|
||||
ESP_ERROR_CHECK(gpio_isr_handler_add(board_config.button_wifi_gpio, button_isr_handler, NULL));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to get partition %s information %s", conf->partition_label, esp_err_to_name(ret));
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Partition %s size: total: %d, used: %d", conf->partition_label, total, used);
|
||||
}
|
||||
}
|
||||
|
||||
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};
|
||||
esp_err_t ret = esp_vfs_spiffs_register(&cfg_conf);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to mount SPIFFS partition 'cfg'. Error: %s", esp_err_to_name(ret));
|
||||
return; // Ou reinicie o dispositivo dependendo do caso
|
||||
}
|
||||
|
||||
esp_vfs_spiffs_conf_t data_conf = {
|
||||
.base_path = "/data",
|
||||
.partition_label = "data",
|
||||
.max_files = 5,
|
||||
.format_if_mount_failed = true};
|
||||
ret = esp_vfs_spiffs_register(&data_conf);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to mount SPIFFS partition 'data'. Error: %s", esp_err_to_name(ret));
|
||||
return; // Ou reinicie o dispositivo dependendo do caso
|
||||
}
|
||||
|
||||
fs_info(&cfg_conf);
|
||||
fs_info(&data_conf);
|
||||
}
|
||||
|
||||
static bool ota_diagnostic(void)
|
||||
{
|
||||
// TODO diagnostic after ota
|
||||
return true;
|
||||
}
|
||||
|
||||
static void init_modules(void)
|
||||
{
|
||||
wifi_ini();
|
||||
peripherals_init();
|
||||
api_init();
|
||||
protocols_init();
|
||||
evse_manager_init();
|
||||
evse_init(); // Cria a task para FSM
|
||||
button_init();
|
||||
|
||||
// Outros módulos (descomente conforme necessário)
|
||||
// meter_init();
|
||||
// ocpp_start();
|
||||
// serial_mdb_start();
|
||||
// currentshaper_start();
|
||||
// initRc522();
|
||||
// initWiegand();
|
||||
// serial_mt_start();
|
||||
// master_sync_start();
|
||||
// slave_sync_start();
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
logger_init();
|
||||
esp_log_set_vprintf(logger_vprintf);
|
||||
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
ESP_LOGI(TAG, "Running partition: %s", running->label);
|
||||
|
||||
esp_ota_img_states_t ota_state;
|
||||
if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK)
|
||||
{
|
||||
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY)
|
||||
{
|
||||
ESP_LOGI(TAG, "OTA pending verify");
|
||||
if (ota_diagnostic())
|
||||
{
|
||||
ESP_LOGI(TAG, "Diagnostics completed successfully! Continuing execution ...");
|
||||
esp_ota_mark_app_valid_cancel_rollback();
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Diagnostics failed! Starting rollback to the previous version ...");
|
||||
esp_ota_mark_app_invalid_rollback_and_reboot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
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();
|
||||
}
|
||||
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();
|
||||
|
||||
init_modules();
|
||||
|
||||
xTaskCreate(wifi_event_task_func, "wifi_event_task", 4 * 1024, NULL, 5, NULL);
|
||||
xTaskCreate(user_input_task_func, "user_input_task", 4 * 1024, NULL, 5, &user_input_task);
|
||||
|
||||
|
||||
|
||||
// Loop principal não é necessário se tudo roda por tasks
|
||||
}
|
||||
Reference in New Issue
Block a user