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

@@ -11,19 +11,19 @@
static const char *TAG = "evse_link";
// NVS keys
#define _NVS_NAMESPACE "evse_link"
#define _NVS_MODE_KEY "mode"
#define _NVS_ID_KEY "self_id"
#define _NVS_NAMESPACE "evse_link"
#define _NVS_MODE_KEY "mode"
#define _NVS_ID_KEY "self_id"
#define _NVS_ENABLED_KEY "enabled"
// UART parameters
#define UART_PORT UART_NUM_2
#define UART_PORT UART_NUM_2
#define UART_RX_BUF_SIZE 256
// Runtime config
static evse_link_mode_t _mode = EVSE_LINK_MODE_MASTER;
static uint8_t _self_id = 0x01;
static bool _enabled = false;
static evse_link_mode_t _mode = EVSE_LINK_MODE_MASTER;
static uint8_t _self_id = 0x01;
static bool _enabled = false;
// Registered Rx callback
static evse_link_rx_cb_t _rx_cb = NULL;
@@ -33,71 +33,100 @@ extern void evse_link_master_init(void);
extern void evse_link_slave_init(void);
static void framing_rx_cb(uint8_t src, uint8_t dest,
const uint8_t *payload, uint8_t len) {
const uint8_t *payload, uint8_t len)
{
ESP_LOGD(TAG, "framing_rx_cb: src=0x%02X dest=0x%02X len=%u", src, dest, len);
if (_rx_cb) {
if (_rx_cb)
{
_rx_cb(src, dest, payload, len);
}
}
// Register protocol-level Rx callback
void evse_link_register_rx_cb(evse_link_rx_cb_t cb) {
void evse_link_register_rx_cb(evse_link_rx_cb_t cb)
{
_rx_cb = cb;
}
// Load config from NVS
enum { EV_OK = ESP_OK };
static void load_link_config(void) {
enum
{
EV_OK = ESP_OK
};
static void load_link_config(void)
{
nvs_handle_t handle;
if (nvs_open(_NVS_NAMESPACE, NVS_READONLY, &handle) != EV_OK) {
if (nvs_open(_NVS_NAMESPACE, NVS_READONLY, &handle) != EV_OK)
{
ESP_LOGW(TAG, "NVS open failed, using defaults");
return;
}
uint8_t mode, id, en;
if (nvs_get_u8(handle, _NVS_MODE_KEY, &mode) == EV_OK &&
(mode == EVSE_LINK_MODE_MASTER || mode == EVSE_LINK_MODE_SLAVE)) {
(mode == EVSE_LINK_MODE_MASTER || mode == EVSE_LINK_MODE_SLAVE))
{
_mode = (evse_link_mode_t)mode;
}
if (nvs_get_u8(handle, _NVS_ID_KEY, &id) == EV_OK) {
if (nvs_get_u8(handle, _NVS_ID_KEY, &id) == EV_OK)
{
_self_id = id;
}
if (nvs_get_u8(handle, _NVS_ENABLED_KEY, &en) == EV_OK) {
if (nvs_get_u8(handle, _NVS_ENABLED_KEY, &en) == EV_OK)
{
_enabled = (en != 0);
}
nvs_close(handle);
}
// Save config to NVS
static void save_link_config(void) {
static void save_link_config(void)
{
nvs_handle_t handle;
if (nvs_open(_NVS_NAMESPACE, NVS_READWRITE, &handle) == EV_OK) {
if (nvs_open(_NVS_NAMESPACE, NVS_READWRITE, &handle) == EV_OK)
{
nvs_set_u8(handle, _NVS_MODE_KEY, (uint8_t)_mode);
nvs_set_u8(handle, _NVS_ID_KEY, _self_id);
nvs_set_u8(handle, _NVS_ENABLED_KEY, _enabled ? 1 : 0);
nvs_commit(handle);
nvs_close(handle);
} else {
}
else
{
ESP_LOGE(TAG, "Failed to save NVS");
}
}
// Getters/setters
void evse_link_set_mode(evse_link_mode_t m) { _mode = m; save_link_config(); }
evse_link_mode_t evse_link_get_mode(void) { return _mode; }
void evse_link_set_self_id(uint8_t id) { _self_id = id; save_link_config(); }
uint8_t evse_link_get_self_id(void) { return _self_id; }
void evse_link_set_enabled(bool en) { _enabled = en; save_link_config(); }
bool evse_link_is_enabled(void) { return _enabled; }
void evse_link_set_mode(evse_link_mode_t m)
{
_mode = m;
save_link_config();
}
evse_link_mode_t evse_link_get_mode(void) { return _mode; }
void evse_link_set_self_id(uint8_t id)
{
_self_id = id;
save_link_config();
}
uint8_t evse_link_get_self_id(void) { return _self_id; }
void evse_link_set_enabled(bool en)
{
_enabled = en;
save_link_config();
}
bool evse_link_is_enabled(void) { return _enabled; }
// RX task: reads bytes from UART and feeds framing
static void evse_link_rx_task(void *arg) {
static void evse_link_rx_task(void *arg)
{
uint8_t buf[UART_RX_BUF_SIZE];
while (true) {
while (true)
{
int len = uart_read_bytes(UART_PORT, buf, sizeof(buf), pdMS_TO_TICKS(1000));
if (len > 0) {
for (int i = 0; i < len; ++i) {
if (len > 0)
{
for (int i = 0; i < len; ++i)
{
evse_link_recv_byte(buf[i]);
}
}
@@ -105,13 +134,15 @@ static void evse_link_rx_task(void *arg) {
}
// Initialize EVSE-Link component
void evse_link_init(void) {
void evse_link_init(void)
{
load_link_config();
ESP_LOGI(TAG, "Link init: mode=%c id=0x%02X enabled=%d",
_mode == EVSE_LINK_MODE_MASTER ? 'M' : 'S',
_self_id, _enabled);
if (!_enabled) return;
if (!_enabled)
return;
// 1) framing layer init (sets up mutex, UART driver, etc.)
evse_link_framing_init();
@@ -121,22 +152,27 @@ void evse_link_init(void) {
xTaskCreate(evse_link_rx_task, "evse_link_rx", 4096, NULL, 4, NULL);
// 3) delegate to master or slave
if (_mode == EVSE_LINK_MODE_MASTER) {
if (_mode == EVSE_LINK_MODE_MASTER)
{
evse_link_master_init();
} else {
}
else
{
evse_link_slave_init();
}
}
// Send a frame (delegates to framing module)
bool evse_link_send(uint8_t dest, const uint8_t *payload, uint8_t len) {
if (!evse_link_is_enabled()) return false;
bool evse_link_send(uint8_t dest, const uint8_t *payload, uint8_t len)
{
if (!evse_link_is_enabled())
return false;
uint8_t src = evse_link_get_self_id();
return evse_link_framing_send(dest, src, payload, len);
}
// Receive byte (delegates to framing module)
void evse_link_recv_byte(uint8_t byte) {
void evse_link_recv_byte(uint8_t byte)
{
evse_link_framing_recv_byte(byte);
}