mirror of https://github.com/eldruin/ds323x-rs
				
				
				
			Implement Rtcc trait
							parent
							
								
									d3329b2598
								
							
						
					
					
						commit
						3c8d378d6f
					
				| 
						 | 
				
			
			@ -26,6 +26,7 @@ maintenance = { status = "actively-developed" }
 | 
			
		|||
 | 
			
		||||
[dependencies]
 | 
			
		||||
embedded-hal = "0.2.3"
 | 
			
		||||
rtcc = "0.2"
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
linux-embedded-hal = "0.3"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20
									
								
								README.md
								
								
								
								
							
							
						
						
									
										20
									
								
								README.md
								
								
								
								
							| 
						 | 
				
			
			@ -137,26 +137,20 @@ Please find additional examples using hardware in this repository: [driver-examp
 | 
			
		|||
[driver-examples]: https://github.com/eldruin/driver-examples
 | 
			
		||||
 | 
			
		||||
```rust
 | 
			
		||||
extern crate linux_embedded_hal as hal;
 | 
			
		||||
extern crate ds323x;
 | 
			
		||||
use ds323x::{ Ds323x, DateTime, Hours };
 | 
			
		||||
extern crate linux_embedded_hal as hal;
 | 
			
		||||
use ds323x::{Ds323x, NaiveDate, Rtcc};
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
    let mut rtc = Ds323x::new_ds3231(dev);
 | 
			
		||||
    let datetime = DateTime {
 | 
			
		||||
                              year: 2018,
 | 
			
		||||
                              month: 8,
 | 
			
		||||
                              day: 20,
 | 
			
		||||
                              weekday: 4,
 | 
			
		||||
                              hour: Hours::H24(19),
 | 
			
		||||
                              minute: 59,
 | 
			
		||||
                              second: 58
 | 
			
		||||
                  };
 | 
			
		||||
    let datetime = NaiveDate::from_ymd(2020, 5, 1).and_hms(19, 59, 58);
 | 
			
		||||
    rtc.set_datetime(&datetime).unwrap();
 | 
			
		||||
    // do something else...
 | 
			
		||||
    let seconds = rtc.get_seconds().unwrap();
 | 
			
		||||
    println!("Seconds: {}", seconds);
 | 
			
		||||
    let time = rtc.get_time().unwrap();
 | 
			
		||||
    println!("Time: {}", time);
 | 
			
		||||
 | 
			
		||||
    let _dev = rtc.destroy_ds3231();
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,26 +1,15 @@
 | 
			
		|||
extern crate ds323x;
 | 
			
		||||
extern crate embedded_hal;
 | 
			
		||||
extern crate linux_embedded_hal;
 | 
			
		||||
 | 
			
		||||
use ds323x::{DateTime, Ds323x, Hours};
 | 
			
		||||
use linux_embedded_hal::I2cdev;
 | 
			
		||||
extern crate linux_embedded_hal as hal;
 | 
			
		||||
use ds323x::{Ds323x, NaiveDate, Rtcc};
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let dev = I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
    let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
    let mut rtc = Ds323x::new_ds3231(dev);
 | 
			
		||||
    let datetime = DateTime {
 | 
			
		||||
        year: 2018,
 | 
			
		||||
        month: 8,
 | 
			
		||||
        day: 20,
 | 
			
		||||
        weekday: 4,
 | 
			
		||||
        hour: Hours::H24(19),
 | 
			
		||||
        minute: 59,
 | 
			
		||||
        second: 58,
 | 
			
		||||
    };
 | 
			
		||||
    let datetime = NaiveDate::from_ymd(2020, 5, 1).and_hms(19, 59, 58);
 | 
			
		||||
    rtc.set_datetime(&datetime).unwrap();
 | 
			
		||||
    // do something else...
 | 
			
		||||
    let seconds = rtc.get_seconds().unwrap();
 | 
			
		||||
    println!("Seconds: {}", seconds);
 | 
			
		||||
    let time = rtc.get_time().unwrap();
 | 
			
		||||
    println!("Time: {}", time);
 | 
			
		||||
 | 
			
		||||
    let _dev = rtc.destroy_ds3231();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,160 +2,156 @@
 | 
			
		|||
 | 
			
		||||
use super::super::{BitFlags, Ds323x, Error, Register};
 | 
			
		||||
use super::{decimal_to_packed_bcd, hours_to_register, packed_bcd_to_decimal};
 | 
			
		||||
use super::{Datelike, Hours, NaiveDate, NaiveDateTime, NaiveTime, Rtcc, Timelike};
 | 
			
		||||
use interface::{ReadData, WriteData};
 | 
			
		||||
 | 
			
		||||
/// Date and time
 | 
			
		||||
#[derive(Debug, Clone, Copy, 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, Copy, PartialEq)]
 | 
			
		||||
pub enum Hours {
 | 
			
		||||
    /// AM [1-12]
 | 
			
		||||
    AM(u8),
 | 
			
		||||
    /// PM [1-12]
 | 
			
		||||
    PM(u8),
 | 
			
		||||
    /// 24H format [0-23]
 | 
			
		||||
    H24(u8),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
 | 
			
		||||
impl<DI, IC, CommE, PinE> Rtcc for Ds323x<DI, IC>
 | 
			
		||||
where
 | 
			
		||||
    DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
 | 
			
		||||
{
 | 
			
		||||
    /// Read the seconds.
 | 
			
		||||
    pub fn get_seconds(&mut self) -> Result<u8, Error<CommE, PinE>> {
 | 
			
		||||
    type Error = Error<CommE, PinE>;
 | 
			
		||||
 | 
			
		||||
    fn get_seconds(&mut self) -> Result<u8, Self::Error> {
 | 
			
		||||
        self.read_register_decimal(Register::SECONDS)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Read the minutes.
 | 
			
		||||
    pub fn get_minutes(&mut self) -> Result<u8, Error<CommE, PinE>> {
 | 
			
		||||
    fn get_minutes(&mut self) -> Result<u8, Self::Error> {
 | 
			
		||||
        self.read_register_decimal(Register::MINUTES)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Read the hours.
 | 
			
		||||
    pub fn get_hours(&mut self) -> Result<Hours, Error<CommE, PinE>> {
 | 
			
		||||
    fn get_hours(&mut self) -> Result<Hours, Self::Error> {
 | 
			
		||||
        let data = self.iface.read_register(Register::HOURS)?;
 | 
			
		||||
        Ok(hours_from_register(data))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Read the day of the week [1-7].
 | 
			
		||||
    pub fn get_weekday(&mut self) -> Result<u8, Error<CommE, PinE>> {
 | 
			
		||||
    fn get_time(&mut self) -> Result<NaiveTime, Self::Error> {
 | 
			
		||||
        let mut data = [0; 4];
 | 
			
		||||
        self.iface.read_data(&mut data)?;
 | 
			
		||||
        let hour = hours_from_register(data[Register::HOURS as usize + 1]);
 | 
			
		||||
        let minute = packed_bcd_to_decimal(data[Register::MINUTES as usize + 1]);
 | 
			
		||||
        let second = packed_bcd_to_decimal(data[Register::SECONDS as usize + 1]);
 | 
			
		||||
 | 
			
		||||
        let h24 = match hour {
 | 
			
		||||
            Hours::H24(h) => h,
 | 
			
		||||
            Hours::AM(h) => h,
 | 
			
		||||
            Hours::PM(h) => h + 12,
 | 
			
		||||
        };
 | 
			
		||||
        Ok(NaiveTime::from_hms(
 | 
			
		||||
            h24.into(),
 | 
			
		||||
            minute.into(),
 | 
			
		||||
            second.into(),
 | 
			
		||||
        ))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_weekday(&mut self) -> Result<u8, Self::Error> {
 | 
			
		||||
        self.read_register_decimal(Register::DOW)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Read the day of the month [1-31].
 | 
			
		||||
    pub fn get_day(&mut self) -> Result<u8, Error<CommE, PinE>> {
 | 
			
		||||
    fn get_day(&mut self) -> Result<u8, Self::Error> {
 | 
			
		||||
        self.read_register_decimal(Register::DOM)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Read the month [1-12].
 | 
			
		||||
    pub fn get_month(&mut self) -> Result<u8, Error<CommE, PinE>> {
 | 
			
		||||
    fn get_month(&mut self) -> Result<u8, Self::Error> {
 | 
			
		||||
        let data = self.iface.read_register(Register::MONTH)?;
 | 
			
		||||
        let value = data & !BitFlags::CENTURY;
 | 
			
		||||
        Ok(packed_bcd_to_decimal(value))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Read the year [2000-2100].
 | 
			
		||||
    pub fn get_year(&mut self) -> Result<u16, Error<CommE, PinE>> {
 | 
			
		||||
    fn get_year(&mut self) -> Result<u16, Self::Error> {
 | 
			
		||||
        let mut data = [0; 3];
 | 
			
		||||
        data[0] = Register::MONTH;
 | 
			
		||||
        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<DateTime, Error<CommE, PinE>> {
 | 
			
		||||
    fn get_date(&mut self) -> Result<NaiveDate, Self::Error> {
 | 
			
		||||
        let mut data = [0; 4];
 | 
			
		||||
        data[0] = Register::DOM;
 | 
			
		||||
        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 day = packed_bcd_to_decimal(data[Register::DOM as usize + 1 - offset]);
 | 
			
		||||
        Ok(NaiveDate::from_ymd(year.into(), month.into(), day.into()))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_datetime(&mut self) -> Result<NaiveDateTime, Self::Error> {
 | 
			
		||||
        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],
 | 
			
		||||
 | 
			
		||||
        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 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]);
 | 
			
		||||
        let second = packed_bcd_to_decimal(data[Register::SECONDS as usize + 1]);
 | 
			
		||||
 | 
			
		||||
        let h24 = match hour {
 | 
			
		||||
            Hours::H24(h) => h,
 | 
			
		||||
            Hours::AM(h) => h,
 | 
			
		||||
            Hours::PM(h) => h + 12,
 | 
			
		||||
        };
 | 
			
		||||
        Ok(
 | 
			
		||||
            rtcc::NaiveDate::from_ymd(year.into(), month.into(), day.into()).and_hms(
 | 
			
		||||
                h24.into(),
 | 
			
		||||
                minute.into(),
 | 
			
		||||
                second.into(),
 | 
			
		||||
            ),
 | 
			
		||||
            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<u8, Error<CommE, PinE>> {
 | 
			
		||||
        let data = self.iface.read_register(register)?;
 | 
			
		||||
        Ok(packed_bcd_to_decimal(data))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the seconds [0-59].
 | 
			
		||||
    ///
 | 
			
		||||
    /// Will return an `Error::InvalidInputData` if the seconds are out of range.
 | 
			
		||||
    pub fn set_seconds(&mut self, seconds: u8) -> Result<(), Error<CommE, PinE>> {
 | 
			
		||||
    fn set_seconds(&mut self, seconds: u8) -> Result<(), Self::Error> {
 | 
			
		||||
        if seconds > 59 {
 | 
			
		||||
            return Err(Error::InvalidInputData);
 | 
			
		||||
        }
 | 
			
		||||
        self.write_register_decimal(Register::SECONDS, seconds)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the minutes [0-59].
 | 
			
		||||
    ///
 | 
			
		||||
    /// Will return an `Error::InvalidInputData` if the minutes are out of range.
 | 
			
		||||
    pub fn set_minutes(&mut self, minutes: u8) -> Result<(), Error<CommE, PinE>> {
 | 
			
		||||
    fn set_minutes(&mut self, minutes: u8) -> Result<(), Self::Error> {
 | 
			
		||||
        if minutes > 59 {
 | 
			
		||||
            return Err(Error::InvalidInputData);
 | 
			
		||||
        }
 | 
			
		||||
        self.write_register_decimal(Register::MINUTES, minutes)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the hours.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Changes the operating mode to 12h/24h depending on the parameter.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Will return an `Error::InvalidInputData` if the hours are out of range.
 | 
			
		||||
    pub fn set_hours(&mut self, hours: Hours) -> Result<(), Error<CommE, PinE>> {
 | 
			
		||||
    fn set_hours(&mut self, hours: Hours) -> Result<(), Self::Error> {
 | 
			
		||||
        let value = hours_to_register(hours)?;
 | 
			
		||||
        self.iface.write_register(Register::HOURS, value)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the day of week [1-7].
 | 
			
		||||
    ///
 | 
			
		||||
    /// Will return an `Error::InvalidInputData` if the day is out of range.
 | 
			
		||||
    pub fn set_weekday(&mut self, weekday: u8) -> Result<(), Error<CommE, PinE>> {
 | 
			
		||||
    fn set_time(&mut self, time: &NaiveTime) -> Result<(), Self::Error> {
 | 
			
		||||
        let mut payload = [
 | 
			
		||||
            Register::SECONDS,
 | 
			
		||||
            decimal_to_packed_bcd(time.second() as u8),
 | 
			
		||||
            decimal_to_packed_bcd(time.minute() as u8),
 | 
			
		||||
            hours_to_register(Hours::H24(time.hour() as u8))?,
 | 
			
		||||
        ];
 | 
			
		||||
        self.iface.write_data(&mut payload)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn set_weekday(&mut self, weekday: u8) -> Result<(), Self::Error> {
 | 
			
		||||
        if weekday < 1 || weekday > 7 {
 | 
			
		||||
            return Err(Error::InvalidInputData);
 | 
			
		||||
        }
 | 
			
		||||
        self.iface.write_register(Register::DOW, weekday)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the day of month [1-31].
 | 
			
		||||
    ///
 | 
			
		||||
    /// Will return an `Error::InvalidInputData` if the day is out of range.
 | 
			
		||||
    pub fn set_day(&mut self, day: u8) -> Result<(), Error<CommE, PinE>> {
 | 
			
		||||
    fn set_day(&mut self, day: u8) -> Result<(), Self::Error> {
 | 
			
		||||
        if day < 1 || day > 7 {
 | 
			
		||||
            return Err(Error::InvalidInputData);
 | 
			
		||||
        }
 | 
			
		||||
        self.iface.write_register(Register::DOM, day)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the month [1-12].
 | 
			
		||||
    ///
 | 
			
		||||
    /// Will return an `Error::InvalidInputData` if the month is out of range.
 | 
			
		||||
    pub fn set_month(&mut self, month: u8) -> Result<(), Error<CommE, PinE>> {
 | 
			
		||||
    fn set_month(&mut self, month: u8) -> Result<(), Self::Error> {
 | 
			
		||||
        if month < 1 || month > 12 {
 | 
			
		||||
            return Err(Error::InvalidInputData);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -165,10 +161,7 @@ where
 | 
			
		|||
        self.iface.write_register(Register::MONTH, value)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the year [2000-2100].
 | 
			
		||||
    ///
 | 
			
		||||
    /// Will return an `Error::InvalidInputData` if the year is out of range.
 | 
			
		||||
    pub fn set_year(&mut self, year: u16) -> Result<(), Error<CommE, PinE>> {
 | 
			
		||||
    fn set_year(&mut self, year: u16) -> Result<(), Self::Error> {
 | 
			
		||||
        if year < 2000 || year > 2100 {
 | 
			
		||||
            return Err(Error::InvalidInputData);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -191,37 +184,49 @@ where
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set the date and time.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
 | 
			
		||||
    pub fn set_datetime(&mut self, datetime: &DateTime) -> Result<(), Error<CommE, PinE>> {
 | 
			
		||||
        if datetime.year < 2000
 | 
			
		||||
            || datetime.year > 2100
 | 
			
		||||
            || datetime.month < 1
 | 
			
		||||
            || datetime.month > 12
 | 
			
		||||
            || datetime.day < 1
 | 
			
		||||
            || datetime.day > 31
 | 
			
		||||
            || datetime.weekday < 1
 | 
			
		||||
            || datetime.weekday > 7
 | 
			
		||||
            || datetime.minute > 59
 | 
			
		||||
            || datetime.second > 59
 | 
			
		||||
        {
 | 
			
		||||
    fn set_date(&mut self, date: &rtcc::NaiveDate) -> Result<(), Self::Error> {
 | 
			
		||||
        if date.year() < 2000 || date.year() > 2100 {
 | 
			
		||||
            return Err(Error::InvalidInputData);
 | 
			
		||||
        }
 | 
			
		||||
        let (month, year) = month_year_to_registers(datetime.month, datetime.year);
 | 
			
		||||
        let (month, year) = month_year_to_registers(date.month() as u8, date.year() as u16);
 | 
			
		||||
        let mut payload = [
 | 
			
		||||
            Register::SECONDS,
 | 
			
		||||
            decimal_to_packed_bcd(datetime.second),
 | 
			
		||||
            decimal_to_packed_bcd(datetime.minute),
 | 
			
		||||
            hours_to_register(datetime.hour)?,
 | 
			
		||||
            decimal_to_packed_bcd(datetime.weekday),
 | 
			
		||||
            decimal_to_packed_bcd(datetime.day),
 | 
			
		||||
            Register::DOW,
 | 
			
		||||
            date.weekday().number_from_sunday() as u8,
 | 
			
		||||
            decimal_to_packed_bcd(date.day() as u8),
 | 
			
		||||
            month,
 | 
			
		||||
            year,
 | 
			
		||||
        ];
 | 
			
		||||
        self.iface.write_data(&mut payload)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn set_datetime(&mut self, datetime: &NaiveDateTime) -> Result<(), Self::Error> {
 | 
			
		||||
        if datetime.year() < 2000 || datetime.year() > 2100 {
 | 
			
		||||
            return Err(Error::InvalidInputData);
 | 
			
		||||
        }
 | 
			
		||||
        let (month, year) = month_year_to_registers(datetime.month() as u8, datetime.year() as u16);
 | 
			
		||||
        let mut payload = [
 | 
			
		||||
            Register::SECONDS,
 | 
			
		||||
            decimal_to_packed_bcd(datetime.second() as u8),
 | 
			
		||||
            decimal_to_packed_bcd(datetime.minute() as u8),
 | 
			
		||||
            hours_to_register(Hours::H24(datetime.hour() as u8))?,
 | 
			
		||||
            datetime.weekday().number_from_sunday() as u8,
 | 
			
		||||
            decimal_to_packed_bcd(datetime.day() as u8),
 | 
			
		||||
            month,
 | 
			
		||||
            year,
 | 
			
		||||
        ];
 | 
			
		||||
        self.iface.write_data(&mut payload)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
 | 
			
		||||
where
 | 
			
		||||
    DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
 | 
			
		||||
{
 | 
			
		||||
    fn read_register_decimal(&mut self, register: u8) -> Result<u8, Error<CommE, PinE>> {
 | 
			
		||||
        let data = self.iface.read_register(register)?;
 | 
			
		||||
        Ok(packed_bcd_to_decimal(data))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn write_register_decimal(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        register: u8,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,8 +5,8 @@ pub use self::alarms::{
 | 
			
		|||
    Alarm1Matching, Alarm2Matching, DayAlarm1, DayAlarm2, WeekdayAlarm1, WeekdayAlarm2,
 | 
			
		||||
};
 | 
			
		||||
mod datetime;
 | 
			
		||||
pub use self::datetime::{DateTime, Hours};
 | 
			
		||||
use super::{BitFlags, Error};
 | 
			
		||||
use super::{Datelike, Hours, NaiveDate, NaiveDateTime, NaiveTime, Rtcc, Timelike};
 | 
			
		||||
 | 
			
		||||
// Transforms a decimal number to packed BCD format
 | 
			
		||||
fn decimal_to_packed_bcd(dec: u8) -> u8 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										90
									
								
								src/lib.rs
								
								
								
								
							
							
						
						
									
										90
									
								
								src/lib.rs
								
								
								
								
							| 
						 | 
				
			
			@ -153,8 +153,8 @@
 | 
			
		|||
//! ### Create a driver instance for the DS3231
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::Ds323x;
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
| 
						 | 
				
			
			@ -170,8 +170,8 @@
 | 
			
		|||
//! ### Create a driver instance for the DS3232
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::Ds323x;
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
| 
						 | 
				
			
			@ -187,8 +187,8 @@
 | 
			
		|||
//! ### Create a driver instance for the DS3234
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::Ds323x;
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
| 
						 | 
				
			
			@ -205,22 +205,14 @@
 | 
			
		|||
//! ### Set the current date and time at once
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, DateTime, Hours };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, NaiveDate, Rtcc};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
//! let mut rtc = Ds323x::new_ds3231(dev);
 | 
			
		||||
//! let datetime = DateTime {
 | 
			
		||||
//!                           year: 2018,
 | 
			
		||||
//!                           month: 8,
 | 
			
		||||
//!                           day: 15,
 | 
			
		||||
//!                           weekday: 4,
 | 
			
		||||
//!                           hour: Hours::H24(19),
 | 
			
		||||
//!                           minute: 59,
 | 
			
		||||
//!                           second: 58
 | 
			
		||||
//!                };
 | 
			
		||||
//! let datetime = NaiveDate::from_ymd(2020, 5, 1).and_hms(19, 59, 58);
 | 
			
		||||
//! rtc.set_datetime(&datetime).unwrap();
 | 
			
		||||
//! # }
 | 
			
		||||
//! ```
 | 
			
		||||
| 
						 | 
				
			
			@ -228,38 +220,27 @@
 | 
			
		|||
//! ### Get the current date and time at once
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, Hours };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, Rtcc};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
//! let mut rtc = Ds323x::new_ds3231(dev);
 | 
			
		||||
