diff --git a/zephcore/ARCHITECTURE.md b/zephcore/ARCHITECTURE.md index d32837a..c24eb50 100644 --- a/zephcore/ARCHITECTURE.md +++ b/zephcore/ARCHITECTURE.md @@ -370,7 +370,7 @@ Autonomous operation features: - **Region filtering**: `RegionMap` with transport key matching per flood packet - **Rate limiting**: 4 requests per 120s (discovery), 4 per 180s (anonymous) - **Neighbor tracking**: 16-slot table with RSSI/SNR/name/timestamp -- **Temporary radio params**: `tempradio` command with auto-revert timer +- **Temporary radio params**: `tempradio` command applies freq/bw/sf/cr via `LoRaRadioBase::setRadioOverride()` (does not mutate `_prefs`); auto-revert timer calls `clearRadioOverride()` to fall back to saved prefs ### 6.4 CommonCLI Commands diff --git a/zephcore/Kconfig b/zephcore/Kconfig index 481695a..db0a841 100644 --- a/zephcore/Kconfig +++ b/zephcore/Kconfig @@ -418,7 +418,7 @@ config ZEPHCORE_LORA_RX_DUTY_CYCLE config ZEPHCORE_APC bool "Adaptive Power Control (APC)" - default n + default y help Automatically reduce TX power when echo packets from neighbors indicate excess SNR margin. Saves battery and reduces channel @@ -428,8 +428,8 @@ config ZEPHCORE_APC Uses rogue-filtering: clusters echo SNRs to avoid one badly placed high-SNR neighbor from over-reducing power. - Off by default. Enable with CONFIG_ZEPHCORE_APC=y in board.conf - or via EXTRA_CONF_FILE. + Compiled in by default; disabled at runtime (enable per-node + via CLI "set tx apc" — persisted in prefs). endmenu diff --git a/zephcore/Repeater_CLI_commands.md b/zephcore/Repeater_CLI_commands.md index 55108a4..ae46962 100644 --- a/zephcore/Repeater_CLI_commands.md +++ b/zephcore/Repeater_CLI_commands.md @@ -131,7 +131,7 @@ Regions control which flood packets the repeater forwards. The region tree is hi | Command | Description | |---------|-------------| -| `tempradio ` | Apply temporary radio parameters; automatically reverts after `timeout_mins`. Constraints: freq 150–2500 MHz, bw 7–500 kHz, sf 5–12, cr 5–8 | +| `tempradio ` | Apply temporary radio parameters; automatically reverts after `timeout_mins`. Constraints: freq 150–2500 MHz, bw 7–500 kHz, sf 5–12, cr 5–8. Saved prefs are never mutated — concurrent `set` commands and reboots both restore the real saved values. | --- diff --git a/zephcore/adapters/gps/ZephyrGPSManager.cpp b/zephcore/adapters/gps/ZephyrGPSManager.cpp index 2ca1140..e436191 100644 --- a/zephcore/adapters/gps/ZephyrGPSManager.cpp +++ b/zephcore/adapters/gps/ZephyrGPSManager.cpp @@ -1464,7 +1464,27 @@ void gps_request_fresh_fix(void) k_work_cancel_delayable(&gps_wake_work); gps_start_acquiring(); } else if (gps_current_state == GPS_STATE_ACQUIRING) { - LOG_DBG("GPS: Fresh fix requested but already acquiring"); + /* Already acquiring — reschedule the timeout so the caller's + * fresh-fix request gets a full window from now. Otherwise, a + * telemetry request that arrives 25s into a 30s acquire window + * only has 5s left, which in marginal signal usually means the + * chip goes to standby before producing a fix the requester + * could use. Repeater mode uses its own 5min timeout; companion + * mode pre-first-fix has no timeout (nothing to reschedule). */ + uint32_t timeout_ms = 0; + if (gps_repeater_mode) { + timeout_ms = GPS_REPEATER_SYNC_TIMEOUT_MS; + } else if (first_fix_acquired) { + timeout_ms = gps_acquire_timeout_ms; + } + if (timeout_ms > 0) { + LOG_INF("GPS: Fresh fix requested, extending acquire " + "timeout by %u ms", timeout_ms); + k_work_reschedule(&gps_timeout_work, K_MSEC(timeout_ms)); + } else { + LOG_DBG("GPS: Fresh fix requested, already acquiring " + "(no timeout active)"); + } } #endif } diff --git a/zephcore/app/RepeaterMesh.cpp b/zephcore/app/RepeaterMesh.cpp index 6426093..05abefb 100644 --- a/zephcore/app/RepeaterMesh.cpp +++ b/zephcore/app/RepeaterMesh.cpp @@ -309,6 +309,15 @@ int RepeaterMesh::handleRequest(ClientInfo* sender, uint32_t sender_timestamp, u gpos.altitude_mm / 1000.0f); } + /* Wake GPS / extend acquire window so the next telemetry poll has + * a fresher fix. In repeater mode GPS is normally off between the + * 48h time-sync cycles — this opportunistically rearms acquire + * when someone actually cares about our position. No-op if GPS + * is disabled in prefs. */ + if (gps_is_available() && gps_is_enabled()) { + gps_request_fresh_fix(); + } + return 4 + lpp.getSize(); } diff --git a/zephcore/helpers/CommonCLI.h b/zephcore/helpers/CommonCLI.h index 71ed6c1..b8c3244 100644 --- a/zephcore/helpers/CommonCLI.h +++ b/zephcore/helpers/CommonCLI.h @@ -59,7 +59,7 @@ public: // Adaptive Power Control virtual int8_t getAPCReduction() const { return 0; } virtual float getAPCMargin() const { return 0.0f; } - virtual bool isAPCEnabled() const { return true; } + virtual bool isAPCEnabled() const { return false; } virtual void setAPCEnabled(bool en) { (void)en; } virtual uint8_t getAPCTargetMargin() const { return 16; } virtual void setAPCTargetMargin(uint8_t margin_db) { (void)margin_db; }