Code formatting

pull/4/head
Diego Barrios Romero 2019-05-16 19:18:07 +02:00
parent c74f6a86f4
commit af20f0321c
19 changed files with 784 additions and 410 deletions

View File

@ -1,9 +1,9 @@
extern crate ds323x;
extern crate embedded_hal; extern crate embedded_hal;
extern crate linux_embedded_hal; extern crate linux_embedded_hal;
extern crate ds323x;
use ds323x::{DateTime, Ds323x, Hours};
use linux_embedded_hal::I2cdev; use linux_embedded_hal::I2cdev;
use ds323x::{ Ds323x, DateTime, Hours };
fn main() { fn main() {
let dev = I2cdev::new("/dev/i2c-1").unwrap(); let dev = I2cdev::new("/dev/i2c-1").unwrap();
@ -15,7 +15,7 @@ fn main() {
weekday: 4, weekday: 4,
hour: Hours::H24(19), hour: Hours::H24(19),
minute: 59, minute: 59,
second: 58 second: 58,
}; };
rtc.set_datetime(&datetime).unwrap(); rtc.set_datetime(&datetime).unwrap();
// do something else... // do something else...

View File

@ -1,25 +1,23 @@
//! Functions exclusive of DS3231 //! Functions exclusive of DS3231
extern crate embedded_hal as hal; extern crate embedded_hal as hal;
use hal::blocking; use super::{ic, BitFlags, Ds323x, CONTROL_POR_VALUE};
use core::marker::PhantomData; use core::marker::PhantomData;
use super::{ Ds323x, BitFlags, ic, CONTROL_POR_VALUE }; use hal::blocking;
use interface::I2cInterface; use interface::I2cInterface;
impl<I2C, E> Ds323x<I2cInterface<I2C>, ic::DS3231> impl<I2C, E> Ds323x<I2cInterface<I2C>, ic::DS3231>
where where
I2C: blocking::i2c::Write<Error = E> + blocking::i2c::WriteRead<Error = E> I2C: blocking::i2c::Write<Error = E> + blocking::i2c::WriteRead<Error = E>,
{ {
/// Create a new instance of the DS3231 device. /// Create a new instance of the DS3231 device.
pub fn new_ds3231(i2c: I2C) -> Self { pub fn new_ds3231(i2c: I2C) -> Self {
const STATUS_POR_VALUE: u8 = BitFlags::OSC_STOP | BitFlags::EN32KHZ; const STATUS_POR_VALUE: u8 = BitFlags::OSC_STOP | BitFlags::EN32KHZ;
Ds323x { Ds323x {
iface: I2cInterface { iface: I2cInterface { i2c },
i2c,
},
control: CONTROL_POR_VALUE, control: CONTROL_POR_VALUE,
status: STATUS_POR_VALUE, status: STATUS_POR_VALUE,
_ic: PhantomData _ic: PhantomData,
} }
} }

View File

@ -1,26 +1,23 @@
//! Functions exclusive of DS3232 //! Functions exclusive of DS3232
extern crate embedded_hal as hal; extern crate embedded_hal as hal;
use hal::blocking; use super::{ic, BitFlags, Ds323x, Error, TempConvRate, CONTROL_POR_VALUE};
use core::marker::PhantomData; use core::marker::PhantomData;
use super::{ Ds323x, TempConvRate, BitFlags, Error, ic, CONTROL_POR_VALUE }; use hal::blocking;
use interface::I2cInterface; use interface::I2cInterface;
impl<I2C, E> Ds323x<I2cInterface<I2C>, ic::DS3232> impl<I2C, E> Ds323x<I2cInterface<I2C>, ic::DS3232>
where where
I2C: blocking::i2c::Write<Error = E> + blocking::i2c::WriteRead<Error = E> I2C: blocking::i2c::Write<Error = E> + blocking::i2c::WriteRead<Error = E>,
{ {
/// Create a new instance of the DS3232 device. /// Create a new instance of the DS3232 device.
pub fn new_ds3232(i2c: I2C) -> Self { pub fn new_ds3232(i2c: I2C) -> Self {
const STATUS_POR_VALUE: u8 = BitFlags::OSC_STOP | BitFlags::BB32KHZ | BitFlags::EN32KHZ; const STATUS_POR_VALUE: u8 = BitFlags::OSC_STOP | BitFlags::BB32KHZ | BitFlags::EN32KHZ;
Ds323x { Ds323x {
iface: I2cInterface { iface: I2cInterface { i2c },
i2c,
},
control: CONTROL_POR_VALUE, control: CONTROL_POR_VALUE,
status: STATUS_POR_VALUE, status: STATUS_POR_VALUE,
_ic: PhantomData _ic: PhantomData,
} }
} }
@ -58,7 +55,10 @@ where
/// temperature changes will not be compensated for. /// temperature changes will not be compensated for.
/// ///
/// Note: This is only available for DS3232 and DS3234 devices. /// Note: This is only available for DS3232 and DS3234 devices.
pub fn set_temperature_conversion_rate(&mut self, rate: TempConvRate) -> Result<(), Error<E, ()>> { pub fn set_temperature_conversion_rate(
&mut self,
rate: TempConvRate,
) -> Result<(), Error<E, ()>> {
let status; let status;
match rate { match rate {
TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0, TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0,

View File

@ -1,15 +1,15 @@
//! Functions exclusive of DS3234 //! Functions exclusive of DS3234
extern crate embedded_hal as hal; extern crate embedded_hal as hal;
use hal::blocking; use super::{ic, BitFlags, Ds323x, Error, Register, TempConvRate, CONTROL_POR_VALUE};
use core::marker::PhantomData; use core::marker::PhantomData;
use super::{ Ds323x, TempConvRate, Register, BitFlags, Error, ic, CONTROL_POR_VALUE }; use hal::blocking;
use interface::{SpiInterface, WriteData}; use interface::{SpiInterface, WriteData};
impl<SPI, CS, CommE, PinE> Ds323x<SpiInterface<SPI, CS>, ic::DS3234> impl<SPI, CS, CommE, PinE> Ds323x<SpiInterface<SPI, CS>, ic::DS3234>
where where
SPI: blocking::spi::Transfer<u8, Error = CommE> + blocking::spi::Write<u8, Error = CommE>, SPI: blocking::spi::Transfer<u8, Error = CommE> + blocking::spi::Write<u8, Error = CommE>,
CS: hal::digital::v2::OutputPin<Error = PinE> CS: hal::digital::v2::OutputPin<Error = PinE>,
{ {
/// Create a new instance. /// Create a new instance.
pub fn new_ds3234(spi: SPI, chip_select: CS) -> Self { pub fn new_ds3234(spi: SPI, chip_select: CS) -> Self {
@ -17,11 +17,11 @@ where
Ds323x { Ds323x {
iface: SpiInterface { iface: SpiInterface {
spi, spi,
cs: chip_select cs: chip_select,
}, },
control: CONTROL_POR_VALUE, control: CONTROL_POR_VALUE,
status: STATUS_POR_VALUE, status: STATUS_POR_VALUE,
_ic: PhantomData _ic: PhantomData,
} }
} }
@ -59,7 +59,10 @@ where
/// temperature changes will not be compensated for. /// temperature changes will not be compensated for.
/// ///
/// Note: This is only available for DS3232 and DS3234 devices. /// Note: This is only available for DS3232 and DS3234 devices.
pub fn set_temperature_conversion_rate(&mut self, rate: TempConvRate) -> Result<(), Error<CommE, PinE>> { pub fn set_temperature_conversion_rate(
&mut self,
rate: TempConvRate,
) -> Result<(), Error<CommE, PinE>> {
let status; let status;
match rate { match rate {
TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0, TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0,
@ -81,6 +84,7 @@ where
/// ///
/// Note: This is only available for DS3234 devices. /// Note: This is only available for DS3234 devices.
pub fn disable_temperature_conversions_on_battery(&mut self) -> Result<(), Error<CommE, PinE>> { pub fn disable_temperature_conversions_on_battery(&mut self) -> Result<(), Error<CommE, PinE>> {
self.iface.write_register(Register::TEMP_CONV, BitFlags::TEMP_CONV_BAT) self.iface
.write_register(Register::TEMP_CONV, BitFlags::TEMP_CONV_BAT)
} }
} }

View File

@ -1,9 +1,9 @@
//! Alarm support //! Alarm support
extern crate embedded_hal as hal; extern crate embedded_hal as hal;
use super::super::{ Ds323x, Hours, Register, BitFlags, Error }; use super::super::{BitFlags, Ds323x, Error, Hours, Register};
use interface::{ ReadData, WriteData };
use super::{decimal_to_packed_bcd, hours_to_register}; use super::{decimal_to_packed_bcd, hours_to_register};
use interface::{ReadData, WriteData};
/// Parameters for setting Alarm1 on a day of the month /// Parameters for setting Alarm1 on a day of the month
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -15,7 +15,7 @@ pub struct DayAlarm1 {
/// Minute [0-59] /// Minute [0-59]
pub minute: u8, pub minute: u8,
/// Second [0-59] /// Second [0-59]
pub second: u8 pub second: u8,
} }
/// Parameters for setting Alarm1 on a weekday /// Parameters for setting Alarm1 on a weekday
@ -28,7 +28,7 @@ pub struct WeekdayAlarm1 {
/// Minute [0-59] /// Minute [0-59]
pub minute: u8, pub minute: u8,
/// Second [0-59] /// Second [0-59]
pub second: u8 pub second: u8,
} }
/// Alarm1 trigger rate /// Alarm1 trigger rate
@ -43,10 +43,9 @@ pub enum Alarm1Matching {
/// Alarm when hours, minutes and seconds match. /// Alarm when hours, minutes and seconds match.
HoursMinutesAndSecondsMatch, HoursMinutesAndSecondsMatch,
/// Alarm when date/weekday, hours, minutes and seconds match. /// Alarm when date/weekday, hours, minutes and seconds match.
AllMatch AllMatch,
} }
/// Parameters for setting Alarm2 on a day of the month /// Parameters for setting Alarm2 on a day of the month
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct DayAlarm2 { pub struct DayAlarm2 {
@ -55,7 +54,7 @@ pub struct DayAlarm2 {
/// Hour /// Hour
pub hour: Hours, pub hour: Hours,
/// Minute [0-59] /// Minute [0-59]
pub minute: u8 pub minute: u8,
} }
/// Parameters for setting Alarm2 on a weekday /// Parameters for setting Alarm2 on a weekday
@ -66,7 +65,7 @@ pub struct WeekdayAlarm2 {
/// Hour /// Hour
pub hour: Hours, pub hour: Hours,
/// Minute [0-59] /// Minute [0-59]
pub minute: u8 pub minute: u8,
} }
/// Alarm2 trigger rate /// Alarm2 trigger rate
@ -79,7 +78,7 @@ pub enum Alarm2Matching {
/// Alarm when hours and minutes match. /// Alarm when hours and minutes match.
HoursAndMinutesMatch, HoursAndMinutesMatch,
/// Alarm when date/weekday, hours and minutes match. /// Alarm when date/weekday, hours and minutes match.
AllMatch AllMatch,
} }
fn get_matching_mask_alarm1(matching: Alarm1Matching) -> [u8; 4] { fn get_matching_mask_alarm1(matching: Alarm1Matching) -> [u8; 4] {
@ -103,76 +102,93 @@ fn get_matching_mask_alarm2(matching: Alarm2Matching) -> [u8; 3] {
} }
} }
impl<DI, IC, CommE, PinE> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>> DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
{ {
/// Set Alarm1 for day of the month. /// Set Alarm1 for day of the month.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_alarm1_day(&mut self, when: DayAlarm1, matching: Alarm1Matching) -> Result<(), Error<CommE, PinE>> { pub fn set_alarm1_day(
if when.day < 1 || when.day > 31 || &mut self,
when.minute > 59 || when: DayAlarm1,
when.second > 59 { matching: Alarm1Matching,
) -> Result<(), Error<CommE, PinE>> {
if when.day < 1 || when.day > 31 || when.minute > 59 || when.second > 59 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let match_mask = get_matching_mask_alarm1(matching); let match_mask = get_matching_mask_alarm1(matching);
let mut data = [ Register::ALARM1_SECONDS, let mut data = [
Register::ALARM1_SECONDS,
decimal_to_packed_bcd(when.second) | match_mask[0], decimal_to_packed_bcd(when.second) | match_mask[0],
decimal_to_packed_bcd(when.minute) | match_mask[1], decimal_to_packed_bcd(when.minute) | match_mask[1],
hours_to_register(when.hour)? | match_mask[2], hours_to_register(when.hour)? | match_mask[2],
decimal_to_packed_bcd(when.day) | match_mask[3]]; decimal_to_packed_bcd(when.day) | match_mask[3],
];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }
/// Set Alarm1 for weekday. /// Set Alarm1 for weekday.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_alarm1_weekday(&mut self, when: WeekdayAlarm1, matching: Alarm1Matching) -> Result<(), Error<CommE, PinE>> { pub fn set_alarm1_weekday(
if when.weekday < 1 || when.weekday > 7 || &mut self,
when.minute > 59 || when: WeekdayAlarm1,
when.second > 59 { matching: Alarm1Matching,
) -> Result<(), Error<CommE, PinE>> {
if when.weekday < 1 || when.weekday > 7 || when.minute > 59 || when.second > 59 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let match_mask = get_matching_mask_alarm1(matching); let match_mask = get_matching_mask_alarm1(matching);
let mut data = [ Register::ALARM1_SECONDS, let mut data = [
Register::ALARM1_SECONDS,
decimal_to_packed_bcd(when.second) | match_mask[0], decimal_to_packed_bcd(when.second) | match_mask[0],
decimal_to_packed_bcd(when.minute) | match_mask[1], decimal_to_packed_bcd(when.minute) | match_mask[1],
hours_to_register(when.hour)? | match_mask[2], hours_to_register(when.hour)? | match_mask[2],
decimal_to_packed_bcd(when.weekday) | match_mask[3] | BitFlags::WEEKDAY]; decimal_to_packed_bcd(when.weekday) | match_mask[3] | BitFlags::WEEKDAY,
];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }
/// Set Alarm2 for date (day of month). /// Set Alarm2 for date (day of month).
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_alarm2_day(&mut self, when: DayAlarm2, matching: Alarm2Matching) -> Result<(), Error<CommE, PinE>> { pub fn set_alarm2_day(
if when.day < 1 || when.day > 31 || &mut self,
when.minute > 59 { when: DayAlarm2,
matching: Alarm2Matching,
) -> Result<(), Error<CommE, PinE>> {
if when.day < 1 || when.day > 31 || when.minute > 59 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let match_mask = get_matching_mask_alarm2(matching); let match_mask = get_matching_mask_alarm2(matching);
let mut data = [ Register::ALARM2_MINUTES, let mut data = [
Register::ALARM2_MINUTES,
decimal_to_packed_bcd(when.minute) | match_mask[0], decimal_to_packed_bcd(when.minute) | match_mask[0],
hours_to_register(when.hour)? | match_mask[1], hours_to_register(when.hour)? | match_mask[1],
decimal_to_packed_bcd(when.day) | match_mask[2]]; decimal_to_packed_bcd(when.day) | match_mask[2],
];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }
/// Set Alarm2 for weekday. /// Set Alarm2 for weekday.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_alarm2_weekday(&mut self, when: WeekdayAlarm2, matching: Alarm2Matching) -> Result<(), Error<CommE, PinE>> { pub fn set_alarm2_weekday(
if when.weekday < 1 || when.weekday > 7 || &mut self,
when.minute > 59 { when: WeekdayAlarm2,
matching: Alarm2Matching,
) -> Result<(), Error<CommE, PinE>> {
if when.weekday < 1 || when.weekday > 7 || when.minute > 59 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let match_mask = get_matching_mask_alarm2(matching); let match_mask = get_matching_mask_alarm2(matching);
let mut data = [ Register::ALARM2_MINUTES, let mut data = [
Register::ALARM2_MINUTES,
decimal_to_packed_bcd(when.minute) | match_mask[0], decimal_to_packed_bcd(when.minute) | match_mask[0],
hours_to_register(when.hour)? | match_mask[1], hours_to_register(when.hour)? | match_mask[1],
decimal_to_packed_bcd(when.weekday) | match_mask[2] | BitFlags::WEEKDAY]; decimal_to_packed_bcd(when.weekday) | match_mask[2] | BitFlags::WEEKDAY,
];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }
} }

View File

@ -1,12 +1,12 @@
//! Device configuration //! Device configuration
extern crate embedded_hal as hal; extern crate embedded_hal as hal;
use super::super::{ Ds323x, SqWFreq, Register, BitFlags, Error }; use super::super::{BitFlags, Ds323x, Error, Register, SqWFreq};
use interface::{ReadData, WriteData}; use interface::{ReadData, WriteData};
impl<DI, IC, CommE, PinE> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>> DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
{ {
/// Enable the oscillator (set the clock running) (default). /// Enable the oscillator (set the clock running) (default).
pub fn enable(&mut self) -> Result<(), Error<CommE, PinE>> { pub fn enable(&mut self) -> Result<(), Error<CommE, PinE>> {
@ -27,7 +27,8 @@ where
let control = self.iface.read_register(Register::CONTROL)?; let control = self.iface.read_register(Register::CONTROL)?;
// do not overwrite if a conversion is in progress // do not overwrite if a conversion is in progress
if (control & BitFlags::TEMP_CONV) == 0 { if (control & BitFlags::TEMP_CONV) == 0 {
self.iface.write_register(Register::CONTROL, control | BitFlags::TEMP_CONV)?; self.iface
.write_register(Register::CONTROL, control | BitFlags::TEMP_CONV)?;
} }
Ok(()) Ok(())
} }
@ -46,7 +47,8 @@ where
/// Set the aging offset. /// Set the aging offset.
pub fn set_aging_offset(&mut self, offset: i8) -> Result<(), Error<CommE, PinE>> { pub fn set_aging_offset(&mut self, offset: i8) -> Result<(), Error<CommE, PinE>> {
self.iface.write_register(Register::AGING_OFFSET, offset as u8) self.iface
.write_register(Register::AGING_OFFSET, offset as u8)
} }
/// Read the aging offset. /// Read the aging offset.
@ -121,7 +123,10 @@ where
Ok(()) Ok(())
} }
pub(crate) fn write_status_without_clearing_alarm(&mut self, status: u8) -> Result<(), Error<CommE, PinE>> { pub(crate) fn write_status_without_clearing_alarm(
&mut self,
status: u8,
) -> Result<(), Error<CommE, PinE>> {
// avoid clearing alarm flags // avoid clearing alarm flags
let new_status = status | BitFlags::ALARM2F | BitFlags::ALARM1F; let new_status = status | BitFlags::ALARM2F | BitFlags::ALARM1F;
self.iface.write_register(Register::STATUS, new_status)?; self.iface.write_register(Register::STATUS, new_status)?;

View File

@ -1,8 +1,8 @@
//! Common implementation //! Common implementation
extern crate embedded_hal as hal; extern crate embedded_hal as hal;
use super::super::{ Ds323x, Register, BitFlags, Error }; use super::super::{BitFlags, Ds323x, Error, Register};
use super::{ decimal_to_packed_bcd, packed_bcd_to_decimal, hours_to_register }; use super::{decimal_to_packed_bcd, hours_to_register, packed_bcd_to_decimal};
use interface::{ReadData, WriteData}; use interface::{ReadData, WriteData};
/// Date and time /// Date and time
@ -37,7 +37,7 @@ pub enum Hours {
impl<DI, IC, CommE, PinE> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>> DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
{ {
/// Read the seconds. /// Read the seconds.
pub fn get_seconds(&mut self) -> Result<u8, Error<CommE, PinE>> { pub fn get_seconds(&mut self) -> Result<u8, Error<CommE, PinE>> {
@ -85,13 +85,16 @@ where
let mut data = [0; 8]; let mut data = [0; 8];
self.iface.read_data(&mut data)?; self.iface.read_data(&mut data)?;
Ok(DateTime { Ok(DateTime {
year: year_from_registers(data[Register::MONTH as usize + 1], data[Register::YEAR as usize + 1]), year: year_from_registers(
data[Register::MONTH as usize + 1],
data[Register::YEAR as usize + 1],
),
month: packed_bcd_to_decimal(data[Register::MONTH as usize + 1] & !BitFlags::CENTURY), month: packed_bcd_to_decimal(data[Register::MONTH as usize + 1] & !BitFlags::CENTURY),
day: packed_bcd_to_decimal(data[Register::DOM as usize + 1]), day: packed_bcd_to_decimal(data[Register::DOM as usize + 1]),
weekday: packed_bcd_to_decimal(data[Register::DOW as usize + 1]), weekday: packed_bcd_to_decimal(data[Register::DOW as usize + 1]),
hour: hours_from_register(data[Register::HOURS as usize + 1]), hour: hours_from_register(data[Register::HOURS as usize + 1]),
minute: packed_bcd_to_decimal(data[Register::MINUTES 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]) second: packed_bcd_to_decimal(data[Register::SECONDS as usize + 1]),
}) })
} }
@ -173,14 +176,18 @@ where
let data = self.iface.read_register(Register::MONTH)?; let data = self.iface.read_register(Register::MONTH)?;
let month_bcd = data & !BitFlags::CENTURY; let month_bcd = data & !BitFlags::CENTURY;
if year > 2099 { if year > 2099 {
let mut data = [ Register::MONTH, let mut data = [
Register::MONTH,
BitFlags::CENTURY | month_bcd, BitFlags::CENTURY | month_bcd,
decimal_to_packed_bcd((year - 2100) as u8) ]; decimal_to_packed_bcd((year - 2100) as u8),
];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} } else {
else { let mut data = [
let mut data = [ Register::MONTH, month_bcd, Register::MONTH,
decimal_to_packed_bcd((year - 2000) as u8) ]; month_bcd,
decimal_to_packed_bcd((year - 2000) as u8),
];
self.iface.write_data(&mut data) self.iface.write_data(&mut data)
} }
} }
@ -189,39 +196,54 @@ where
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// 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>> { pub fn set_datetime(&mut self, datetime: &DateTime) -> Result<(), Error<CommE, PinE>> {
if datetime.year < 2000 || datetime.year > 2100 || if datetime.year < 2000
datetime.month < 1 || datetime.month > 12 || || datetime.year > 2100
datetime.day < 1 || datetime.day > 31 || || datetime.month < 1
datetime.weekday < 1 || datetime.weekday > 7 || || datetime.month > 12
datetime.minute > 59 || || datetime.day < 1
datetime.second > 59 { || datetime.day > 31
|| datetime.weekday < 1
|| datetime.weekday > 7
|| datetime.minute > 59
|| datetime.second > 59
{
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
let (month, year) = month_year_to_registers(datetime.month, datetime.year); let (month, year) = month_year_to_registers(datetime.month, datetime.year);
let mut payload = [Register::SECONDS, let mut payload = [
Register::SECONDS,
decimal_to_packed_bcd(datetime.second), decimal_to_packed_bcd(datetime.second),
decimal_to_packed_bcd(datetime.minute), decimal_to_packed_bcd(datetime.minute),
hours_to_register(datetime.hour)?, hours_to_register(datetime.hour)?,
decimal_to_packed_bcd(datetime.weekday), decimal_to_packed_bcd(datetime.weekday),
decimal_to_packed_bcd(datetime.day), decimal_to_packed_bcd(datetime.day),
month, year]; month,
year,
];
self.iface.write_data(&mut payload) self.iface.write_data(&mut payload)
} }
fn write_register_decimal(&mut self, register: u8, decimal_number: u8) -> Result<(), Error<CommE, PinE>> { fn write_register_decimal(
self.iface.write_register(register, decimal_to_packed_bcd(decimal_number)) &mut self,
register: u8,
decimal_number: u8,
) -> Result<(), Error<CommE, PinE>> {
self.iface
.write_register(register, decimal_to_packed_bcd(decimal_number))
} }
} }
fn hours_from_register(data: u8) -> Hours { fn hours_from_register(data: u8) -> Hours {
if is_24h_format(data) { if is_24h_format(data) {
Hours::H24(packed_bcd_to_decimal(data & !BitFlags::H24_H12)) Hours::H24(packed_bcd_to_decimal(data & !BitFlags::H24_H12))
} } else if is_am(data) {
else if is_am(data) { Hours::AM(packed_bcd_to_decimal(
Hours::AM(packed_bcd_to_decimal(data & !(BitFlags::H24_H12 | BitFlags::AM_PM))) data & !(BitFlags::H24_H12 | BitFlags::AM_PM),
} ))
else { } else {
Hours::PM(packed_bcd_to_decimal(data & !(BitFlags::H24_H12 | BitFlags::AM_PM))) Hours::PM(packed_bcd_to_decimal(
data & !(BitFlags::H24_H12 | BitFlags::AM_PM),
))
} }
} }
@ -230,8 +252,7 @@ fn year_from_registers(month: u8, year: u8) -> u16 {
let year = packed_bcd_to_decimal(year); let year = packed_bcd_to_decimal(year);
if century != 0 { if century != 0 {
2100 + u16::from(year) 2100 + u16::from(year)
} } else {
else {
2000 + u16::from(year) 2000 + u16::from(year)
} }
} }
@ -240,9 +261,11 @@ fn month_year_to_registers(month: u8, year: u16) -> (u8, u8) {
if year > 2099 { if year > 2099 {
let month = BitFlags::CENTURY | decimal_to_packed_bcd(month); let month = BitFlags::CENTURY | decimal_to_packed_bcd(month);
(month, decimal_to_packed_bcd((year - 2100) as u8)) (month, decimal_to_packed_bcd((year - 2100) as u8))
} } else {
else { (
(decimal_to_packed_bcd(month), decimal_to_packed_bcd((year - 2000) as u8)) decimal_to_packed_bcd(month),
decimal_to_packed_bcd((year - 2000) as u8),
)
} }
} }
@ -253,4 +276,3 @@ fn is_24h_format(hours_data: u8) -> bool {
fn is_am(hours_data: u8) -> bool { fn is_am(hours_data: u8) -> bool {
hours_data & BitFlags::AM_PM == 0 hours_data & BitFlags::AM_PM == 0
} }

View File

@ -1,10 +1,11 @@
mod alarms;
mod configuration; mod configuration;
mod status; mod status;
mod alarms; pub use self::alarms::{
pub use self::alarms::{ DayAlarm1, WeekdayAlarm1, Alarm1Matching, Alarm1Matching, Alarm2Matching, DayAlarm1, DayAlarm2, WeekdayAlarm1, WeekdayAlarm2,
DayAlarm2, WeekdayAlarm2, Alarm2Matching }; };
mod datetime; mod datetime;
pub use self::datetime::{ Hours, DateTime }; pub use self::datetime::{DateTime, Hours};
use super::{BitFlags, Error}; use super::{BitFlags, Error};
// Transforms a decimal number to packed BCD format // Transforms a decimal number to packed BCD format
@ -28,7 +29,6 @@ fn hours_to_register<CommE, PinE>(hours: Hours) -> Result<u8, Error<CommE, PinE>
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -1,12 +1,12 @@
//! Device status //! Device status
extern crate embedded_hal as hal; extern crate embedded_hal as hal;
use super::super::{ Ds323x, Register, BitFlags, Error }; use super::super::{BitFlags, Ds323x, Error, Register};
use interface::{ReadData, WriteData}; use interface::{ReadData, WriteData};
impl<DI, IC, CommE, PinE> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>> DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
{ {
/// Read whether the oscillator is running /// Read whether the oscillator is running
pub fn is_running(&mut self) -> Result<bool, Error<CommE, PinE>> { pub fn is_running(&mut self) -> Result<bool, Error<CommE, PinE>> {
@ -87,8 +87,7 @@ where
if is_negative { if is_negative {
let temp_sign_extended = temp | 0b1111_1100_0000_0000; let temp_sign_extended = temp | 0b1111_1100_0000_0000;
Ok(f32::from(temp_sign_extended as i16) * 0.25) Ok(f32::from(temp_sign_extended as i16) * 0.25)
} } else {
else {
Ok(f32::from(temp) * 0.25) Ok(f32::from(temp) * 0.25)
} }
} }

View File

@ -3,8 +3,8 @@
#![deny(missing_docs)] #![deny(missing_docs)]
extern crate embedded_hal as hal; extern crate embedded_hal as hal;
use super::{Error, DEVICE_ADDRESS};
use hal::blocking; use hal::blocking;
use super::{ DEVICE_ADDRESS, Error };
/// I2C interface /// I2C interface
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -16,7 +16,7 @@ pub struct I2cInterface<I2C> {
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct SpiInterface<SPI, CS> { pub struct SpiInterface<SPI, CS> {
pub(crate) spi: SPI, pub(crate) spi: SPI,
pub(crate) cs: CS pub(crate) cs: CS,
} }
/// Write data /// Write data
@ -31,7 +31,7 @@ pub trait WriteData {
impl<I2C, E> WriteData for I2cInterface<I2C> impl<I2C, E> WriteData for I2cInterface<I2C>
where where
I2C: blocking::i2c::Write<Error = E> I2C: blocking::i2c::Write<Error = E>,
{ {
type Error = Error<E, ()>; type Error = Error<E, ()>;
fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> { fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> {
@ -51,16 +51,14 @@ where
impl<SPI, CS, CommE, PinE> WriteData for SpiInterface<SPI, CS> impl<SPI, CS, CommE, PinE> WriteData for SpiInterface<SPI, CS>
where where
SPI: blocking::spi::Write<u8, Error = CommE>, SPI: blocking::spi::Write<u8, Error = CommE>,
CS: hal::digital::v2::OutputPin<Error = PinE> CS: hal::digital::v2::OutputPin<Error = PinE>,
{ {
type Error = Error<CommE, PinE>; type Error = Error<CommE, PinE>;
fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> { fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> {
self.cs.set_low().map_err(Error::Pin)?; self.cs.set_low().map_err(Error::Pin)?;
let payload: [u8; 2] = [register + 0x80, data]; let payload: [u8; 2] = [register + 0x80, data];
let result = self.spi let result = self.spi.write(&payload).map_err(Error::Comm);
.write(&payload)
.map_err(Error::Comm);
self.cs.set_high().map_err(Error::Pin)?; self.cs.set_high().map_err(Error::Pin)?;
result result
@ -69,16 +67,13 @@ where
fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> { fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
self.cs.set_low().map_err(Error::Pin)?; self.cs.set_low().map_err(Error::Pin)?;
payload[0] += 0x80; payload[0] += 0x80;
let result = self.spi let result = self.spi.write(&payload).map_err(Error::Comm);
.write(&payload)
.map_err(Error::Comm);
self.cs.set_high().map_err(Error::Pin)?; self.cs.set_high().map_err(Error::Pin)?;
result result
} }
} }
/// Read data /// Read data
pub trait ReadData { pub trait ReadData {
/// Error type /// Error type
@ -91,7 +86,7 @@ pub trait ReadData {
impl<I2C, E> ReadData for I2cInterface<I2C> impl<I2C, E> ReadData for I2cInterface<I2C>
where where
I2C: blocking::i2c::WriteRead<Error = E> I2C: blocking::i2c::WriteRead<Error = E>,
{ {
type Error = Error<E, ()>; type Error = Error<E, ()>;
fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> { fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
@ -113,24 +108,20 @@ where
impl<SPI, CS, CommE, PinE> ReadData for SpiInterface<SPI, CS> impl<SPI, CS, CommE, PinE> ReadData for SpiInterface<SPI, CS>
where where
SPI: blocking::spi::Transfer<u8, Error = CommE>, SPI: blocking::spi::Transfer<u8, Error = CommE>,
CS: hal::digital::v2::OutputPin<Error = PinE> CS: hal::digital::v2::OutputPin<Error = PinE>,
{ {
type Error = Error<CommE, PinE>; type Error = Error<CommE, PinE>;
fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> { fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
self.cs.set_low().map_err(Error::Pin)?; self.cs.set_low().map_err(Error::Pin)?;
let mut data = [register, 0]; let mut data = [register, 0];
let result = self.spi let result = self.spi.transfer(&mut data).map_err(Error::Comm);
.transfer(&mut data)
.map_err(Error::Comm);
self.cs.set_high().map_err(Error::Pin)?; self.cs.set_high().map_err(Error::Pin)?;
Ok(result?[1]) Ok(result?[1])
} }
fn read_data(&mut self, mut payload: &mut [u8]) -> Result<(), Self::Error> { fn read_data(&mut self, mut payload: &mut [u8]) -> Result<(), Self::Error> {
self.cs.set_low().map_err(Error::Pin)?; self.cs.set_low().map_err(Error::Pin)?;
let result = self.spi let result = self.spi.transfer(&mut payload).map_err(Error::Comm);
.transfer(&mut payload)
.map_err(Error::Comm);
self.cs.set_high().map_err(Error::Pin)?; self.cs.set_high().map_err(Error::Pin)?;
result?; result?;
Ok(()) Ok(())

View File

@ -439,7 +439,6 @@
//! # } //! # }
//! ``` //! ```
#![deny(unsafe_code, missing_docs)] #![deny(unsafe_code, missing_docs)]
#![no_std] #![no_std]
@ -460,7 +459,7 @@ pub enum Error<CommE, PinE> {
/// Pin setting error /// Pin setting error
Pin(PinE), Pin(PinE),
/// Invalid input data provided /// Invalid input data provided
InvalidInputData InvalidInputData,
} }
/// Square-wave output frequency /// Square-wave output frequency
@ -556,13 +555,15 @@ pub struct Ds323x<DI, IC> {
iface: DI, iface: DI,
control: u8, control: u8,
status: u8, status: u8,
_ic: PhantomData<IC> _ic: PhantomData<IC>,
} }
pub mod interface;
mod ds323x; mod ds323x;
pub use ds323x::{ Hours, DateTime, DayAlarm1, WeekdayAlarm1, Alarm1Matching, pub mod interface;
DayAlarm2, WeekdayAlarm2, Alarm2Matching }; pub use ds323x::{
Alarm1Matching, Alarm2Matching, DateTime, DayAlarm1, DayAlarm2, Hours, WeekdayAlarm1,
WeekdayAlarm2,
};
mod ds3231; mod ds3231;
mod ds3232; mod ds3232;
mod ds3234; mod ds3234;

View File

@ -2,12 +2,15 @@ extern crate embedded_hal_mock as hal;
use hal::i2c::Transaction as I2cTrans; use hal::i2c::Transaction as I2cTrans;
use hal::spi::Transaction as SpiTrans; use hal::spi::Transaction as SpiTrans;
mod common; mod common;
use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, new_ds3231, use common::{
new_ds3232, new_ds3234, destroy_ds3231, destroy_ds3232, destroy_ds3231, destroy_ds3232, destroy_ds3234, new_ds3231, new_ds3232, new_ds3234,
destroy_ds3234, BitFlags as BF }; BitFlags as BF, Register, DEVICE_ADDRESS as DEV_ADDR,
};
extern crate ds323x; extern crate ds323x;
use ds323x::{ DayAlarm1, WeekdayAlarm1, Alarm1Matching as A1M, DayAlarm2, use ds323x::{
WeekdayAlarm2, Alarm2Matching as A2M, Hours, Error }; Alarm1Matching as A1M, Alarm2Matching as A2M, DayAlarm1, DayAlarm2, Error, Hours,
WeekdayAlarm1, WeekdayAlarm2,
};
#[macro_export] #[macro_export]
macro_rules! _set_invalid_alarm_test { macro_rules! _set_invalid_alarm_test {

View File

@ -1,6 +1,6 @@
extern crate embedded_hal;
extern crate ds323x; extern crate ds323x;
use self::ds323x::{ Ds323x, interface, ic }; extern crate embedded_hal;
use self::ds323x::{ic, interface, Ds323x};
extern crate embedded_hal_mock as hal; extern crate embedded_hal_mock as hal;
use self::hal::i2c::{Mock as I2cMock, Transaction as I2cTrans}; use self::hal::i2c::{Mock as I2cMock, Transaction as I2cTrans};
use self::hal::spi::{Mock as SpiMock, Transaction as SpiTrans}; use self::hal::spi::{Mock as SpiMock, Transaction as SpiTrans};
@ -62,21 +62,29 @@ pub struct DummyOutputPin;
impl embedded_hal::digital::v2::OutputPin for DummyOutputPin { impl embedded_hal::digital::v2::OutputPin for DummyOutputPin {
type Error = (); type Error = ();
fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) } fn set_low(&mut self) -> Result<(), Self::Error> {
fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } Ok(())
}
fn set_high(&mut self) -> Result<(), Self::Error> {
Ok(())
}
} }
pub fn new_ds3231(
pub fn new_ds3231(transactions: &[I2cTrans]) -> Ds323x<interface::I2cInterface<I2cMock>, ic::DS3231> { transactions: &[I2cTrans],
) -> Ds323x<interface::I2cInterface<I2cMock>, ic::DS3231> {
Ds323x::new_ds3231(I2cMock::new(&transactions)) Ds323x::new_ds3231(I2cMock::new(&transactions))
} }
pub fn new_ds3232(transactions: &[I2cTrans]) -> Ds323x<interface::I2cInterface<I2cMock>, ic::DS3232> { pub fn new_ds3232(
transactions: &[I2cTrans],
) -> Ds323x<interface::I2cInterface<I2cMock>, ic::DS3232> {
Ds323x::new_ds3232(I2cMock::new(&transactions)) Ds323x::new_ds3232(I2cMock::new(&transactions))
} }
pub fn new_ds3234(transactions: &[SpiTrans]) pub fn new_ds3234(
-> Ds323x<interface::SpiInterface<SpiMock, DummyOutputPin>, ic::DS3234> { transactions: &[SpiTrans],
) -> Ds323x<interface::SpiInterface<SpiMock, DummyOutputPin>, ic::DS3234> {
Ds323x::new_ds3234(SpiMock::new(&transactions), DummyOutputPin) Ds323x::new_ds3234(SpiMock::new(&transactions), DummyOutputPin)
} }
@ -123,7 +131,7 @@ macro_rules! assert_invalid_input_data {
($result:expr) => { ($result:expr) => {
match $result { match $result {
Err(Error::InvalidInputData) => (), Err(Error::InvalidInputData) => (),
_ => panic!("InvalidInputData error not returned.") _ => panic!("InvalidInputData error not returned."),
} }
}; };
} }
@ -158,9 +166,30 @@ macro_rules! _get_param_test {
($name:ident, $method:ident, $value:expr, $i2c_transactions:expr, $spi_transactions:expr) => { ($name:ident, $method:ident, $value:expr, $i2c_transactions:expr, $spi_transactions:expr) => {
mod $name { mod $name {
use super::*; use super::*;
get_test!(can_get_ds3231, $method, new_ds3231, destroy_ds3231, $value, $i2c_transactions); get_test!(
get_test!(can_get_ds3232, $method, new_ds3232, destroy_ds3232, $value, $i2c_transactions); can_get_ds3231,
get_test!(can_get_ds3234, $method, new_ds3234, destroy_ds3234, $value, $spi_transactions); $method,
new_ds3231,
destroy_ds3231,
$value,
$i2c_transactions
);
get_test!(
can_get_ds3232,
$method,
new_ds3232,
destroy_ds3232,
$value,
$i2c_transactions
);
get_test!(
can_get_ds3234,
$method,
new_ds3234,
destroy_ds3234,
$value,
$spi_transactions
);
} }
}; };
} }
@ -168,9 +197,20 @@ macro_rules! _get_param_test {
#[macro_export] #[macro_export]
macro_rules! get_param_test { macro_rules! get_param_test {
($name:ident, $method:ident, $register:ident, $value:expr, $binary_value:expr) => { ($name:ident, $method:ident, $register:ident, $value:expr, $binary_value:expr) => {
_get_param_test!($name, $method, $value, _get_param_test!(
[ I2cTrans::write_read(DEV_ADDR, vec![Register::$register], vec![$binary_value]) ], $name,
[ SpiTrans::transfer(vec![Register::$register, 0], vec![Register::$register, $binary_value]) ]); $method,
$value,
[I2cTrans::write_read(
DEV_ADDR,
vec![Register::$register],
vec![$binary_value]
)],
[SpiTrans::transfer(
vec![Register::$register, 0],
vec![Register::$register, $binary_value]
)]
);
}; };
} }
@ -188,9 +228,30 @@ macro_rules! _set_param_test {
($name:ident, $method:ident, $value:expr, $i2c_transactions:expr, $spi_transactions:expr) => { ($name:ident, $method:ident, $value:expr, $i2c_transactions:expr, $spi_transactions:expr) => {
mod $name { mod $name {
use super::*; use super::*;
set_test!(can_set_ds3231, $method, new_ds3231, destroy_ds3231, $value, $i2c_transactions); set_test!(
set_test!(can_set_ds3232, $method, new_ds3232, destroy_ds3232, $value, $i2c_transactions); can_set_ds3231,
set_test!(can_set_ds3234, $method, new_ds3234, destroy_ds3234, $value, $spi_transactions); $method,
new_ds3231,
destroy_ds3231,
$value,
$i2c_transactions
);
set_test!(
can_set_ds3232,
$method,
new_ds3232,
destroy_ds3232,
$value,
$i2c_transactions
);
set_test!(
can_set_ds3234,
$method,
new_ds3234,
destroy_ds3234,
$value,
$spi_transactions
);
} }
}; };
} }
@ -198,8 +259,18 @@ macro_rules! _set_param_test {
#[macro_export] #[macro_export]
macro_rules! set_param_test { macro_rules! set_param_test {
($name:ident, $method:ident, $register:ident, $value:expr, $binary_value:expr) => { ($name:ident, $method:ident, $register:ident, $value:expr, $binary_value:expr) => {
_set_param_test!($name, $method, $value, _set_param_test!(
[ I2cTrans::write(DEV_ADDR, vec![Register::$register, $binary_value]) ], $name,
[ SpiTrans::write(vec![Register::$register + 0x80, $binary_value]) ]); $method,
$value,
[I2cTrans::write(
DEV_ADDR,
vec![Register::$register, $binary_value]
)],
[SpiTrans::write(vec![
Register::$register + 0x80,
$binary_value
])]
);
}; };
} }

View File

@ -6,27 +6,55 @@ extern crate ds323x;
use ds323x::SqWFreq; use ds323x::SqWFreq;
mod common; mod common;
use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, new_ds3231, use common::{
new_ds3232, new_ds3234, destroy_ds3231, destroy_ds3232, destroy_ds3231, destroy_ds3232, destroy_ds3234, new_ds3231, new_ds3232, new_ds3234,
destroy_ds3234, BitFlags as BF, CONTROL_POR_VALUE, BitFlags as BF, Register, CONTROL_POR_VALUE, DEVICE_ADDRESS as DEV_ADDR, DS3231_POR_STATUS,
DS3231_POR_STATUS, DS323X_POR_STATUS }; DS323X_POR_STATUS,
};
macro_rules! call_triple_test { macro_rules! call_triple_test {
($name:ident, $method:ident, $i2c_transactions:expr, $spi_transactions:expr) => { ($name:ident, $method:ident, $i2c_transactions:expr, $spi_transactions:expr) => {
mod $name { mod $name {
use super::*; use super::*;
call_test!(can_call_ds3231, $method, new_ds3231, destroy_ds3231, $i2c_transactions); call_test!(
call_test!(can_call_ds3232, $method, new_ds3232, destroy_ds3232, $i2c_transactions); can_call_ds3231,
call_test!(can_call_ds3234, $method, new_ds3234, destroy_ds3234, $spi_transactions); $method,
new_ds3231,
destroy_ds3231,
$i2c_transactions
);
call_test!(
can_call_ds3232,
$method,
new_ds3232,
destroy_ds3232,
$i2c_transactions
);
call_test!(
can_call_ds3234,
$method,
new_ds3234,
destroy_ds3234,
$spi_transactions
);
} }
}; };
} }
macro_rules! call_method_test { macro_rules! call_method_test {
($name:ident, $method:ident, $register:ident, $value_enabled:expr) => { ($name:ident, $method:ident, $register:ident, $value_enabled:expr) => {
call_triple_test!($name, $method, call_triple_test!(
[ I2cTrans::write(DEV_ADDR, vec![Register::$register, $value_enabled]) ], $name,
[ SpiTrans::write(vec![Register::$register + 0x80, $value_enabled]) ]); $method,
[I2cTrans::write(
DEV_ADDR,
vec![Register::$register, $value_enabled]
)],
[SpiTrans::write(vec![
Register::$register + 0x80,
$value_enabled
])]
);
}; };
} }
@ -34,12 +62,36 @@ macro_rules! call_method_status_test {
($name:ident, $method:ident, $value_ds3231:expr, $value_ds323x:expr) => { ($name:ident, $method:ident, $value_ds3231:expr, $value_ds323x:expr) => {
mod $name { mod $name {
use super::*; use super::*;
call_test!(can_call_ds3231, $method, new_ds3231, destroy_ds3231, call_test!(
[ I2cTrans::write(DEV_ADDR, vec![Register::STATUS, $value_ds3231]) ]); can_call_ds3231,
call_test!(can_call_ds3232, $method, new_ds3232, destroy_ds3232, $method,
[ I2cTrans::write(DEV_ADDR, vec![Register::STATUS, $value_ds323x]) ]); new_ds3231,
call_test!(can_call_ds3234, $method, new_ds3234, destroy_ds3234, destroy_ds3231,
[ SpiTrans::write(vec![Register::STATUS + 0x80, $value_ds323x]) ]); [I2cTrans::write(
DEV_ADDR,
vec![Register::STATUS, $value_ds3231]
)]
);
call_test!(
can_call_ds3232,
$method,
new_ds3232,
destroy_ds3232,
[I2cTrans::write(
DEV_ADDR,
vec![Register::STATUS, $value_ds323x]
)]
);
call_test!(
can_call_ds3234,
$method,
new_ds3234,
destroy_ds3234,
[SpiTrans::write(vec![
Register::STATUS + 0x80,
$value_ds323x
])]
);
} }
}; };
} }
@ -48,16 +100,39 @@ macro_rules! change_if_necessary_test {
($name:ident, $method:ident, $register:ident, $value_enabled:expr, $value_disabled:expr) => { ($name:ident, $method:ident, $register:ident, $value_enabled:expr, $value_disabled:expr) => {
mod $name { mod $name {
use super::*; use super::*;
call_triple_test!(do_nothing_if_not_necessary, $method, call_triple_test!(
[ I2cTrans::write_read(DEV_ADDR, vec![Register::$register], vec![$value_enabled]) ], do_nothing_if_not_necessary,
[ SpiTrans::transfer(vec![Register::$register, 0], vec![Register::$register, $value_enabled]) ]); $method,
[I2cTrans::write_read(
DEV_ADDR,
vec![Register::$register],
vec![$value_enabled]
)],
[SpiTrans::transfer(
vec![Register::$register, 0],
vec![Register::$register, $value_enabled]
)]
);
call_triple_test!(change, $method, call_triple_test!(
[ I2cTrans::write_read(DEV_ADDR, vec![Register::$register], vec![$value_disabled]), change,
I2cTrans::write(DEV_ADDR, vec![Register::$register, $value_enabled]) ], $method,
[
[ SpiTrans::transfer(vec![Register::$register, 0], vec![Register::$register, $value_disabled]), I2cTrans::write_read(
SpiTrans::write(vec![Register::$register + 0x80, $value_enabled]) ]); DEV_ADDR,
vec![Register::$register],
vec![$value_disabled]
),
I2cTrans::write(DEV_ADDR, vec![Register::$register, $value_enabled])
],
[
SpiTrans::transfer(
vec![Register::$register, 0],
vec![Register::$register, $value_disabled]
),
SpiTrans::write(vec![Register::$register + 0x80, $value_enabled])
]
);
} }
}; };
} }

View File

@ -1,6 +1,5 @@
mod common; mod common;
use common::{ new_ds3231, destroy_ds3231, new_ds3232, destroy_ds3232, use common::{destroy_ds3231, destroy_ds3232, destroy_ds3234, new_ds3231, new_ds3232, new_ds3234};
new_ds3234, destroy_ds3234 };
macro_rules! construction_test { macro_rules! construction_test {
($name:ident, $create:ident, $destroy:ident) => { ($name:ident, $create:ident, $destroy:ident) => {

View File

@ -2,11 +2,12 @@ extern crate embedded_hal_mock as hal;
use hal::i2c::Transaction as I2cTrans; use hal::i2c::Transaction as I2cTrans;
use hal::spi::Transaction as SpiTrans; use hal::spi::Transaction as SpiTrans;
mod common; mod common;
use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, new_ds3231, use common::{
new_ds3232, new_ds3234, destroy_ds3231, destroy_ds3232, destroy_ds3231, destroy_ds3232, destroy_ds3234, new_ds3231, new_ds3232, new_ds3234, Register,
destroy_ds3234 }; DEVICE_ADDRESS as DEV_ADDR,
};
extern crate ds323x; extern crate ds323x;
use ds323x::{ Hours, DateTime, Error }; use ds323x::{DateTime, Error, Hours};
macro_rules! set_param_write_array_test { macro_rules! set_param_write_array_test {
($name:ident, $method:ident, $value:expr, $register:ident, [ $( $exp_bin:expr ),+ ] ) => { ($name:ident, $method:ident, $value:expr, $register:ident, [ $( $exp_bin:expr ),+ ] ) => {
@ -18,23 +19,51 @@ macro_rules! set_param_write_array_test {
macro_rules! read_set_param_write_two_test { macro_rules! read_set_param_write_two_test {
($name:ident, $method:ident, $value:expr, $register:ident, $binary_value1_read:expr, $bin1:expr, $bin2:expr) => { ($name:ident, $method:ident, $value:expr, $register:ident, $binary_value1_read:expr, $bin1:expr, $bin2:expr) => {
_set_param_test!($name, $method, $value, _set_param_test!(
[ I2cTrans::write_read(DEV_ADDR, vec![Register::$register], vec![$binary_value1_read]), $name,
I2cTrans::write(DEV_ADDR, vec![Register::$register, $bin1, $bin2]) ], $method,
$value,
[ SpiTrans::transfer(vec![Register::$register, 0], vec![Register::$register, $binary_value1_read]), [
SpiTrans::write(vec![Register::$register + 0x80, $bin1, $bin2]) ]); I2cTrans::write_read(
DEV_ADDR,
vec![Register::$register],
vec![$binary_value1_read]
),
I2cTrans::write(DEV_ADDR, vec![Register::$register, $bin1, $bin2])
],
[
SpiTrans::transfer(
vec![Register::$register, 0],
vec![Register::$register, $binary_value1_read]
),
SpiTrans::write(vec![Register::$register + 0x80, $bin1, $bin2])
]
);
}; };
} }
macro_rules! read_set_param_test { macro_rules! read_set_param_test {
($name:ident, $method:ident, $register:ident, $value:expr, $binary_value_read:expr, $binary_value_write:expr) => { ($name:ident, $method:ident, $register:ident, $value:expr, $binary_value_read:expr, $binary_value_write:expr) => {
_set_param_test!($name, $method, $value, _set_param_test!(
[ I2cTrans::write_read(DEV_ADDR, vec![Register::$register], vec![$binary_value_read]), $name,
I2cTrans::write(DEV_ADDR, vec![Register::$register, $binary_value_write]) ], $method,
$value,
[ SpiTrans::transfer(vec![Register::$register, 0], vec![Register::$register, $binary_value_read]), [
SpiTrans::write(vec![Register::$register + 0x80, $binary_value_write]) ]); I2cTrans::write_read(
DEV_ADDR,
vec![Register::$register],
vec![$binary_value_read]
),
I2cTrans::write(DEV_ADDR, vec![Register::$register, $binary_value_write])
],
[
SpiTrans::transfer(
vec![Register::$register, 0],
vec![Register::$register, $binary_value_read]
),
SpiTrans::write(vec![Register::$register + 0x80, $binary_value_write])
]
);
}; };
} }
@ -42,9 +71,27 @@ macro_rules! set_invalid_param_test {
($name:ident, $method:ident, $value:expr) => { ($name:ident, $method:ident, $value:expr) => {
mod $name { mod $name {
use super::*; use super::*;
set_invalid_test!(cannot_set_invalid_ds3231, $method, new_ds3231, destroy_ds3231, $value); set_invalid_test!(
set_invalid_test!(cannot_set_invalid_ds3232, $method, new_ds3232, destroy_ds3232, $value); cannot_set_invalid_ds3231,
set_invalid_test!(cannot_set_invalid_ds3234, $method, new_ds3234, destroy_ds3234, $value); $method,
new_ds3231,
destroy_ds3231,
$value
);
set_invalid_test!(
cannot_set_invalid_ds3232,
$method,
new_ds3232,
destroy_ds3232,
$value
);
set_invalid_test!(
cannot_set_invalid_ds3234,
$method,
new_ds3234,
destroy_ds3234,
$value
);
} }
}; };
} }
@ -123,11 +170,41 @@ mod month {
mod year { mod year {
use super::*; use super::*;
get_param_read_array_test!(century0_get, get_year, 2099, MONTH, [ 0, 0b1001_1001 ], [0, 0]); get_param_read_array_test!(
read_set_param_write_two_test!(century0_set, set_year, 2099, MONTH, 0b1001_0010, 0b0001_0010, 0b1001_1001); century0_get,
get_year,
2099,
MONTH,
[0, 0b1001_1001],
[0, 0]
);
read_set_param_write_two_test!(
century0_set,
set_year,
2099,
MONTH,
0b1001_0010,
0b0001_0010,
0b1001_1001
);
get_param_read_array_test!(century1_get, get_year, 2100, MONTH, [ 0b1000_0000, 0 ], [0, 0]); get_param_read_array_test!(
read_set_param_write_two_test!(century1_set, set_year, 2100, MONTH, 0b0001_0010, 0b1001_0010, 0); century1_get,
get_year,
2100,
MONTH,
[0b1000_0000, 0],
[0, 0]
);
read_set_param_write_two_test!(
century1_set,
set_year,
2100,
MONTH,
0b0001_0010,
0b1001_0010,
0
);
set_invalid_param_range_test!(invalid, set_year, 1999, 2101); set_invalid_param_range_test!(invalid, set_year, 1999, 2101);
} }
@ -137,8 +214,15 @@ macro_rules! invalid_dt_test {
$hour:expr, $minute:expr, $second:expr) => { $hour:expr, $minute:expr, $second:expr) => {
mod $name { mod $name {
use super::*; use super::*;
const DT : DateTime = DateTime { year: $year, month: $month, day: $day, weekday: $weekday, const DT: DateTime = DateTime {
hour: $hour, minute: $minute, second: $second }; year: $year,
month: $month,
day: $day,
weekday: $weekday,
hour: $hour,
minute: $minute,
second: $second,
};
set_invalid_param_test!($name, set_datetime, &DT); set_invalid_param_test!($name, set_datetime, &DT);
} }
}; };
@ -146,16 +230,47 @@ macro_rules! invalid_dt_test {
mod datetime { mod datetime {
use super::*; use super::*;
const DT : DateTime = DateTime { year: 2018, month: 8, day: 13, weekday: 2, const DT: DateTime = DateTime {
hour: Hours::H24(23), minute: 59, second: 58 }; year: 2018,
get_param_read_array_test!(get, get_datetime, DT, SECONDS, month: 8,
[0b0101_1000, 0b0101_1001, 0b0010_0011, 0b0000_0010, day: 13,
0b0001_0011, 0b0000_1000, 0b0001_1000], weekday: 2,
[0, 0, 0, 0, 0, 0, 0]); 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]
);
set_param_write_array_test!(set, set_datetime, &DT, SECONDS, set_param_write_array_test!(
[0b0101_1000, 0b0101_1001, 0b0010_0011, 0b0000_0010, set,
0b0001_0011, 0b0000_1000, 0b0001_1000]); 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_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_big_year, 2101, 8, 13, 2, Hours::H24(23), 59, 58);

View File

@ -7,18 +7,29 @@ use ds323x::TempConvRate;
#[allow(unused)] #[allow(unused)]
mod common; mod common;
use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, use common::{
new_ds3232, new_ds3234, destroy_ds3232, destroy_ds3232, destroy_ds3234, new_ds3232, new_ds3234, BitFlags as BF, Register,
destroy_ds3234, BitFlags as BF, DS323X_POR_STATUS }; DEVICE_ADDRESS as DEV_ADDR, DS323X_POR_STATUS,
};
macro_rules! call_method_status_test { macro_rules! call_method_status_test {
($name:ident, $method:ident, $value:expr) => { ($name:ident, $method:ident, $value:expr) => {
mod $name { mod $name {
use super::*; use super::*;
call_test!(can_call_ds3232, $method, new_ds3232, destroy_ds3232, call_test!(
[ I2cTrans::write(DEV_ADDR, vec![Register::STATUS, $value]) ]); can_call_ds3232,
call_test!(can_call_ds3234, $method, new_ds3234, destroy_ds3234, $method,
[ SpiTrans::write(vec![Register::STATUS + 0x80, $value]) ]); new_ds3232,
destroy_ds3232,
[I2cTrans::write(DEV_ADDR, vec![Register::STATUS, $value])]
);
call_test!(
can_call_ds3234,
$method,
new_ds3234,
destroy_ds3234,
[SpiTrans::write(vec![Register::STATUS + 0x80, $value])]
);
} }
}; };
} }
@ -28,8 +39,22 @@ macro_rules! _set_param_test_2_4 {
($name:ident, $method:ident, $value:expr, $i2c_transactions:expr, $spi_transactions:expr) => { ($name:ident, $method:ident, $value:expr, $i2c_transactions:expr, $spi_transactions:expr) => {
mod $name { mod $name {
use super::*; use super::*;
set_test!(can_set_ds3232, $method, new_ds3232, destroy_ds3232, $value, $i2c_transactions); set_test!(
set_test!(can_set_ds3234, $method, new_ds3234, destroy_ds3234, $value, $spi_transactions); can_set_ds3232,
$method,
new_ds3232,
destroy_ds3232,
$value,
$i2c_transactions
);
set_test!(
can_set_ds3234,
$method,
new_ds3234,
destroy_ds3234,
$value,
$spi_transactions
);
} }
}; };
} }
@ -37,9 +62,19 @@ macro_rules! _set_param_test_2_4 {
#[macro_export] #[macro_export]
macro_rules! set_param_test_2_4 { macro_rules! set_param_test_2_4 {
($name:ident, $method:ident, $register:ident, $value:expr, $binary_value:expr) => { ($name:ident, $method:ident, $register:ident, $value:expr, $binary_value:expr) => {
_set_param_test_2_4!($name, $method, $value, _set_param_test_2_4!(
[ I2cTrans::write(DEV_ADDR, vec![Register::$register, $binary_value]) ], $name,
[ SpiTrans::write(vec![Register::$register + 0x80, $binary_value]) ]); $method,
$value,
[I2cTrans::write(
DEV_ADDR,
vec![Register::$register, $binary_value]
)],
[SpiTrans::write(vec![
Register::$register + 0x80,
$binary_value
])]
);
}; };
} }

View File

@ -3,10 +3,23 @@ use hal::spi::Transaction as SpiTrans;
#[allow(unused)] #[allow(unused)]
mod common; mod common;
use common::{ new_ds3234, destroy_ds3234, Register, BitFlags }; use common::{destroy_ds3234, new_ds3234, BitFlags, Register};
call_test!(can_en_temp_conv_bat, enable_temperature_conversions_on_battery, new_ds3234, destroy_ds3234, call_test!(
[ SpiTrans::write(vec![Register::TEMP_CONV + 0x80, 0]) ]); can_en_temp_conv_bat,
enable_temperature_conversions_on_battery,
new_ds3234,
destroy_ds3234,
[SpiTrans::write(vec![Register::TEMP_CONV + 0x80, 0])]
);
call_test!(can_dis_temp_conv_bat, disable_temperature_conversions_on_battery, new_ds3234, destroy_ds3234, call_test!(
[ SpiTrans::write(vec![Register::TEMP_CONV + 0x80, BitFlags::TEMP_CONV_BAT]) ]); can_dis_temp_conv_bat,
disable_temperature_conversions_on_battery,
new_ds3234,
destroy_ds3234,
[SpiTrans::write(vec![
Register::TEMP_CONV + 0x80,
BitFlags::TEMP_CONV_BAT
])]
);

View File

@ -2,9 +2,10 @@ extern crate embedded_hal_mock as hal;
use hal::i2c::Transaction as I2cTrans; use hal::i2c::Transaction as I2cTrans;
use hal::spi::Transaction as SpiTrans; use hal::spi::Transaction as SpiTrans;
mod common; mod common;
use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, new_ds3231, use common::{
new_ds3232, new_ds3234, destroy_ds3231, destroy_ds3232, destroy_ds3231, destroy_ds3232, destroy_ds3234, new_ds3231, new_ds3232, new_ds3234,
destroy_ds3234, BitFlags as BF }; BitFlags as BF, Register, DEVICE_ADDRESS as DEV_ADDR,
};
get_param_test!(is_running, is_running, CONTROL, true, 0); get_param_test!(is_running, is_running, CONTROL, true, 0);
get_param_test!(is_not_running, is_running, CONTROL, false, BF::EOSC); get_param_test!(is_not_running, is_running, CONTROL, false, BF::EOSC);
@ -16,11 +17,37 @@ get_param_test!(stopped, has_been_stopped, STATUS, true, 0xFF);
get_param_test!(not_stopped, has_been_stopped, STATUS, false, !BF::OSC_STOP); get_param_test!(not_stopped, has_been_stopped, STATUS, false, !BF::OSC_STOP);
get_param_test!(alarm1_matched, has_alarm1_matched, STATUS, true, 0xFF); get_param_test!(alarm1_matched, has_alarm1_matched, STATUS, true, 0xFF);
get_param_test!(alarm1_not_matched, has_alarm1_matched, STATUS, false, !BF::ALARM1F); get_param_test!(
alarm1_not_matched,
has_alarm1_matched,
STATUS,
false,
!BF::ALARM1F
);
get_param_test!(alarm2_matched, has_alarm2_matched, STATUS, true, 0xFF); get_param_test!(alarm2_matched, has_alarm2_matched, STATUS, true, 0xFF);
get_param_test!(alarm2_not_matched, has_alarm2_matched, STATUS, false, !BF::ALARM2F); get_param_test!(
alarm2_not_matched,
has_alarm2_matched,
STATUS,
false,
!BF::ALARM2F
);
get_param_read_array_test!(temp_0, get_temperature, 0.0, TEMP_MSB, [0, 0], [0, 0]); get_param_read_array_test!(temp_0, get_temperature, 0.0, TEMP_MSB, [0, 0], [0, 0]);
get_param_read_array_test!(temp_min, get_temperature, -128.0, TEMP_MSB, [0b1000_0000, 0], [0, 0]); get_param_read_array_test!(
get_param_read_array_test!(temp_max, get_temperature, 127.75, TEMP_MSB, [0b0111_1111, 0b1100_0000], [0, 0]); temp_min,
get_temperature,
-128.0,
TEMP_MSB,
[0b1000_0000, 0],
[0, 0]
);
get_param_read_array_test!(
temp_max,
get_temperature,
127.75,
TEMP_MSB,
[0b0111_1111, 0b1100_0000],
[0, 0]
);