Files
gps/hardware/external/gps/rtl
onur f59d6ebb43 fix(gps): correct week-number handling across almanac, ephemeris and flash
Persisting navigation data changed its lifetime from one power cycle to
weeks, and every piece of arithmetic that had only ever run over the
shorter lifetime turned out to be wrong. Each fix below reproduces in a
host test that fails against the previous behaviour.

Almanac (gps_almanac.c, gps_lnav_parser.c)

WNa was lifted against gps_ephems.toe.week, a field nothing ever writes,
so any WNa above 128 underflowed to ~4.29e9. The propagation then reduced
tk with a while-loop, turning one visibility refresh into 4.29e9
iterations - hours on the target, inside a 10 s periodic call. WNa is the
week modulo 256, so this armed at GPS week 2433 and then for 127 weeks in
every 256. Now lifted against tow.week in signed arithmetic, refused if
impossible, and the propagation is closed form.

The IS-GPS-200 20.3.3.5.2.3 half-week wrap was also applied to tk
unconditionally. It is a week-crossover correction, not a general
reduction: a GPS week is 14.0384 orbital periods, so aliasing one week
moves a satellite 5161 km, enough to report one 5.1 degrees below the
horizon as 5.7 above. The crossover guess now lives in
gps_almanac_assumed_week(), used only before page 25 arrives, and an
almanac too old to propagate yields no prediction rather than a wrong one.

Ephemeris age (gps_ephemeris_validity.c, gps_lnav_parser.c)

The curve-fit check compared two second-of-week values and never read a
week at all, so a record exactly N weeks old read as current. Harmless
while ephemeris lived in RAM; directly reachable once persisted across a
power-off. gps_resolve_toe_week() now reconstructs Toe's week at commit
time from the subframe 1 week number and the handover word; an
unresolvable week yields no age, which reads as a rejection.

A restored record could also outrank the live broadcast, because the Toe
ordering inverts past half a week. Flash records are now marked restored
and are candidates, never incumbents.

Flash wear (gps_nav_context_store.c, gps_interrupt_handlers.c)

The CRC wear policy never engaged: the payload carried the live WLS
position and a receiver timestamp nothing on the restore path read, so
every 60 s save was an erase - about 139 days to wear-out. The seed is
now held and refreshed only on 5 km of movement, at most hourly: one
erase per day instead of 1440.

Measurement model (NavEquations.c)

The elevation weighting was floored at 10 degrees, capping its term at
17.3 m where the model's own answer is 34.4 m at 5 degrees and 86 m at 2,
so a low satellite was trusted several times more than the model allowed.
Floor lowered to 3 degrees, which is where 1/sin must still be bounded
because a zero weight fails the whole epoch. Measured on a six-satellite
geometry, 30 m of uncorrected delay now moves the fix 4.18 m through a
4-degree satellite against 48.50 m through a 72-degree one.

Both atmospheric corrections switched off below the horizon, so a
satellite crossing it lost 78.8 m of tropospheric delay in one step.
Elevation is now clamped at the horizon for the models, and the
extrapolation is paid for in variance.

Also: gps_pps_select_reference() returned early on the preferred PRN,
leaving later non-finite capture times unscreened.

Checked and found correct, with regressions added: the epoch assembly
under satellite connect/disconnect and reassignment, coalesced captures,
the 32-bit RF sample counter wrap (pseudoranges agree to 3.3 um across
it), the refusal to publish a solvable subset of an incoherent epoch, and
the Klobuchar model against IS-GPS-200 20.3.3.5.2.5.

Tests: 22 host suites, 5 RTL testbenches, sanitizer clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 01:45:35 +03:00
..
2026-07-12 11:01:51 +03:00
2026-07-12 11:01:51 +03:00
2026-07-12 11:01:51 +03:00
2026-07-12 11:01:51 +03:00
2026-07-12 11:01:51 +03:00

GPS RTL

Take Ankasys_Pulpissimo_SoC/pulpissimo/rtl/gps_system/hdl folder from Ankasys_Pulpissimo_SoC svn repo, it has these subfolders:

common: common header & hdl modules used in both acq and trcq ips.

apb_wrappers: apb wrapper interface ips for each trck and acq ips.

