Add runtime UV protection toggle and treat near-zero sense as external power.

Per-pod NVS enable (default off) via UART/ESP-NOW/dashboard, and skip UV latch when LiPo ADC reads ~0 mV so USB/external supply still boots.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-11-01 22:51:17 +01:00
co-authored by Cursor
parent c3b20887bf
commit 7f28a48a10
33 changed files with 1411 additions and 240 deletions
+30 -4
View File
@@ -38,7 +38,9 @@ typedef enum _alox_EspNowMessageType {
/* * Master → slave: forget persisted master/id binding (debug reset). */
alox_EspNowMessageType_ESPNOW_CLEAR_ID_BINDING = 23,
/* * Master → slave: accel/tap ESP-NOW send path (best_effort/fast/wait/reliable). */
alox_EspNowMessageType_ESPNOW_SET_INPUT_SEND_MODE = 24
alox_EspNowMessageType_ESPNOW_SET_INPUT_SEND_MODE = 24,
/* * Master → slave: enable/disable software LiPo UV protection (NVS). */
alox_EspNowMessageType_ESPNOW_SET_BATTERY_UV = 25
} alox_EspNowMessageType;
/* Struct definitions */
@@ -161,6 +163,12 @@ typedef struct _alox_EspNowInputSendMode {
uint32_t mode;
} alox_EspNowInputSendMode;
/* * Master → slave: software LiPo UV protection enable (persisted in NVS). */
typedef struct _alox_EspNowBatteryUv {
uint32_t client_id; /* 0 = all slaves; otherwise only matching slave_id applies */
bool enabled;
} alox_EspNowBatteryUv;
/* * Slave → master: LiPo voltages (periodic ~30 s and on query). */
typedef struct _alox_EspNowBatteryReport {
uint32_t client_id;
@@ -236,6 +244,7 @@ typedef struct _alox_EspNowMessage {
alox_EspNowAssignId assign_id;
alox_EspNowClearIdBinding clear_id_binding;
alox_EspNowInputSendMode input_send_mode;
alox_EspNowBatteryUv battery_uv;
} payload;
} alox_EspNowMessage;
@@ -246,8 +255,9 @@ extern "C" {
/* Helper constants for enums */
#define _alox_EspNowMessageType_MIN alox_EspNowMessageType_ESPNOW_UNKNOWN
#define _alox_EspNowMessageType_MAX alox_EspNowMessageType_ESPNOW_SET_INPUT_SEND_MODE
#define _alox_EspNowMessageType_ARRAYSIZE ((alox_EspNowMessageType)(alox_EspNowMessageType_ESPNOW_SET_INPUT_SEND_MODE+1))
#define _alox_EspNowMessageType_MAX alox_EspNowMessageType_ESPNOW_SET_BATTERY_UV
#define _alox_EspNowMessageType_ARRAYSIZE ((alox_EspNowMessageType)(alox_EspNowMessageType_ESPNOW_SET_BATTERY_UV+1))
@@ -293,6 +303,7 @@ extern "C" {
#define alox_EspNowTapConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define alox_EspNowTapEvent_init_default {0, 0}
#define alox_EspNowInputSendMode_init_default {0, 0}
#define alox_EspNowBatteryUv_init_default {0, 0}
#define alox_EspNowBatteryReport_init_default {0, 0, 0, 0, 0}
#define alox_EspNowLedRing_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define alox_EspNowOtaStart_init_default {0}
@@ -317,6 +328,7 @@ extern "C" {
#define alox_EspNowTapConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define alox_EspNowTapEvent_init_zero {0, 0}
#define alox_EspNowInputSendMode_init_zero {0, 0}
#define alox_EspNowBatteryUv_init_zero {0, 0}
#define alox_EspNowBatteryReport_init_zero {0, 0, 0, 0, 0}
#define alox_EspNowLedRing_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define alox_EspNowOtaStart_init_zero {0}
@@ -370,6 +382,8 @@ extern "C" {
#define alox_EspNowTapEvent_kind_tag 2
#define alox_EspNowInputSendMode_client_id_tag 1
#define alox_EspNowInputSendMode_mode_tag 2
#define alox_EspNowBatteryUv_client_id_tag 1
#define alox_EspNowBatteryUv_enabled_tag 2
#define alox_EspNowBatteryReport_client_id_tag 1
#define alox_EspNowBatteryReport_lipo1_valid_tag 2
#define alox_EspNowBatteryReport_lipo2_valid_tag 3
@@ -416,6 +430,7 @@ extern "C" {
#define alox_EspNowMessage_assign_id_tag 23
#define alox_EspNowMessage_clear_id_binding_tag 24
#define alox_EspNowMessage_input_send_mode_tag 25
#define alox_EspNowMessage_battery_uv_tag 26
/* Struct field encoding specification for nanopb */
#define alox_EspNowUnicastTest_FIELDLIST(X, a) \
@@ -531,6 +546,12 @@ X(a, STATIC, SINGULAR, UINT32, mode, 2)
#define alox_EspNowInputSendMode_CALLBACK NULL
#define alox_EspNowInputSendMode_DEFAULT NULL
#define alox_EspNowBatteryUv_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, client_id, 1) \
X(a, STATIC, SINGULAR, BOOL, enabled, 2)
#define alox_EspNowBatteryUv_CALLBACK NULL
#define alox_EspNowBatteryUv_DEFAULT NULL
#define alox_EspNowBatteryReport_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, client_id, 1) \
X(a, STATIC, SINGULAR, BOOL, lipo1_valid, 2) \
@@ -602,7 +623,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,echo_pong,payload.echo_pong), 21) \
X(a, STATIC, ONEOF, MESSAGE, (payload,tap_config,payload.tap_config), 22) \
X(a, STATIC, ONEOF, MESSAGE, (payload,assign_id,payload.assign_id), 23) \
X(a, STATIC, ONEOF, MESSAGE, (payload,clear_id_binding,payload.clear_id_binding), 24) \
X(a, STATIC, ONEOF, MESSAGE, (payload,input_send_mode,payload.input_send_mode), 25)
X(a, STATIC, ONEOF, MESSAGE, (payload,input_send_mode,payload.input_send_mode), 25) \
X(a, STATIC, ONEOF, MESSAGE, (payload,battery_uv,payload.battery_uv), 26)
#define alox_EspNowMessage_CALLBACK NULL
#define alox_EspNowMessage_DEFAULT NULL
#define alox_EspNowMessage_payload_discover_MSGTYPE alox_EspNowDiscover
@@ -629,6 +651,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,input_send_mode,payload.input_send_m
#define alox_EspNowMessage_payload_assign_id_MSGTYPE alox_EspNowAssignId
#define alox_EspNowMessage_payload_clear_id_binding_MSGTYPE alox_EspNowClearIdBinding
#define alox_EspNowMessage_payload_input_send_mode_MSGTYPE alox_EspNowInputSendMode
#define alox_EspNowMessage_payload_battery_uv_MSGTYPE alox_EspNowBatteryUv
extern const pb_msgdesc_t alox_EspNowUnicastTest_msg;
extern const pb_msgdesc_t alox_EspNowEchoPing_msg;
@@ -647,6 +670,7 @@ extern const pb_msgdesc_t alox_EspNowTapNotify_msg;
extern const pb_msgdesc_t alox_EspNowTapConfig_msg;
extern const pb_msgdesc_t alox_EspNowTapEvent_msg;
extern const pb_msgdesc_t alox_EspNowInputSendMode_msg;
extern const pb_msgdesc_t alox_EspNowBatteryUv_msg;
extern const pb_msgdesc_t alox_EspNowBatteryReport_msg;
extern const pb_msgdesc_t alox_EspNowLedRing_msg;
extern const pb_msgdesc_t alox_EspNowOtaStart_msg;
@@ -673,6 +697,7 @@ extern const pb_msgdesc_t alox_EspNowMessage_msg;
#define alox_EspNowTapConfig_fields &alox_EspNowTapConfig_msg
#define alox_EspNowTapEvent_fields &alox_EspNowTapEvent_msg
#define alox_EspNowInputSendMode_fields &alox_EspNowInputSendMode_msg
#define alox_EspNowBatteryUv_fields &alox_EspNowBatteryUv_msg
#define alox_EspNowBatteryReport_fields &alox_EspNowBatteryReport_msg
#define alox_EspNowLedRing_fields &alox_EspNowLedRing_msg
#define alox_EspNowOtaStart_fields &alox_EspNowOtaStart_msg
@@ -691,6 +716,7 @@ extern const pb_msgdesc_t alox_EspNowMessage_msg;
#define alox_EspNowAssignId_size 6
#define alox_EspNowBatteryQuery_size 6
#define alox_EspNowBatteryReport_size 22
#define alox_EspNowBatteryUv_size 8
#define alox_EspNowClearIdBinding_size 0
#define alox_EspNowDiscover_size 19
#define alox_EspNowEchoPing_size 22