From db87f18fca1218f91f0731c52942112f9fd09b37 Mon Sep 17 00:00:00 2001 From: Sachymetsu Date: Wed, 24 Dec 2025 09:47:17 +0000 Subject: [PATCH] Differential timestamp generation --- src/detector.rs | 11 +++------- src/rtc.rs | 56 ++++++++++++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/detector.rs b/src/detector.rs index 3c3f963..ce140d6 100644 --- a/src/detector.rs +++ b/src/detector.rs @@ -4,7 +4,6 @@ mod data; use core::cell::Cell; use alloc::vec::Vec; -use chrono::TimeDelta; use sachy_fmt::{info, unwrap}; use embassy_futures::select::select3; @@ -148,13 +147,9 @@ impl Detector<'_> { data: &mut Sender<'static, NoopRawMutex, (i64, Vec)>, rtc: GlobalRtc<'static>, ) { - let time = unwrap!(rtc.get_timestamp().await, "Unable to get timestamp").and_utc(); - let now = Instant::now(); - loop { let (timestamp, buf) = data.send().await; - let elapsed = now.elapsed().as_micros() as i64; - *timestamp = (time + TimeDelta::microseconds(elapsed)).timestamp(); + *timestamp = rtc.get_timestamp().await.timestamp(); self.adc.sample(buf).await; data.send_done(); } @@ -235,8 +230,8 @@ impl Detector<'_> { } None => { if let Some(net_data) = self.get_data_channel() { - let now = unwrap!(rtc.get_timestamp().await, "Unable to get timestamp"); - data::transmit_level_update(now.and_utc().timestamp(), decay, net_data); + let now = rtc.get_timestamp().await; + data::transmit_level_update(now.timestamp(), decay, net_data); } } _ => continue, diff --git a/src/rtc.rs b/src/rtc.rs index cd5d504..9bdee5e 100644 --- a/src/rtc.rs +++ b/src/rtc.rs @@ -1,52 +1,53 @@ #![allow(dead_code)] -use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike}; +use chrono::{DateTime as ChronoTime, Datelike, TimeDelta, Timelike, Utc}; use embassy_rp::{ peripherals, rtc::{DateTime, DateTimeError, DayOfWeek, Rtc, RtcError}, }; use embassy_sync::mutex::Mutex; +use embassy_time::Instant; use sachy_fmt::unwrap; use sachy_sntp::SntpTimestamp; use static_cell::StaticCell; use crate::locks::RtcLock; +struct RtcInner<'device> { + rtc: Rtc<'device, peripherals::RTC>, + timestamp: ChronoTime, + offset: Instant, +} + #[derive(Clone, Copy)] -pub struct GlobalRtc<'device>(&'device Mutex>); +pub struct GlobalRtc<'device>(&'device Mutex>); impl GlobalRtc<'static> { pub fn init(rtc: Rtc<'static, peripherals::RTC>) -> Self { - static RTC: StaticCell>> = StaticCell::new(); - - Self(&*RTC.init_with(|| Mutex::new(rtc))) + static RTC: StaticCell>> = StaticCell::new(); + + Self(&*RTC.init_with(|| { + Mutex::new(RtcInner { + rtc, + timestamp: Default::default(), + offset: Instant::MIN, + }) + })) } } impl GlobalRtc<'_> { pub async fn is_running(&self) -> bool { - let rtc = self.0.lock().await; + let inner = self.0.lock().await; - rtc.is_running() + inner.rtc.is_running() } - pub async fn get_timestamp(&self) -> Result { - let rtc = self.0.lock().await; - - let now = rtc.now()?; + pub async fn get_timestamp(&self) -> ChronoTime { + let inner = self.0.lock().await; - let date = unwrap!(NaiveDate::from_ymd_opt( - now.year as i32, - now.month as u32, - now.day as u32 - )); - let time = unwrap!(NaiveTime::from_hms_opt( - now.hour as u32, - now.minute as u32, - now.second as u32 - )); - - Ok(NaiveDateTime::new(date, time)) + let elapsed = inner.offset.elapsed().as_micros() as i64; + inner.timestamp + TimeDelta::microseconds(elapsed) } pub async fn set_rtc_datetime(&self, timestamp: SntpTimestamp) -> Result<(), RtcError> { @@ -57,6 +58,8 @@ impl GlobalRtc<'_> { return Err(RtcError::InvalidDateTime(DateTimeError::InvalidYear)); } + let ms = timestamp.and_utc(); + let timestamp: DateTime = DateTime { year: year as u16, month: timestamp.month() as u8, @@ -75,8 +78,9 @@ impl GlobalRtc<'_> { second: timestamp.second() as u8, }; - let mut rtc = self.0.lock().await; - - rtc.set_datetime(timestamp) + let mut inner = self.0.lock().await; + inner.offset = Instant::now(); + inner.timestamp = ms; + inner.rtc.set_datetime(timestamp) } } -- 2.51.2