trck_src: trcking top and instantiated sub ips hdl codes from Hilal & Ahmet's implementations. trck_src/pulp_fifo: added manually from gps_hw svn repo, svn info is shared below.*

acq_src: acqusition top and instantiated sub ips hdl codes from Hilal & Ahmet's implementations.

20 ms Tracking Measurement Mailbox

Her tracking kanali, decode edilen her GPS L1 C/A navigation biti icin bir atomik olcum uretir. Veri yolu:

1 ms prompt I/Q
    -> tracking_measurement (20 ornek akumulasyonu ve snapshot)
    -> tracking clock domaininde 20 ms sabit payload
    -> her alan icin iki FF senkronizer
    -> iki tam PCLK settle cevrimi
    -> tracking_wrapper APB register bankasi
    -> measurement flag/interrupt
    -> bare-metal software

trck_src/tracking_measurement.sv bir bit boyunca su degerleri toplar:

sum_i = sum(I_prompt)
sum_q = sum(Q_prompt)
wbp   = sum(I_prompt^2 + Q_prompt^2)
M     = 20 adet 1 ms prompt ornegi

Prompt enerji karesi lock detector'daki mevcut multiplier sonucundan alinir; ayni is icin ikinci bir multiplier/DSP yolu acilmaz. Bit epoch'unda total carrier NCO frekansi Q7 formatinda, absolute sample, remaining-code phase, navigation bit ve 16-bit sequence degeriyle birlikte snapshot edilir. Payload bir sonraki bit olcumune kadar degismez.

Bu arayuz bir event FIFO'su degildir. Kaynak veri en az bir 20 ms bit boyunca sabit kaldigi icin wrapper her multi-bit alani mevcut double_ff_syn yapisindan gecirir, senkronize valid rising edge'inden sonra iki tam PCLK cevrimi bekler ve butun bankayi tek seferde register eder. Measurement interrupt'i APB snapshot'tan bir PCLK sonra uretilir; software interrupt'a girdiginde veri ve status stabildir. Software yine de coherent read icin sequence degerini payload'dan once ve sonra okuyup esitligini kontrol eder.

APB registerlari

Offset Alan Aciklama
0x50 MEASUREMENT_META [31:24]=version(1), [12:8]=M, bit 2 lock, bit 1 NAV bit, bit 0 valid
0x54 MEASUREMENT_SEQUENCE 16-bit, her 20 ms olcumde artar
0x58 MEASUREMENT_CARRIER_Q7 Signed total carrier NCO frekansi, Hz icin /128
0x5c MEASUREMENT_ABS_SAMPLE Olcum epoch absolute sample
0x60 MEASUREMENT_REM_CODE_PHASE 26-bit remaining-code residue
0x64 MEASUREMENT_SUM_I Signed coherent prompt-I toplami
0x68 MEASUREMENT_SUM_Q Signed coherent prompt-Q toplami
0x6c MEASUREMENT_WBP_LO Wideband power alt 32 bit
0x70 MEASUREMENT_WBP_HI Wideband power ust bitleri
0x74 NAV_SOLVE_PHASE_SEED Warm/hot reacquisition icin navigation-bit fazi

CONTROL_REG bit 13 measurement interrupt enable, bit 14 measurement flag enable'dir. STATUS_REG bit 7 measurement flag'dir. Genel interrupt clear islemi bu flag'i de temizler.

NAV solve phase seed (warm/hot reacquisition)

nav_solve_timer normalde IDLE'dan yalniz subframe_ready ile cikar ve fazini HOW Z-count'tan (Z * 300) mod N olarak hesaplar. Kanal yeniden kilitlendiginde trck_busy dustugu icin timer IDLE'a doner; yani bir uydu geri geldiginde ephemeris RAM cache'te hazir olsa bile yeni bir subframe cozulene kadar (en fazla 6 s) hic NAV solve pulse'i uretilmez.

Bunun icin NAV_SOLVE_PHASE_SEED (0x74) ve CONTROL_REG bit 15 (TRCK_NAV_SOLVE_SEED_ARM) eklendi. Software once fazi yazar, sonra arm bitini set eder.

Seed anlami: seed, timer istegi tukettikten sonra gelen bir sonraki navigation bitinde gecerli olacak sayac degeridir. Donanim sayac N-1 iken epoch uretir, dolayisiyla:

