Support embedded-time without Error trait

embedded-time-no-error-trait
Diego Barrios Romero 2020-07-17 22:38:11 +02:00
parent 2799590575
commit e4fdd1a882
4 changed files with 103 additions and 1 deletions

View File

@ -27,6 +27,7 @@ coveralls = { repository = "eldruin/ds323x-rs", branch = "master", service = "gi
[dependencies] [dependencies]
embedded-hal = "0.2.3" embedded-hal = "0.2.3"
rtcc = "0.2" rtcc = "0.2"
embedded-time = "0.7.1"
[dev-dependencies] [dev-dependencies]
linux-embedded-hal = "0.3" linux-embedded-hal = "0.3"
@ -34,3 +35,6 @@ embedded-hal-mock = "0.7"
[profile.release] [profile.release]
lto = true lto = true
[patch.crates-io]
embedded-time = { git="https://github.com/eldruin/embedded-time.git", branch="remove-error-trait" }

View File

@ -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::<Hours>().unwrap();
println!("Hours since epoch: {}", hours_since_epoch);
let _dev = rtc.into_inner().destroy_ds3231();
}

View File

@ -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<CommE, PinE> {
/// Device could not be acquired. It may be already acquired.
CouldNotAcquireDevice,
/// Other error
Other(Error<CommE, PinE>),
}
/// Wrapper around `Ds323x` driver to support `embedded-time`.
pub struct Ds323xWrapper<DI, IC> {
dev: RefCell<Ds323x<DI, IC>>,
}
impl<CommE, PinE, DI, IC> Clock for Ds323xWrapper<DI, IC>
where
DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
{
/// Number of non-leap-seconds since January 1, 1970 UTC
type Rep = u64;
const PERIOD: Period = Period::new(1, 1);
type ImplError = WrapperError<CommE, PinE>;
fn now(&self) -> Result<Instant<Self>, clock::Error<Self::ImplError>> {
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<CommE, PinE, DI, IC> From<Ds323x<DI, IC>> for Ds323xWrapper<DI, IC>
where
DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
{
fn from(dev: Ds323x<DI, IC>) -> Self {
Ds323xWrapper {
dev: RefCell::new(dev),
}
}
}
impl<DI, IC> Ds323xWrapper<DI, IC> {
/// Return inner `Ds323x` driver instance.
pub fn into_inner(self) -> Ds323x<DI, IC> {
self.dev.into_inner()
}
}
/*
impl<CommE, PinE, DI, IC> Ds323xWrapper<DI, IC>
where
DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
{
/// Run function on mutable borrowed inner device
pub fn do_on_borrow_mut<R>(
&self,
f: impl FnOnce(RefMut<Ds323x<DI, IC>>) -> Result<R, Error<CommE, PinE>>,
) -> Result<R, WrapperError<CommE, PinE>> {
let dev = self
.dev
.try_borrow_mut()
.map_err(|_| WrapperError::<CommE, PinE>::CouldNotAcquireDevice)?;
f(dev).map_err(WrapperError::Other)
}
}
*/

View File

@ -400,7 +400,7 @@ pub const SPI_MODE_1: Mode = MODE_1;
pub const SPI_MODE_3: Mode = MODE_3; pub const SPI_MODE_3: Mode = MODE_3;
/// All possible errors in this crate /// All possible errors in this crate
#[derive(Debug)] #[derive(Debug, PartialEq, Eq)]
pub enum Error<CommE, PinE> { pub enum Error<CommE, PinE> {
/// I²C/SPI bus error /// I²C/SPI bus error
Comm(CommE), Comm(CommE),
@ -514,6 +514,8 @@ pub use crate::ds323x::{
mod ds3231; mod ds3231;
mod ds3232; mod ds3232;
mod ds3234; mod ds3234;
mod embedded_time;
pub use crate::embedded_time::{Ds323xWrapper, WrapperError};
mod private { mod private {
use super::{ic, interface}; use super::{ic, interface};