From b191a3f01df139ef17ac3a9cfe951a2b8b7d47c8 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 7 Dec 2020 18:11:46 +0100 Subject: [PATCH] Updating timestamp timer to be more precise --- src/main.rs | 19 +++++++++++++------ src/timers.rs | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 425b401..2520ad9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -289,14 +289,21 @@ const APP: () = { let sampling_timer_channels = sampling_timer.channels(); let mut timestamp_timer = { - // TODO: This needs to be precisely controlled via the prescaler of the timer. - let timer5 = dp.TIM5.timer( - (SAMPLE_FREQUENCY_KHZ / SAMPLE_BUFFER_SIZE as u32).khz(), - ccdr.peripheral.TIM5, - &ccdr.clocks, + // The timer frequency is manually adjusted below, so the 1KHz setting here is a + // dont-care. + let timer5 = + dp.TIM5.timer(1.khz(), ccdr.peripheral.TIM5, &ccdr.clocks); + + // The time stamp timer must run at exactly a multiple of the sample timer based on the + // batch size. To accomodate this, we manually set the period identical to the sample + // timer, but use a prescaler that is `BATCH_SIZE` longer. + let mut timer = timers::TimestampTimer::new(timer5); + timer.set_period(sampling_timer.get_period()); + timer.set_prescaler( + sampling_timer.get_prescaler() * SAMPLE_BUFFER_SIZE as u16, ); - timers::TimestampTimer::new(timer5) + timer }; let timestamp_timer_channels = timestamp_timer.channels(); diff --git a/src/timers.rs b/src/timers.rs index 36f8c01..a3c2dce 100644 --- a/src/timers.rs +++ b/src/timers.rs @@ -32,8 +32,36 @@ macro_rules! timer_channels { self.channels.take().unwrap() } - /// Start the sampling timer. - pub fn start(&mut self) { + #[allow(dead_code)] + pub fn get_prescaler(&self) -> u16 { + let regs = unsafe { &*hal::stm32::$TY::ptr() }; + regs.psc.read().psc().bits() + 1 + } + + #[allow(dead_code)] + pub fn set_prescaler(&mut self, prescaler: u16) { + let regs = unsafe { &*hal::stm32::$TY::ptr() }; + assert!(prescaler >= 1); + regs.psc.write(|w| w.psc().bits(prescaler - 1)); + } + + #[allow(dead_code)] + pub fn get_period(&self) -> u32 { + let regs = unsafe { &*hal::stm32::$TY::ptr() }; + regs.arr.read().arr().bits() + } + + #[allow(dead_code)] + pub fn set_period(&mut self, period: u32) { + let regs = unsafe { &*hal::stm32::$TY::ptr() }; + regs.arr.write(|w| w.arr().bits(period)); + } + + /// Start the timer. + pub fn start(mut self) { + // Force a refresh of the frequency settings. + self.timer.apply_freq(); + self.timer.reset_counter(); self.timer.resume(); }