diff --git a/src/ds323x/alarms.rs b/src/ds323x/alarms.rs index 6507275..7b7c702 100644 --- a/src/ds323x/alarms.rs +++ b/src/ds323x/alarms.rs @@ -18,6 +18,19 @@ pub struct DateAlarm1 { pub second: u8 } +/// Parameters for setting Alarm1 on a weekday +#[derive(Debug, Clone, PartialEq)] +pub struct WeekdayAlarm1 { + /// Weekday [1-7] + pub weekday: u8, + /// Hour + pub hour: Hours, + /// Minute [0-59] + pub minute: u8, + /// Second [0-59] + pub second: u8 +} + /// Alarm1 trigger rate #[derive(Debug, Clone, PartialEq)] pub enum Alarm1Matching { @@ -68,4 +81,22 @@ where self.iface.write_data(&mut data) } + /// Set Alarm1 for weekday. + /// + /// Will return an `Error::InvalidInputData` if any of the parameters is out of range. + pub fn set_alarm1_weekday(&mut self, when: WeekdayAlarm1, matching: Alarm1Matching) -> Result<(), Error> { + if when.weekday < 1 || when.weekday > 7 || + when.minute > 59 || + when.second > 59 { + return Err(Error::InvalidInputData); + } + let match_mask = get_matching_mask_alarm1(matching); + let mut data = [ Register::ALARM1_SECONDS, + decimal_to_packed_bcd(when.second) | match_mask[0], + decimal_to_packed_bcd(when.minute) | match_mask[1], + hours_to_register(&when.hour)? | match_mask[2], + decimal_to_packed_bcd(when.weekday) | match_mask[3] | BitFlags::WEEKDAY]; + self.iface.write_data(&mut data) + } + } diff --git a/src/ds323x/mod.rs b/src/ds323x/mod.rs index 62a7570..a2e7d98 100644 --- a/src/ds323x/mod.rs +++ b/src/ds323x/mod.rs @@ -1,7 +1,7 @@ mod configuration; mod status; mod alarms; -pub use self::alarms::{ DateAlarm1, Alarm1Matching }; +pub use self::alarms::{ DateAlarm1, WeekdayAlarm1, Alarm1Matching }; mod datetime; pub use self::datetime::{ Hours, DateTime }; use super::{ BitFlags, Error }; diff --git a/src/lib.rs b/src/lib.rs index 9df2fe0..b15b257 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -474,6 +474,7 @@ impl BitFlags { const ALARM1F : u8 = 0b0000_0001; const TEMP_CONV_BAT : u8 = 0b0000_0001; const ALARM_MATCH : u8 = 0b1000_0000; + const WEEKDAY : u8 = 0b0100_0000; } const DEVICE_ADDRESS : u8 = 0b110_1000; @@ -500,7 +501,7 @@ pub struct Ds323x { pub mod interface; mod ds323x; -pub use ds323x::{ Hours, DateTime, DateAlarm1, Alarm1Matching }; +pub use ds323x::{ Hours, DateTime, DateAlarm1, WeekdayAlarm1, Alarm1Matching }; mod ds3231; mod ds3232; mod ds3234; diff --git a/tests/alarms.rs b/tests/alarms.rs index f5e344b..8636490 100644 --- a/tests/alarms.rs +++ b/tests/alarms.rs @@ -8,6 +8,7 @@ use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, new_ds3231, new_ds3232, new_ds3234, destroy_ds3231, destroy_ds3232, destroy_ds3234, BitFlags as BF }; extern crate ds323x; +use ds323x::{ DateAlarm1, WeekdayAlarm1, Alarm1Matching as A1M, Hours, Error }; use ds323x::{ DateAlarm1, Alarm1Matching as A1M, Hours, Error }; #[macro_export] @@ -44,6 +45,17 @@ mod alarm1 { set_invalid_alarm_test!(date_invalid_pm2, set_alarm1_date, DateAlarm1{ date: 1, hour: Hours::PM(13), minute: 1, second: 1 }, A1M::AllMatch); set_invalid_alarm_test!(date_invalid_d1, set_alarm1_date, DateAlarm1{ date: 0, hour: Hours::H24(1), minute: 1, second: 1 }, A1M::AllMatch); set_invalid_alarm_test!(date_invalid_d2, set_alarm1_date, DateAlarm1{ date: 32, hour: Hours::H24(1), minute: 1, second: 1 }, A1M::AllMatch); + + set_invalid_alarm_test!(wd_invalid_s, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::H24(1), minute: 1, second: 60 }, A1M::AllMatch); + set_invalid_alarm_test!(wd_invalid_min, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::H24(1), minute: 60, second: 1 }, A1M::AllMatch); + set_invalid_alarm_test!(wd_invalid_h, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::H24(24), minute: 1, second: 1 }, A1M::AllMatch); + set_invalid_alarm_test!(wd_invalid_am1, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::AM(0), minute: 1, second: 1 }, A1M::AllMatch); + set_invalid_alarm_test!(wd_invalid_am2, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::AM(13), minute: 1, second: 1 }, A1M::AllMatch); + set_invalid_alarm_test!(wd_invalid_pm1, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::PM(0), minute: 1, second: 1 }, A1M::AllMatch); + set_invalid_alarm_test!(wd_invalid_pm2, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::PM(13), minute: 1, second: 1 }, A1M::AllMatch); + set_invalid_alarm_test!(wd_invalid_d1, set_alarm1_weekday, WeekdayAlarm1{ weekday: 0, hour: Hours::H24(1), minute: 1, second: 1 }, A1M::AllMatch); + set_invalid_alarm_test!(wd_invalid_d2, set_alarm1_weekday, WeekdayAlarm1{ weekday: 32, hour: Hours::H24(1), minute: 1, second: 1 }, A1M::AllMatch); +} } macro_rules! _set_values_test { @@ -97,3 +109,22 @@ mod alarm1_date { set_alarm_test!(match_ops, set_alarm1_date, DateAlarm1{ date: 1, hour: Hours::H24(2), minute: 3, second: 4 }, A1M::OncePerSecond, ALARM1_SECONDS, [AM | 4, AM | 3, AM | 2, AM | 1]); } + +mod alarm1_weekday { + use super::*; + set_alarm_test!(h24, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, A1M::AllMatch, + ALARM1_SECONDS, [4, 3, 2, BF::WEEKDAY | 1]); + set_alarm_test!(am, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::AM(2), minute: 3, second: 4 }, A1M::AllMatch, + ALARM1_SECONDS, [4, 3, 0b0100_0010, BF::WEEKDAY | 1]); + set_alarm_test!(pm, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::PM(2), minute: 3, second: 4 }, A1M::AllMatch, + ALARM1_SECONDS, [4, 3, 0b0110_0010, BF::WEEKDAY | 1]); + + set_alarm_test!(match_hms, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, A1M::HoursMinutesAndSecondsMatch, + ALARM1_SECONDS, [ 4, 3, 2, AM | BF::WEEKDAY | 1]); + set_alarm_test!(match_ms, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, A1M::MinutesAndSecondsMatch, + ALARM1_SECONDS, [ 4, 3, AM | 2, AM | BF::WEEKDAY | 1]); + set_alarm_test!(match_s, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, A1M::SecondsMatch, + ALARM1_SECONDS, [ 4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1]); + set_alarm_test!(match_ops, set_alarm1_weekday, WeekdayAlarm1{ weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, A1M::OncePerSecond, + ALARM1_SECONDS, [AM | 4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1]); +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 7ec452c..46a031a 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -52,6 +52,7 @@ impl BitFlags { pub const ALARM1F : u8 = 0b0000_0001; pub const TEMP_CONV_BAT : u8 = 0b0000_0001; pub const ALARM_MATCH : u8 = 0b1000_0000; + pub const WEEKDAY : u8 = 0b0100_0000; } pub struct DummyOutputPin;