From e4fdd1a8824a035699967ce689b868f760a386fc Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Fri, 17 Jul 2020 22:38:11 +0200 Subject: [PATCH] Support embedded-time without Error trait --- Cargo.toml | 4 ++ examples/embedded_time_linux.rs | 17 +++++++ src/embedded_time.rs | 79 +++++++++++++++++++++++++++++++++ src/lib.rs | 4 +- 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 examples/embedded_time_linux.rs create mode 100644 src/embedded_time.rs diff --git a/Cargo.toml b/Cargo.toml index c388af2..cbd9edd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ coveralls = { repository = "eldruin/ds323x-rs", branch = "master", service = "gi [dependencies] embedded-hal = "0.2.3" rtcc = "0.2" +embedded-time = "0.7.1" [dev-dependencies] linux-embedded-hal = "0.3" @@ -34,3 +35,6 @@ embedded-hal-mock = "0.7" [profile.release] lto = true + +[patch.crates-io] +embedded-time = { git="https://github.com/eldruin/embedded-time.git", branch="remove-error-trait" } \ No newline at end of file diff --git a/examples/embedded_time_linux.rs b/examples/embedded_time_linux.rs new file mode 100644 index 0000000..6ba0c09 --- /dev/null +++ b/examples/embedded_time_linux.rs @@ -0,0 +1,17 @@ +use ds323x::{Ds323x, Ds323xWrapper, NaiveDate, Rtcc}; +use embedded_time::{duration::units::Hours, Clock}; +use linux_embedded_hal::I2cdev; + +fn main() { + let dev = I2cdev::new("/dev/i2c-1").unwrap(); + let mut rtc = Ds323x::new_ds3231(dev); + let datetime = NaiveDate::from_ymd(2020, 5, 1).and_hms(19, 59, 58); + rtc.set_datetime(&datetime).unwrap(); + let rtc = Ds323xWrapper::from(rtc); + // do something else... + let instant = rtc.now().unwrap(); + let hours_since_epoch = instant.duration_since_epoch::().unwrap(); + println!("Hours since epoch: {}", hours_since_epoch); + + let _dev = rtc.into_inner().destroy_ds3231(); +} diff --git a/src/embedded_time.rs b/src/embedded_time.rs new file mode 100644 index 0000000..544a737 --- /dev/null +++ b/src/embedded_time.rs @@ -0,0 +1,79 @@ +//! embedded-time `Clock` implementation + +use crate::{ + interface::{ReadData, WriteData}, + Ds323x, Error, Rtcc, +}; +use core::cell::RefCell; +use core::convert::From; +use embedded_time::{clock, Clock, Instant, Period}; + +/// Wrapper error +#[derive(Debug)] +pub enum WrapperError { + /// Device could not be acquired. It may be already acquired. + CouldNotAcquireDevice, + /// Other error + Other(Error), +} + +/// Wrapper around `Ds323x` driver to support `embedded-time`. +pub struct Ds323xWrapper { + dev: RefCell>, +} + +impl Clock for Ds323xWrapper +where + DI: ReadData> + WriteData>, +{ + /// Number of non-leap-seconds since January 1, 1970 UTC + type Rep = u64; + const PERIOD: Period = Period::new(1, 1); + type ImplError = WrapperError; + + fn now(&self) -> Result, clock::Error> { + let datetime = self + .dev + .try_borrow_mut() + .map_err(|_| clock::Error::Other(Self::ImplError::CouldNotAcquireDevice))? + .get_datetime() + .map_err(|e| clock::Error::Other(Self::ImplError::Other(e)))?; + Ok(Instant::new((datetime.timestamp_millis() as u64) / 1_000)) + } +} + +impl From> for Ds323xWrapper +where + DI: ReadData> + WriteData>, +{ + fn from(dev: Ds323x) -> Self { + Ds323xWrapper { + dev: RefCell::new(dev), + } + } +} + +impl Ds323xWrapper { + /// Return inner `Ds323x` driver instance. + pub fn into_inner(self) -> Ds323x { + self.dev.into_inner() + } +} +/* +impl Ds323xWrapper +where + DI: ReadData> + WriteData>, +{ + /// Run function on mutable borrowed inner device + pub fn do_on_borrow_mut( + &self, + f: impl FnOnce(RefMut>) -> Result>, + ) -> Result> { + let dev = self + .dev + .try_borrow_mut() + .map_err(|_| WrapperError::::CouldNotAcquireDevice)?; + f(dev).map_err(WrapperError::Other) + } +} +*/ diff --git a/src/lib.rs b/src/lib.rs index 0639307..59b2c0d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -400,7 +400,7 @@ pub const SPI_MODE_1: Mode = MODE_1; pub const SPI_MODE_3: Mode = MODE_3; /// All possible errors in this crate -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub enum Error { /// I²C/SPI bus error Comm(CommE), @@ -514,6 +514,8 @@ pub use crate::ds323x::{ mod ds3231; mod ds3232; mod ds3234; +mod embedded_time; +pub use crate::embedded_time::{Ds323xWrapper, WrapperError}; mod private { use super::{ic, interface};