pub use rtc_hal::control::RtcPowerControl;
use crate::{
Ds3231,
registers::{EOSC_BIT, Register},
};
impl<I2C> RtcPowerControl for Ds3231<I2C>
where
I2C: embedded_hal::i2c::I2c,
{
fn start_clock(&mut self) -> Result<(), Self::Error> {
self.clear_register_bits(Register::Control, EOSC_BIT)
}
fn halt_clock(&mut self) -> Result<(), Self::Error> {
self.set_register_bits(Register::Control, EOSC_BIT)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::registers::{EOSC_BIT, Register};
use embedded_hal_mock::eh1::i2c::{Mock as I2cMock, Transaction as I2cTransaction};
use rtc_hal::control::RtcPowerControl;
const DS3231_ADDR: u8 = 0x68;
#[test]
fn test_start_clock_sets_eosc_bit_to_zero() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![EOSC_BIT], ),
I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.start_clock();
assert!(result.is_ok());
i2c_mock.done();
}
#[test]
fn test_start_clock_already_running() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![0b0000_0000], ),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.start_clock();
assert!(result.is_ok());
i2c_mock.done();
}
#[test]
fn test_start_clock_preserves_other_bits() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![0b0100_0101 | EOSC_BIT], ),
I2cTransaction::write(
DS3231_ADDR,
vec![Register::Control.addr(), 0b0100_0101], ),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.start_clock();
assert!(result.is_ok());
i2c_mock.done();
}
#[test]
fn test_halt_clock_sets_eosc_bit_to_one() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![0b0000_0000], ),
I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), EOSC_BIT]),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.halt_clock();
assert!(result.is_ok());
i2c_mock.done();
}
#[test]
fn test_halt_clock_already_halted() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![EOSC_BIT], ),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.halt_clock();
assert!(result.is_ok());
i2c_mock.done();
}
#[test]
fn test_halt_clock_preserves_other_bits() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![0b0010_1010], ),
I2cTransaction::write(
DS3231_ADDR,
vec![Register::Control.addr(), 0b1010_1010 | EOSC_BIT], ),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.halt_clock();
assert!(result.is_ok());
i2c_mock.done();
}
#[test]
fn test_start_clock_i2c_read_error() {
let expectations = vec![
I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![0x00])
.with_error(embedded_hal::i2c::ErrorKind::Other),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.start_clock();
assert!(result.is_err());
i2c_mock.done();
}
#[test]
fn test_start_clock_i2c_write_error() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![EOSC_BIT], ),
I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000])
.with_error(embedded_hal::i2c::ErrorKind::Other),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.start_clock();
assert!(result.is_err());
i2c_mock.done();
}
#[test]
fn test_halt_clock_i2c_read_error() {
let expectations = vec![
I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![0x00])
.with_error(embedded_hal::i2c::ErrorKind::Other),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.halt_clock();
assert!(result.is_err());
i2c_mock.done();
}
#[test]
fn test_halt_clock_i2c_write_error() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![0b0000_0000], ),
I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), EOSC_BIT])
.with_error(embedded_hal::i2c::ErrorKind::Other),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.halt_clock();
assert!(result.is_err());
i2c_mock.done();
}
#[test]
fn test_power_control_sequence_start_halt_start() {
let expectations = vec![
I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![EOSC_BIT]),
I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![0b0000_0000],
),
I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), EOSC_BIT]),
I2cTransaction::write_read(DS3231_ADDR, vec![Register::Control.addr()], vec![EOSC_BIT]),
I2cTransaction::write(DS3231_ADDR, vec![Register::Control.addr(), 0b0000_0000]),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
assert!(ds3231.start_clock().is_ok());
assert!(ds3231.halt_clock().is_ok());
assert!(ds3231.start_clock().is_ok());
i2c_mock.done();
}
#[test]
fn test_start_clock_clears_only_eosc_bit() {
let expectations = vec![
I2cTransaction::write_read(
DS3231_ADDR,
vec![Register::Control.addr()],
vec![0b1111_1111], ),
I2cTransaction::write(
DS3231_ADDR,
vec![Register::Control.addr(), !EOSC_BIT], ),
];
let mut i2c_mock = I2cMock::new(&expectations);
let mut ds3231 = Ds3231::new(&mut i2c_mock);
let result = ds3231.start_clock();
assert!(result.is_ok());
i2c_mock.done();
}
}