From 2ba9e9c2f71f6ee781eb379865c71140d5f886cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Thu, 3 Jun 2021 07:57:18 +0000 Subject: [PATCH] pounder_timestamper: use input capture prescaler --- src/hardware/pounder/timestamp.rs | 14 +++++++++++--- src/hardware/timers.rs | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/hardware/pounder/timestamp.rs b/src/hardware/pounder/timestamp.rs index 1e8f862..a527f7f 100644 --- a/src/hardware/pounder/timestamp.rs +++ b/src/hardware/pounder/timestamp.rs @@ -22,10 +22,10 @@ ///! mode. As soon as the DMA transfer completes, the hardware automatically swaps over to a second ///! buffer to continue capturing. This alleviates timing sensitivities of the DMA transfer ///! schedule. +use crate::hardware::{design_parameters, timers}; +use core::convert::TryFrom; use stm32h7xx_hal as hal; -use crate::hardware::timers; - /// Software unit to timestamp stabilizer ADC samples using an external pounder reference clock. pub struct Timestamper { timer: timers::PounderTimestampTimer, @@ -64,9 +64,17 @@ impl Timestamper { timestamp_timer.set_trigger_source(timers::TriggerSource::Trigger1); // The capture channel should capture whenever the trigger input occurs. - let input_capture = capture_channel + let mut input_capture = capture_channel .into_input_capture(timers::tim8::CaptureSource1::TRC); + // Capture at the batch period. + input_capture.configure_prescaler( + timers::Prescaler::try_from( + design_parameters::SAMPLE_BUFFER_SIZE_LOG2, + ) + .unwrap(), + ); + Self { timer: timestamp_timer, capture_channel: input_capture, diff --git a/src/hardware/timers.rs b/src/hardware/timers.rs index 78d27b6..23e15ca 100644 --- a/src/hardware/timers.rs +++ b/src/hardware/timers.rs @@ -1,5 +1,6 @@ ///! The sampling timer is used for managing ADC sampling and external reference timestamping. use super::hal; +use num_enum::TryFromPrimitive; use hal::stm32::{ // TIM1 and TIM8 have identical registers. @@ -34,6 +35,8 @@ pub enum TriggerSource { /// Prescalers for externally-supplied reference clocks. #[allow(dead_code)] +#[derive(TryFromPrimitive)] +#[repr(u8)] pub enum Prescaler { Div1 = 0b00, Div2 = 0b01, @@ -353,6 +356,21 @@ macro_rules! timer_channels { let regs = unsafe { &*<$TY>::ptr() }; regs.[< $ccmrx _input >]().modify(|_, w| w.[< ic $index f >]().bits(filter as u8)); } + + /// Configure the input capture prescaler. + /// + /// # Args + /// * `psc` - Prescaler exponent. + #[allow(dead_code)] + pub fn configure_prescaler(&mut self, prescaler: super::Prescaler) { + // Note(unsafe): This channel owns all access to the specific timer channel. + // Only atomic operations on completed on the timer registers. + let regs = unsafe { &*<$TY>::ptr() }; + // Note(unsafe): Enum values are all valid. + #[allow(unused_unsafe)] + regs.[< $ccmrx _input >]().modify(|_, w| unsafe { + w.[< ic $index psc >]().bits(prescaler as u8)}); + } } // Note(unsafe): This manually implements DMA support for input-capture channels. This