seed = (bir sonraki navigation bitinin mutlak indeksi) mod N

Bu, subframe yolunun urettigi izgaranin aynisidir: Z * 300 zaten subframe sinirindan sonraki ilk bitin mutlak indeksidir. Iki yol da (b + 1) mod N == 0 olan mutlak bit indekslerine dusen tek bir global izgara uretir.

Donanim garantileri (her biri gps_timer/tb/nav_solve_timer_seed_tb.sv icinde bir test ile karsilanir):

  • Arm istegi her state'te bir cevrimde cevaplanir ve phase_seed_consumed ile temizlenir; boylece bir seed sonraki bir reacquisition'a tasinmaz.
  • Seed yalniz IDLE'da uygulanir; ayni cevrimde gelen subframe_ready kazanir.
  • phase_seed_value >= counter_max_val ise seed reddedilir (yanlis izgaraya alias yapilmaz), ama arm biti yine temizlenir; software beklemede kalmaz.
  • Seed ile baslayan kanal STATUS_REG bit 8 (TRCK_NAV_SOLVE_PROVISIONAL) ile isaretlenir. Ilk cozulen subframe otoriter HOW hizalamasini tekrar calistirir ve bu biti temizler: yanlis bir seed en fazla bir subframe icinde kendini duzeltir.
  • trck_busy dustugunde timer IDLE'a doner ve provisional temizlenir.

Bu register'i olmayan eski bir bitstream'e karsi yazmak APB default case'ine duser ve PSLVERR uretir; TLToAPB bunu denied olarak dondurdugu icin Rocket store access fault alabilir. Bu yuzden firmware tarafinda GPS_WARM_SEED_ENABLE=0 build secenegi vardir.

Neden Doppler IIR RTL'de degil?

IIR RTL'de de uygulanabilir; her kanal icin onceki Doppler state'i, signed coefficient multiply, rounding/saturation ve reacquisition reset kurali eklenmesi yeterlidir. Mevcut tasarimda bilerek software'de tutulur:

  • APB bankasi ham ve tekrar analiz edilebilir carrier olcumunu korur.
  • Filtre katsayisi hareket profiline gore bitstream almadan degistirilebilir.
  • C/N0, satellite state ve WLS zaten software'de hesaplanir.
  • Filtre veri/interrupt hizini azaltmaz; measurement yine 50 Hz'dir.
  • Kart testinde kesintisiz kosuda measurement missed, invalid ve event overflow sayaclari sifir kalmistir; CPU veya CDC baskisi RTL filtresi gerektirmemistir.

RTL filtresi ancak bu ham register sozlesmesinin yaninda ikinci bir filtered alan istenirse, olcum tamamen donanim icinde tuketilecekse veya software latency/CPU butcesi kart testinde yetersiz kalirsa anlamli olur.

RTL dogrulama

Questa testleri:

make -C hardware/external/gps/rtl/trck_src/tb test

Testler prompt enerjisini, 20-ornek akumulasyonunu, iki ard arda bit epoch'unu, 20 ms hold davranisini, double-FF + settle + atomik APB capture'i ve interrupt/status-clear yolunu kontrol eder.

SVN Revision

svn info Path: . Working Copy Root Path: /storage/projects/gnss_soc/Ankasys_Pulpissimo_SoC URL: svn://192.168.1.46/Ankasys_Pulpissimo_SoC Repository Root: svn://192.168.1.46/Ankasys_Pulpissimo_SoC Repository UUID: e6ee3b13-bfec-4c27-9df0-a71801fb71fc Revision: 111 Node Kind: directory Schedule: normal Last Changed Author: ankaoc Last Changed Rev: 111 Last Changed Date: 2025-07-18 15:33:18 +0300 (Fri, 18 Jul 2025)

SVN Revision of gps_hw*

svn info Path: . Working Copy Root Path: /storage/projects/gnss_soc/gps_hw URL: svn://192.168.1.46/gps_hw Repository Root: svn://192.168.1.46/gps_hw Repository UUID: f2c31683-5921-4142-8047-6a984122e95c Revision: 89 Node Kind: directory Schedule: normal Last Changed Author: ankaaa Last Changed Rev: 89 Last Changed Date: 2025-07-08 14:20:14 +0300 (Tue, 08 Jul 2025)