30179df8e6
Remove the fixed pseudorange start offset, preserve per-PRN navigation assistance across RF loss and power cycles, and seed coherent navigation measurement phase on reacquisition. Add full LNAV almanac visibility scheduling, power-safe QSPI journaling, RF-domain reset isolation, and PPS Gray CDC hardening with Linux, sanitizer, RTL, and end-to-end coverage.
83 lines
2.9 KiB
C
83 lines
2.9 KiB
C
#include "gps/gps_measurement_freshness.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
|
|
#define SYSTICK_HZ 10u
|
|
#define PERIODIC_DEADLINE_TICKS (3u * SYSTICK_HZ)
|
|
#define LNAV_SUBFRAME_TICKS (6u * SYSTICK_HZ)
|
|
|
|
static void cold_lnav_cadence_never_uses_periodic_deadline(void)
|
|
{
|
|
gps_measurement_freshness_t freshness;
|
|
gps_measurement_freshness_init(&freshness);
|
|
|
|
/* Three cold-acquisition subframes span the full ephemeris collection
|
|
* interval. Every gap is longer than the periodic deadline. */
|
|
for(uint64_t subframe = 0u; subframe < 3u; subframe++)
|
|
{
|
|
uint64_t event_tick = subframe * LNAV_SUBFRAME_TICKS;
|
|
gps_measurement_freshness_note_lnav(
|
|
&freshness, true, event_tick);
|
|
assert(gps_measurement_freshness_usable(
|
|
&freshness,
|
|
event_tick + LNAV_SUBFRAME_TICKS - 1u,
|
|
PERIODIC_DEADLINE_TICKS));
|
|
assert(!gps_measurement_freshness_expired(
|
|
&freshness,
|
|
event_tick + LNAV_SUBFRAME_TICKS - 1u,
|
|
PERIODIC_DEADLINE_TICKS));
|
|
}
|
|
assert(freshness.phase == GPS_MEASUREMENT_PHASE_LNAV);
|
|
}
|
|
|
|
static void armed_and_active_measurements_use_periodic_deadline(void)
|
|
{
|
|
gps_measurement_freshness_t freshness;
|
|
gps_measurement_freshness_init(&freshness);
|
|
gps_measurement_freshness_note_lnav(&freshness, true, 120u);
|
|
gps_measurement_freshness_arm_nav_solve(&freshness, true, 121u);
|
|
assert(freshness.phase == GPS_MEASUREMENT_PHASE_NAV_SOLVE_ARMED);
|
|
assert(gps_measurement_freshness_usable(
|
|
&freshness, 151u, PERIODIC_DEADLINE_TICKS));
|
|
assert(gps_measurement_freshness_expired(
|
|
&freshness, 152u, PERIODIC_DEADLINE_TICKS));
|
|
|
|
/* A six-second LNAV event is still decoded in NAV-solve mode, but cannot
|
|
* hide the missing short-period measurement stream. */
|
|
gps_measurement_freshness_note_lnav(&freshness, true, 160u);
|
|
assert(gps_measurement_freshness_expired(
|
|
&freshness, 160u, PERIODIC_DEADLINE_TICKS));
|
|
|
|
gps_measurement_freshness_note_nav_solve(&freshness, true, 161u);
|
|
assert(freshness.phase == GPS_MEASUREMENT_PHASE_NAV_SOLVE_ACTIVE);
|
|
assert(gps_measurement_freshness_usable(
|
|
&freshness, 180u, PERIODIC_DEADLINE_TICKS));
|
|
assert(gps_measurement_freshness_expired(
|
|
&freshness, 192u, PERIODIC_DEADLINE_TICKS));
|
|
}
|
|
|
|
static void unlock_invalidates_every_phase(void)
|
|
{
|
|
gps_measurement_freshness_t freshness;
|
|
gps_measurement_freshness_init(&freshness);
|
|
gps_measurement_freshness_note_lnav(&freshness, true, 10u);
|
|
gps_measurement_freshness_note_lnav(&freshness, false, 11u);
|
|
assert(!gps_measurement_freshness_usable(
|
|
&freshness, 11u, PERIODIC_DEADLINE_TICKS));
|
|
|
|
gps_measurement_freshness_arm_nav_solve(&freshness, true, 20u);
|
|
gps_measurement_freshness_note_nav_solve(&freshness, false, 21u);
|
|
assert(!gps_measurement_freshness_usable(
|
|
&freshness, 21u, PERIODIC_DEADLINE_TICKS));
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
cold_lnav_cadence_never_uses_periodic_deadline();
|
|
armed_and_active_measurements_use_periodic_deadline();
|
|
unlock_invalidates_every_phase();
|
|
puts("gps measurement freshness tests passed");
|
|
return 0;
|
|
}
|