//!
 | 
			
		||||
//! let datetime = rtc.get_datetime().unwrap();
 | 
			
		||||
//!
 | 
			
		||||
//! // The hours depend on the RTC running mode
 | 
			
		||||
//! match datetime.hour {
 | 
			
		||||
//!     Hours::H24(h) => println!("{}-{}-{}, {} {}:{}:{}", datetime.year,
 | 
			
		||||
//!                               datetime.month, datetime.day, datetime.weekday,
 | 
			
		||||
//!                               h, datetime.minute, datetime.second),
 | 
			
		||||
//!     Hours::AM(h) => println!("{}-{}-{}, {} {}:{}:{} AM", datetime.year,
 | 
			
		||||
//!                               datetime.month, datetime.day, datetime.weekday,
 | 
			
		||||
//!                               h, datetime.minute, datetime.second),
 | 
			
		||||
//!     Hours::PM(h) => println!("{}-{}-{}, {} {}:{}:{} PM", datetime.year,
 | 
			
		||||
//!                               datetime.month, datetime.day, datetime.weekday,
 | 
			
		||||
//!                               h, datetime.minute, datetime.second),
 | 
			
		||||
//! }
 | 
			
		||||
//! // This will print something like: 2018-08-15, 4 19:59:58
 | 
			
		||||
