Add BLE host transport selectable via DIP8 alongside UART.

Master can speak the same framed protobuf protocol over NimBLE or UART; goTool gains -ble, ble-rtt, and ble-stream timing checks for ESP-NOW coexistence.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-23 16:11:10 +02:00
co-authored by Cursor
parent d7441cb85f
commit 92a13d7fd0
28 changed files with 2306 additions and 250 deletions
+3
View File
@@ -81,6 +81,9 @@ PB_BIND(alox_CacheClientStatus, alox_CacheClientStatus, AUTO)
PB_BIND(alox_CacheStatusResponse, alox_CacheStatusResponse, 2)
PB_BIND(alox_BleStreamTick, alox_BleStreamTick, 2)
PB_BIND(alox_EspNowUnicastTestRequest, alox_EspNowUnicastTestRequest, AUTO)
+45 -10
View File
@@ -38,7 +38,9 @@ typedef enum _alox_MessageType {
/* * Host → master: get/set ESP-IDF log level for tag "*" (global). */
alox_MessageType_SET_LOG_LEVEL = 31,
/* * Host → master: get/set BMA456H multitap detection parameters. */
alox_MessageType_TAP_CONFIG = 32
alox_MessageType_TAP_CONFIG = 32,
/* * Master → host (BLE only): periodic pushed cache snapshot with ESP timestamp. */
alox_MessageType_BLE_STREAM_TICK = 33
} alox_MessageType;
typedef enum _alox_TapKind {
@@ -113,12 +115,14 @@ typedef struct _alox_AccelDeadzoneResponse {
} alox_AccelDeadzoneResponse;
/* Host → master: enable/disable slave accel ESP-NOW stream (~16 ms per slave).
write=false: read; write=true: apply. client_id 0 invalid for write (use >0 or all_clients). */
write=false: read; write=true: apply. client_id 0 invalid for write (use >0 or all_clients).
period_ms (8–16): BLE host push interval for BleStreamTick; ignored on UART (default 16). */
typedef struct _alox_AccelStreamRequest {
bool write;
bool enable;
uint32_t client_id;
bool all_clients;
uint32_t period_ms;
} alox_AccelStreamRequest;
typedef struct _alox_AccelStreamResponse {
@@ -231,6 +235,14 @@ typedef struct _alox_CacheStatusResponse {
alox_CacheClientStatus clients[16];
} alox_CacheStatusResponse;
/* * Master → host over BLE notify: aggregated cache + ESP timer timestamp. */
typedef struct _alox_BleStreamTick {
uint64_t esp_timestamp_us;
uint32_t period_ms;
pb_size_t clients_count;
alox_CacheClientStatus clients[16];
} alox_BleStreamTick;
typedef struct _alox_EspNowUnicastTestRequest {
uint32_t client_id;
uint32_t seq;
@@ -443,6 +455,7 @@ typedef struct _alox_UartMessage {
alox_SetLogLevelResponse set_log_level_response;
alox_TapConfigRequest tap_config_request;
alox_TapConfigResponse tap_config_response;
alox_BleStreamTick ble_stream_tick;
} payload;
} alox_UartMessage;
@@ -453,8 +466,8 @@ extern "C" {
/* Helper constants for enums */
#define _alox_MessageType_MIN alox_MessageType_UNKNOWN
#define _alox_MessageType_MAX alox_MessageType_TAP_CONFIG
#define _alox_MessageType_ARRAYSIZE ((alox_MessageType)(alox_MessageType_TAP_CONFIG+1))
#define _alox_MessageType_MAX alox_MessageType_BLE_STREAM_TICK
#define _alox_MessageType_ARRAYSIZE ((alox_MessageType)(alox_MessageType_BLE_STREAM_TICK+1))
#define _alox_TapKind_MIN alox_TapKind_TAP_NONE
#define _alox_TapKind_MAX alox_TapKind_TAP_TRIPLE
@@ -508,6 +521,7 @@ extern "C" {
/* Initializer values for message structs */
@@ -521,7 +535,7 @@ extern "C" {
#define alox_ClientInputResponse_init_default {{{NULL}, NULL}}
#define alox_AccelDeadzoneRequest_init_default {0, 0, 0, 0}
#define alox_AccelDeadzoneResponse_init_default {0, 0, 0, 0}
#define alox_AccelStreamRequest_init_default {0, 0, 0, 0}
#define alox_AccelStreamRequest_init_default {0, 0, 0, 0, 0}
#define alox_AccelStreamResponse_init_default {0, 0, 0, 0}
#define alox_BatteryStatusRequest_init_default {0, 0}
#define alox_LipoReading_init_default {0, 0}
@@ -536,6 +550,7 @@ extern "C" {
#define alox_CacheClientTap_init_default {_alox_TapKind_MIN, 0}
#define alox_CacheClientStatus_init_default {0, false, alox_CacheClientAccel_init_default, false, alox_CacheClientTap_init_default}
#define alox_CacheStatusResponse_init_default {0, {alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default}}
#define alox_BleStreamTick_init_default {0, 0, 0, {alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default}}
#define alox_EspNowUnicastTestRequest_init_default {0, 0}
#define alox_EspNowUnicastTestResponse_init_default {0, 0}
#define alox_EspNowEchoPingRequest_init_default {0, 0}
@@ -567,7 +582,7 @@ extern "C" {
#define alox_ClientInputResponse_init_zero {{{NULL}, NULL}}
#define alox_AccelDeadzoneRequest_init_zero {0, 0, 0, 0}
#define alox_AccelDeadzoneResponse_init_zero {0, 0, 0, 0}
#define alox_AccelStreamRequest_init_zero {0, 0, 0, 0}
#define alox_AccelStreamRequest_init_zero {0, 0, 0, 0, 0}
#define alox_AccelStreamResponse_init_zero {0, 0, 0, 0}
#define alox_BatteryStatusRequest_init_zero {0, 0}
#define alox_LipoReading_init_zero {0, 0}
@@ -582,6 +597,7 @@ extern "C" {
#define alox_CacheClientTap_init_zero {_alox_TapKind_MIN, 0}
#define alox_CacheClientStatus_init_zero {0, false, alox_CacheClientAccel_init_zero, false, alox_CacheClientTap_init_zero}
#define alox_CacheStatusResponse_init_zero {0, {alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero}}
#define alox_BleStreamTick_init_zero {0, 0, 0, {alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero}}
#define alox_EspNowUnicastTestRequest_init_zero {0, 0}
#define alox_EspNowUnicastTestResponse_init_zero {0, 0}
#define alox_EspNowEchoPingRequest_init_zero {0, 0}
@@ -638,6 +654,7 @@ extern "C" {
#define alox_AccelStreamRequest_enable_tag 2
#define alox_AccelStreamRequest_client_id_tag 3
#define alox_AccelStreamRequest_all_clients_tag 4
#define alox_AccelStreamRequest_period_ms_tag 5
#define alox_AccelStreamResponse_enabled_tag 1
#define alox_AccelStreamResponse_client_id_tag 2
#define alox_AccelStreamResponse_success_tag 3
@@ -685,6 +702,9 @@ extern "C" {
#define alox_CacheClientStatus_accel_tag 2
#define alox_CacheClientStatus_tap_tag 3
#define alox_CacheStatusResponse_clients_tag 1
#define alox_BleStreamTick_esp_timestamp_us_tag 1
#define alox_BleStreamTick_period_ms_tag 2
#define alox_BleStreamTick_clients_tag 3
#define alox_EspNowUnicastTestRequest_client_id_tag 1
#define alox_EspNowUnicastTestRequest_seq_tag 2
#define alox_EspNowUnicastTestResponse_success_tag 1
@@ -801,6 +821,7 @@ extern "C" {
#define alox_UartMessage_set_log_level_response_tag 38
#define alox_UartMessage_tap_config_request_tag 39
#define alox_UartMessage_tap_config_response_tag 40
#define alox_UartMessage_ble_stream_tick_tag 41
/* Struct field encoding specification for nanopb */
#define alox_UartMessage_FIELDLIST(X, a) \
@@ -839,7 +860,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,espnow_echo_ping_response,payload.es
X(a, STATIC, ONEOF, MESSAGE, (payload,set_log_level_request,payload.set_log_level_request), 37) \
X(a, STATIC, ONEOF, MESSAGE, (payload,set_log_level_response,payload.set_log_level_response), 38) \
X(a, STATIC, ONEOF, MESSAGE, (payload,tap_config_request,payload.tap_config_request), 39) \
X(a, STATIC, ONEOF, MESSAGE, (payload,tap_config_response,payload.tap_config_response), 40)
X(a, STATIC, ONEOF, MESSAGE, (payload,tap_config_response,payload.tap_config_response), 40) \
X(a, STATIC, ONEOF, MESSAGE, (payload,ble_stream_tick,payload.ble_stream_tick), 41)
#define alox_UartMessage_CALLBACK NULL
#define alox_UartMessage_DEFAULT NULL
#define alox_UartMessage_payload_ack_payload_MSGTYPE alox_Ack
@@ -877,6 +899,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,tap_config_response,payload.tap_conf
#define alox_UartMessage_payload_set_log_level_response_MSGTYPE alox_SetLogLevelResponse
#define alox_UartMessage_payload_tap_config_request_MSGTYPE alox_TapConfigRequest
#define alox_UartMessage_payload_tap_config_response_MSGTYPE alox_TapConfigResponse
#define alox_UartMessage_payload_ble_stream_tick_MSGTYPE alox_BleStreamTick
#define alox_Ack_FIELDLIST(X, a) \
@@ -950,7 +973,8 @@ X(a, STATIC, SINGULAR, UINT32, slaves_updated, 4)
X(a, STATIC, SINGULAR, BOOL, write, 1) \
X(a, STATIC, SINGULAR, BOOL, enable, 2) \
X(a, STATIC, SINGULAR, UINT32, client_id, 3) \
X(a, STATIC, SINGULAR, BOOL, all_clients, 4)
X(a, STATIC, SINGULAR, BOOL, all_clients, 4) \
X(a, STATIC, SINGULAR, UINT32, period_ms, 5)
#define alox_AccelStreamRequest_CALLBACK NULL
#define alox_AccelStreamRequest_DEFAULT NULL
@@ -1064,6 +1088,14 @@ X(a, STATIC, REPEATED, MESSAGE, clients, 1)
#define alox_CacheStatusResponse_DEFAULT NULL
#define alox_CacheStatusResponse_clients_MSGTYPE alox_CacheClientStatus
#define alox_BleStreamTick_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT64, esp_timestamp_us, 1) \
X(a, STATIC, SINGULAR, UINT32, period_ms, 2) \
X(a, STATIC, REPEATED, MESSAGE, clients, 3)
#define alox_BleStreamTick_CALLBACK NULL
#define alox_BleStreamTick_DEFAULT NULL
#define alox_BleStreamTick_clients_MSGTYPE alox_CacheClientStatus
#define alox_EspNowUnicastTestRequest_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, client_id, 1) \
X(a, STATIC, SINGULAR, UINT32, seq, 2)
@@ -1255,6 +1287,7 @@ extern const pb_msgdesc_t alox_CacheClientAccel_msg;
extern const pb_msgdesc_t alox_CacheClientTap_msg;
extern const pb_msgdesc_t alox_CacheClientStatus_msg;
extern const pb_msgdesc_t alox_CacheStatusResponse_msg;
extern const pb_msgdesc_t alox_BleStreamTick_msg;
extern const pb_msgdesc_t alox_EspNowUnicastTestRequest_msg;
extern const pb_msgdesc_t alox_EspNowUnicastTestResponse_msg;
extern const pb_msgdesc_t alox_EspNowEchoPingRequest_msg;
@@ -1303,6 +1336,7 @@ extern const pb_msgdesc_t alox_OtaSlaveProgressResponse_msg;
#define alox_CacheClientTap_fields &alox_CacheClientTap_msg
#define alox_CacheClientStatus_fields &alox_CacheClientStatus_msg
#define alox_CacheStatusResponse_fields &alox_CacheStatusResponse_msg
#define alox_BleStreamTick_fields &alox_BleStreamTick_msg
#define alox_EspNowUnicastTestRequest_fields &alox_EspNowUnicastTestRequest_msg
#define alox_EspNowUnicastTestResponse_fields &alox_EspNowUnicastTestResponse_msg
#define alox_EspNowEchoPingRequest_fields &alox_EspNowEchoPingRequest_msg
@@ -1332,16 +1366,17 @@ extern const pb_msgdesc_t alox_OtaSlaveProgressResponse_msg;
/* alox_ClientInfo_size depends on runtime parameters */
/* alox_ClientInfoResponse_size depends on runtime parameters */
/* alox_ClientInputResponse_size depends on runtime parameters */
#define ALOX_UART_MESSAGES_PB_H_MAX_SIZE alox_CacheStatusResponse_size
#define ALOX_UART_MESSAGES_PB_H_MAX_SIZE alox_BleStreamTick_size
#define alox_AccelDeadzoneRequest_size 16
#define alox_AccelDeadzoneResponse_size 20
#define alox_AccelSample_size 32
#define alox_AccelStreamRequest_size 12
#define alox_AccelStreamRequest_size 18
#define alox_AccelStreamResponse_size 16
#define alox_Ack_size 0
#define alox_BatterySample_size 32
#define alox_BatteryStatusRequest_size 8
#define alox_BatteryStatusResponse_size 580
#define alox_BleStreamTick_size 753
#define alox_CacheClientAccel_size 26
#define alox_CacheClientStatus_size 44
#define alox_CacheClientTap_size 8
+12
View File
@@ -35,6 +35,8 @@ enum MessageType {
SET_LOG_LEVEL = 31;
/** Host → master: get/set BMA456H multitap detection parameters. */
TAP_CONFIG = 32;
/** Master → host (BLE only): periodic pushed cache snapshot with ESP timestamp. */
BLE_STREAM_TICK = 33;
}
message UartMessage {
@@ -75,6 +77,7 @@ message UartMessage {
SetLogLevelResponse set_log_level_response = 38;
TapConfigRequest tap_config_request = 39;
TapConfigResponse tap_config_response = 40;
BleStreamTick ble_stream_tick = 41;
}
}
@@ -141,11 +144,13 @@ message AccelDeadzoneResponse {
// Host → master: enable/disable slave accel ESP-NOW stream (~16 ms per slave).
// write=false: read; write=true: apply. client_id 0 invalid for write (use >0 or all_clients).
// period_ms (8–16): BLE host push interval for BleStreamTick; ignored on UART (default 16).
message AccelStreamRequest {
bool write = 1;
bool enable = 2;
uint32 client_id = 3;
bool all_clients = 4;
uint32 period_ms = 5;
}
message AccelStreamResponse {
@@ -257,6 +262,13 @@ message CacheStatusResponse {
repeated CacheClientStatus clients = 1 [(nanopb).max_count = 16];
}
/** Master → host over BLE notify: aggregated cache + ESP timer timestamp. */
message BleStreamTick {
uint64 esp_timestamp_us = 1;
uint32 period_ms = 2;
repeated CacheClientStatus clients = 3 [(nanopb).max_count = 16];
}
message EspNowUnicastTestRequest {
uint32 client_id = 1;
uint32 seq = 2;