use crate::error::DriverError;
use crate::models::ClockData;
use crate::rtc::{address::SlaveAddress, registers as ClockRegisters};
use core::marker::PhantomData;
use embedded_hal::i2c::{I2c, SevenBitAddress};
pub mod address;
pub mod registers;
pub mod now;
pub mod update;
pub trait AddressingMode {
type Mode;
}
impl AddressingMode for SevenBitAddress {
type Mode = SevenBitAddress;
}
pub struct Driver<I2C, A> {
addr: u8,
i2c: I2C,
_addr_mode: core::marker::PhantomData<A>,
}
impl<I2C, A> Driver<I2C, A>
where
I2C: I2c<A::Mode>,
I2C::Error: Into<DriverError<I2C::Error>>,
A: AddressingMode<Mode = SevenBitAddress> + embedded_hal::i2c::AddressMode,
{
pub fn new(i2c: I2C) -> Self {
Driver {
addr: SlaveAddress::Default.into(),
i2c,
_addr_mode: PhantomData,
}
}
pub fn set_address(&mut self, addr: SlaveAddress) -> u8 {
self.addr = addr.into();
self.addr
}
pub fn free(self) -> I2C {
self.i2c
}
pub fn now(
&mut self,
mut rtc_chip: impl crate::rtc::now::Readable,
) -> Result<ClockData, DriverError<I2C::Error>>
where
I2C: I2c<SevenBitAddress>,
I2C::Error: Into<DriverError<I2C::Error>>,
{
let mut data = crate::models::ClockData::new();
rtc_chip.now(&mut self.i2c, self.addr, &mut data)?;
Ok(data)
}
pub fn update(
&mut self,
mut rtc_chip: impl crate::rtc::update::Updatable,
data: &Option<ClockData>,
) -> Result<impl crate::rtc::update::Updatable, DriverError<I2C::Error>>
where
I2C: I2c<SevenBitAddress>,
I2C::Error: Into<DriverError<I2C::Error>>,
{
let mut cu = ClockRegisters::new(self.addr);
if let Some(d) = data {
rtc_chip.set_datetime(&mut self.i2c, self.addr, &mut cu, d)?;
}
Ok(rtc_chip)
}
}
#[allow(dead_code)]
pub struct DriverAsync<I2C, A> {
addr: u8,
i2c: I2C,
_addr_mode: core::marker::PhantomData<A>,
}
impl<I2C, A> DriverAsync<I2C, A>
where
I2C: embedded_hal_async::i2c::I2c<A::Mode>,
I2C::Error: Into<DriverError<I2C::Error>>,
A: AddressingMode<Mode = SevenBitAddress> + embedded_hal_async::i2c::AddressMode,
{
#[allow(dead_code)]
pub fn new(i2c: I2C) -> Self {
DriverAsync {
addr: SlaveAddress::Default.into(),
i2c,
_addr_mode: PhantomData,
}
}
pub async fn get_year(&mut self, buf: u8) -> Result<(), DriverError<I2C::Error>> {
self.i2c.write_read(self.addr, &[0x06], &mut [buf]).await?;
Ok(())
}
}