disable GPS cycle until reboot if no GNSS messages present

This commit is contained in:
liquidraver
2026-04-28 13:49:08 +02:00
parent e30644d01d
commit c9b6d6bded
@@ -104,6 +104,8 @@ static uint32_t gps_wake_interval_ms = CONFIG_ZEPHCORE_GPS_POLL_INTERVAL_SEC *
#define GPS_REPEATER_SYNC_TIMEOUT_MS (5 * 60 * 1000) /* 5 minutes */
static bool gps_repeater_mode = false; /* True = repeater (time sync only), False = companion */
static bool gnss_activity_seen_this_cycle = false; /* Runtime-only: set by GNSS callback while acquiring */
static bool gps_runtime_no_gnss_activity = false; /* Runtime-only: repeater disables periodic GPS until reboot */
/* Forward declarations for work handlers and state functions */
static void gps_wake_work_fn(struct k_work *work);
@@ -213,6 +215,11 @@ static void gnss_data_cb(const struct device *dev, const struct gnss_data *data)
return;
}
if (gps_current_state == GPS_STATE_ACQUIRING) {
/* Any callback means GNSS hardware/UART path is alive, even without a fix. */
gnss_activity_seen_this_cycle = true;
}
LOG_DBG("GNSS callback: fix=%d sats=%d state=%d",
data->info.fix_status, data->info.satellites_cnt, gps_current_state);
@@ -878,6 +885,21 @@ static void gps_software_wake(void)
* FORCE_ON pin LOW for L76K hardware standby. */
static void gps_go_to_standby(void)
{
if (gps_repeater_mode && gps_runtime_no_gnss_activity) {
LOG_WRN("GPS: No GNSS activity detected; disabling repeater GPS cycles until reboot");
gps_current_state = GPS_STATE_OFF;
consecutive_good_fixes = 0;
standby_start_ms = 0;
standby_interval_ms = 0;
#if HAS_GPS_POWER_CONTROL
gps_power_control(false, true);
#elif HAS_GPS_UART
gps_software_sleep();
#endif
return;
}
uint64_t wake_interval = gps_repeater_mode ?
GPS_REPEATER_SYNC_INTERVAL_MS : gps_wake_interval_ms;
@@ -921,9 +943,15 @@ static void gps_go_to_standby(void)
* queue which may be processing stale UART data. */
static void gps_start_acquiring(void)
{
if (gps_repeater_mode && gps_runtime_no_gnss_activity) {
LOG_INF("GPS: Repeater cycles are runtime-disabled (no GNSS activity detected)");
return;
}
LOG_INF("GPS: Waking for %s", gps_repeater_mode ? "time sync" : "position fix");
gps_current_state = GPS_STATE_ACQUIRING;
consecutive_good_fixes = 0;
gnss_activity_seen_this_cycle = false;
#if HAS_GPS_POWER_CONTROL
gps_power_control(true);
@@ -976,6 +1004,11 @@ static void gps_timeout_work_fn(struct k_work *work)
LOG_WRN("GPS: Timeout after %d/%d fixes, deferring standby to main thread",
consecutive_good_fixes, GPS_GOOD_FIX_COUNT);
if (gps_repeater_mode && !gnss_activity_seen_this_cycle) {
LOG_WRN("GPS: Repeater acquire window had no GNSS callbacks; disabling periodic GPS until reboot");
gps_runtime_no_gnss_activity = true;
}
atomic_or(&pending_gps_actions, GPS_ACTION_TIMEOUT);
if (gps_event_cb) {
gps_event_cb();
@@ -1257,6 +1290,7 @@ void gps_set_repeater_mode(bool repeater)
LOG_INF("GPS: Repeater mode - starting initial time sync, then every 48h");
gps_enabled = true; /* Logically enabled */
gps_runtime_no_gnss_activity = false;
/* Start acquiring immediately for initial time sync at boot.
* GPS hardware is already powered from bootloader, so we just