use super::{decode_bcd, encode_bcd, I2c, BitFlags, Error, Register, DEVICE_ADDRESS, PCF8563};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct DateTime {
pub year: u8,
pub month: u8,
pub weekday: u8,
pub day: u8,
pub hours: u8,
pub minutes: u8,
pub seconds: u8,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Time {
pub hours: u8,
pub minutes: u8,
pub seconds: u8,
}
impl<I2C, E> PCF8563<I2C>
where
I2C: I2c<Error = E>,
{
pub fn get_datetime(&mut self) -> Result<DateTime, Error<E>> {
let mut data = [0; 7];
self.i2c
.write_read(DEVICE_ADDRESS, &[Register::VL_SECONDS], &mut data)
.map_err(Error::I2C)?;
Ok(DateTime {
year: decode_bcd(data[6]),
month: decode_bcd(data[5] & 0x1f),
weekday: decode_bcd(data[4] & 0x07),
day: decode_bcd(data[3] & 0x3f),
hours: decode_bcd(data[2] & 0x3f),
minutes: decode_bcd(data[1] & 0x7f),
seconds: decode_bcd(data[0]),
})
}
pub fn set_datetime(&mut self, datetime: &DateTime) -> Result<(), Error<E>> {
if datetime.year > 99
|| datetime.month < 1
|| datetime.month > 12
|| datetime.weekday > 6
|| datetime.day < 1
|| datetime.month > 31
|| datetime.hours > 23
|| datetime.minutes > 59
|| datetime.seconds > 59
{
return Err(Error::InvalidInputData);
}
let payload = [
Register::VL_SECONDS, encode_bcd(datetime.seconds),
encode_bcd(datetime.minutes),
encode_bcd(datetime.hours),
encode_bcd(datetime.day),
encode_bcd(datetime.weekday),
encode_bcd(datetime.month), encode_bcd(datetime.year),
];
self.i2c.write(DEVICE_ADDRESS, &payload).map_err(Error::I2C)
}
pub fn set_time(&mut self, datetime: &Time) -> Result<(), Error<E>> {
if datetime.hours > 23 || datetime.minutes > 59 || datetime.seconds > 59 {
return Err(Error::InvalidInputData);
}
let payload = [
Register::VL_SECONDS, encode_bcd(datetime.seconds),
encode_bcd(datetime.minutes),
encode_bcd(datetime.hours),
];
self.i2c.write(DEVICE_ADDRESS, &payload).map_err(Error::I2C)
}
pub fn get_century_flag(&mut self) -> Result<u8, Error<E>> {
let flag = self.is_register_bit_flag_high(Register::CENTURY_MONTHS, BitFlags::C)?;
if flag {
Ok(1)
} else {
Ok(0)
}
}
pub fn set_century_flag(&mut self, century: u8) -> Result<(), Error<E>> {
match century {
0 => self.clear_register_bit_flag(Register::CENTURY_MONTHS, BitFlags::C),
1 => self.set_register_bit_flag(Register::CENTURY_MONTHS, BitFlags::C),
_ => return Err(Error::InvalidInputData),
}
}
}