mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-17 01:54:17 +00:00
refactor / unify probes
This commit is contained in:
@@ -43,6 +43,8 @@ Dispatcher::Dispatcher(Radio &radio, MillisecondClock &ms, PacketManager &mgr)
|
||||
n_recv_flood = n_recv_direct = 0;
|
||||
_tx_queued_cb = nullptr;
|
||||
_tx_queued_user_data = nullptr;
|
||||
_wake_cb = nullptr;
|
||||
_wake_user_data = nullptr;
|
||||
}
|
||||
|
||||
void Dispatcher::begin()
|
||||
|
||||
@@ -737,7 +737,7 @@ public:
|
||||
void applyCadPrefs() override {
|
||||
lora_radio.setCadParams(companion_mesh.prefs.cad_auto != 0,
|
||||
companion_mesh.prefs.cad_offset,
|
||||
companion_mesh.prefs.cad_probe_interval,
|
||||
companion_mesh.prefs.probe_interval,
|
||||
companion_mesh.prefs.cad_busycap);
|
||||
}
|
||||
void resetCadStats() override {
|
||||
@@ -1385,7 +1385,7 @@ int main(void)
|
||||
* its proper default. A hand-maintained subset here silently drifts: any
|
||||
* field not listed defaults to 0, and on upgrade the past-EOF read in
|
||||
* loadPrefs then keeps that 0 instead of the real default (this is what
|
||||
* zeroed cad_probe_interval / cad_auto and, earlier, the GPS settings). */
|
||||
* zeroed probe_interval / cad_auto and, earlier, the GPS settings). */
|
||||
initNodePrefs(&companion_mesh.prefs);
|
||||
/* Companion-specific overrides vs. initNodePrefs defaults: */
|
||||
companion_mesh.prefs.auto_shutdown_mv = CONFIG_ZEPHCORE_AUTO_SHUTDOWN_MILLIVOLTS; /* low-batt cutoff (0=off) */
|
||||
@@ -1547,7 +1547,7 @@ int main(void)
|
||||
lora_radio.enableRxDutyCycle(companion_mesh.prefs.rx_duty_cycle != 0);
|
||||
lora_radio.setCadParams(companion_mesh.prefs.cad_auto != 0,
|
||||
companion_mesh.prefs.cad_offset,
|
||||
companion_mesh.prefs.cad_probe_interval,
|
||||
companion_mesh.prefs.probe_interval,
|
||||
companion_mesh.prefs.cad_busycap);
|
||||
ui_set_radio_runtime(
|
||||
lora_radio.getActiveSyncWord(),
|
||||
|
||||
@@ -103,7 +103,8 @@ static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
|
||||
#define MESH_EVENT_TX_DRAIN BIT(5) /* Outbound packet delay expired, run checkSend */
|
||||
#define MESH_EVENT_RTC_SAVE BIT(6) /* Hardware-RTC write requested off-main */
|
||||
#define MESH_EVENT_INIT_ADVERT BIT(7) /* Deferred boot advert — send on main thread */
|
||||
#define MESH_EVENT_ALL (MESH_EVENT_LORA_RX | MESH_EVENT_LORA_TX_DONE | MESH_EVENT_CLI_RX | MESH_EVENT_MAINTENANCE | MESH_EVENT_GPS_ACTION | MESH_EVENT_TX_DRAIN | MESH_EVENT_RTC_SAVE | MESH_EVENT_INIT_ADVERT)
|
||||
#define MESH_EVENT_WAKE BIT(8) /* Off-main state set; run loop() promptly */
|
||||
#define MESH_EVENT_ALL (MESH_EVENT_LORA_RX | MESH_EVENT_LORA_TX_DONE | MESH_EVENT_CLI_RX | MESH_EVENT_MAINTENANCE | MESH_EVENT_GPS_ACTION | MESH_EVENT_TX_DRAIN | MESH_EVENT_RTC_SAVE | MESH_EVENT_INIT_ADVERT | MESH_EVENT_WAKE)
|
||||
|
||||
/* Maintenance is deadline-driven, not periodic: after every pass the loop asks
|
||||
* the mesh when its soonest pending deadline is (msUntilNextMaintenance) and
|
||||
@@ -290,10 +291,11 @@ static void maintenance_timer_fn(struct k_timer *timer)
|
||||
static void arm_maintenance_wake(void)
|
||||
{
|
||||
uint32_t delay = MAINTENANCE_BACKSTOP_MS;
|
||||
uint32_t next = MAINTENANCE_BACKSTOP_MS;
|
||||
|
||||
#ifdef ZEPHCORE_LORA
|
||||
if (repeater_mesh_ptr) {
|
||||
uint32_t next = repeater_mesh_ptr->msUntilNextMaintenance();
|
||||
next = repeater_mesh_ptr->msUntilNextMaintenance();
|
||||
|
||||
if (next < delay) {
|
||||
delay = next;
|
||||
@@ -305,6 +307,15 @@ static void arm_maintenance_wake(void)
|
||||
delay = MAINTENANCE_MIN_MS;
|
||||
}
|
||||
|
||||
/* Both figures, because which one is binding is the whole diagnosis:
|
||||
* next=15000 armed=15000 — a real deadline won; working as intended
|
||||
* next=15000 armed=5000 — the backstop is clamping (it must stay
|
||||
* above the noise-floor/CAD intervals)
|
||||
* next=0 armed=50 — a deadline reports due but its state is
|
||||
* not advancing; repeated = spin
|
||||
* mesh::MAINTENANCE_IDLE (0x7FFFFFFF) as `next` means nothing pending. */
|
||||
LOG_DBG("maint: next=%u armed=%u", (unsigned)next, (unsigned)delay);
|
||||
|
||||
k_timer_start(&maintenance_timer, K_MSEC(delay), K_NO_WAIT);
|
||||
}
|
||||
|
||||
@@ -346,6 +357,15 @@ static void tx_queued_callback(uint32_t delay_ms, void *user_data)
|
||||
ARG_UNUSED(user_data);
|
||||
k_work_reschedule(&tx_drain_work, K_MSEC(delay_ms));
|
||||
}
|
||||
|
||||
/* Off-main code (MQTT CONNACK, SNTP) set state that loop() must drain. Post
|
||||
* only — this runs on the MQTT publisher / WiFi thread, and k_event_post is
|
||||
* the sole thing safe to do from there. */
|
||||
static void wake_callback(void *user_data)
|
||||
{
|
||||
ARG_UNUSED(user_data);
|
||||
k_event_post(&mesh_events, MESH_EVENT_WAKE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Global instances */
|
||||
@@ -487,23 +507,44 @@ static void repeater_event_loop(void)
|
||||
/* Packet processing — only on radio/CLI/TX events */
|
||||
if (repeater_mesh_ptr &&
|
||||
(events & (MESH_EVENT_LORA_RX | MESH_EVENT_LORA_TX_DONE |
|
||||
MESH_EVENT_CLI_RX | MESH_EVENT_TX_DRAIN))) {
|
||||
MESH_EVENT_CLI_RX | MESH_EVENT_TX_DRAIN |
|
||||
MESH_EVENT_WAKE))) {
|
||||
repeater_mesh_ptr->loop();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* A maintenance deadline came due — run the pass. */
|
||||
#ifdef ZEPHCORE_LORA
|
||||
/* Radio maintenance runs OPPORTUNISTICALLY, on every pass, whatever
|
||||
* woke us — not only when its own timer fired.
|
||||
*
|
||||
* Every item inside is deadline-gated internally, so this is nearly
|
||||
* free when nothing is due. The point is what it does to a busy
|
||||
* node: a hilltop repeater is already waking constantly for packets,
|
||||
* so maintenance rides along on those wakes, its deadlines advance,
|
||||
* and arm_maintenance_wake() below keeps pushing the timer out — the
|
||||
* maintenance timer then almost never fires and costs no wakes at
|
||||
* all. Running it only on its own event (as this did originally)
|
||||
* inverted that: the busiest nodes, which can least afford it, paid
|
||||
* the full timer cadence on top of their packet wakes, and every
|
||||
* blocked sample burned a retry against a channel that is busy for
|
||||
* sustained reasons (real traffic in isReceiving(), the RSSI
|
||||
* prefilter) rather than the transient duty-cycle sleep window the
|
||||
* retries were sized for.
|
||||
*
|
||||
* Ordering matters: this sits AFTER packet processing so an inbound
|
||||
* frame is handled before we spend SPI time on an RSSI sweep. */
|
||||
if (repeater_mesh_ptr) {
|
||||
repeater_mesh_ptr->maintenanceLoop();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* A maintenance deadline came due — run the time-based work too. */
|
||||
if (events & MESH_EVENT_MAINTENANCE) {
|
||||
#ifdef ZEPHCORE_LORA
|
||||
/* Radio maintenance: noise floor calibration, AGC reset,
|
||||
* RX watchdog. Separated from loop() so these never run
|
||||
* on packet-driven events. */
|
||||
/* Drive loop() so time-based actions (advert timers,
|
||||
* tempradio set/revert, contacts flush, uplink status)
|
||||
* still fire when no LoRa/CLI traffic wakes the loop. */
|
||||
if (repeater_mesh_ptr) {
|
||||
repeater_mesh_ptr->maintenanceLoop();
|
||||
/* Also drive loop() so time-based actions (advert
|
||||
* timers, tempradio set/revert, contacts flush,
|
||||
* uplink status) still fire when no LoRa/CLI
|
||||
* traffic wakes the event loop. */
|
||||
repeater_mesh_ptr->loop();
|
||||
}
|
||||
#endif
|
||||
@@ -633,6 +674,7 @@ int main(void)
|
||||
lora_radio.setRxCallback(lora_rx_callback, nullptr);
|
||||
lora_radio.setTxDoneCallback(lora_tx_done_callback, nullptr);
|
||||
repeater_mesh.setTxQueuedCallback(tx_queued_callback, nullptr);
|
||||
repeater_mesh.setWakeCallback(wake_callback, nullptr);
|
||||
|
||||
/* Load or generate identity BEFORE begin(). First-boot keygen runs
|
||||
* the layered entropy mixer + Ed25519 derive + reserved-prefix
|
||||
@@ -680,7 +722,7 @@ int main(void)
|
||||
lora_radio.setRxBoost(prefs->rx_boost != 0);
|
||||
lora_radio.enableRxDutyCycle(prefs->rx_duty_cycle != 0);
|
||||
lora_radio.setCadParams(prefs->cad_auto != 0, prefs->cad_offset,
|
||||
prefs->cad_probe_interval, prefs->cad_busycap);
|
||||
prefs->probe_interval, prefs->cad_busycap);
|
||||
|
||||
/* Feed initial UI state from loaded prefs */
|
||||
ui_set_node_name(prefs->node_name);
|
||||
|
||||
@@ -610,7 +610,7 @@ int main(void)
|
||||
lora_radio.setRxBoost(prefs->rx_boost != 0);
|
||||
lora_radio.enableRxDutyCycle(prefs->rx_duty_cycle != 0);
|
||||
lora_radio.setCadParams(prefs->cad_auto != 0, prefs->cad_offset,
|
||||
prefs->cad_probe_interval, prefs->cad_busycap);
|
||||
prefs->probe_interval, prefs->cad_busycap);
|
||||
|
||||
/* Feed initial UI state from loaded prefs */
|
||||
ui_set_node_name(prefs->node_name);
|
||||
|
||||
Reference in New Issue
Block a user