From dfc98a6900703e0b37eb9ee90d7a6dfab08df00d Mon Sep 17 00:00:00 2001 From: Alexander Chemeris Date: Wed, 26 Jul 2017 22:03:20 +0300 Subject: [PATCH] zpu: More precision for GPSDO. Now we really get to +-1 Hz of the base TCXO frequency precision. Previously we ignored least significant bits of the frequency due to integer arithmetics rounding, which meant that we could get up to about 80 ppb of static frequency error which is not good enough for telco systems. --- zpu/lib/gpsdo.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/zpu/lib/gpsdo.c b/zpu/lib/gpsdo.c index 8157812a..d623b20e 100644 --- a/zpu/lib/gpsdo.c +++ b/zpu/lib/gpsdo.c @@ -148,7 +148,11 @@ _gpsdo_pid_step(int32_t val) /* Driver */ /* ------ */ -static int32_t g_val_lpf = PID_TARGET; +/* Extra bits of precision for g_val_lpf */ +#define VAL_LPF_PRECISION 3 +#define VAL_LPF_INIT_VALUE (PID_TARGET<csr & GPSDO_CSR_RDY) { /* Counter value */ - int32_t val = gpsdo_regs->cnt; + uint32_t val = gpsdo_regs->cnt; #ifdef GPSDO_DEBUG printf("GPSDO Count: %d\n", val); @@ -173,10 +177,12 @@ _gpsdo_irq_handler(unsigned irq) if (abs(val - PID_TARGET) < 100000) { /* LPF the value */ - g_val_lpf = (g_val_lpf * 7 + val + 4) >> 3; + /* Integer overlow warning! */ + /* This works for val ~= 52M, but don't try to use it with much larger values - it will overflow */ + g_val_lpf = (g_val_lpf * 7 + (val<> 3; /* Update PID */ - _gpsdo_pid_step(g_val_lpf); + _gpsdo_pid_step(g_val_lpf>>VAL_LPF_PRECISION); } } }