fix(gps): make acquisition and reacquisition deterministic
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
#ifndef GPS_ACQ_MANAGER_H
|
||||
#define GPS_ACQ_MANAGER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define GPS_ACQ_MANAGER_PRN_COUNT 32u
|
||||
#define GPS_ACQ_MANAGER_INVALID_PRN 0xffu
|
||||
|
||||
typedef enum {
|
||||
GPS_ACQ_PRN_DISABLED = 0,
|
||||
GPS_ACQ_PRN_COLD,
|
||||
GPS_ACQ_PRN_HOT,
|
||||
GPS_ACQ_PRN_ACQUIRING,
|
||||
GPS_ACQ_PRN_ACQUIRED,
|
||||
GPS_ACQ_PRN_TRACKING,
|
||||
GPS_ACQ_PRN_STALE
|
||||
} gps_acq_prn_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t retry_delay_ticks;
|
||||
uint64_t hot_retry_delay_ticks;
|
||||
uint64_t hot_window_ticks;
|
||||
unsigned int max_hot_streak;
|
||||
} gps_acq_manager_config_t;
|
||||
|
||||
typedef struct {
|
||||
gps_acq_prn_state_t state;
|
||||
uint64_t last_attempt_tick;
|
||||
uint64_t hot_until_tick;
|
||||
bool has_attempted;
|
||||
bool attempt_was_hot;
|
||||
} gps_acq_prn_entry_t;
|
||||
|
||||
typedef struct {
|
||||
gps_acq_manager_config_t config;
|
||||
gps_acq_prn_entry_t prn[GPS_ACQ_MANAGER_PRN_COUNT];
|
||||
unsigned int cold_cursor;
|
||||
unsigned int hot_cursor;
|
||||
unsigned int hot_streak;
|
||||
} gps_acq_manager_t;
|
||||
|
||||
void gps_acq_manager_init(
|
||||
gps_acq_manager_t* manager,
|
||||
const gps_acq_manager_config_t* config);
|
||||
bool gps_acq_manager_enable_cold(
|
||||
gps_acq_manager_t* manager,
|
||||
unsigned int prn);
|
||||
gps_acq_prn_state_t gps_acq_manager_state(
|
||||
const gps_acq_manager_t* manager,
|
||||
unsigned int prn);
|
||||
const char* gps_acq_manager_state_name(gps_acq_prn_state_t state);
|
||||
|
||||
void gps_acq_manager_mark_acquired(
|
||||
gps_acq_manager_t* manager,
|
||||
unsigned int prn);
|
||||
void gps_acq_manager_mark_tracking(
|
||||
gps_acq_manager_t* manager,
|
||||
unsigned int prn);
|
||||
void gps_acq_manager_mark_stale(
|
||||
gps_acq_manager_t* manager,
|
||||
unsigned int prn);
|
||||
void gps_acq_manager_mark_lost(
|
||||
gps_acq_manager_t* manager,
|
||||
unsigned int prn,
|
||||
uint64_t now);
|
||||
void gps_acq_manager_mark_failed(
|
||||
gps_acq_manager_t* manager,
|
||||
unsigned int prn,
|
||||
uint64_t now);
|
||||
|
||||
bool gps_acq_manager_start_next(
|
||||
gps_acq_manager_t* manager,
|
||||
uint64_t now,
|
||||
unsigned int* prn_out,
|
||||
bool* hot_out);
|
||||
unsigned int gps_acq_manager_count_state(
|
||||
const gps_acq_manager_t* manager,
|
||||
gps_acq_prn_state_t state);
|
||||
unsigned int gps_acq_manager_count_searchable(
|
||||
const gps_acq_manager_t* manager);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef GPS_EPHEMERIS_CACHE_H
|
||||
#define GPS_EPHEMERIS_CACHE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "gps/gps_ip_defines.h"
|
||||
|
||||
typedef struct {
|
||||
gps_ephemeris_t ephemeris;
|
||||
uint64_t committed_tick;
|
||||
bool valid;
|
||||
} gps_ephemeris_cache_entry_t;
|
||||
|
||||
typedef struct {
|
||||
gps_ephemeris_cache_entry_t entry[GPS_PRN_COUNT];
|
||||
uint64_t max_age_ticks;
|
||||
} gps_ephemeris_cache_t;
|
||||
|
||||
void gps_ephemeris_cache_init(
|
||||
gps_ephemeris_cache_t* cache,
|
||||
uint64_t max_age_ticks);
|
||||
bool gps_ephemeris_cache_store(
|
||||
gps_ephemeris_cache_t* cache,
|
||||
unsigned int prn,
|
||||
const gps_ephemeris_t* ephemeris,
|
||||
uint64_t now);
|
||||
bool gps_ephemeris_cache_restore(
|
||||
gps_ephemeris_cache_t* cache,
|
||||
unsigned int prn,
|
||||
uint64_t now,
|
||||
gps_ephemeris_t* ephemeris_out);
|
||||
void gps_ephemeris_cache_invalidate(
|
||||
gps_ephemeris_cache_t* cache,
|
||||
unsigned int prn);
|
||||
|
||||
#endif
|
||||
@@ -14,6 +14,8 @@
|
||||
uint32_t how_anchor_rejected_total;
|
||||
uint32_t satellite_connected_total;
|
||||
uint32_t satellite_lost_total;
|
||||
uint32_t ephemeris_cache_store_total;
|
||||
uint32_t ephemeris_cache_restore_total;
|
||||
uint32_t last_connected_prn;
|
||||
uint32_t last_lost_prn;
|
||||
uint64_t last_connected_tick;
|
||||
@@ -42,6 +44,9 @@
|
||||
gps_external_irq_handler_t handler);
|
||||
void gps_irq_handler(void) GPS_IRQ_HANDLER_ATTR;
|
||||
void gps_process_isr_events(void);
|
||||
void gps_acq_configure_prns(
|
||||
const unsigned char* prns,
|
||||
unsigned int count);
|
||||
void gps_acq_scheduler_run(void);
|
||||
void gps_background_task(void);
|
||||
bool gps_take_nav_epoch_snapshot(gps_nav_epoch_snapshot_t* snapshot);
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
#include "gps/matrixLib.h"
|
||||
#include "gps/gps_macros.h"
|
||||
|
||||
#ifdef __riscv
|
||||
#define GPS_IRQ_HANDLER_ATTR __attribute__((interrupt("machine"), aligned(4)))
|
||||
#else
|
||||
#define GPS_IRQ_HANDLER_ATTR
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +62,14 @@
|
||||
#define GPS_NAV_ENABLE_FDE 0u
|
||||
#define GPS_PROFILE_CPU_HZ 50000000ULL
|
||||
#define GPS_ACQ_RETRY_DELAY_TICKS (GPS_SYSTICK_HZ / 2u)
|
||||
#define GPS_ACQ_STUCK_WARN_TICKS (GPS_SYSTICK_HZ * 2u)
|
||||
#define GPS_ACQ_HOT_RETRY_DELAY_TICKS (GPS_SYSTICK_HZ * 30u)
|
||||
#define GPS_ACQ_REACQ_PRIORITY_TICKS \
|
||||
(GPS_SYSTICK_HZ * 2u * 60u * 60u)
|
||||
#define GPS_ACQ_MAX_HOT_STREAK 4u
|
||||
#define GPS_ACQ_STUCK_WARN_TICKS (GPS_SYSTICK_HZ * 8u)
|
||||
#define GPS_EPHEMERIS_CACHE_MAX_AGE_TICKS \
|
||||
(GPS_SYSTICK_HZ * 2u * 60u * 60u)
|
||||
#define GPS_ACQ_STATUS_LOG_PERIOD_TICKS (GPS_SYSTICK_HZ * 5u)
|
||||
#define GPS_NAV_STATUS_LOG_PERIOD_TICKS GPS_SYSTICK_HZ
|
||||
#define GPS_TRK_MEASUREMENT_STALE_TICKS (GPS_SYSTICK_HZ * 3u)
|
||||
#define GPS_NAV_ABS_SAMPLE_SYNC_WINDOW_MS 25u
|
||||
@@ -223,15 +234,6 @@
|
||||
uint32_t REM_CODE_PHASE_REG; // 'h4c
|
||||
}gps_trck_t;
|
||||
|
||||
typedef enum {
|
||||
GPS_SAT_NOT_SEEN = 0,
|
||||
GPS_SAT_ACQUIRING,
|
||||
GPS_SAT_ACQUIRED,
|
||||
GPS_SAT_TRACKING,
|
||||
GPS_SAT_LOST,
|
||||
GPS_SAT_STALE
|
||||
} gps_satellite_state_t;
|
||||
|
||||
typedef enum {
|
||||
GPS_ACQ_ENGINE_IDLE = 0,
|
||||
GPS_ACQ_ENGINE_BUSY
|
||||
@@ -458,9 +460,13 @@
|
||||
uint64_t gps_get_systick(void);
|
||||
static inline uint64_t gps_read_cycle_counter(void)
|
||||
{
|
||||
#ifdef __riscv
|
||||
uint64_t cycles;
|
||||
asm volatile("rdcycle %0" : "=r"(cycles));
|
||||
return cycles;
|
||||
#else
|
||||
return 0u;
|
||||
#endif
|
||||
}
|
||||
bool gps_get_ionoutc(ionoutc_t* ionoutc);
|
||||
void gps_background_task(void);
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
/*
|
||||
* Verbosity is cumulative:
|
||||
* 1: navigation result (position and all DOP values) plus tracked
|
||||
* satellite count/PRN summary
|
||||
* 1: navigation result (position and all DOP values), tracked
|
||||
* satellite summary and low-rate acquisition/reacquisition status
|
||||
* 2: reserved for additional status detail
|
||||
* 3: state transitions, warnings/errors and integrity summary
|
||||
* 4: performance, NAV satellite and low-level diagnostic detail
|
||||
|
||||
@@ -29,13 +29,7 @@ typedef struct gps_ephem_ll {
|
||||
volatile bool gps_measurement_valid;
|
||||
} gps_ephem_ll_t;
|
||||
|
||||
typedef struct gps_acq_ll {
|
||||
unsigned int prn_no;
|
||||
struct gps_acq_ll* next;
|
||||
} gps_acq_ll_t;
|
||||
|
||||
extern volatile gps_ephem_ll_t* tracking_node;
|
||||
extern volatile gps_acq_ll_t* acquisition_node;
|
||||
|
||||
bool insert_element(volatile gps_ephem_ll_t** node,
|
||||
volatile gps_ephemeris_t* data_p,
|
||||
@@ -45,8 +39,4 @@ bool trck_ip_exists(volatile gps_ephem_ll_t** node, unsigned char trck_ip_no);
|
||||
volatile gps_ephem_ll_t* get_element_by_ip_number(volatile gps_ephem_ll_t** node,
|
||||
unsigned char trck_ip_no);
|
||||
|
||||
bool insert_acq_element(volatile gps_acq_ll_t** node, unsigned int prn_no);
|
||||
bool delete_acq_element_by_prn_number(volatile gps_acq_ll_t** node, unsigned int prn_no);
|
||||
bool acq_prn_exists(volatile gps_acq_ll_t** node, unsigned int prn_no);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user