//! let dt = rtc.get_datetime().unwrap();
 | 
			
		||||
//! println!("{}", dt);
 | 
			
		||||
//! // This will print something like: 2020-05-01 19:59:58
 | 
			
		||||
//! # }
 | 
			
		||||
//! ```
 | 
			
		||||
//!
 | 
			
		||||
//! ### Get the year
 | 
			
		||||
//!
 | 
			
		||||
//! Similar methods exist for month, day, weekday, hours, minutes and seconds.
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, Hours };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, Rtcc};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -268,14 +249,15 @@
 | 
			
		|||
//! println!("Year: {}", year);
 | 
			
		||||
//! # }
 | 
			
		||||
//! ```
 | 
			
		||||
//! Similar methods exist for month, day, weekday, hours, minutes and seconds.
 | 
			
		||||
//!
 | 
			
		||||
//! ### Set the year
 | 
			
		||||
//!
 | 
			
		||||
//! Similar methods exist for month, day, weekday, hours, minutes and seconds.
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, Hours };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, Rtcc};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -283,13 +265,12 @@
 | 
			
		|||
//! rtc.set_year(2018).unwrap();
 | 
			
		||||
//! # }
 | 
			
		||||
//! ```
 | 
			
		||||
//! Similar methods exist for month, day, weekday, hours, minutes and seconds.
 | 
			
		||||
//!
 | 
			
		||||
//! ### Enable/disable the device
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::Ds323x;
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
| 
						 | 
				
			
			@ -306,8 +287,8 @@
 | 
			
		|||
//! ### Read the temperature
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::Ds323x;
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
| 
						 | 
				
			
			@ -320,8 +301,8 @@
 | 
			
		|||
//! ### Read busy status
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::Ds323x;
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
| 
						 | 
				
			
			@ -334,9 +315,9 @@
 | 
			
		|||
//! ### Enable the square-wave output with a frequency of 4.096Hz
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, SqWFreq };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, SqWFreq};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -354,9 +335,9 @@
 | 
			
		|||
//! available for the devices DS3232 and DS3234.
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, SqWFreq };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, SqWFreq};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -369,8 +350,8 @@
 | 
			
		|||
//! ### Set the aging offset
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::Ds323x;
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
| 
						 | 
				
			
			@ -385,9 +366,9 @@
 | 
			
		|||
//! This is only available for the devices DS3232 and DS3234.
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, TempConvRate };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, TempConvRate};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -399,9 +380,9 @@
 | 
			
		|||
//! ### Set the Alarm1 to each week on a week day at a specific time
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, Hours, WeekdayAlarm1, Alarm1Matching };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, Hours, WeekdayAlarm1, Alarm1Matching};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -421,9 +402,9 @@
 | 
			
		|||
//! The INT/SQW output pin will be set to 1 when it the alarm matches.
 | 
			
		||||
//!
 | 
			
		||||
//! ```no_run
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! extern crate ds323x;
 | 
			
		||||
//! use ds323x::{ Ds323x, Hours, DayAlarm2, Alarm2Matching };
 | 
			
		||||
//! extern crate linux_embedded_hal as hal;
 | 
			
		||||
//! use ds323x::{Ds323x, Hours, DayAlarm2, Alarm2Matching};
 | 
			
		||||
//!
 | 
			
		||||
//! # fn main() {
 | 
			
		||||
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -445,6 +426,8 @@
 | 
			
		|||
extern crate embedded_hal as hal;
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use hal::spi::{Mode, MODE_1, MODE_3};
 | 
			
		||||
extern crate rtcc;
 | 
			
		||||
pub use self::rtcc::{Datelike, Hours, NaiveDate, NaiveDateTime, NaiveTime, Rtcc, Timelike};
 | 
			
		||||
 | 
			
		||||
/// SPI mode 1 (CPOL = 0, CPHA = 1)
 | 
			
		||||
pub const SPI_MODE_1: Mode = MODE_1;
 | 
			
		||||
