feat(firmware): ADR-063 mmWave sensor fusion — full implementation

Phase 1-2 of ADR-063:

mmwave_sensor.c/h:
- MR60BHA2 UART parser (60 GHz: HR, BR, presence, distance)
- LD2410 UART parser (24 GHz: presence, distance)
- Auto-detection: probes UART for known frame headers at boot
- Mock generator for QEMU testing (synthetic HR 72±2, BR 16±1)
- Capability flag registration per sensor type

edge_processing.c/h:
- 48-byte fused vitals packet (magic 0xC5110004)
- Kalman-style fusion: mmWave 80% + CSI 20% when both available
- Automatic fallback to CSI-only 32-byte packet when no mmWave
- Dual presence flag (Bit3 = mmwave_present)

main.c:
- mmwave_sensor_init() called at boot with auto-detect
- Status logged in startup banner

Fuzz stubs updated for mmwave_sensor API.
Build verified: QEMU mock build passes.

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv
2026-03-15 15:40:43 -04:00
parent 4a50136365
commit f42df4afaa
7 changed files with 725 additions and 4 deletions
+16 -2
View File
@@ -27,6 +27,7 @@
#include "wasm_runtime.h"
#include "wasm_upload.h"
#include "display_task.h"
#include "mmwave_sensor.h"
#ifdef CONFIG_CSI_MOCK_ENABLED
#include "mock_csi.h"
#endif
@@ -227,6 +228,18 @@ void app_main(void)
}
}
/* ADR-063: Initialize mmWave sensor (auto-detect on UART). */
esp_err_t mmwave_ret = mmwave_sensor_init(-1, -1); /* -1 = use default GPIO pins */
if (mmwave_ret == ESP_OK) {
mmwave_state_t mw;
if (mmwave_sensor_get_state(&mw)) {
ESP_LOGI(TAG, "mmWave sensor: %s (caps=0x%04x)",
mmwave_type_name(mw.type), mw.capabilities);
}
} else {
ESP_LOGI(TAG, "No mmWave sensor detected (CSI-only mode)");
}
/* Initialize power management. */
power_mgmt_init(g_nvs_config.power_duty);
@@ -238,11 +251,12 @@ void app_main(void)
}
#endif
ESP_LOGI(TAG, "CSI streaming active → %s:%d (edge_tier=%u, OTA=%s, WASM=%s)",
ESP_LOGI(TAG, "CSI streaming active → %s:%d (edge_tier=%u, OTA=%s, WASM=%s, mmWave=%s)",
g_nvs_config.target_ip, g_nvs_config.target_port,
g_nvs_config.edge_tier,
(ota_ret == ESP_OK) ? "ready" : "off",
(wasm_ret == ESP_OK) ? "ready" : "off");
(wasm_ret == ESP_OK) ? "ready" : "off",
(mmwave_ret == ESP_OK) ? "active" : "off");
/* Main loop — keep alive */
while (1) {