diff --git a/src/ds323x/alarms.rs b/src/ds323x/alarms.rs index 9774794..d5b91f2 100644 --- a/src/ds323x/alarms.rs +++ b/src/ds323x/alarms.rs @@ -5,6 +5,12 @@ use super::{decimal_to_packed_bcd, hours_to_register}; use interface::{ReadData, WriteData}; /// Parameters for setting Alarm1 on a day of the month +/// +/// Depending on the matching strategy, some fields may not be relevant. In this +/// case, invalid values are ignored and basic values are used instead to +/// configure the alarm: +/// - second, minute and hour : 0 +/// - day: 1 #[derive(Debug, Clone, Copy, PartialEq)] pub struct DayAlarm1 { /// Day of the month [1-31] @@ -18,6 +24,12 @@ pub struct DayAlarm1 { } /// Parameters for setting Alarm1 on a weekday +/// +/// Depending on the matching strategy, some fields may not be relevant. In this +/// case, invalid values are ignored and basic values are used instead to +/// configure the alarm: +/// - second, minute and hour : 0 +/// - weekday: 1 #[derive(Debug, Clone, Copy, PartialEq)] pub struct WeekdayAlarm1 { /// Weekday [1-7] @@ -46,6 +58,12 @@ pub enum Alarm1Matching { } /// Parameters for setting Alarm2 on a day of the month +/// +/// Depending on the matching strategy, some fields may not be relevant. In this +/// case, invalid values are ignored and basic values are used instead to +/// configure the alarm: +/// - minute and hour : 0 +/// - day: 1 #[derive(Debug, Clone, Copy, PartialEq)] pub struct DayAlarm2 { /// Day of month [1-31] @@ -57,6 +75,12 @@ pub struct DayAlarm2 { } /// Parameters for setting Alarm2 on a weekday +/// +/// Depending on the matching strategy, some fields may not be relevant. In this +/// case, invalid values are ignored and basic values are used instead to +/// configure the alarm: +/// - minute and hour : 0 +/// - weekday: 1 #[derive(Debug, Clone, Copy, PartialEq)] pub struct WeekdayAlarm2 { /// Weekday [1-7] @@ -101,92 +125,187 @@ fn get_matching_mask_alarm2(matching: Alarm2Matching) -> [u8; 3] { } } +/// Test if hours value is valid +/// +/// Will return true if valid, false if not +fn is_hour_valid(hours: Hours) -> bool { + match hours { + Hours::H24(h) if h > 23 => true, + Hours::AM(h) if h < 1 || h > 12 => true, + Hours::PM(h) if h < 1 || h > 12 => true, + _ => false, + } +} + +/// Relax the hour value by changing an incorrect value by 0 +fn relax_hour(hours: Hours) -> Hours { + match hours { + Hours::H24(h) if h > 23 => Hours::H24(0), + Hours::H24(h) => Hours::H24(h), + Hours::AM(h) if h < 1 || h > 12 => Hours::AM(1), + Hours::AM(h) => Hours::AM(h), + Hours::PM(h) if h < 1 || h > 12 => Hours::PM(1), + Hours::PM(h) => Hours::PM(h), + } +} + impl Ds323x where DI: ReadData> + WriteData>, { /// Set Alarm1 for day of the month. /// - /// Will return an `Error::InvalidInputData` if any of the parameters is out of range. + /// Will return an `Error::InvalidInputData` if any of the used parameters + /// (depending on the matching startegy) is out of range. Any unused + /// parameter is set to basic valid value: + /// - second, minute, hour: 0 + /// - day: 1 pub fn set_alarm1_day( &mut self, when: DayAlarm1, matching: Alarm1Matching, ) -> Result<(), Error> { - if when.day < 1 || when.day > 31 || when.minute > 59 || when.second > 59 { + let day_invalid = when.day < 1 || when.day > 31; + let hour_invalid = is_hour_valid(when.hour); + let minute_invalid = when.minute > 59; + let second_invalid = when.second > 59; + + let day = if day_invalid { 1 } else { when.day }; + let hour = relax_hour(when.hour); + let minute = if minute_invalid { 0 } else { when.minute }; + + if (matching == Alarm1Matching::AllMatch && (day_invalid || hour_invalid)) + || (hour_invalid && matching == Alarm1Matching::HoursMinutesAndSecondsMatch) + || ((matching != Alarm1Matching::SecondsMatch + && matching != Alarm1Matching::OncePerSecond) + && minute_invalid) + || second_invalid + { 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.day) | match_mask[3], + decimal_to_packed_bcd(minute) | match_mask[1], + hours_to_register(hour)? | match_mask[2], + decimal_to_packed_bcd(day) | match_mask[3], ]; self.iface.write_data(&mut data) } /// Set Alarm1 for weekday. /// - /// Will return an `Error::InvalidInputData` if any of the parameters is out of range. + /// Will return an `Error::InvalidInputData` if any of the used parameters + /// (depending on the matching startegy) is out of range. Any unused + /// parameter is set to basic valid value: + /// - second, minute, hour: 0 + /// - weekday: 1 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 { + let weekday_invalid = when.weekday < 1 || when.weekday > 7; + let hour_invalid = is_hour_valid(when.hour); + let minute_invalid = when.minute > 59; + let second_invalid = when.second > 59; + + let weekday = if weekday_invalid { 1 } else { when.weekday }; + let hour = relax_hour(when.hour); + let minute = if minute_invalid { 0 } else { when.minute }; + let second = if second_invalid { 0 } else { when.second }; + + if ((hour_invalid || weekday_invalid) && matching == Alarm1Matching::AllMatch) + || (hour_invalid && matching == Alarm1Matching::HoursMinutesAndSecondsMatch) + || (minute_invalid + && (matching != Alarm1Matching::OncePerSecond + && matching != Alarm1Matching::SecondsMatch)) + || (second_invalid && matching != Alarm1Matching::OncePerSecond) + { 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, + decimal_to_packed_bcd(second) | match_mask[0], + decimal_to_packed_bcd(minute) | match_mask[1], + hours_to_register(hour)? | match_mask[2], + decimal_to_packed_bcd(weekday) | match_mask[3] | BitFlags::WEEKDAY, ]; self.iface.write_data(&mut data) } /// Set Alarm2 for date (day of month). /// - /// Will return an `Error::InvalidInputData` if any of the parameters is out of range. + /// Will return an `Error::InvalidInputData` if any of the used parameters + /// (depending on the matching startegy) is out of range. Any unused + /// parameter is set to basic valid value: + /// - minute, hour: 0 + /// - day: 1 pub fn set_alarm2_day( &mut self, when: DayAlarm2, matching: Alarm2Matching, ) -> Result<(), Error> { - if when.day < 1 || when.day > 31 || when.minute > 59 { + let day_invalid = when.day < 1 || when.day > 31; + let hour_invalid = is_hour_valid(when.hour); + let minute_invalid = when.minute > 59; + + let day = if day_invalid { 1 } else { when.day }; + let hour = relax_hour(when.hour); + let minute = if minute_invalid { 0 } else { when.minute }; + + if ((day_invalid || hour_invalid) && matching == Alarm2Matching::AllMatch) + || (hour_invalid && matching == Alarm2Matching::HoursAndMinutesMatch) + || (matching != Alarm2Matching::OncePerMinute && minute_invalid) + { return Err(Error::InvalidInputData); } + let match_mask = get_matching_mask_alarm2(matching); let mut data = [ Register::ALARM2_MINUTES, - decimal_to_packed_bcd(when.minute) | match_mask[0], - hours_to_register(when.hour)? | match_mask[1], - decimal_to_packed_bcd(when.day) | match_mask[2], + decimal_to_packed_bcd(minute) | match_mask[0], + hours_to_register(hour)? | match_mask[1], + decimal_to_packed_bcd(day) | match_mask[2], ]; self.iface.write_data(&mut data) } /// Set Alarm2 for weekday. /// - /// Will return an `Error::InvalidInputData` if any of the parameters is out of range. + /// Will return an `Error::InvalidInputData` if any of the used parameters + /// (depending on the matching startegy) is out of range. Any unused + /// parameter is set to basic valid value: + /// - minute, hour: 0 + /// - weekday: 1 pub fn set_alarm2_weekday( &mut self, when: WeekdayAlarm2, matching: Alarm2Matching, ) -> Result<(), Error> { - if when.weekday < 1 || when.weekday > 7 || when.minute > 59 { + let weekday_invalid = when.weekday < 1 || when.weekday > 7; + let hour_invalid = is_hour_valid(when.hour); + let minute_invalid = when.minute > 59; + + let weekday = if weekday_invalid { 1 } else { when.weekday }; + let hour = relax_hour(when.hour); + let minute = if minute_invalid { 0 } else { when.minute }; + + if (matching == Alarm2Matching::AllMatch && (weekday_invalid || hour_invalid)) + || (matching == Alarm2Matching::HoursAndMinutesMatch && hour_invalid) + || (minute_invalid && matching != Alarm2Matching::OncePerMinute) + { return Err(Error::InvalidInputData); } let match_mask = get_matching_mask_alarm2(matching); let mut data = [ Register::ALARM2_MINUTES, - decimal_to_packed_bcd(when.minute) | match_mask[0], - hours_to_register(when.hour)? | match_mask[1], - decimal_to_packed_bcd(when.weekday) | match_mask[2] | BitFlags::WEEKDAY, + decimal_to_packed_bcd(minute) | match_mask[0], + hours_to_register(hour)? | match_mask[1], + decimal_to_packed_bcd(weekday) | match_mask[2] | BitFlags::WEEKDAY, ]; self.iface.write_data(&mut data) } diff --git a/tests/alarms.rs b/tests/alarms.rs index 6ebc786..c9f3908 100644 --- a/tests/alarms.rs +++ b/tests/alarms.rs @@ -14,18 +14,18 @@ use ds323x::{ #[macro_export] macro_rules! _set_invalid_alarm_test { - ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $alarm:expr, $matching:expr) => { + ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $( $value:expr ),+) => { #[test] fn $name() { let mut dev = $create_method(&[]); - assert_invalid_input_data!(dev.$method($alarm, $matching)); + assert_invalid_input_data!(dev.$method($($value),*)); $destroy_method(dev); } }; } macro_rules! set_invalid_alarm_test { - ($name:ident, $method:ident, $alarm:expr, $matching:expr) => { + ($name:ident, $method:ident, $( $value:expr ),+) => { mod $name { use super::*; _set_invalid_alarm_test!( @@ -33,24 +33,21 @@ macro_rules! set_invalid_alarm_test { $method, new_ds3231, destroy_ds3231, - $alarm, - $matching + $($value),* ); _set_invalid_alarm_test!( cannot_set_invalid_ds3232, $method, new_ds3232, destroy_ds3232, - $alarm, - $matching + $($value),* ); _set_invalid_alarm_test!( cannot_set_invalid_ds3234, $method, new_ds3234, destroy_ds3234, - $alarm, - $matching + $($value),* ); } }; @@ -80,6 +77,28 @@ mod alarm1 { }, A1M::AllMatch ); + set_invalid_alarm_test!( + day_invalid_second, + set_alarm1_day, + DayAlarm1 { + day: 1, + hour: Hours::H24(1), + minute: 59, + second: 60 + }, + A1M::SecondsMatch + ); + set_invalid_alarm_test!( + day_invalid_minute, + set_alarm1_day, + DayAlarm1 { + day: 1, + hour: Hours::H24(1), + minute: 60, + second: 10 + }, + A1M::MinutesAndSecondsMatch + ); set_invalid_alarm_test!( day_invalid_h, set_alarm1_day, @@ -91,6 +110,17 @@ mod alarm1 { }, A1M::AllMatch ); + set_invalid_alarm_test!( + day_invalid_h_hmasm, + set_alarm1_day, + DayAlarm1 { + day: 1, + hour: Hours::H24(24), + minute: 1, + second: 1 + }, + A1M::HoursMinutesAndSecondsMatch + ); set_invalid_alarm_test!( day_invalid_am1, set_alarm1_day, @@ -191,6 +221,18 @@ mod alarm1 { }, A1M::AllMatch ); + set_invalid_alarm_test!( + wd_invalid_h_hmasm, + set_alarm1_weekday, + WeekdayAlarm1 { + weekday: 1, + hour: Hours::H24(24), + minute: 1, + second: 1 + }, + A1M::HoursMinutesAndSecondsMatch + ); + set_invalid_alarm_test!( wd_invalid_am1, set_alarm1_weekday, @@ -257,10 +299,42 @@ mod alarm1 { }, A1M::AllMatch ); + set_invalid_alarm_test!( + wd_invalid_sec_sm, + set_alarm1_weekday, + WeekdayAlarm1 { + weekday: 1, + hour: Hours::H24(1), + minute: 1, + second: 60 + }, + A1M::SecondsMatch + ); + set_invalid_alarm_test!( + wd_invalid_min_masm, + set_alarm1_weekday, + WeekdayAlarm1 { + weekday: 1, + hour: Hours::H24(1), + minute: 60, + second: 1 + }, + A1M::MinutesAndSecondsMatch + ); } mod alarm2 { use super::*; + set_invalid_alarm_test!( + day_invalid_min_mm, + set_alarm2_day, + DayAlarm2 { + day: 1, + hour: Hours::H24(1), + minute: 60 + }, + A2M::MinutesMatch + ); set_invalid_alarm_test!( day_invalid_min, set_alarm2_day, @@ -281,6 +355,16 @@ mod alarm2 { }, A2M::AllMatch ); + set_invalid_alarm_test!( + day_invalid_h_hamm, + set_alarm2_day, + DayAlarm2 { + day: 1, + hour: Hours::H24(24), + minute: 1 + }, + A2M::HoursAndMinutesMatch + ); set_invalid_alarm_test!( day_invalid_am1, set_alarm2_day, @@ -342,6 +426,16 @@ mod alarm2 { A2M::AllMatch ); + set_invalid_alarm_test!( + wd_invalid_min_mm, + set_alarm2_weekday, + WeekdayAlarm2 { + weekday: 1, + hour: Hours::H24(1), + minute: 60 + }, + A2M::MinutesMatch + ); set_invalid_alarm_test!( wd_invalid_min, set_alarm2_weekday, @@ -362,6 +456,16 @@ mod alarm2 { }, A2M::AllMatch ); + set_invalid_alarm_test!( + wd_invalid_h_hmm, + set_alarm2_weekday, + WeekdayAlarm2 { + weekday: 1, + hour: Hours::H24(24), + minute: 1 + }, + A2M::HoursAndMinutesMatch + ); set_invalid_alarm_test!( wd_invalid_am1, set_alarm2_weekday, @@ -422,22 +526,32 @@ mod alarm2 { }, A2M::AllMatch ); + set_invalid_alarm_test!( + wd_invalid_minute, + set_alarm2_weekday, + WeekdayAlarm2 { + weekday: 1, + hour: Hours::H24(1), + minute: 60 + }, + A2M::HoursAndMinutesMatch + ); } macro_rules! _set_values_test { - ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $value1:expr, $value2:expr, $transactions:expr) => { + ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $transactions:expr, $( $value:expr ),+) => { #[test] fn $name() { let trans = $transactions; let mut dev = $create_method(&trans); - dev.$method($value1, $value2).unwrap(); + dev.$method($($value),*).unwrap(); $destroy_method(dev); } }; } macro_rules! set_values_test { - ($name:ident, $method:ident, $value1:expr, $value2:expr, $i2c_transactions:expr, $spi_transactions:expr) => { + ($name:ident, $method:ident, $i2c_transactions:expr, $spi_transactions:expr, $( $value:expr ),+) => { mod $name { use super::*; _set_values_test!( @@ -445,37 +559,36 @@ macro_rules! set_values_test { $method, new_ds3231, destroy_ds3231, - $value1, - $value2, - $i2c_transactions + $i2c_transactions, + $($value),* ); _set_values_test!( can_set_ds3232, $method, new_ds3232, destroy_ds3232, - $value1, - $value2, - $i2c_transactions + $i2c_transactions, + $($value),* ); _set_values_test!( can_set_ds3234, $method, new_ds3234, destroy_ds3234, - $value1, - $value2, - $spi_transactions + $spi_transactions, + $($value),* ); } }; } macro_rules! set_alarm_test { - ($name:ident, $method:ident, $alarm:expr, $matching:expr, $register:ident, [ $( $registers:expr ),+ ]) => { - set_values_test!($name, $method, $alarm, $matching, + ($name:ident, $method:ident, $register:ident, [ $( $registers:expr ),+ ], $( $value:expr ),+) => { + set_values_test!($name, $method, [ I2cTrans::write(DEV_ADDR, vec![Register::$register, $( $registers ),*]) ], - [ SpiTrans::write(vec![Register::$register + 0x80, $( $registers ),*]) ]); + [ SpiTrans::write(vec![Register::$register + 0x80, $( $registers ),*]) ], + $($value),* + ); }; } @@ -486,94 +599,146 @@ mod alarm1_day { set_alarm_test!( h24, set_alarm1_day, + ALARM1_SECONDS, + [4, 3, 2, 1], DayAlarm1 { day: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::AllMatch, - ALARM1_SECONDS, - [4, 3, 2, 1] + A1M::AllMatch ); set_alarm_test!( am, set_alarm1_day, + ALARM1_SECONDS, + [4, 3, 0b0100_0010, 1], DayAlarm1 { day: 1, hour: Hours::AM(2), minute: 3, second: 4 }, - A1M::AllMatch, - ALARM1_SECONDS, - [4, 3, 0b0100_0010, 1] + A1M::AllMatch ); set_alarm_test!( pm, set_alarm1_day, + ALARM1_SECONDS, + [4, 3, 0b0110_0010, 1], DayAlarm1 { day: 1, hour: Hours::PM(2), minute: 3, second: 4 }, - A1M::AllMatch, - ALARM1_SECONDS, - [4, 3, 0b0110_0010, 1] + A1M::AllMatch ); set_alarm_test!( match_hms, set_alarm1_day, + ALARM1_SECONDS, + [4, 3, 2, AM | 1], DayAlarm1 { day: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::HoursMinutesAndSecondsMatch, + A1M::HoursMinutesAndSecondsMatch + ); + set_alarm_test!( + match_hms_ignore_incorrect_day, + set_alarm1_day, ALARM1_SECONDS, - [4, 3, 2, AM | 1] + [4, 3, 2, AM | 1], + DayAlarm1 { + day: 0, + hour: Hours::H24(2), + minute: 3, + second: 4 + }, + A1M::HoursMinutesAndSecondsMatch + ); + set_alarm_test!( + match_ms_ignore_invalid_hour, + set_alarm1_day, + ALARM1_SECONDS, + [4, 3, AM | 0, AM | 1], + DayAlarm1 { + day: 1, + hour: Hours::H24(24), + minute: 3, + second: 4 + }, + A1M::MinutesAndSecondsMatch ); set_alarm_test!( match_ms, set_alarm1_day, + ALARM1_SECONDS, + [4, 3, AM | 2, AM | 1], DayAlarm1 { day: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::MinutesAndSecondsMatch, + A1M::MinutesAndSecondsMatch + ); + set_alarm_test!( + match_ms_ignore_incorrect_day, + set_alarm1_day, ALARM1_SECONDS, - [4, 3, AM | 2, AM | 1] + [4, 3, AM | 2, AM | 1], + DayAlarm1 { + day: 0, + hour: Hours::H24(2), + minute: 3, + second: 4 + }, + A1M::MinutesAndSecondsMatch ); set_alarm_test!( match_s, set_alarm1_day, + ALARM1_SECONDS, + [4, AM | 3, AM | 2, AM | 1], DayAlarm1 { day: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::SecondsMatch, + A1M::SecondsMatch + ); + set_alarm_test!( + match_s_ignore_incorrect_min, + set_alarm1_day, ALARM1_SECONDS, - [4, AM | 3, AM | 2, AM | 1] + [4, AM | 0, AM | 2, AM | 1], + DayAlarm1 { + day: 1, + hour: Hours::H24(2), + minute: 60, + second: 4 + }, + A1M::SecondsMatch ); set_alarm_test!( match_ops, set_alarm1_day, + ALARM1_SECONDS, + [AM | 4, AM | 3, AM | 2, AM | 1], DayAlarm1 { day: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::OncePerSecond, - ALARM1_SECONDS, - [AM | 4, AM | 3, AM | 2, AM | 1] + A1M::OncePerSecond ); } @@ -582,94 +747,132 @@ mod alarm1_weekday { set_alarm_test!( h24, set_alarm1_weekday, + ALARM1_SECONDS, + [4, 3, 2, BF::WEEKDAY | 1], WeekdayAlarm1 { weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::AllMatch, - ALARM1_SECONDS, - [4, 3, 2, BF::WEEKDAY | 1] + A1M::AllMatch ); set_alarm_test!( am, set_alarm1_weekday, + ALARM1_SECONDS, + [4, 3, 0b0100_0010, BF::WEEKDAY | 1], WeekdayAlarm1 { weekday: 1, hour: Hours::AM(2), minute: 3, second: 4 }, - A1M::AllMatch, - ALARM1_SECONDS, - [4, 3, 0b0100_0010, BF::WEEKDAY | 1] + A1M::AllMatch ); set_alarm_test!( pm, set_alarm1_weekday, + ALARM1_SECONDS, + [4, 3, 0b0110_0010, BF::WEEKDAY | 1], WeekdayAlarm1 { weekday: 1, hour: Hours::PM(2), minute: 3, second: 4 }, - A1M::AllMatch, - ALARM1_SECONDS, - [4, 3, 0b0110_0010, BF::WEEKDAY | 1] + A1M::AllMatch + ); + set_alarm_test!( + match_hms_ignore_incorrect_wd, + set_alarm1_weekday, + ALARM1_SECONDS, + [4, 3, 2, AM | BF::WEEKDAY | 1], + WeekdayAlarm1 { + weekday: 0, + hour: Hours::H24(2), + minute: 3, + second: 4 + }, + A1M::HoursMinutesAndSecondsMatch ); - set_alarm_test!( match_hms, set_alarm1_weekday, + ALARM1_SECONDS, + [4, 3, 2, AM | BF::WEEKDAY | 1], WeekdayAlarm1 { weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::HoursMinutesAndSecondsMatch, - ALARM1_SECONDS, - [4, 3, 2, AM | BF::WEEKDAY | 1] + A1M::HoursMinutesAndSecondsMatch ); set_alarm_test!( match_ms, set_alarm1_weekday, + ALARM1_SECONDS, + [4, 3, AM | 2, AM | BF::WEEKDAY | 1], WeekdayAlarm1 { weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::MinutesAndSecondsMatch, - ALARM1_SECONDS, - [4, 3, AM | 2, AM | BF::WEEKDAY | 1] + A1M::MinutesAndSecondsMatch ); set_alarm_test!( match_s, set_alarm1_weekday, + ALARM1_SECONDS, + [4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1], WeekdayAlarm1 { weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::SecondsMatch, + A1M::SecondsMatch + ); + set_alarm_test!( + match_s_ignore_incorrect_min, + set_alarm1_weekday, ALARM1_SECONDS, - [4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1] + [4, AM | 0, AM | 2, AM | BF::WEEKDAY | 1], + WeekdayAlarm1 { + weekday: 1, + hour: Hours::H24(2), + minute: 60, + second: 4 + }, + A1M::SecondsMatch ); set_alarm_test!( match_ops, set_alarm1_weekday, + ALARM1_SECONDS, + [AM | 4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1], WeekdayAlarm1 { weekday: 1, hour: Hours::H24(2), minute: 3, second: 4 }, - A1M::OncePerSecond, + A1M::OncePerSecond + ); + set_alarm_test!( + match_ops_ignore_incorrect_sec, + set_alarm1_weekday, ALARM1_SECONDS, - [AM | 4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1] + [AM | 0, AM | 3, AM | 2, AM | BF::WEEKDAY | 1], + WeekdayAlarm1 { + weekday: 1, + hour: Hours::H24(2), + minute: 3, + second: 60 + }, + A1M::OncePerSecond ); } @@ -678,75 +881,111 @@ mod alarm2_day { set_alarm_test!( h24, set_alarm2_day, + ALARM2_MINUTES, + [3, 2, 1], DayAlarm2 { day: 1, hour: Hours::H24(2), minute: 3 }, - A2M::AllMatch, - ALARM2_MINUTES, - [3, 2, 1] + A2M::AllMatch ); set_alarm_test!( am, set_alarm2_day, + ALARM2_MINUTES, + [3, 0b0100_0010, 1], DayAlarm2 { day: 1, hour: Hours::AM(2), minute: 3 }, - A2M::AllMatch, - ALARM2_MINUTES, - [3, 0b0100_0010, 1] + A2M::AllMatch ); set_alarm_test!( pm, set_alarm2_day, + ALARM2_MINUTES, + [3, 0b0110_0010, 1], DayAlarm2 { day: 1, hour: Hours::PM(2), minute: 3 }, - A2M::AllMatch, - ALARM2_MINUTES, - [3, 0b0110_0010, 1] + A2M::AllMatch ); set_alarm_test!( match_hm, set_alarm2_day, + ALARM2_MINUTES, + [3, 2, AM | 1], DayAlarm2 { day: 1, hour: Hours::H24(2), minute: 3 }, - A2M::HoursAndMinutesMatch, + A2M::HoursAndMinutesMatch + ); + set_alarm_test!( + match_hm_ignore_incorrect_day, + set_alarm2_day, ALARM2_MINUTES, - [3, 2, AM | 1] + [3, 2, AM | 1], + DayAlarm2 { + day: 0, + hour: Hours::H24(2), + minute: 3 + }, + A2M::HoursAndMinutesMatch ); set_alarm_test!( match_m, set_alarm2_day, + ALARM2_MINUTES, + [3, AM | 2, AM | 1], DayAlarm2 { day: 1, hour: Hours::H24(2), minute: 3 }, - A2M::MinutesMatch, + A2M::MinutesMatch + ); + set_alarm_test!( + match_m_ignore_invalid_h, + set_alarm2_day, ALARM2_MINUTES, - [3, AM | 2, AM | 1] + [3, AM | 0, AM | 1], + DayAlarm2 { + day: 1, + hour: Hours::H24(25), + minute: 3 + }, + A2M::MinutesMatch ); set_alarm_test!( match_opm, set_alarm2_day, + ALARM2_MINUTES, + [AM | 3, AM | 2, AM | 1], DayAlarm2 { day: 1, hour: Hours::H24(2), minute: 3 }, - A2M::OncePerMinute, + A2M::OncePerMinute + ); + set_alarm_test!( + match_opm_ignore_incorrect_min, + set_alarm2_day, ALARM2_MINUTES, - [AM | 3, AM | 2, AM | 1] + [AM | 0, AM | 2, AM | 1], + DayAlarm2 { + day: 1, + hour: Hours::H24(2), + minute: 60 + }, + A2M::OncePerMinute ); } @@ -755,74 +994,109 @@ mod alarm2_weekday { set_alarm_test!( h24, set_alarm2_weekday, + ALARM2_MINUTES, + [3, 2, BF::WEEKDAY | 1], WeekdayAlarm2 { weekday: 1, hour: Hours::H24(2), minute: 3 }, - A2M::AllMatch, - ALARM2_MINUTES, - [3, 2, BF::WEEKDAY | 1] + A2M::AllMatch ); set_alarm_test!( am, set_alarm2_weekday, + ALARM2_MINUTES, + [3, 0b0100_0010, BF::WEEKDAY | 1], WeekdayAlarm2 { weekday: 1, hour: Hours::AM(2), minute: 3 }, - A2M::AllMatch, - ALARM2_MINUTES, - [3, 0b0100_0010, BF::WEEKDAY | 1] + A2M::AllMatch ); set_alarm_test!( pm, set_alarm2_weekday, + ALARM2_MINUTES, + [3, 0b0110_0010, BF::WEEKDAY | 1], WeekdayAlarm2 { weekday: 1, hour: Hours::PM(2), minute: 3 }, - A2M::AllMatch, - ALARM2_MINUTES, - [3, 0b0110_0010, BF::WEEKDAY | 1] + A2M::AllMatch ); - set_alarm_test!( match_hm, set_alarm2_weekday, + ALARM2_MINUTES, + [3, 2, AM | BF::WEEKDAY | 1], WeekdayAlarm2 { weekday: 1, hour: Hours::H24(2), minute: 3 }, - A2M::HoursAndMinutesMatch, + A2M::HoursAndMinutesMatch + ); + set_alarm_test!( + match_hm_ignore_incorrect_wd, + set_alarm2_weekday, ALARM2_MINUTES, - [3, 2, AM | BF::WEEKDAY | 1] + [3, 2, AM | BF::WEEKDAY | 1], + WeekdayAlarm2 { + weekday: 0, + hour: Hours::H24(2), + minute: 3 + }, + A2M::HoursAndMinutesMatch ); set_alarm_test!( match_m, set_alarm2_weekday, + ALARM2_MINUTES, + [3, AM | 2, AM | BF::WEEKDAY | 1], WeekdayAlarm2 { weekday: 1, hour: Hours::H24(2), minute: 3 }, - A2M::MinutesMatch, + A2M::MinutesMatch + ); + set_alarm_test!( + match_m_ignore_invalid_hour, + set_alarm2_weekday, ALARM2_MINUTES, - [3, AM | 2, AM | BF::WEEKDAY | 1] + [3, AM | 0, AM | BF::WEEKDAY | 1], + WeekdayAlarm2 { + weekday: 1, + hour: Hours::H24(24), + minute: 3 + }, + A2M::MinutesMatch ); set_alarm_test!( match_opm, set_alarm2_weekday, + ALARM2_MINUTES, + [AM | 3, AM | 2, AM | BF::WEEKDAY | 1], WeekdayAlarm2 { weekday: 1, hour: Hours::H24(2), minute: 3 }, - A2M::OncePerMinute, + A2M::OncePerMinute + ); + set_alarm_test!( + match_opm_ignore_incorrect_min, + set_alarm2_weekday, ALARM2_MINUTES, - [AM | 3, AM | 2, AM | BF::WEEKDAY | 1] + [AM | 0, AM | 2, AM | BF::WEEKDAY | 1], + WeekdayAlarm2 { + weekday: 1, + hour: Hours::H24(2), + minute: 60 + }, + A2M::OncePerMinute ); }