diff --git a/src/ds323x/datetime.rs b/src/ds323x/datetime.rs index 6f0b390..17e250d 100644 --- a/src/ds323x/datetime.rs +++ b/src/ds323x/datetime.rs @@ -4,6 +4,25 @@ extern crate embedded_hal as hal; use super::super::{ Ds323x, Register, BitFlags, Error }; use interface::{ ReadData, WriteData }; +/// Date and time +#[derive(Debug, Clone, PartialEq)] +pub struct DateTime { + /// Year [2000-2099] + pub year : u16, + /// Month [1-12] + pub month : u8, + /// Day [1-31] + pub day : u8, + /// Weekday [1-7] + pub weekday : u8, + /// Hour in 24h/12h format + pub hour : Hours, + /// Minute [0-59] + pub minute : u8, + /// Second [0-59] + pub second : u8, +} + /// Hours in either 12-hour (AM/PM) or 24-hour format #[derive(Debug, Clone, PartialEq)] pub enum Hours { @@ -59,6 +78,20 @@ where self.iface.read_data(&mut data)?; Ok(year_from_registers(data[1], data[2])) } + + /// Read the date and time. + pub fn get_datetime(&mut self) -> Result> { + let mut data = [0; 8]; + self.iface.read_data(&mut data)?; + Ok(DateTime { + year: year_from_registers(data[Register::MONTH as usize + 1], data[Register::YEAR as usize + 1]), + month: packed_bcd_to_decimal(data[Register::MONTH as usize + 1] & !BitFlags::CENTURY), + day: packed_bcd_to_decimal(data[Register::DOM as usize + 1]), + weekday: packed_bcd_to_decimal(data[Register::DOW as usize + 1]), + hour: hours_from_register(data[Register::HOURS as usize + 1]), + minute: packed_bcd_to_decimal(data[Register::MINUTES as usize + 1]), + second: packed_bcd_to_decimal(data[Register::SECONDS as usize + 1]) + }) } fn read_register_decimal(&mut self, register: u8) -> Result> { diff --git a/src/ds323x/mod.rs b/src/ds323x/mod.rs index 6de57ea..aae4efd 100644 --- a/src/ds323x/mod.rs +++ b/src/ds323x/mod.rs @@ -1,2 +1,2 @@ mod datetime; -pub use self::datetime::Hours; +pub use self::datetime::{ Hours, DateTime }; diff --git a/src/lib.rs b/src/lib.rs index d014de0..9fe6c5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -188,6 +188,7 @@ impl Register { const DOW : u8 = 0x03; const DOM : u8 = 0x04; const MONTH : u8 = 0x05; + const YEAR : u8 = 0x06; } struct BitFlags; @@ -282,4 +283,4 @@ where } mod ds323x; -pub use ds323x::Hours; +pub use ds323x::{ Hours, DateTime }; diff --git a/tests/ds323x.rs b/tests/ds323x.rs index 5a68840..d9c6f5a 100644 --- a/tests/ds323x.rs +++ b/tests/ds323x.rs @@ -7,7 +7,7 @@ mod common; use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, new_ds3231, new_ds3232, new_ds3234 }; extern crate ds323x; -use ds323x::{ Hours, Error }; +use ds323x::{ Hours, DateTime, Error }; macro_rules! _get_param_test { ($method:ident, $value:expr, $i2c_transactions:expr, $spi_transactions:expr) => { @@ -26,10 +26,10 @@ macro_rules! get_param_test { } macro_rules! get_param_read_array_test { - ($method:ident, $value:expr, $register1:ident, [ $( $bin:expr ),+ ]) => { + ($method:ident, $value:expr, $register1:ident, [ $( $bin:expr ),+ ], [ $( $bin2:expr ),+ ]) => { _get_param_test!($method, $value, [ I2cTrans::write_read(DEV_ADDR, vec![Register::$register1], vec![$( $bin ),*]) ], - [ SpiTrans::transfer(vec![Register::$register1, 0, 0], vec![Register::$register1, $( $bin ),*]) ]); + [ SpiTrans::transfer(vec![Register::$register1, $( $bin2 ),*], vec![Register::$register1, $( $bin ),*]) ]); }; } @@ -159,14 +159,23 @@ mod year { use super::*; mod century0 { use super::*; - get_param_read_array_test!(get_year, 2099, MONTH, [ 0, 0b1001_1001 ]); + get_param_read_array_test!(get_year, 2099, MONTH, [ 0, 0b1001_1001 ], [0, 0]); read_set_param_write_two_test!(set_year, 2099, MONTH, 0b1001_0010, 0b0001_0010, 0b1001_1001); } mod century1 { use super::*; - get_param_read_array_test!(get_year, 2100, MONTH, [ 0b1000_0000, 0 ]); + get_param_read_array_test!(get_year, 2100, MONTH, [ 0b1000_0000, 0 ], [0, 0]); read_set_param_write_two_test!(set_year, 2100, MONTH, 0b0001_0010, 0b1001_0010, 0); } set_invalid_param_range_test!(set_year, 1999, 2101); } + +mod datetime { + use super::*; + const DT : DateTime = DateTime { year: 2018, month: 8, day: 13, weekday: 2, + hour: Hours::H24(23), minute: 59, second: 58 }; + get_param_read_array_test!(get_datetime, DT, SECONDS, + [0b0101_1000, 0b0101_1001, 0b0010_0011, 0b0000_0010, + 0b0001_0011, 0b0000_1000, 0b0001_1000], + [0, 0, 0, 0, 0, 0, 0]); }