From e7c41a64241d50a3a604660af56f2ddcccfee847 Mon Sep 17 00:00:00 2001 From: Paul Bender Date: Fri, 10 Oct 2025 13:17:53 -0700 Subject: [PATCH] Generate error when century bit is set in functions already reading the century bit --- src/ds323x/datetime.rs | 56 ++++++++++++++++++++++++------------------ src/lib.rs | 5 ++++ tests/datetime.rs | 6 ----- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/ds323x/datetime.rs b/src/ds323x/datetime.rs index 1a48e4c..3491ea7 100644 --- a/src/ds323x/datetime.rs +++ b/src/ds323x/datetime.rs @@ -19,11 +19,13 @@ where let mut data = [0; 8]; self.iface.read_data(&mut data)?; - let year = year_from_registers( - data[Register::MONTH as usize + 1], - data[Register::YEAR as usize + 1], - ); - let month = packed_bcd_to_decimal(data[Register::MONTH as usize + 1] & !BitFlags::CENTURY); + let century = data[Register::MONTH as usize + 1] & BitFlags::CENTURY; + if century != 0 { + return Err(Error::InvalidDeviceCentury); + } + + let year = 2000 + (packed_bcd_to_decimal(data[Register::YEAR as usize + 1]) as u16); + let month = packed_bcd_to_decimal(data[Register::MONTH as usize + 1]); let day = packed_bcd_to_decimal(data[Register::DOM as usize + 1]); let hour = hours_from_register(data[Register::HOURS as usize + 1]); let minute = packed_bcd_to_decimal(data[Register::MINUTES as usize + 1]); @@ -91,15 +93,28 @@ where fn month(&mut self) -> Result { let data = self.iface.read_register(Register::MONTH)?; - let value = data & !BitFlags::CENTURY; - Ok(packed_bcd_to_decimal(value)) + + let century = data & BitFlags::CENTURY; + if century != 0 { + return Err(Error::InvalidDeviceCentury); + } + + Ok(packed_bcd_to_decimal(data)) } fn year(&mut self) -> Result { let mut data = [0; 3]; data[0] = Register::MONTH; self.iface.read_data(&mut data)?; - Ok(year_from_registers(data[1], data[2])) + + let century = data[1] & BitFlags::CENTURY; + if century != 0 { + return Err(Error::InvalidDeviceCentury); + } + + let year = 2000 + (packed_bcd_to_decimal(data[2]) as u16); + + Ok(year) } fn date(&mut self) -> Result { @@ -108,12 +123,15 @@ where self.iface.read_data(&mut data)?; let offset = Register::DOM as usize; - let year = year_from_registers( - data[Register::MONTH as usize + 1 - offset], - data[Register::YEAR as usize + 1 - offset], - ); - let month = - packed_bcd_to_decimal(data[Register::MONTH as usize + 1 - offset] & !BitFlags::CENTURY); + + let century = data[Register::MONTH as usize + 1 - offset] & BitFlags::CENTURY; + if century != 0 { + return Err(Error::InvalidDeviceCentury); + } + + let year = + 2000 + (packed_bcd_to_decimal(data[Register::YEAR as usize + 1 - offset]) as u16); + let month = packed_bcd_to_decimal(data[Register::MONTH as usize + 1 - offset]); let day = packed_bcd_to_decimal(data[Register::DOM as usize + 1 - offset]); let date = NaiveDate::from_ymd_opt(year.into(), month.into(), day.into()); some_or_invalid_error(date) @@ -231,16 +249,6 @@ fn hours_from_register(data: u8) -> Hours { } } -fn year_from_registers(month: u8, year: u8) -> u16 { - let century = month & BitFlags::CENTURY; - let year = packed_bcd_to_decimal(year); - if century != 0 { - 2100 + u16::from(year) - } else { - 2000 + u16::from(year) - } -} - fn is_24h_format(hours_data: u8) -> bool { hours_data & BitFlags::H24_H12 == 0 } diff --git a/src/lib.rs b/src/lib.rs index 5efa490..f98afda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -388,6 +388,11 @@ pub enum Error { /// It was not possible to read a valid date and/or time. /// The device is probably missing initialization. InvalidDeviceState, + /// Device century is not the 20th century. + /// + /// The device does not produce valid dates for centuries + /// other than the 20th century. + InvalidDeviceCentury, } /// Square-wave output frequency diff --git a/tests/datetime.rs b/tests/datetime.rs index eb465c3..ec88bdf 100644 --- a/tests/datetime.rs +++ b/tests/datetime.rs @@ -185,12 +185,6 @@ mod month { get_param_test!(get, month, MONTH, 1, 1); read_set_param_test!(set, set_month, MONTH, 12, 0b0000_0010, 0b0001_0010); set_invalid_param_range_test!(invalid, set_month, 0, 13); - - mod keeps_century { - use super::*; - get_param_test!(get, month, MONTH, 12, 0b1001_0010); - read_set_param_test!(set, set_month, MONTH, 12, 0b1000_0010, 0b1001_0010); - } } mod year {