| 
						 | 
				
			
			@ -561,8 +544,7 @@ pub struct Ds323x<DI, IC> {
 | 
			
		|||
mod ds323x;
 | 
			
		||||
pub mod interface;
 | 
			
		||||
pub use ds323x::{
 | 
			
		||||
    Alarm1Matching, Alarm2Matching, DateTime, DayAlarm1, DayAlarm2, Hours, WeekdayAlarm1,
 | 
			
		||||
    WeekdayAlarm2,
 | 
			
		||||
    Alarm1Matching, Alarm2Matching, DayAlarm1, DayAlarm2, WeekdayAlarm1, WeekdayAlarm2,
 | 
			
		||||
};
 | 
			
		||||
mod ds3231;
 | 
			
		||||
mod ds3232;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										830
									
								
								tests/alarms.rs
								
								
								
								
							
							
						
						
									
										830
									
								
								tests/alarms.rs
								
								
								
								
							| 
						 | 
				
			
			@ -28,58 +28,402 @@ macro_rules! set_invalid_alarm_test {
 | 
			
		|||
    ($name:ident, $method:ident, $alarm:expr, $matching:expr) => {
 | 
			
		||||
        mod $name {
 | 
			
		||||
            use super::*;
 | 
			
		||||
            _set_invalid_alarm_test!(cannot_set_invalid_ds3231, $method, new_ds3231, destroy_ds3231, $alarm, $matching);
 | 
			
		||||
            _set_invalid_alarm_test!(cannot_set_invalid_ds3232, $method, new_ds3232, destroy_ds3232, $alarm, $matching);
 | 
			
		||||
            _set_invalid_alarm_test!(cannot_set_invalid_ds3234, $method, new_ds3234, destroy_ds3234, $alarm, $matching);
 | 
			
		||||
            _set_invalid_alarm_test!(
 | 
			
		||||
                cannot_set_invalid_ds3231,
 | 
			
		||||
                $method,
 | 
			
		||||
                new_ds3231,
 | 
			
		||||
                destroy_ds3231,
 | 
			
		||||
                $alarm,
 | 
			
		||||
                $matching
 | 
			
		||||
            );
 | 
			
		||||
            _set_invalid_alarm_test!(
 | 
			
		||||
                cannot_set_invalid_ds3232,
 | 
			
		||||
                $method,
 | 
			
		||||
                new_ds3232,
 | 
			
		||||
                destroy_ds3232,
 | 
			
		||||
                $alarm,
 | 
			
		||||
                $matching
 | 
			
		||||
            );
 | 
			
		||||
            _set_invalid_alarm_test!(
 | 
			
		||||
                cannot_set_invalid_ds3234,
 | 
			
		||||
                $method,
 | 
			
		||||
                new_ds3234,
 | 
			
		||||
                destroy_ds3234,
 | 
			
		||||
                $alarm,
 | 
			
		||||
                $matching
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mod alarm1 {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_s,   set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::H24(1),  minute: 1,  second: 60 }, A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_min, set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::H24(1),  minute: 60, second: 1 },  A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_h,   set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::H24(24), minute: 1,  second: 1 },  A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_am1, set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::AM(0),   minute: 1,  second: 1 },  A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_am2, set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::AM(13),  minute: 1,  second: 1 },  A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_pm1, set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::PM(0),   minute: 1,  second: 1 },  A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_pm2, set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::PM(13),  minute: 1,  second: 1 },  A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_d1,  set_alarm1_day, DayAlarm1{ day: 0,  hour: Hours::H24(1),  minute: 1,  second: 1 },  A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_d2,  set_alarm1_day, DayAlarm1{ day: 32, hour: Hours::H24(1),  minute: 1,  second: 1 },  A1M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_s,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 1,
 | 
			
		||||
            second: 60
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_min,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 60,
 | 
			
		||||
            second: 1
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_h,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(24),
 | 
			
		||||
            minute: 1,
 | 
			
		||||
            second: 1
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_am1,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::AM(0),
 | 
			
		||||
            minute: 1,
 | 
			
		||||
            second: 1
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_am2,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::AM(13),
 | 
			
		||||
            minute: 1,
 | 
			
		||||
            second: 1
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_pm1,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::PM(0),
 | 
			
		||||
            minute: 1,
 | 
			
		||||
            second: 1
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_pm2,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::PM(13),
 | 
			
		||||
            minute: 1,
 | 
			
		||||
            second: 1
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_d1,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 0,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 1,
 | 
			
		||||
            second: 1
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_d2,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 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);
 | 
			
		||||
    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
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mod alarm2 {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_min, set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::H24(1),  minute: 60 }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_h,   set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::H24(24), minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_am1, set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::AM(0),   minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_am2, set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::AM(13),  minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_pm1, set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::PM(0),   minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_pm2, set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::PM(13),  minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_d1,  set_alarm2_day, DayAlarm2{ day: 0,  hour: Hours::H24(1),  minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(day_invalid_d2,  set_alarm2_day, DayAlarm2{ day: 32, hour: Hours::H24(1),  minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_min,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 60
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_h,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(24),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_am1,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::AM(0),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_am2,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::AM(13),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_pm1,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::PM(0),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_pm2,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::PM(13),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_d1,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 0,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        day_invalid_d2,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 32,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    set_invalid_alarm_test!(wd_invalid_min, set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::H24(1),  minute: 60 }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(wd_invalid_h,   set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::H24(24), minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(wd_invalid_am1, set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::AM(0),   minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(wd_invalid_am2, set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::AM(13),  minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(wd_invalid_pm1, set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::PM(0),   minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(wd_invalid_pm2, set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::PM(13),  minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(wd_invalid_d1,  set_alarm2_weekday, WeekdayAlarm2{ weekday: 0,  hour: Hours::H24(1),  minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(wd_invalid_d2,  set_alarm2_weekday, WeekdayAlarm2{ weekday: 32, hour: Hours::H24(1),  minute: 1  }, A2M::AllMatch);
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        wd_invalid_min,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 60
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        wd_invalid_h,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::H24(24),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        wd_invalid_am1,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::AM(0),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        wd_invalid_am2,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::AM(13),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        wd_invalid_pm1,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::PM(0),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        wd_invalid_pm2,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::PM(13),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        wd_invalid_d1,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 0,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
    set_invalid_alarm_test!(
 | 
			
		||||
        wd_invalid_d2,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 32,
 | 
			
		||||
            hour: Hours::H24(1),
 | 
			
		||||
            minute: 1
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
macro_rules! _set_values_test {
 | 
			
		||||
    ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $value1:expr, $value2:expr, $transactions:expr) => {
 | 
			
		||||
        #[test]
 | 
			
		||||
| 
						 | 
				
			
			@ -96,9 +440,33 @@ macro_rules! set_values_test {
 | 
			
		|||
    ($name:ident, $method:ident, $value1:expr, $value2:expr, $i2c_transactions:expr, $spi_transactions:expr) => {
 | 
			
		||||
        mod $name {
 | 
			
		||||
            use super::*;
 | 
			
		||||
            _set_values_test!(can_set_ds3231, $method, new_ds3231, destroy_ds3231, $value1, $value2, $i2c_transactions);
 | 
			
		||||
            _set_values_test!(can_set_ds3232, $method, new_ds3232, destroy_ds3232, $value1, $value2, $i2c_transactions);
 | 
			
		||||
            _set_values_test!(can_set_ds3234, $method, new_ds3234, destroy_ds3234, $value1, $value2, $spi_transactions);
 | 
			
		||||
            _set_values_test!(
 | 
			
		||||
                can_set_ds3231,
 | 
			
		||||
                $method,
 | 
			
		||||
                new_ds3231,
 | 
			
		||||
                destroy_ds3231,
 | 
			
		||||
                $value1,
 | 
			
		||||
                $value2,
 | 
			
		||||
                $i2c_transactions
 | 
			
		||||
            );
 | 
			
		||||
            _set_values_test!(
 | 
			
		||||
                can_set_ds3232,
 | 
			
		||||
                $method,
 | 
			
		||||
                new_ds3232,
 | 
			
		||||
                destroy_ds3232,
 | 
			
		||||
                $value1,
 | 
			
		||||
                $value2,
 | 
			
		||||
                $i2c_transactions
 | 
			
		||||
            );
 | 
			
		||||
            _set_values_test!(
 | 
			
		||||
                can_set_ds3234,
 | 
			
		||||
                $method,
 | 
			
		||||
                new_ds3234,
 | 
			
		||||
                destroy_ds3234,
 | 
			
		||||
                $value1,
 | 
			
		||||
                $value2,
 | 
			
		||||
                $spi_transactions
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -111,76 +479,350 @@ macro_rules! set_alarm_test {
 | 
			
		|||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const AM : u8 = BF::ALARM_MATCH;
 | 
			
		||||
const AM: u8 = BF::ALARM_MATCH;
 | 
			
		||||
 | 
			
		||||
mod alarm1_day {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    set_alarm_test!(h24, set_alarm1_day, DayAlarm1{ day: 1, hour: Hours::H24(2), minute: 3, second: 4 }, A1M::AllMatch,
 | 
			
		||||
                    ALARM1_SECONDS, [4, 3, 2, 1]);
 | 
			
		||||
    set_alarm_test!(am,  set_alarm1_day, DayAlarm1{ day: 1, hour: Hours::AM(2),  minute: 3, second: 4 }, A1M::AllMatch,
 | 
			
		||||
                    ALARM1_SECONDS, [4, 3, 0b0100_0010, 1]);
 | 
			
		||||
    set_alarm_test!(pm,  set_alarm1_day, DayAlarm1{ day: 1, hour: Hours::PM(2),  minute: 3, second: 4 }, A1M::AllMatch,
 | 
			
		||||
                    ALARM1_SECONDS, [4, 3, 0b0110_0010, 1]);
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        h24,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3,
 | 
			
		||||
            second: 4
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch,
 | 
			
		||||
        ALARM1_SECONDS,
 | 
			
		||||
        [4, 3, 2, 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        am,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::AM(2),
 | 
			
		||||
            minute: 3,
 | 
			
		||||
            second: 4
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch,
 | 
			
		||||
        ALARM1_SECONDS,
 | 
			
		||||
        [4, 3, 0b0100_0010, 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        pm,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::PM(2),
 | 
			
		||||
            minute: 3,
 | 
			
		||||
            second: 4
 | 
			
		||||
        },
 | 
			
		||||
        A1M::AllMatch,
 | 
			
		||||
        ALARM1_SECONDS,
 | 
			
		||||
        [4, 3, 0b0110_0010, 1]
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    set_alarm_test!(match_hms, set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::H24(2), minute: 3, second: 4 }, A1M::HoursMinutesAndSecondsMatch,
 | 
			
		||||
                    ALARM1_SECONDS, [     4,      3,      2, AM | 1]);
 | 
			
		||||
    set_alarm_test!(match_ms,  set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::H24(2), minute: 3, second: 4 }, A1M::MinutesAndSecondsMatch,
 | 
			
		||||
                    ALARM1_SECONDS, [     4,      3, AM | 2, AM | 1]);
 | 
			
		||||
    set_alarm_test!(match_s,   set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::H24(2), minute: 3, second: 4 }, A1M::SecondsMatch,
 | 
			
		||||
                    ALARM1_SECONDS, [     4, AM | 3, AM | 2, AM | 1]);
 | 
			
		||||
    set_alarm_test!(match_ops, set_alarm1_day, DayAlarm1{ day: 1,  hour: Hours::H24(2), minute: 3, second: 4 }, A1M::OncePerSecond,
 | 
			
		||||
                    ALARM1_SECONDS, [AM | 4, AM | 3, AM | 2, AM | 1]);
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_hms,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3,
 | 
			
		||||
            second: 4
 | 
			
		||||
        },
 | 
			
		||||
        A1M::HoursMinutesAndSecondsMatch,
 | 
			
		||||
        ALARM1_SECONDS,
 | 
			
		||||
        [4, 3, 2, AM | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_ms,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3,
 | 
			
		||||
            second: 4
 | 
			
		||||
        },
 | 
			
		||||
        A1M::MinutesAndSecondsMatch,
 | 
			
		||||
        ALARM1_SECONDS,
 | 
			
		||||
        [4, 3, AM | 2, AM | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_s,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3,
 | 
			
		||||
            second: 4
 | 
			
		||||
        },
 | 
			
		||||
        A1M::SecondsMatch,
 | 
			
		||||
        ALARM1_SECONDS,
 | 
			
		||||
        [4, AM | 3, AM | 2, AM | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_ops,
 | 
			
		||||
        set_alarm1_day,
 | 
			
		||||
        DayAlarm1 {
 | 
			
		||||
            day: 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!(
 | 
			
		||||
        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]);
 | 
			
		||||
    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]
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mod alarm2_day {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    set_alarm_test!(h24, set_alarm2_day, DayAlarm2{ day: 1, hour: Hours::H24(2), minute: 3 }, A2M::AllMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [3, 2, 1]);
 | 
			
		||||
    set_alarm_test!(am,  set_alarm2_day, DayAlarm2{ day: 1, hour: Hours::AM(2),  minute: 3 }, A2M::AllMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [3, 0b0100_0010, 1]);
 | 
			
		||||
    set_alarm_test!(pm,  set_alarm2_day, DayAlarm2{ day: 1, hour: Hours::PM(2),  minute: 3 }, A2M::AllMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [3, 0b0110_0010, 1]);
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        h24,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, 2, 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        am,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::AM(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, 0b0100_0010, 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        pm,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::PM(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, 0b0110_0010, 1]
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    set_alarm_test!(match_hm,  set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::H24(2), minute: 3 }, A2M::HoursAndMinutesMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [     3,      2, AM | 1]);
 | 
			
		||||
    set_alarm_test!(match_m,   set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::H24(2), minute: 3 }, A2M::MinutesMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [     3, AM | 2, AM | 1]);
 | 
			
		||||
    set_alarm_test!(match_opm, set_alarm2_day, DayAlarm2{ day: 1,  hour: Hours::H24(2), minute: 3 }, A2M::OncePerMinute,
 | 
			
		||||
                    ALARM2_MINUTES, [AM | 3, AM | 2, AM | 1]);
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_hm,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::HoursAndMinutesMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, 2, AM | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_m,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::MinutesMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, AM | 2, AM | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_opm,
 | 
			
		||||
        set_alarm2_day,
 | 
			
		||||
        DayAlarm2 {
 | 
			
		||||
            day: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::OncePerMinute,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [AM | 3, AM | 2, AM | 1]
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mod alarm2_weekday {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    set_alarm_test!(h24, set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::H24(2), minute: 3 }, A2M::AllMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [3, 2,           BF::WEEKDAY | 1]);
 | 
			
		||||
    set_alarm_test!(am,  set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::AM(2),  minute: 3 }, A2M::AllMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [3, 0b0100_0010, BF::WEEKDAY | 1]);
 | 
			
		||||
    set_alarm_test!(pm,  set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::PM(2),  minute: 3 }, A2M::AllMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [3, 0b0110_0010, BF::WEEKDAY | 1]);
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        h24,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, 2, BF::WEEKDAY | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        am,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::AM(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, 0b0100_0010, BF::WEEKDAY | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        pm,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::PM(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::AllMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, 0b0110_0010, BF::WEEKDAY | 1]
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    set_alarm_test!(match_hm,  set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::H24(2), minute: 3 }, A2M::HoursAndMinutesMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [     3,      2, AM | BF::WEEKDAY | 1]);
 | 
			
		||||
    set_alarm_test!(match_m,   set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::H24(2), minute: 3 }, A2M::MinutesMatch,
 | 
			
		||||
                    ALARM2_MINUTES, [     3, AM | 2, AM | BF::WEEKDAY | 1]);
 | 
			
		||||
    set_alarm_test!(match_opm, set_alarm2_weekday, WeekdayAlarm2{ weekday: 1,  hour: Hours::H24(2), minute: 3 }, A2M::OncePerMinute,
 | 
			
		||||
                    ALARM2_MINUTES, [AM | 3, AM | 2, AM | BF::WEEKDAY | 1]);
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_hm,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::HoursAndMinutesMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, 2, AM | BF::WEEKDAY | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_m,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::MinutesMatch,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [3, AM | 2, AM | BF::WEEKDAY | 1]
 | 
			
		||||
    );
 | 
			
		||||
    set_alarm_test!(
 | 
			
		||||
        match_opm,
 | 
			
		||||
        set_alarm2_weekday,
 | 
			
		||||
        WeekdayAlarm2 {
 | 
			
		||||
            weekday: 1,
 | 
			
		||||
            hour: Hours::H24(2),
 | 
			
		||||
            minute: 3
 | 
			
		||||
        },
 | 
			
		||||
        A2M::OncePerMinute,
 | 
			
		||||
        ALARM2_MINUTES,
 | 
			
		||||
        [AM | 3, AM | 2, AM | BF::WEEKDAY | 1]
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,12 +214,26 @@ macro_rules! get_param_test {
 | 
			
		|||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! transactions_i2c_read {
 | 
			
		||||
    ($register1:ident, [ $( $read_bin:expr ),+ ], [ $( $read_bin2:expr ),* ]) => {
 | 
			
		||||
        [ I2cTrans::write_read(DEV_ADDR, vec![Register::$register1], vec![$( $read_bin ),*]) ]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! transactions_spi_read {
 | 
			
		||||
    ($register1:ident, [ $( $read_bin:expr ),+ ], [ $( $read_bin2:expr ),+ ]) => {
 | 
			
		||||
        [ SpiTrans::transfer(vec![Register::$register1, $( $read_bin2 ),*], vec![Register::$register1, $( $read_bin ),*]) ]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! get_param_read_array_test {
 | 
			
		||||
    ($name:ident, $method:ident, $value:expr, $register1:ident, [ $( $read_bin:expr ),+ ], [ $( $read_bin2:expr ),+ ]) => {
 | 
			
		||||
        _get_param_test!($name, $method, $value,
 | 
			
		||||
            [ I2cTrans::write_read(DEV_ADDR, vec![Register::$register1], vec![$( $read_bin ),*]) ],
 | 
			
		||||
            [ SpiTrans::transfer(vec![Register::$register1, $( $read_bin2 ),*], vec![Register::$register1, $( $read_bin ),*]) ]);
 | 
			
		||||
            transactions_i2c_read!($register1, [ $( $read_bin ),* ], [ ]),
 | 
			
		||||
            transactions_spi_read!($register1, [ $( $read_bin ),* ], [ $( $read_bin2 ),* ]) );
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,49 +137,157 @@ macro_rules! change_if_necessary_test {
 | 
			
		|||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
call_method_test!(enable,  enable,  CONTROL, CONTROL_POR_VALUE & !BF::EOSC);
 | 
			
		||||
call_method_test!(disable, disable, CONTROL, CONTROL_POR_VALUE |  BF::EOSC);
 | 
			
		||||
call_method_status_test!(en_32khz_out,  enable_32khz_output,
 | 
			
		||||
    DS3231_POR_STATUS |  BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F,
 | 
			
		||||
    DS323X_POR_STATUS |  BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F);
 | 
			
		||||
call_method_status_test!(dis_32khz_out, disable_32khz_output,
 | 
			
		||||
call_method_test!(enable, enable, CONTROL, CONTROL_POR_VALUE & !BF::EOSC);
 | 
			
		||||
call_method_test!(disable, disable, CONTROL, CONTROL_POR_VALUE | BF::EOSC);
 | 
			
		||||
call_method_status_test!(
 | 
			
		||||
    en_32khz_out,
 | 
			
		||||
    enable_32khz_output,
 | 
			
		||||
    DS3231_POR_STATUS | BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F,
 | 
			
		||||
    DS323X_POR_STATUS | BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F
 | 
			
		||||
);
 | 
			
		||||
call_method_status_test!(
 | 
			
		||||
    dis_32khz_out,
 | 
			
		||||
    disable_32khz_output,
 | 
			
		||||
    DS3231_POR_STATUS & !BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F,
 | 
			
		||||
    DS323X_POR_STATUS & !BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F);
 | 
			
		||||
    DS323X_POR_STATUS & !BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
call_method_status_test!(clear_alarm1_matched,  clear_alarm1_matched_flag,
 | 
			
		||||
call_method_status_test!(
 | 
			
		||||
    clear_alarm1_matched,
 | 
			
		||||
    clear_alarm1_matched_flag,
 | 
			
		||||
    DS3231_POR_STATUS | BF::ALARM2F,
 | 
			
		||||
    DS323X_POR_STATUS | BF::ALARM2F);
 | 
			
		||||
    DS323X_POR_STATUS | BF::ALARM2F
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
call_method_status_test!(clear_alarm2_matched,  clear_alarm2_matched_flag,
 | 
			
		||||
call_method_status_test!(
 | 
			
		||||
    clear_alarm2_matched,
 | 
			
		||||
    clear_alarm2_matched_flag,
 | 
			
		||||
    DS3231_POR_STATUS | BF::ALARM1F,
 | 
			
		||||
    DS323X_POR_STATUS | BF::ALARM1F);
 | 
			
		||||
    DS323X_POR_STATUS | BF::ALARM1F
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
call_method_status_test!(clr_stop, clear_has_been_stopped_flag,
 | 
			
		||||
call_method_status_test!(
 | 
			
		||||
    clr_stop,
 | 
			
		||||
    clear_has_been_stopped_flag,
 | 
			
		||||
    DS3231_POR_STATUS & !BF::OSC_STOP | BF::ALARM2F | BF::ALARM1F,
 | 
			
		||||
    DS323X_POR_STATUS & !BF::OSC_STOP | BF::ALARM2F | BF::ALARM1F);
 | 
			
		||||
    DS323X_POR_STATUS & !BF::OSC_STOP | BF::ALARM2F | BF::ALARM1F
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
change_if_necessary_test!(conv_temp, convert_temperature, CONTROL, CONTROL_POR_VALUE | BF::TEMP_CONV, CONTROL_POR_VALUE & !BF::TEMP_CONV);
 | 
			
		||||
change_if_necessary_test!(
 | 
			
		||||
    conv_temp,
 | 
			
		||||
    convert_temperature,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE | BF::TEMP_CONV,
 | 
			
		||||
    CONTROL_POR_VALUE & !BF::TEMP_CONV
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
call_method_test!(en_al1_int,  enable_alarm1_interrupts,  CONTROL, CONTROL_POR_VALUE |  BF::ALARM1_INT_EN);
 | 
			
		||||
call_method_test!(dis_al1_int, disable_alarm1_interrupts, CONTROL, CONTROL_POR_VALUE & !BF::ALARM1_INT_EN);
 | 
			
		||||
call_method_test!(
 | 
			
		||||
    en_al1_int,
 | 
			
		||||
    enable_alarm1_interrupts,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE | BF::ALARM1_INT_EN
 | 
			
		||||
);
 | 
			
		||||
call_method_test!(
 | 
			
		||||
    dis_al1_int,
 | 
			
		||||
    disable_alarm1_interrupts,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE & !BF::ALARM1_INT_EN
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
call_method_test!(en_al2_int,  enable_alarm2_interrupts,  CONTROL, CONTROL_POR_VALUE |  BF::ALARM2_INT_EN);
 | 
			
		||||
call_method_test!(dis_al2_int, disable_alarm2_interrupts, CONTROL, CONTROL_POR_VALUE & !BF::ALARM2_INT_EN);
 | 
			
		||||
call_method_test!(
 | 
			
		||||
    en_al2_int,
 | 
			
		||||
    enable_alarm2_interrupts,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE | BF::ALARM2_INT_EN
 | 
			
		||||
);
 | 
			
		||||
call_method_test!(
 | 
			
		||||
    dis_al2_int,
 | 
			
		||||
    disable_alarm2_interrupts,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE & !BF::ALARM2_INT_EN
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
set_param_test!(set_aging_offset_min, set_aging_offset, AGING_OFFSET, -128, 0b1000_0000);
 | 
			
		||||
set_param_test!(set_aging_offset_max, set_aging_offset, AGING_OFFSET,  127, 127);
 | 
			
		||||
set_param_test!(
 | 
			
		||||
    set_aging_offset_min,
 | 
			
		||||
    set_aging_offset,
 | 
			
		||||
    AGING_OFFSET,
 | 
			
		||||
    -128,
 | 
			
		||||
    0b1000_0000
 | 
			
		||||
);
 | 
			
		||||
set_param_test!(
 | 
			
		||||
    set_aging_offset_max,
 | 
			
		||||
    set_aging_offset,
 | 
			
		||||
    AGING_OFFSET,
 | 
			
		||||
    127,
 | 
			
		||||
    127
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
get_param_test!(get_aging_offset_min, get_aging_offset, AGING_OFFSET, -128, 0b1000_0000);
 | 
			
		||||
get_param_test!(get_aging_offset_max, get_aging_offset, AGING_OFFSET,  127, 127);
 | 
			
		||||
get_param_test!(
 | 
			
		||||
    get_aging_offset_min,
 | 
			
		||||
    get_aging_offset,
 | 
			
		||||
    AGING_OFFSET,
 | 
			
		||||
    -128,
 | 
			
		||||
    0b1000_0000
 | 
			
		||||
);
 | 
			
		||||
get_param_test!(
 | 
			
		||||
    get_aging_offset_max,
 | 
			
		||||
    get_aging_offset,
 | 
			
		||||
    AGING_OFFSET,
 | 
			
		||||
    127,
 | 
			
		||||
    127
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
call_method_test!(int_sqw_out_int, use_int_sqw_output_as_interrupt,   CONTROL, CONTROL_POR_VALUE |  BF::INTCN);
 | 
			
		||||
call_method_test!(int_sqw_out_sqw, use_int_sqw_output_as_square_wave, CONTROL, CONTROL_POR_VALUE & !BF::INTCN);
 | 
			
		||||
call_method_test!(
 | 
			
		||||
    int_sqw_out_int,
 | 
			
		||||
    use_int_sqw_output_as_interrupt,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE | BF::INTCN
 | 
			
		||||
);
 | 
			
		||||
call_method_test!(
 | 
			
		||||
    int_sqw_out_sqw,
 | 
			
		||||
    use_int_sqw_output_as_square_wave,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE & !BF::INTCN
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
call_method_test!(enable_sqw,  enable_square_wave,  CONTROL, CONTROL_POR_VALUE |  BF::BBSQW);
 | 
			
		||||
call_method_test!(disable_sqw, disable_square_wave, CONTROL, CONTROL_POR_VALUE & !BF::BBSQW);
 | 
			
		||||
 | 
			
		||||
set_param_test!(set_sqw_freq_1,     set_square_wave_frequency, CONTROL, SqWFreq::_1Hz,     CONTROL_POR_VALUE & !BF::RS2 & !BF::RS1);
 | 
			
		||||
set_param_test!(set_sqw_freq_1_024, set_square_wave_frequency, CONTROL, SqWFreq::_1_024Hz, CONTROL_POR_VALUE & !BF::RS2 |  BF::RS1);
 | 
			
		||||
set_param_test!(set_sqw_freq_4_096, set_square_wave_frequency, CONTROL, SqWFreq::_4_096Hz, CONTROL_POR_VALUE |  BF::RS2 & !BF::RS1);
 | 
			
		||||
set_param_test!(set_sqw_freq_8_192, set_square_wave_frequency, CONTROL, SqWFreq::_8_192Hz, CONTROL_POR_VALUE |  BF::RS2 |  BF::RS1);
 | 
			
		||||
call_method_test!(
 | 
			
		||||
    enable_sqw,
 | 
			
		||||
    enable_square_wave,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE | BF::BBSQW
 | 
			
		||||
);
 | 
			
		||||
call_method_test!(
 | 
			
		||||
    disable_sqw,
 | 
			
		||||
    disable_square_wave,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    CONTROL_POR_VALUE & !BF::BBSQW
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
set_param_test!(
 | 
			
		||||
    set_sqw_freq_1,
 | 
			
		||||
    set_square_wave_frequency,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    SqWFreq::_1Hz,
 | 
			
		||||
    CONTROL_POR_VALUE & !BF::RS2 & !BF::RS1
 | 
			
		||||
);
 | 
			
		||||
set_param_test!(
 | 
			
		||||
    set_sqw_freq_1_024,
 | 
			
		||||
    set_square_wave_frequency,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    SqWFreq::_1_024Hz,
 | 
			
		||||
    CONTROL_POR_VALUE & !BF::RS2 | BF::RS1
 | 
			
		||||
);
 | 
			
		||||
set_param_test!(
 | 
			
		||||
    set_sqw_freq_4_096,
 | 
			
		||||
    set_square_wave_frequency,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    SqWFreq::_4_096Hz,
 | 
			
		||||
    CONTROL_POR_VALUE | BF::RS2 & !BF::RS1
 | 
			
		||||
);
 | 
			
		||||
set_param_test!(
 | 
			
		||||
    set_sqw_freq_8_192,
 | 
			
		||||
    set_square_wave_frequency,
 | 
			
		||||
    CONTROL,
 | 
			
		||||
    SqWFreq::_8_192Hz,
 | 
			
		||||
    CONTROL_POR_VALUE | BF::RS2 | BF::RS1
 | 
			
		||||
);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,15 +7,7 @@ use common::{
 | 
			
		|||
    DEVICE_ADDRESS as DEV_ADDR,
 | 
			
		||||
};
 | 
			
		||||
extern crate ds323x;
 | 
			
		||||
use ds323x::{DateTime, Error, Hours};
 | 
			
		||||
 | 
			
		||||
macro_rules! set_param_write_array_test {
 | 
			
		||||
    ($name:ident, $method:ident, $value:expr, $register:ident, [ $( $exp_bin:expr ),+ ] ) => {
 | 
			
		||||
        _set_param_test!($name, $method, $value,
 | 
			
		||||
            [ I2cTrans::write(DEV_ADDR, vec![Register::$register, $( $exp_bin ),*]) ],
 | 
			
		||||
            [ SpiTrans::write(vec![Register::$register + 0x80, $( $exp_bin ),*]) ]);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
use ds323x::{Error, Hours, NaiveDate, NaiveTime, Rtcc};
 | 
			
		||||
 | 
			
		||||
macro_rules! read_set_param_write_two_test {
 | 
			
		||||
    ($name:ident, $method:ident, $value:expr, $register:ident, $binary_value1_read:expr, $bin1:expr, $bin2:expr) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +98,20 @@ macro_rules! set_invalid_param_range_test {
 | 
			
		|||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! for_all {
 | 
			
		||||
    ($name:ident) => {
 | 
			
		||||
        mod $name {
 | 
			
		||||
            use super::*;
 | 
			
		||||
            $name!(for_ds3231, new_ds3231, destroy_ds3231);
 | 
			
		||||
            $name!(for_ds3232, new_ds3232, destroy_ds3232);
 | 
			
		||||
            $name!(for_ds3234, new_ds3234, destroy_ds3234);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO set/get date
 | 
			
		||||
// TODO set/get time
 | 
			
		||||
 | 
			
		||||
mod seconds {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    get_param_test!(get, get_seconds, SECONDS, 1, 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -210,77 +216,156 @@ mod year {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! invalid_dt_test {
 | 
			
		||||
    ($name:ident, $year:expr, $month:expr, $day:expr, $weekday:expr,
 | 
			
		||||
     $hour:expr, $minute:expr, $second:expr) => {
 | 
			
		||||
    ($name:ident, $create_method:ident, $destroy_method:ident) => {
 | 
			
		||||
        mod $name {
 | 
			
		||||
            use super::*;
 | 
			
		||||
            const DT: DateTime = DateTime {
 | 
			
		||||
                year: $year,
 | 
			
		||||
                month: $month,
 | 
			
		||||
                day: $day,
 | 
			
		||||
                weekday: $weekday,
 | 
			
		||||
                hour: $hour,
 | 
			
		||||
                minute: $minute,
 | 
			
		||||
                second: $second,
 | 
			
		||||
            };
 | 
			
		||||
            set_invalid_param_test!($name, set_datetime, &DT);
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn too_small() {
 | 
			
		||||
                let dt = NaiveDate::from_ymd(1999, 1, 2).and_hms(3, 4, 5);
 | 
			
		||||
                let mut dev = $create_method(&[]);
 | 
			
		||||
                assert_invalid_input_data!(dev.set_datetime(&dt));
 | 
			
		||||
                $destroy_method(dev);
 | 
			
		||||
            }
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn too_big() {
 | 
			
		||||
                let dt = NaiveDate::from_ymd(2101, 1, 2).and_hms(3, 4, 5);
 | 
			
		||||
                let mut dev = $create_method(&[]);
 | 
			
		||||
                assert_invalid_input_data!(dev.set_datetime(&dt));
 | 
			
		||||
                $destroy_method(dev);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! transactions_i2c_write {
 | 
			
		||||
    ($register:ident, [ $( $exp_bin:expr ),+ ]) => {
 | 
			
		||||
        [ I2cTrans::write(DEV_ADDR, vec![Register::$register, $( $exp_bin ),*]) ]
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! transactions_spi_write {
 | 
			
		||||
    ($register:ident, [ $( $exp_bin:expr ),+ ]) => {
 | 
			
		||||
            [ SpiTrans::write(vec![Register::$register + 0x80, $( $exp_bin ),*]) ]
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! dt_test {
 | 
			
		||||
    ($name:ident, $create_method:ident, $destroy_method:ident,
 | 
			
		||||
    $mac_trans_read:ident, $mac_trans_write:ident) => {
 | 
			
		||||
        mod $name {
 | 
			
		||||
            use super::*;
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn get_datetime() {
 | 
			
		||||
                let dt = NaiveDate::from_ymd(2018, 8, 13).and_hms(23, 59, 58);
 | 
			
		||||
                let mut dev = $create_method(&$mac_trans_read!(
 | 
			
		||||
                    SECONDS,
 | 
			
		||||
                    [
 | 
			
		||||
                        0b0101_1000,
 | 
			
		||||
                        0b0101_1001,
 | 
			
		||||
                        0b0010_0011,
 | 
			
		||||
                        0b0000_0010,
 | 
			
		||||
                        0b0001_0011,
 | 
			
		||||
                        0b0000_1000,
 | 
			
		||||
                        0b0001_1000
 | 
			
		||||
                    ],
 | 
			
		||||
                    [0, 0, 0, 0, 0, 0, 0]
 | 
			
		||||
                ));
 | 
			
		||||
                assert_eq!(dt, dev.get_datetime().unwrap());
 | 
			
		||||
                $destroy_method(dev);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn set_datetime() {
 | 
			
		||||
                let dt = NaiveDate::from_ymd(2018, 8, 13).and_hms(23, 59, 58);
 | 
			
		||||
                let mut dev = $create_method(&$mac_trans_write!(
 | 
			
		||||
                    SECONDS,
 | 
			
		||||
                    [
 | 
			
		||||
                        0b0101_1000,
 | 
			
		||||
                        0b0101_1001,
 | 
			
		||||
                        0b0010_0011,
 | 
			
		||||
                        0b0000_0010,
 | 
			
		||||
                        0b0001_0011,
 | 
			
		||||
                        0b0000_1000,
 | 
			
		||||
                        0b0001_1000
 | 
			
		||||
                    ]
 | 
			
		||||
                ));
 | 
			
		||||
                dev.set_datetime(&dt).unwrap();
 | 
			
		||||
                $destroy_method(dev);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn get_date() {
 | 
			
		||||
                let d = NaiveDate::from_ymd(2018, 8, 13);
 | 
			
		||||
                let mut dev = $create_method(&$mac_trans_read!(
 | 
			
		||||
                    DOM,
 | 
			
		||||
                    [0b0001_0011, 0b0000_1000, 0b0001_1000],
 | 
			
		||||
                    [0, 0, 0]
 | 
			
		||||
                ));
 | 
			
		||||
                assert_eq!(d, dev.get_date().unwrap());
 | 
			
		||||
                $destroy_method(dev);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn set_date() {
 | 
			
		||||
                let d = NaiveDate::from_ymd(2018, 8, 13);
 | 
			
		||||
                let mut dev = $create_method(&$mac_trans_write!(
 | 
			
		||||
                    DOW,
 | 
			
		||||
                    [0b0000_0010, 0b0001_0011, 0b0000_1000, 0b0001_1000]
 | 
			
		||||
                ));
 | 
			
		||||
                dev.set_date(&d).unwrap();
 | 
			
		||||
                $destroy_method(dev);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn get_time() {
 | 
			
		||||
                let t = NaiveTime::from_hms(23, 59, 58);
 | 
			
		||||
                let mut dev = $create_method(&$mac_trans_read!(
 | 
			
		||||
                    SECONDS,
 | 
			
		||||
                    [0b0101_1000, 0b0101_1001, 0b0010_0011],
 | 
			
		||||
                    [0, 0, 0]
 | 
			
		||||
                ));
 | 
			
		||||
                assert_eq!(t, dev.get_time().unwrap());
 | 
			
		||||
                $destroy_method(dev);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn set_time() {
 | 
			
		||||
                let t = NaiveTime::from_hms(23, 59, 58);
 | 
			
		||||
                let mut dev = $create_method(&$mac_trans_write!(
 | 
			
		||||
                    SECONDS,
 | 
			
		||||
                    [0b0101_1000, 0b0101_1001, 0b0010_0011]
 | 
			
		||||
                ));
 | 
			
		||||
                dev.set_time(&t).unwrap();
 | 
			
		||||
                $destroy_method(dev);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
        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]
 | 
			
		||||
 | 
			
		||||
    dt_test!(
 | 
			
		||||
        for_ds3231,
 | 
			
		||||
        new_ds3231,
 | 
			
		||||
        destroy_ds3231,
 | 
			
		||||
        transactions_i2c_read,
 | 
			
		||||
        transactions_i2c_write
 | 
			
		||||
    );
 | 
			
		||||
    dt_test!(
 | 
			
		||||
        for_ds3232,
 | 
			
		||||
        new_ds3232,
 | 
			
		||||
        destroy_ds3232,
 | 
			
		||||
        transactions_i2c_read,
 | 
			
		||||
        transactions_i2c_write
 | 
			
		||||
    );
 | 
			
		||||
    dt_test!(
 | 
			
		||||
        for_ds3234,
 | 
			
		||||
        new_ds3234,
 | 
			
		||||
        destroy_ds3234,
 | 
			
		||||
        transactions_spi_read,
 | 
			
		||||
        transactions_spi_write
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    set_param_write_array_test!(
 | 
			
		||||
        set,
 | 
			
		||||
        set_datetime,
 | 
			
		||||
        &DT,
 | 
			
		||||
        SECONDS,
 | 
			
		||||
        [
 | 
			
		||||
            0b0101_1000,
 | 
			
		||||
            0b0101_1001,
 | 
			
		||||
            0b0010_0011,
 | 
			
		||||
            0b0000_0010,
 | 
			
		||||
            0b0001_0011,
 | 
			
		||||
            0b0000_1000,
 | 
			
		||||
            0b0001_1000
 | 
			
		||||
        ]
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    invalid_dt_test!(too_small_year, 1999, 8, 13, 2, Hours::H24(23), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_big_year, 2101, 8, 13, 2, Hours::H24(23), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_small_month, 2018, 0, 13, 2, Hours::H24(23), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_big_month, 2018, 13, 13, 2, Hours::H24(23), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_small_day, 2018, 8, 0, 2, Hours::H24(23), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_big_day, 2018, 8, 32, 2, Hours::H24(23), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_small_wd, 2018, 8, 13, 0, Hours::H24(23), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_big_wd, 2018, 8, 13, 8, Hours::H24(23), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_big_hours, 2018, 8, 13, 2, Hours::H24(24), 59, 58);
 | 
			
		||||
    invalid_dt_test!(too_big_min, 2018, 8, 13, 2, Hours::H24(24), 60, 58);
 | 
			
		||||
    invalid_dt_test!(too_big_seconds, 2018, 8, 13, 2, Hours::H24(24), 59, 60);
 | 
			
		||||
    for_all!(invalid_dt_test);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,17 +80,42 @@ macro_rules! set_param_test_2_4 {
 | 
			
		|||
 | 
			
		||||
const DEFAULT_WRITE_STATUS: u8 = DS323X_POR_STATUS | BF::ALARM2F | BF::ALARM1F;
 | 
			
		||||
 | 
			
		||||
call_method_status_test!(can_en_32khz_bat, enable_32khz_output_on_battery,
 | 
			
		||||
    DEFAULT_WRITE_STATUS |  BF::BB32KHZ );
 | 
			
		||||
call_method_status_test!(can_dis_32khz_bat, disable_32khz_output_on_battery,
 | 
			
		||||
    DEFAULT_WRITE_STATUS & !BF::BB32KHZ);
 | 
			
		||||
 | 
			
		||||
set_param_test_2_4!(can_set_cr_64s, set_temperature_conversion_rate, STATUS, TempConvRate::_64s,
 | 
			
		||||
    DEFAULT_WRITE_STATUS & !BF::CRATE1 & !BF::CRATE0);
 | 
			
		||||
set_param_test_2_4!(can_set_cr_128s, set_temperature_conversion_rate, STATUS, TempConvRate::_128s,
 | 
			
		||||
    DEFAULT_WRITE_STATUS & !BF::CRATE1 |  BF::CRATE0);
 | 
			
		||||
set_param_test_2_4!(can_set_cr_256s, set_temperature_conversion_rate, STATUS, TempConvRate::_256s,
 | 
			
		||||
    DEFAULT_WRITE_STATUS |  BF::CRATE1 & !BF::CRATE0);
 | 
			
		||||
set_param_test_2_4!(can_set_cr_512s, set_temperature_conversion_rate, STATUS, TempConvRate::_512s,
 | 
			
		||||
    DEFAULT_WRITE_STATUS |  BF::CRATE1 |  BF::CRATE0);
 | 
			
		||||
call_method_status_test!(
 | 
			
		||||
    can_en_32khz_bat,
 | 
			
		||||
    enable_32khz_output_on_battery,
 | 
			
		||||
    DEFAULT_WRITE_STATUS | BF::BB32KHZ
 | 
			
		||||
);
 | 
			
		||||
call_method_status_test!(
 | 
			
		||||
    can_dis_32khz_bat,
 | 
			
		||||
    disable_32khz_output_on_battery,
 | 
			
		||||
    DEFAULT_WRITE_STATUS & !BF::BB32KHZ
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
set_param_test_2_4!(
 | 
			
		||||
    can_set_cr_64s,
 | 
			
		||||
    set_temperature_conversion_rate,
 | 
			
		||||
    STATUS,
 | 
			
		||||
    TempConvRate::_64s,
 | 
			
		||||
    DEFAULT_WRITE_STATUS & !BF::CRATE1 & !BF::CRATE0
 | 
			
		||||
);
 | 
			
		||||
set_param_test_2_4!(
 | 
			
		||||
    can_set_cr_128s,
 | 
			
		||||
    set_temperature_conversion_rate,
 | 
			
		||||
    STATUS,
 | 
			
		||||
    TempConvRate::_128s,
 | 
			
		||||
    DEFAULT_WRITE_STATUS & !BF::CRATE1 | BF::CRATE0
 | 
			
		||||
);
 | 
			
		||||
set_param_test_2_4!(
 | 
			
		||||
    can_set_cr_256s,
 | 
			
		||||
    set_temperature_conversion_rate,
 | 
			
		||||
    STATUS,
 | 
			
		||||
    TempConvRate::_256s,
 | 
			
		||||
    DEFAULT_WRITE_STATUS | BF::CRATE1 & !BF::CRATE0
 | 
			
		||||
);
 | 
			
		||||
set_param_test_2_4!(
 | 
			
		||||
    can_set_cr_512s,
 | 
			
		||||
    set_temperature_conversion_rate,
 | 
			
		||||
    STATUS,
 | 
			
		||||
    TempConvRate::_512s,
 | 
			
		||||
    DEFAULT_WRITE_STATUS | BF::CRATE1 | BF::CRATE0
 | 
			
		||||
);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue