chore: snapshot before shared RS485 bus integration
This commit is contained in:
2
components/evse/CMakeLists.txt
Executable file → Normal file
2
components/evse/CMakeLists.txt
Executable file → Normal file
@@ -17,6 +17,6 @@ set(srcs
|
||||
idf_component_register(
|
||||
SRCS ${srcs}
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES driver
|
||||
PRIV_REQUIRES driver esp_adc
|
||||
REQUIRES peripherals auth loadbalancer scheduler storage_service
|
||||
)
|
||||
0
components/evse/evse_api.c
Executable file → Normal file
0
components/evse/evse_api.c
Executable file → Normal file
0
components/evse/evse_config.c
Executable file → Normal file
0
components/evse/evse_config.c
Executable file → Normal file
0
components/evse/evse_core.c
Executable file → Normal file
0
components/evse/evse_core.c
Executable file → Normal file
0
components/evse/evse_error.c
Executable file → Normal file
0
components/evse/evse_error.c
Executable file → Normal file
0
components/evse/evse_events.c
Executable file → Normal file
0
components/evse/evse_events.c
Executable file → Normal file
0
components/evse/evse_fsm.c
Executable file → Normal file
0
components/evse/evse_fsm.c
Executable file → Normal file
0
components/evse/evse_hardware.c
Executable file → Normal file
0
components/evse/evse_hardware.c
Executable file → Normal file
0
components/evse/evse_limits.c
Executable file → Normal file
0
components/evse/evse_limits.c
Executable file → Normal file
72
components/evse/evse_manager.c
Executable file → Normal file
72
components/evse/evse_manager.c
Executable file → Normal file
@@ -22,6 +22,8 @@
|
||||
#include "loadbalancer_events.h"
|
||||
#include "ocpp_events.h"
|
||||
#include "scheduler_events.h"
|
||||
#include "evse_link_events.h"
|
||||
|
||||
|
||||
static const char *TAG = "EVSE_Manager";
|
||||
|
||||
@@ -61,6 +63,72 @@ bool evse_sched_is_allowed(void)
|
||||
return v;
|
||||
}
|
||||
|
||||
static void on_evse_link_event(void *arg, esp_event_base_t base, int32_t id, void *data)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
if (base != EVSE_LINK_EVENTS || id != LINK_EVENT_CURRENT_LIMIT_APPLIED || data == NULL)
|
||||
return;
|
||||
|
||||
uint16_t current = *(const uint16_t *)data;
|
||||
|
||||
ESP_LOGI(TAG, "[EVSE-LINK] current limit applied: %uA", current);
|
||||
|
||||
if (current == 0)
|
||||
{
|
||||
bool prev_auth = evse_state_get_authorized();
|
||||
|
||||
portENTER_CRITICAL(&s_mgr_mux);
|
||||
lb_paused = true;
|
||||
lb_prev_authorized = prev_auth;
|
||||
portEXIT_CRITICAL(&s_mgr_mux);
|
||||
|
||||
if (prev_auth)
|
||||
{
|
||||
ESP_LOGI(TAG, "[EVSE-LINK] limit=0A → paused by master");
|
||||
evse_state_set_authorized(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
evse_set_runtime_charging_current(current);
|
||||
|
||||
bool was_paused;
|
||||
bool prev_auth;
|
||||
bool local_auth_enabled;
|
||||
|
||||
portENTER_CRITICAL(&s_mgr_mux);
|
||||
was_paused = lb_paused;
|
||||
prev_auth = lb_prev_authorized;
|
||||
local_auth_enabled = auth_enabled;
|
||||
lb_paused = false;
|
||||
lb_prev_authorized = false;
|
||||
portEXIT_CRITICAL(&s_mgr_mux);
|
||||
|
||||
if (was_paused)
|
||||
{
|
||||
bool can_resume =
|
||||
(evse_get_error() == 0) &&
|
||||
evse_config_is_available() &&
|
||||
evse_config_is_enabled() &&
|
||||
evse_sched_is_allowed() &&
|
||||
!evse_is_limit_reached();
|
||||
|
||||
if (!can_resume)
|
||||
{
|
||||
ESP_LOGW(TAG, "[EVSE-LINK] limit=%uA → cannot resume", current);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!local_auth_enabled || prev_auth)
|
||||
{
|
||||
ESP_LOGI(TAG, "[EVSE-LINK] limit=%uA → resuming after master pause", current);
|
||||
evse_state_set_authorized(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void evse_manager_handle_auth_on_tick(void)
|
||||
{
|
||||
bool sched_allowed = evse_sched_is_allowed();
|
||||
@@ -423,6 +491,10 @@ void evse_manager_init(void)
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(LOADBALANCER_EVENTS, ESP_EVENT_ANY_ID, &on_loadbalancer_event, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(OCPP_EVENTS, ESP_EVENT_ANY_ID, &on_ocpp_event, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(SCHED_EVENTS, ESP_EVENT_ANY_ID, &on_sched_event, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(EVSE_LINK_EVENTS,
|
||||
ESP_EVENT_ANY_ID,
|
||||
&on_evse_link_event,
|
||||
NULL));
|
||||
|
||||
ESP_LOGI(TAG, "EVSE Manager inicializado.");
|
||||
|
||||
|
||||
109
components/evse/evse_pilot.c
Executable file → Normal file
109
components/evse/evse_pilot.c
Executable file → Normal file
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "evse_pilot.h"
|
||||
#include "adc121s021_dma.h"
|
||||
#include "adc.h"
|
||||
#include "board_config.h"
|
||||
|
||||
#define PILOT_PWM_TIMER LEDC_TIMER_0
|
||||
@@ -27,7 +28,8 @@
|
||||
// Percentagem para descartar extremos superior/inferior (ruído)
|
||||
#define PILOT_EXTREME_PERCENT 10 // 10% superior e inferior
|
||||
|
||||
// ADC referência
|
||||
// Referência usada pelo ADC121S021 externo.
|
||||
// No ADC interno, o valor já é convertido para mV por adc_cali_raw_to_voltage().
|
||||
#define ADC121_VREF_MV 3300
|
||||
#define ADC121_MAX 4095
|
||||
|
||||
@@ -41,24 +43,100 @@ typedef enum {
|
||||
|
||||
static pilot_mode_t s_mode = PILOT_MODE_DC_LOW;
|
||||
static uint32_t last_pwm_duty = 0;
|
||||
static bool s_internal_adc_configured = false;
|
||||
|
||||
// ---------------------
|
||||
// Helpers internos
|
||||
// ---------------------
|
||||
static int adc_raw_to_mv(uint16_t raw)
|
||||
static int adc121_raw_to_mv(uint16_t raw)
|
||||
{
|
||||
return (int)((raw * ADC121_VREF_MV) / ADC121_MAX);
|
||||
}
|
||||
|
||||
static int compare_uint16(const void *a, const void *b)
|
||||
static int compare_int(const void *a, const void *b)
|
||||
{
|
||||
uint16_t va = *(const uint16_t *)a;
|
||||
uint16_t vb = *(const uint16_t *)b;
|
||||
int va = *(const int *)a;
|
||||
int vb = *(const int *)b;
|
||||
if (va < vb) return -1;
|
||||
if (va > vb) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pilot_adc_read_mv(int *mv)
|
||||
{
|
||||
if (!mv)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (board_config.pilot_adc_source == BOARD_CONFIG_PILOT_ADC_INTERNAL_ESP32)
|
||||
{
|
||||
if (!adc_handle || !adc_cali_handle)
|
||||
{
|
||||
ESP_LOGE(TAG, "ADC interno não inicializado/calibrado");
|
||||
return false;
|
||||
}
|
||||
|
||||
int raw = 0;
|
||||
esp_err_t err;
|
||||
|
||||
adc_lock();
|
||||
err = adc_oneshot_read(adc_handle, board_config.pilot_adc_channel, &raw);
|
||||
if (err == ESP_OK)
|
||||
{
|
||||
err = adc_cali_raw_to_voltage(adc_cali_handle, raw, mv);
|
||||
}
|
||||
adc_unlock();
|
||||
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Erro ao ler/converter ADC interno do pilot: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t raw = 0;
|
||||
if (!adc121s021_dma_get_sample(&raw))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*mv = adc121_raw_to_mv(raw);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void pilot_adc_init(void)
|
||||
{
|
||||
if (board_config.pilot_adc_source == BOARD_CONFIG_PILOT_ADC_INTERNAL_ESP32)
|
||||
{
|
||||
if (!adc_handle)
|
||||
{
|
||||
adc_init();
|
||||
}
|
||||
|
||||
if (!s_internal_adc_configured)
|
||||
{
|
||||
adc_oneshot_chan_cfg_t config = {
|
||||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||
.atten = ADC_ATTEN_DB_12
|
||||
};
|
||||
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_handle,
|
||||
board_config.pilot_adc_channel,
|
||||
&config));
|
||||
s_internal_adc_configured = true;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Pilot ADC: interno ESP32 ADC1_CH%d",
|
||||
(int)board_config.pilot_adc_channel);
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Pilot ADC: ADC121S021 externo via SPI");
|
||||
adc121s021_dma_init();
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
// Inicialização PWM + ADC
|
||||
// ---------------------
|
||||
@@ -91,8 +169,8 @@ void pilot_init(void)
|
||||
s_mode = PILOT_MODE_DC_LOW;
|
||||
last_pwm_duty = 0;
|
||||
|
||||
// Inicializa driver do ADC121S021
|
||||
adc121s021_dma_init();
|
||||
// Inicializa o backend de leitura do pilot configurado na board.
|
||||
pilot_adc_init();
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
@@ -165,17 +243,17 @@ void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
{
|
||||
ESP_LOGD(TAG, "pilot_measure");
|
||||
|
||||
uint16_t samples[NUM_PILOT_SAMPLES];
|
||||
int samples_mv[NUM_PILOT_SAMPLES];
|
||||
int collected = 0;
|
||||
int attempts = 0;
|
||||
|
||||
while (collected < NUM_PILOT_SAMPLES && attempts < MAX_SAMPLE_ATTEMPTS)
|
||||
{
|
||||
uint16_t adc_sample;
|
||||
int sample_mv = 0;
|
||||
|
||||
if (adc121s021_dma_get_sample(&adc_sample))
|
||||
if (pilot_adc_read_mv(&sample_mv))
|
||||
{
|
||||
samples[collected++] = adc_sample;
|
||||
samples_mv[collected++] = sample_mv;
|
||||
esp_rom_delay_us(PILOT_SAMPLE_DELAY_US);
|
||||
}
|
||||
else
|
||||
@@ -194,7 +272,7 @@ void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
}
|
||||
|
||||
// Ordena as amostras para eliminar extremos (ruído/espúrios)
|
||||
qsort(samples, collected, sizeof(uint16_t), compare_uint16);
|
||||
qsort(samples_mv, collected, sizeof(int), compare_int);
|
||||
|
||||
int k = (collected * PILOT_EXTREME_PERCENT) / 100;
|
||||
if (k < 2) k = 2; // garante margem mínima
|
||||
@@ -207,11 +285,8 @@ void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
if (high_index >= collected) high_index = collected - 1;
|
||||
if (high_index <= low_index) high_index = low_index;
|
||||
|
||||
uint16_t low_raw = samples[low_index];
|
||||
uint16_t high_raw = samples[high_index];
|
||||
|
||||
int high_mv = adc_raw_to_mv(high_raw);
|
||||
int low_mv = adc_raw_to_mv(low_raw);
|
||||
int low_mv = samples_mv[low_index];
|
||||
int high_mv = samples_mv[high_index];
|
||||
|
||||
// Determina o nível positivo (+12, +9, +6, +3 ou <3 V)
|
||||
if (high_mv >= board_config.pilot_down_threshold_12)
|
||||
|
||||
0
components/evse/evse_state.c
Executable file → Normal file
0
components/evse/evse_state.c
Executable file → Normal file
0
components/evse/include/evse_api.h
Executable file → Normal file
0
components/evse/include/evse_api.h
Executable file → Normal file
0
components/evse/include/evse_config.h
Executable file → Normal file
0
components/evse/include/evse_config.h
Executable file → Normal file
0
components/evse/include/evse_error.h
Executable file → Normal file
0
components/evse/include/evse_error.h
Executable file → Normal file
0
components/evse/include/evse_events.h
Executable file → Normal file
0
components/evse/include/evse_events.h
Executable file → Normal file
0
components/evse/include/evse_fsm.h
Executable file → Normal file
0
components/evse/include/evse_fsm.h
Executable file → Normal file
0
components/evse/include/evse_hardware.h
Executable file → Normal file
0
components/evse/include/evse_hardware.h
Executable file → Normal file
0
components/evse/include/evse_limits.h
Executable file → Normal file
0
components/evse/include/evse_limits.h
Executable file → Normal file
0
components/evse/include/evse_manager.h
Executable file → Normal file
0
components/evse/include/evse_manager.h
Executable file → Normal file
0
components/evse/include/evse_pilot.h
Executable file → Normal file
0
components/evse/include/evse_pilot.h
Executable file → Normal file
0
components/evse/include/evse_state.h
Executable file → Normal file
0
components/evse/include/evse_state.h
Executable file → Normal file
Reference in New Issue
Block a user