use bitfield::bitfield;
#[allow(unused)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum RegAddr {
Seconds = 0x00,
Minutes = 0x01,
Hours = 0x02,
Day = 0x03,
Date = 0x04,
Month = 0x05,
Year = 0x06,
Alarm1Seconds = 0x07,
Alarm1Minutes = 0x08,
Alarm1Hours = 0x09,
Alarm1DayDate = 0x0A,
Alarm2Minutes = 0x0B,
Alarm2Hours = 0x0C,
Alarm2DayDate = 0x0D,
Control = 0x0E,
ControlStatus = 0x0F,
AgingOffset = 0x10,
MSBTemp = 0x11,
LSBTemp = 0x12,
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum TimeRepresentation {
TwentyFourHour = 0,
TwelveHour = 1,
}
impl From<u8> for TimeRepresentation {
fn from(v: u8) -> Self {
match v {
0 => TimeRepresentation::TwentyFourHour,
1 => TimeRepresentation::TwelveHour,
_ => panic!("Invalid value for TimeRepresentation: {}", v),
}
}
}
impl From<TimeRepresentation> for u8 {
fn from(v: TimeRepresentation) -> Self {
v as u8
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Oscillator {
Enabled = 0,
Disabled = 1,
}
impl From<u8> for Oscillator {
fn from(v: u8) -> Self {
match v {
0 => Oscillator::Enabled,
1 => Oscillator::Disabled,
_ => panic!("Invalid value for Oscillator: {}", v),
}
}
}
impl From<Oscillator> for u8 {
fn from(v: Oscillator) -> Self {
v as u8
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum InterruptControl {
SquareWave = 0,
Interrupt = 1,
}
impl From<u8> for InterruptControl {
fn from(v: u8) -> Self {
match v {
0 => InterruptControl::SquareWave,
1 => InterruptControl::Interrupt,
_ => panic!("Invalid value for InterruptControl: {}", v),
}
}
}
impl From<InterruptControl> for u8 {
fn from(v: InterruptControl) -> Self {
v as u8
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum SquareWaveFrequency {
Hz1 = 0b00,
Hz1024 = 0b01,
Hz4096 = 0b10,
Hz8192 = 0b11,
}
impl From<u8> for SquareWaveFrequency {
fn from(v: u8) -> Self {
match v {
0b00 => SquareWaveFrequency::Hz1,
0b01 => SquareWaveFrequency::Hz1024,
0b10 => SquareWaveFrequency::Hz4096,
0b11 => SquareWaveFrequency::Hz8192,
_ => panic!("Invalid value for SquareWaveFrequency: {}", v),
}
}
}
impl From<SquareWaveFrequency> for u8 {
fn from(v: SquareWaveFrequency) -> Self {
v as u8
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum DayDateSelect {
Date = 0,
Day = 1,
}
impl From<u8> for DayDateSelect {
fn from(v: u8) -> Self {
match v {
0 => DayDateSelect::Date,
1 => DayDateSelect::Day,
_ => panic!("Invalid value for DayDateSelect: {}", v),
}
}
}
impl From<DayDateSelect> for u8 {
fn from(v: DayDateSelect) -> Self {
v as u8
}
}
macro_rules! from_register_u8 {
($typ:ty) => {
impl From<u8> for $typ {
fn from(v: u8) -> Self {
paste::paste!([< $typ >](v))
}
}
impl From<$typ> for u8 {
fn from(v: $typ) -> Self {
v.0
}
}
};
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Seconds(u8);
impl Debug;
pub ten_seconds, set_ten_seconds: 6, 4;
pub seconds, set_seconds: 3, 0;
}
from_register_u8!(Seconds);
#[cfg(feature = "defmt")]
impl defmt::Format for Seconds {
fn format(&self, f: defmt::Formatter) {
let seconds = 10 * self.ten_seconds() + self.seconds();
defmt::write!(f, "Seconds({}s)", seconds);
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Minutes(u8);
impl Debug;
pub ten_minutes, set_ten_minutes: 6, 4;
pub minutes, set_minutes: 3, 0;
}
from_register_u8!(Minutes);
#[cfg(feature = "defmt")]
impl defmt::Format for Minutes {
fn format(&self, f: defmt::Formatter) {
let minutes = 10 * self.ten_minutes() + self.minutes();
defmt::write!(f, "Minutes({}m)", minutes);
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Hours(u8);
impl Debug;
pub from into TimeRepresentation, time_representation, set_time_representation: 6, 6;
pub pm_or_twenty_hours, set_pm_or_twenty_hours: 5, 5;
pub ten_hours, set_ten_hours: 4, 4;
pub hours, set_hours: 3, 0;
}
from_register_u8!(Hours);
#[cfg(feature = "defmt")]
impl defmt::Format for Hours {
fn format(&self, f: defmt::Formatter) {
let hours = 10 * self.ten_hours() + self.hours();
match self.time_representation() {
TimeRepresentation::TwentyFourHour => {
let hours = hours + 20 * self.pm_or_twenty_hours();
defmt::write!(f, "Hours({}h 24h)", hours);
}
TimeRepresentation::TwelveHour => {
let is_pm = self.pm_or_twenty_hours() != 0;
defmt::write!(f, "Hours({}h {})", hours, if is_pm { "PM" } else { "AM" });
}
}
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Day(u8);
impl Debug;
pub day, set_day: 2, 0;
}
from_register_u8!(Day);
#[cfg(feature = "defmt")]
impl defmt::Format for Day {
fn format(&self, f: defmt::Formatter) {
defmt::write!(f, "Day({})", self.day());
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Date(u8);
impl Debug;
pub ten_date, set_ten_date: 5, 4;
pub date, set_date: 3, 0;
}
from_register_u8!(Date);
#[cfg(feature = "defmt")]
impl defmt::Format for Date {
fn format(&self, f: defmt::Formatter) {
let date = 10 * self.ten_date() + self.date();
defmt::write!(f, "Date({})", date);
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Month(u8);
impl Debug;
pub century, set_century: 7;
pub ten_month, set_ten_month: 4, 4;
pub month, set_month: 3, 0;
}
from_register_u8!(Month);
#[cfg(feature = "defmt")]
impl defmt::Format for Month {
fn format(&self, f: defmt::Formatter) {
let month = 10 * self.ten_month() + self.month();
defmt::write!(f, "Month({}", month);
if self.century() {
defmt::write!(f, ", century");
}
defmt::write!(f, ")");
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Year(u8);
impl Debug;
pub ten_year, set_ten_year: 7, 4;
pub year, set_year: 3, 0;
}
from_register_u8!(Year);
#[cfg(feature = "defmt")]
impl defmt::Format for Year {
fn format(&self, f: defmt::Formatter) {
let year = 10 * self.ten_year() + self.year();
defmt::write!(f, "Year({})", year);
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Control(u8);
impl Debug;
pub from into Oscillator, oscillator_enable, set_oscillator_enable: 7, 7;
pub battery_backed_square_wave, set_battery_backed_square_wave: 6;
pub convert_temperature, set_convert_temperature: 5;
pub from into SquareWaveFrequency, square_wave_frequency, set_square_wave_frequency: 4, 3;
pub from into InterruptControl, interrupt_control, set_interrupt_control: 2, 2;
pub alarm2_interrupt_enable, set_alarm2_interrupt_enable: 1;
pub alarm1_interrupt_enable, set_alarm1_interrupt_enable: 0;
}
from_register_u8!(Control);
#[cfg(feature = "defmt")]
impl defmt::Format for Control {
fn format(&self, f: defmt::Formatter) {
match self.oscillator_enable() {
Oscillator::Enabled => defmt::write!(f, "Oscillator enabled"),
Oscillator::Disabled => defmt::write!(f, "Oscillator disabled"),
}
if self.battery_backed_square_wave() {
defmt::write!(f, ", Battery backed square wave enabled");
}
if self.convert_temperature() {
defmt::write!(f, ", Temperature conversion enabled");
}
match self.square_wave_frequency() {
SquareWaveFrequency::Hz1 => defmt::write!(f, ", 1 Hz square wave"),
SquareWaveFrequency::Hz1024 => defmt::write!(f, ", 1024 Hz square wave"),
SquareWaveFrequency::Hz4096 => defmt::write!(f, ", 4096 Hz square wave"),
SquareWaveFrequency::Hz8192 => defmt::write!(f, ", 8192 Hz square wave"),
}
match self.interrupt_control() {
InterruptControl::SquareWave => defmt::write!(f, ", Square wave output"),
InterruptControl::Interrupt => defmt::write!(f, ", Interrupt output"),
}
if self.alarm2_interrupt_enable() {
defmt::write!(f, ", Alarm 2 interrupt enabled");
}
if self.alarm1_interrupt_enable() {
defmt::write!(f, ", Alarm 1 interrupt enabled");
}
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Status(u8);
impl Debug;
pub oscillator_stop_flag, set_oscillator_stop_flag: 7;
pub enable_32khz_output, set_enable_32khz_output: 3;
pub busy, set_busy: 2;
pub alarm2_flag, set_alarm2_flag: 1;
pub alarm1_flag, set_alarm1_flag: 0;
}
from_register_u8!(Status);
#[cfg(feature = "defmt")]
impl defmt::Format for Status {
fn format(&self, f: defmt::Formatter) {
defmt::write!(f, "Status(");
let mut first = true;
if self.oscillator_stop_flag() {
defmt::write!(f, "OSF");
first = false;
}
if self.enable_32khz_output() {
if !first {
defmt::write!(f, ", ");
}
defmt::write!(f, "EN32kHz");
first = false;
}
if self.busy() {
if !first {
defmt::write!(f, ", ");
}
defmt::write!(f, "BSY");
first = false;
}
if self.alarm2_flag() {
if !first {
defmt::write!(f, ", ");
}
defmt::write!(f, "A2F");
first = false;
}
if self.alarm1_flag() {
if !first {
defmt::write!(f, ", ");
}
defmt::write!(f, "A1F");
first = false;
}
if first {
defmt::write!(f, "clear");
}
defmt::write!(f, ")");
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct AgingOffset(u8);
impl Debug;
pub i8, aging_offset, set_aging_offset: 7, 0;
}
from_register_u8!(AgingOffset);
#[cfg(feature = "defmt")]
impl defmt::Format for AgingOffset {
fn format(&self, f: defmt::Formatter) {
defmt::write!(f, "AgingOffset({})", self.aging_offset());
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct Temperature(u8);
impl Debug;
pub i8, temperature, set_temperature: 7, 0;
}
from_register_u8!(Temperature);
#[cfg(feature = "defmt")]
impl defmt::Format for Temperature {
fn format(&self, f: defmt::Formatter) {
defmt::write!(f, "Temperature({}°C)", self.temperature());
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct TemperatureFraction(u8);
impl Debug;
pub temperature_fraction, set_temperature_fraction: 7, 6;
}
from_register_u8!(TemperatureFraction);
#[cfg(feature = "defmt")]
impl defmt::Format for TemperatureFraction {
fn format(&self, f: defmt::Formatter) {
let fraction = self.temperature_fraction();
let quarter_degrees = (fraction >> 6) & 0x03;
match quarter_degrees {
0 => defmt::write!(f, "TemperatureFraction(0.00°C)"),
1 => defmt::write!(f, "TemperatureFraction(0.25°C)"),
2 => defmt::write!(f, "TemperatureFraction(0.50°C)"),
3 => defmt::write!(f, "TemperatureFraction(0.75°C)"),
_ => defmt::write!(f, "TemperatureFraction(invalid)"),
}
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct AlarmSeconds(u8);
impl Debug;
pub alarm_mask1, set_alarm_mask1: 7;
pub ten_seconds, set_ten_seconds: 6, 4;
pub seconds, set_seconds: 3, 0;
}
from_register_u8!(AlarmSeconds);
#[cfg(feature = "defmt")]
impl defmt::Format for AlarmSeconds {
fn format(&self, f: defmt::Formatter) {
let seconds = 10 * self.ten_seconds() + self.seconds();
defmt::write!(f, "AlarmSeconds({}s", seconds);
if self.alarm_mask1() {
defmt::write!(f, ", masked");
}
defmt::write!(f, ")");
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct AlarmMinutes(u8);
impl Debug;
pub alarm_mask2, set_alarm_mask2: 7;
pub ten_minutes, set_ten_minutes: 6, 4;
pub minutes, set_minutes: 3, 0;
}
from_register_u8!(AlarmMinutes);
#[cfg(feature = "defmt")]
impl defmt::Format for AlarmMinutes {
fn format(&self, f: defmt::Formatter) {
let minutes = 10 * self.ten_minutes() + self.minutes();
defmt::write!(f, "AlarmMinutes({}m", minutes);
if self.alarm_mask2() {
defmt::write!(f, ", masked");
}
defmt::write!(f, ")");
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct AlarmHours(u8);
impl Debug;
pub alarm_mask3, set_alarm_mask3: 7;
pub from into TimeRepresentation, time_representation, set_time_representation: 6, 6;
pub pm_or_twenty_hours, set_pm_or_twenty_hours: 5, 5;
pub ten_hours, set_ten_hours: 4, 4;
pub hours, set_hours: 3, 0;
}
from_register_u8!(AlarmHours);
#[cfg(feature = "defmt")]
impl defmt::Format for AlarmHours {
fn format(&self, f: defmt::Formatter) {
let hours = 10 * self.ten_hours() + self.hours();
match self.time_representation() {
TimeRepresentation::TwentyFourHour => {
let hours = hours + 20 * self.pm_or_twenty_hours();
defmt::write!(f, "AlarmHours({}h", hours);
}
TimeRepresentation::TwelveHour => {
let is_pm = self.pm_or_twenty_hours() != 0;
defmt::write!(
f,
"AlarmHours({}h {}",
hours,
if is_pm { "PM" } else { "AM" }
);
}
}
if self.alarm_mask3() {
defmt::write!(f, ", masked");
}
defmt::write!(f, ")");
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
pub struct AlarmDayDate(u8);
impl Debug;
pub alarm_mask4, set_alarm_mask4: 7;
pub from into DayDateSelect, day_date_select, set_day_date_select: 6, 6;
pub ten_date, set_ten_date: 5, 4;
pub day_or_date, set_day_or_date: 3, 0;
}
from_register_u8!(AlarmDayDate);
#[cfg(feature = "defmt")]
impl defmt::Format for AlarmDayDate {
fn format(&self, f: defmt::Formatter) {
match self.day_date_select() {
DayDateSelect::Day => {
defmt::write!(f, "AlarmDayDate(day {})", self.day_or_date());
}
DayDateSelect::Date => {
let date = 10 * self.ten_date() + self.day_or_date();
defmt::write!(f, "AlarmDayDate(date {})", date);
}
}
if self.alarm_mask4() {
defmt::write!(f, ", masked");
}
defmt::write!(f, ")");
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_day_date_select_conversions() {
assert_eq!(DayDateSelect::from(0), DayDateSelect::Date);
assert_eq!(DayDateSelect::from(1), DayDateSelect::Day);
assert_eq!(u8::from(DayDateSelect::Date), 0);
assert_eq!(u8::from(DayDateSelect::Day), 1);
}
#[test]
#[should_panic(expected = "Invalid value for DayDateSelect: 2")]
fn test_invalid_day_date_select_conversion() {
let _ = DayDateSelect::from(2);
}
#[test]
fn test_seconds_register_conversions() {
let seconds = Seconds::from(0x59); assert_eq!(seconds.ten_seconds(), 5);
assert_eq!(seconds.seconds(), 9);
assert_eq!(u8::from(seconds), 0x59);
let seconds = Seconds::from(0x00); assert_eq!(seconds.ten_seconds(), 0);
assert_eq!(seconds.seconds(), 0);
assert_eq!(u8::from(seconds), 0x00);
let seconds = Seconds::from(0x30); assert_eq!(seconds.ten_seconds(), 3);
assert_eq!(seconds.seconds(), 0);
assert_eq!(u8::from(seconds), 0x30);
}
#[test]
fn test_minutes_register_conversions() {
let minutes = Minutes::from(0x59); assert_eq!(minutes.ten_minutes(), 5);
assert_eq!(minutes.minutes(), 9);
assert_eq!(u8::from(minutes), 0x59);
let minutes = Minutes::from(0x00); assert_eq!(minutes.ten_minutes(), 0);
assert_eq!(minutes.minutes(), 0);
assert_eq!(u8::from(minutes), 0x00);
let minutes = Minutes::from(0x45); assert_eq!(minutes.ten_minutes(), 4);
assert_eq!(minutes.minutes(), 5);
assert_eq!(u8::from(minutes), 0x45);
}
#[test]
fn test_hours_register_conversions() {
let hours = Hours::from(0x23); assert_eq!(
hours.time_representation(),
TimeRepresentation::TwentyFourHour
);
assert_eq!(hours.pm_or_twenty_hours(), 1); assert_eq!(hours.ten_hours(), 0);
assert_eq!(hours.hours(), 3);
assert_eq!(u8::from(hours), 0x23);
let hours = Hours::from(0x72); assert_eq!(hours.time_representation(), TimeRepresentation::TwelveHour);
assert_eq!(hours.pm_or_twenty_hours(), 1); assert_eq!(hours.ten_hours(), 1);
assert_eq!(hours.hours(), 2);
assert_eq!(u8::from(hours), 0x72);
let hours = Hours::from(0x48); assert_eq!(hours.time_representation(), TimeRepresentation::TwelveHour);
assert_eq!(hours.pm_or_twenty_hours(), 0); assert_eq!(hours.ten_hours(), 0);
assert_eq!(hours.hours(), 8);
assert_eq!(u8::from(hours), 0x48);
}
#[test]
fn test_day_register_conversions() {
let day = Day::from(0x01); assert_eq!(day.day(), 1);
assert_eq!(u8::from(day), 0x01);
let day = Day::from(0x07); assert_eq!(day.day(), 7);
assert_eq!(u8::from(day), 0x07);
let day = Day::from(0x04); assert_eq!(day.day(), 4);
assert_eq!(u8::from(day), 0x04);
}
#[test]
fn test_date_register_conversions() {
let date = Date::from(0x31); assert_eq!(date.ten_date(), 3);
assert_eq!(date.date(), 1);
assert_eq!(u8::from(date), 0x31);
let date = Date::from(0x01); assert_eq!(date.ten_date(), 0);
assert_eq!(date.date(), 1);
assert_eq!(u8::from(date), 0x01);
let date = Date::from(0x15); assert_eq!(date.ten_date(), 1);
assert_eq!(date.date(), 5);
assert_eq!(u8::from(date), 0x15);
}
#[test]
fn test_month_register_conversions() {
let month = Month::from(0x12); assert_eq!(month.century(), false);
assert_eq!(month.ten_month(), 1);
assert_eq!(month.month(), 2);
assert_eq!(u8::from(month), 0x12);
let month = Month::from(0x81); assert_eq!(month.century(), true);
assert_eq!(month.ten_month(), 0);
assert_eq!(month.month(), 1);
assert_eq!(u8::from(month), 0x81);
let month = Month::from(0x06); assert_eq!(month.century(), false);
assert_eq!(month.ten_month(), 0);
assert_eq!(month.month(), 6);
assert_eq!(u8::from(month), 0x06);
}
#[test]
fn test_year_register_conversions() {
let year = Year::from(0x99); assert_eq!(year.ten_year(), 9);
assert_eq!(year.year(), 9);
assert_eq!(u8::from(year), 0x99);
let year = Year::from(0x00); assert_eq!(year.ten_year(), 0);
assert_eq!(year.year(), 0);
assert_eq!(u8::from(year), 0x00);
let year = Year::from(0x24); assert_eq!(year.ten_year(), 2);
assert_eq!(year.year(), 4);
assert_eq!(u8::from(year), 0x24);
}
#[test]
fn test_control_register_conversions() {
let control = Control::from(0xFF);
assert_eq!(control.oscillator_enable(), Oscillator::Disabled);
assert_eq!(control.battery_backed_square_wave(), true);
assert_eq!(control.convert_temperature(), true);
assert_eq!(control.square_wave_frequency(), SquareWaveFrequency::Hz8192);
assert_eq!(control.interrupt_control(), InterruptControl::Interrupt);
assert_eq!(control.alarm2_interrupt_enable(), true);
assert_eq!(control.alarm1_interrupt_enable(), true);
assert_eq!(u8::from(control), 0xFF);
let control = Control::from(0x00);
assert_eq!(control.oscillator_enable(), Oscillator::Enabled);
assert_eq!(control.battery_backed_square_wave(), false);
assert_eq!(control.convert_temperature(), false);
assert_eq!(control.square_wave_frequency(), SquareWaveFrequency::Hz1);
assert_eq!(control.interrupt_control(), InterruptControl::SquareWave);
assert_eq!(control.alarm2_interrupt_enable(), false);
assert_eq!(control.alarm1_interrupt_enable(), false);
assert_eq!(u8::from(control), 0x00);
let control = Control::from(0x1C); assert_eq!(control.oscillator_enable(), Oscillator::Enabled);
assert_eq!(control.battery_backed_square_wave(), false);
assert_eq!(control.convert_temperature(), false);
assert_eq!(control.square_wave_frequency(), SquareWaveFrequency::Hz8192); assert_eq!(control.interrupt_control(), InterruptControl::Interrupt);
assert_eq!(control.alarm2_interrupt_enable(), false);
assert_eq!(control.alarm1_interrupt_enable(), false);
assert_eq!(u8::from(control), 0x1C);
}
#[test]
fn test_status_register_conversions() {
let status = Status::from(0x8F);
assert_eq!(status.oscillator_stop_flag(), true);
assert_eq!(status.enable_32khz_output(), true);
assert_eq!(status.busy(), true);
assert_eq!(status.alarm2_flag(), true);
assert_eq!(status.alarm1_flag(), true);
assert_eq!(u8::from(status), 0x8F);
let status = Status::from(0x00);
assert_eq!(status.oscillator_stop_flag(), false);
assert_eq!(status.enable_32khz_output(), false);
assert_eq!(status.busy(), false);
assert_eq!(status.alarm2_flag(), false);
assert_eq!(status.alarm1_flag(), false);
assert_eq!(u8::from(status), 0x00);
let status = Status::from(0x88); assert_eq!(status.oscillator_stop_flag(), true);
assert_eq!(status.enable_32khz_output(), true);
assert_eq!(status.busy(), false);
assert_eq!(status.alarm2_flag(), false);
assert_eq!(status.alarm1_flag(), false);
assert_eq!(u8::from(status), 0x88);
}
#[test]
fn test_aging_offset_register_conversions() {
let aging_offset = AgingOffset::from(0x05);
assert_eq!(aging_offset.aging_offset(), 5);
assert_eq!(u8::from(aging_offset), 0x05);
let aging_offset = AgingOffset::from(0xF6); assert_eq!(aging_offset.aging_offset(), -10);
assert_eq!(u8::from(aging_offset), 0xF6);
let aging_offset = AgingOffset::from(0x00);
assert_eq!(aging_offset.aging_offset(), 0);
assert_eq!(u8::from(aging_offset), 0x00);
let aging_offset = AgingOffset::from(0x7F); assert_eq!(aging_offset.aging_offset(), 127);
assert_eq!(u8::from(aging_offset), 0x7F);
let aging_offset = AgingOffset::from(0x80); assert_eq!(aging_offset.aging_offset(), -128);
assert_eq!(u8::from(aging_offset), 0x80);
}
#[test]
fn test_temperature_register_conversions() {
let temperature = Temperature::from(0x19); assert_eq!(temperature.temperature(), 25);
assert_eq!(u8::from(temperature), 0x19);
let temperature = Temperature::from(0xF6); assert_eq!(temperature.temperature(), -10);
assert_eq!(u8::from(temperature), 0xF6);
let temperature = Temperature::from(0x00);
assert_eq!(temperature.temperature(), 0);
assert_eq!(u8::from(temperature), 0x00);
let temperature = Temperature::from(0x7F); assert_eq!(temperature.temperature(), 127);
assert_eq!(u8::from(temperature), 0x7F);
let temperature = Temperature::from(0x80); assert_eq!(temperature.temperature(), -128);
assert_eq!(u8::from(temperature), 0x80);
}
#[test]
fn test_temperature_fraction_register_conversions() {
let temp_frac = TemperatureFraction::from(0x00); assert_eq!(temp_frac.temperature_fraction(), 0b00); assert_eq!(u8::from(temp_frac), 0x00);
let temp_frac = TemperatureFraction::from(0x40); assert_eq!(temp_frac.temperature_fraction(), 0b01); assert_eq!(u8::from(temp_frac), 0x40);
let temp_frac = TemperatureFraction::from(0x80); assert_eq!(temp_frac.temperature_fraction(), 0b10); assert_eq!(u8::from(temp_frac), 0x80);
let temp_frac = TemperatureFraction::from(0xC0); assert_eq!(temp_frac.temperature_fraction(), 0b11); assert_eq!(u8::from(temp_frac), 0xC0);
let temp_frac_arbitrary = TemperatureFraction::from(0x55); assert_eq!(temp_frac_arbitrary.temperature_fraction(), 0b01); assert_eq!(u8::from(temp_frac_arbitrary), 0x55);
let mut temp_frac_setter = TemperatureFraction::default(); temp_frac_setter.set_temperature_fraction(0b10); assert_eq!(u8::from(temp_frac_setter), 0x80);
assert_eq!(temp_frac_setter.temperature_fraction(), 0b10);
temp_frac_setter.set_temperature_fraction(0b01); assert_eq!(u8::from(temp_frac_setter), 0x40);
assert_eq!(temp_frac_setter.temperature_fraction(), 0b01);
}
#[test]
fn test_alarm_seconds_register_conversions() {
let alarm_seconds = AlarmSeconds::from(0x80); assert_eq!(alarm_seconds.alarm_mask1(), true);
assert_eq!(alarm_seconds.ten_seconds(), 0);
assert_eq!(alarm_seconds.seconds(), 0);
assert_eq!(u8::from(alarm_seconds), 0x80);
let alarm_seconds = AlarmSeconds::from(0x35); assert_eq!(alarm_seconds.alarm_mask1(), false);
assert_eq!(alarm_seconds.ten_seconds(), 3);
assert_eq!(alarm_seconds.seconds(), 5);
assert_eq!(u8::from(alarm_seconds), 0x35);
let alarm_seconds = AlarmSeconds::from(0xB9); assert_eq!(alarm_seconds.alarm_mask1(), true);
assert_eq!(alarm_seconds.ten_seconds(), 3); assert_eq!(alarm_seconds.seconds(), 9); assert_eq!(u8::from(alarm_seconds), 0xB9);
}
#[test]
fn test_alarm_minutes_register_conversions() {
let alarm_minutes = AlarmMinutes::from(0x80); assert_eq!(alarm_minutes.alarm_mask2(), true);
assert_eq!(alarm_minutes.ten_minutes(), 0);
assert_eq!(alarm_minutes.minutes(), 0);
assert_eq!(u8::from(alarm_minutes), 0x80);
let alarm_minutes = AlarmMinutes::from(0x42); assert_eq!(alarm_minutes.alarm_mask2(), false);
assert_eq!(alarm_minutes.ten_minutes(), 4);
assert_eq!(alarm_minutes.minutes(), 2);
assert_eq!(u8::from(alarm_minutes), 0x42);
let alarm_minutes = AlarmMinutes::from(0xD7); assert_eq!(alarm_minutes.alarm_mask2(), true);
assert_eq!(alarm_minutes.ten_minutes(), 5);
assert_eq!(alarm_minutes.minutes(), 7);
assert_eq!(u8::from(alarm_minutes), 0xD7);
}
#[test]
fn test_alarm_hours_register_conversions() {
let alarm_hours = AlarmHours::from(0x95); assert_eq!(alarm_hours.alarm_mask3(), true);
assert_eq!(
alarm_hours.time_representation(),
TimeRepresentation::TwentyFourHour
);
assert_eq!(alarm_hours.pm_or_twenty_hours(), 0);
assert_eq!(alarm_hours.ten_hours(), 1);
assert_eq!(alarm_hours.hours(), 5);
assert_eq!(u8::from(alarm_hours), 0x95);
let alarm_hours = AlarmHours::from(0x72); assert_eq!(alarm_hours.alarm_mask3(), false);
assert_eq!(
alarm_hours.time_representation(),
TimeRepresentation::TwelveHour
);
assert_eq!(alarm_hours.pm_or_twenty_hours(), 1); assert_eq!(alarm_hours.ten_hours(), 1);
assert_eq!(alarm_hours.hours(), 2);
assert_eq!(u8::from(alarm_hours), 0x72);
let alarm_hours = AlarmHours::from(0xC8); assert_eq!(alarm_hours.alarm_mask3(), true);
assert_eq!(
alarm_hours.time_representation(),
TimeRepresentation::TwelveHour
);
assert_eq!(alarm_hours.pm_or_twenty_hours(), 0); assert_eq!(alarm_hours.ten_hours(), 0);
assert_eq!(alarm_hours.hours(), 8);
assert_eq!(u8::from(alarm_hours), 0xC8);
}
#[test]
fn test_alarm_day_date_register_conversions() {
let alarm_day_date = AlarmDayDate::from(0xC3); assert_eq!(alarm_day_date.alarm_mask4(), true);
assert_eq!(alarm_day_date.day_date_select(), DayDateSelect::Day);
assert_eq!(alarm_day_date.ten_date(), 0); assert_eq!(alarm_day_date.day_or_date(), 3);
assert_eq!(u8::from(alarm_day_date), 0xC3);
let alarm_day_date = AlarmDayDate::from(0x15); assert_eq!(alarm_day_date.alarm_mask4(), false);
assert_eq!(alarm_day_date.day_date_select(), DayDateSelect::Date);
assert_eq!(alarm_day_date.ten_date(), 1);
assert_eq!(alarm_day_date.day_or_date(), 5);
assert_eq!(u8::from(alarm_day_date), 0x15);
let alarm_day_date = AlarmDayDate::from(0x47); assert_eq!(alarm_day_date.alarm_mask4(), false);
assert_eq!(alarm_day_date.day_date_select(), DayDateSelect::Day);
assert_eq!(alarm_day_date.ten_date(), 0); assert_eq!(alarm_day_date.day_or_date(), 7);
assert_eq!(u8::from(alarm_day_date), 0x47);
let alarm_day_date = AlarmDayDate::from(0xA9); assert_eq!(alarm_day_date.alarm_mask4(), true);
assert_eq!(alarm_day_date.day_date_select(), DayDateSelect::Date);
assert_eq!(alarm_day_date.ten_date(), 2);
assert_eq!(alarm_day_date.day_or_date(), 9);
assert_eq!(u8::from(alarm_day_date), 0xA9);
}
#[test]
fn test_register_roundtrip_conversions() {
let test_values = [
0x00, 0x55, 0xAA, 0xFF, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE,
];
for &value in &test_values {
assert_eq!(u8::from(Seconds::from(value)), value);
assert_eq!(u8::from(Minutes::from(value)), value);
assert_eq!(u8::from(Hours::from(value)), value);
assert_eq!(u8::from(Day::from(value)), value);
assert_eq!(u8::from(Date::from(value)), value);
assert_eq!(u8::from(Month::from(value)), value);
assert_eq!(u8::from(Year::from(value)), value);
assert_eq!(u8::from(Control::from(value)), value);
assert_eq!(u8::from(Status::from(value)), value);
assert_eq!(u8::from(AgingOffset::from(value)), value);
assert_eq!(u8::from(Temperature::from(value)), value);
assert_eq!(u8::from(TemperatureFraction::from(value)), value);
assert_eq!(u8::from(AlarmSeconds::from(value)), value);
assert_eq!(u8::from(AlarmMinutes::from(value)), value);
assert_eq!(u8::from(AlarmHours::from(value)), value);
assert_eq!(u8::from(AlarmDayDate::from(value)), value);
}
}
#[test]
fn test_register_bitfield_operations() {
let mut seconds = Seconds::default();
seconds.set_seconds(5);
seconds.set_ten_seconds(3);
assert_eq!(seconds.seconds(), 5);
assert_eq!(seconds.ten_seconds(), 3);
let mut minutes = Minutes::default();
minutes.set_minutes(8);
minutes.set_ten_minutes(4);
assert_eq!(minutes.minutes(), 8);
assert_eq!(minutes.ten_minutes(), 4);
let mut hours = Hours::default();
hours.set_time_representation(TimeRepresentation::TwelveHour);
hours.set_pm_or_twenty_hours(1);
hours.set_ten_hours(1);
hours.set_hours(2);
assert_eq!(hours.time_representation(), TimeRepresentation::TwelveHour);
assert_eq!(hours.pm_or_twenty_hours(), 1);
assert_eq!(hours.ten_hours(), 1);
assert_eq!(hours.hours(), 2);
let mut day = Day::default();
day.set_day(3);
assert_eq!(day.day(), 3);
let mut date = Date::default();
date.set_date(5);
date.set_ten_date(2);
assert_eq!(date.date(), 5);
assert_eq!(date.ten_date(), 2);
let mut month = Month::default();
month.set_month(2);
month.set_ten_month(1);
month.set_century(true);
assert_eq!(month.month(), 2);
assert_eq!(month.ten_month(), 1);
assert!(month.century());
let mut year = Year::default();
year.set_year(4);
year.set_ten_year(2);
assert_eq!(year.year(), 4);
assert_eq!(year.ten_year(), 2);
let mut control = Control::default();
control.set_oscillator_enable(Oscillator::Disabled);
control.set_battery_backed_square_wave(true);
control.set_convert_temperature(true);
control.set_square_wave_frequency(SquareWaveFrequency::Hz4096);
control.set_interrupt_control(InterruptControl::Interrupt);
control.set_alarm2_interrupt_enable(true);
control.set_alarm1_interrupt_enable(true);
assert_eq!(control.oscillator_enable(), Oscillator::Disabled);
assert!(control.battery_backed_square_wave());
assert!(control.convert_temperature());
assert_eq!(control.square_wave_frequency(), SquareWaveFrequency::Hz4096);
assert_eq!(control.interrupt_control(), InterruptControl::Interrupt);
assert!(control.alarm2_interrupt_enable());
assert!(control.alarm1_interrupt_enable());
let mut status = Status::default();
status.set_oscillator_stop_flag(true);
status.set_enable_32khz_output(true);
status.set_busy(true);
status.set_alarm2_flag(true);
status.set_alarm1_flag(true);
assert!(status.oscillator_stop_flag());
assert!(status.enable_32khz_output());
assert!(status.busy());
assert!(status.alarm2_flag());
assert!(status.alarm1_flag());
let mut aging_offset = AgingOffset::default();
aging_offset.set_aging_offset(-10);
assert_eq!(aging_offset.aging_offset(), -10);
let mut temperature = Temperature::default();
temperature.set_temperature(25);
assert_eq!(temperature.temperature(), 25);
let mut temp_frac = TemperatureFraction::default(); temp_frac.set_temperature_fraction(0b01);
assert_eq!(temp_frac.temperature_fraction(), 0b01);
assert_eq!(u8::from(temp_frac), 0x40);
temp_frac.set_temperature_fraction(0b11);
assert_eq!(temp_frac.temperature_fraction(), 0b11); assert_eq!(u8::from(temp_frac), 0xC0); }
#[test]
fn test_alarm_register_bitfield_operations() {
let mut alarm_seconds = AlarmSeconds::default();
alarm_seconds.set_alarm_mask1(true);
alarm_seconds.set_ten_seconds(3);
alarm_seconds.set_seconds(5);
assert!(alarm_seconds.alarm_mask1());
assert_eq!(alarm_seconds.ten_seconds(), 3);
assert_eq!(alarm_seconds.seconds(), 5);
let mut alarm_minutes = AlarmMinutes::default();
alarm_minutes.set_alarm_mask2(true);
alarm_minutes.set_ten_minutes(4);
alarm_minutes.set_minutes(8);
assert!(alarm_minutes.alarm_mask2());
assert_eq!(alarm_minutes.ten_minutes(), 4);
assert_eq!(alarm_minutes.minutes(), 8);
let mut alarm_hours = AlarmHours::default();
alarm_hours.set_alarm_mask3(true);
alarm_hours.set_time_representation(TimeRepresentation::TwelveHour);
alarm_hours.set_pm_or_twenty_hours(1);
alarm_hours.set_ten_hours(1);
alarm_hours.set_hours(2);
assert!(alarm_hours.alarm_mask3());
assert_eq!(
alarm_hours.time_representation(),
TimeRepresentation::TwelveHour
);
assert_eq!(alarm_hours.pm_or_twenty_hours(), 1);
assert_eq!(alarm_hours.ten_hours(), 1);
assert_eq!(alarm_hours.hours(), 2);
let mut alarm_day_date = AlarmDayDate::default();
alarm_day_date.set_alarm_mask4(true);
alarm_day_date.set_day_date_select(DayDateSelect::Day);
alarm_day_date.set_ten_date(2);
alarm_day_date.set_day_or_date(5);
assert!(alarm_day_date.alarm_mask4());
assert_eq!(alarm_day_date.day_date_select(), DayDateSelect::Day);
assert_eq!(alarm_day_date.ten_date(), 2);
assert_eq!(alarm_day_date.day_or_date(), 5);
}
#[test]
#[should_panic(expected = "Invalid value for TimeRepresentation: 2")]
fn test_invalid_time_representation_conversion() {
let _ = TimeRepresentation::from(2);
}
#[test]
#[should_panic(expected = "Invalid value for Oscillator: 2")]
fn test_invalid_oscillator_conversion() {
let _ = Oscillator::from(2);
}
#[test]
#[should_panic(expected = "Invalid value for InterruptControl: 2")]
fn test_invalid_interrupt_control_conversion() {
let _ = InterruptControl::from(2);
}
#[test]
#[should_panic(expected = "Invalid value for SquareWaveFrequency: 4")]
fn test_invalid_square_wave_frequency_conversion() {
let _ = SquareWaveFrequency::from(4);
}
}