timestamp: pass overflows to the top and ignore them there
This commit is contained in:
parent
4475a2d040
commit
854ed29b1a
|
@ -117,8 +117,14 @@ const APP: () = {
|
||||||
let iir_state = c.resources.iir_state;
|
let iir_state = c.resources.iir_state;
|
||||||
let lockin = c.resources.lockin;
|
let lockin = c.resources.lockin;
|
||||||
|
|
||||||
|
let t = c
|
||||||
|
.resources
|
||||||
|
.timestamper
|
||||||
|
.latest_timestamp()
|
||||||
|
.unwrap_or_else(|t| t) // Ignore timer capture overflows.
|
||||||
|
.map(|t| t as i32);
|
||||||
let (pll_phase, pll_frequency) = c.resources.pll.update(
|
let (pll_phase, pll_frequency) = c.resources.pll.update(
|
||||||
c.resources.timestamper.latest_timestamp().map(|t| t as i32),
|
t,
|
||||||
22, // frequency settling time (log2 counter cycles), TODO: expose
|
22, // frequency settling time (log2 counter cycles), TODO: expose
|
||||||
22, // phase settling time, TODO: expose
|
22, // phase settling time, TODO: expose
|
||||||
);
|
);
|
||||||
|
|
|
@ -62,15 +62,12 @@ impl InputStamper {
|
||||||
/// Get the latest timestamp that has occurred.
|
/// Get the latest timestamp that has occurred.
|
||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
/// This function must be called sufficiently often. If an over-capture event occurs, this
|
/// This function must be called at least as often as timestamps arrive.
|
||||||
/// function will panic, as this indicates a timestamp was inadvertently dropped.
|
/// If an over-capture event occurs, this function will clear the overflow,
|
||||||
///
|
/// and return a new timestamp of unknown recency an `Err()`.
|
||||||
/// To prevent timestamp loss, the batch size and sampling rate must be adjusted such that at
|
/// Note that this indicates at least one timestamp was inadvertently dropped.
|
||||||
/// most one timestamp will occur in each data processing cycle.
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn latest_timestamp(&mut self) -> Option<u32> {
|
pub fn latest_timestamp(&mut self) -> Result<Option<u32>, Option<u32>> {
|
||||||
self.capture_channel
|
self.capture_channel.latest_capture()
|
||||||
.latest_capture()
|
|
||||||
.expect("DI0 timestamp overrun")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,28 +281,26 @@ macro_rules! timer_channels {
|
||||||
impl [< Channel $index InputCapture >] {
|
impl [< Channel $index InputCapture >] {
|
||||||
/// Get the latest capture from the channel.
|
/// Get the latest capture from the channel.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn latest_capture(&mut self) -> Result<Option<$size>, ()> {
|
pub fn latest_capture(&mut self) -> Result<Option<$size>, Option<$size>> {
|
||||||
// Note(unsafe): This channel owns all access to the specific timer channel.
|
// Note(unsafe): This channel owns all access to the specific timer channel.
|
||||||
// Only atomic operations on completed on the timer registers.
|
// Only atomic operations on completed on the timer registers.
|
||||||
let regs = unsafe { &*<$TY>::ptr() };
|
let regs = unsafe { &*<$TY>::ptr() };
|
||||||
let sr = regs.sr.read();
|
|
||||||
|
|
||||||
let result = if sr.[< cc $index if >]().bit_is_set() {
|
let result = if regs.sr.read().[< cc $index if >]().bit_is_set() {
|
||||||
// Read the capture value. Reading the captured value clears the flag in the
|
// Read the capture value. Reading the captured value clears the flag in the
|
||||||
// status register automatically.
|
// status register automatically.
|
||||||
let ccx = regs.[< ccr $index >].read();
|
Some(regs.[< ccr $index >].read().ccr().bits())
|
||||||
Some(ccx.ccr().bits())
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// Read SR again to check for a potential over-capture. If there is an
|
// Read SR again to check for a potential over-capture. If there is an
|
||||||
// overcapture, return an error.
|
// overcapture, return an error.
|
||||||
if regs.sr.read().[< cc $index of >]().bit_is_clear() {
|
if regs.sr.read().[< cc $index of >]().bit_is_set() {
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
regs.sr.modify(|_, w| w.[< cc $index of >]().clear_bit());
|
regs.sr.modify(|_, w| w.[< cc $index of >]().clear_bit());
|
||||||
Err(())
|
Err(result)
|
||||||
|
} else {
|
||||||
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue