From 45e7d6de3cb09d7b722bfcbc5b47d2cd42a3ca51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Tue, 26 Jan 2021 22:30:46 +0100 Subject: [PATCH] rpll: auto-align counter --- dsp/src/rpll.rs | 18 ++++++++++++++---- src/bin/lockin.rs | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/dsp/src/rpll.rs b/dsp/src/rpll.rs index 2bfd29c..292c523 100644 --- a/dsp/src/rpll.rs +++ b/dsp/src/rpll.rs @@ -18,14 +18,12 @@ impl RPLL { /// /// Args: /// * dt2: inverse update() rate. 1 << dt2 is the counter rate to update() rate ratio. - /// * t: Counter time. Counter value at the first update() call. Typically 0. /// /// Returns: /// Initialized RPLL instance. - pub fn new(dt2: u8, t: i32) -> RPLL { + pub fn new(dt2: u8) -> RPLL { RPLL { dt2, - t, ..Default::default() } } @@ -69,7 +67,19 @@ impl RPLL { // Update frequency lock self.ff = self.ff.wrapping_add(p_ref.wrapping_sub(p_sig)); // Time in counter cycles between timestamp and "now" - let dt = self.t.wrapping_sub(x); + let mut dt = self.t.wrapping_sub(x); + + if dt < 0 { + // Timestamp is in the future + // Advance phase and time until we are just past the most recent + // timestamp. + let mut dt_ceil = dt >> self.dt2; + self.y = self.y.wrapping_sub(self.f.wrapping_mul(dt_ceil)); + dt_ceil <<= self.dt2; + self.t = self.t.wrapping_sub(dt_ceil); + dt = dt.wrapping_sub(dt_ceil); + } + // Reference phase estimate "now" let y_ref = (self.f >> self.dt2).wrapping_mul(dt); // Phase error diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index 7066ad8..1c2aa1f 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -53,7 +53,7 @@ const APP: () = { // Configure the microcontroller let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); - let pll = RPLL::new(ADC_SAMPLE_TICKS_LOG2 + SAMPLE_BUFFER_SIZE_LOG2, 0); + let pll = RPLL::new(ADC_SAMPLE_TICKS_LOG2 + SAMPLE_BUFFER_SIZE_LOG2); let lockin = Lockin::new( &iir_int::IIRState::lowpass(1e-3, 0.707, 2.), // TODO: expose