mirror of https://github.com/eldruin/ds323x-rs
Cache status value in the driver
parent
d18de45f95
commit
73ca2703c9
|
@ -33,24 +33,20 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable the 32kHz output.
|
/// Enable the 32kHz output.
|
||||||
///
|
|
||||||
/// (Does not alter the device register if already enabled).
|
|
||||||
pub fn enable_32khz_output(&mut self) -> Result<(), Error<E>> {
|
pub fn enable_32khz_output(&mut self) -> Result<(), Error<E>> {
|
||||||
let status = self.iface.read_register(Register::STATUS)?;
|
// avoid clearing alarm flags
|
||||||
if (status & BitFlags::EN32KHZ) == 0 {
|
let status = self.status | BitFlags::EN32KHZ | BitFlags::ALARM2F | BitFlags::ALARM1F;
|
||||||
self.iface.write_register(Register::STATUS, status | BitFlags::EN32KHZ)?;
|
self.iface.write_register(Register::STATUS, status)?;
|
||||||
}
|
self.status = status;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable the 32kHz output.
|
/// Disable the 32kHz output.
|
||||||
///
|
|
||||||
/// (Does not alter the device register if already disabled).
|
|
||||||
pub fn disable_32khz_output(&mut self) -> Result<(), Error<E>> {
|
pub fn disable_32khz_output(&mut self) -> Result<(), Error<E>> {
|
||||||
let status = self.iface.read_register(Register::STATUS)?;
|
// avoid clearing alarm flags
|
||||||
if (status & BitFlags::EN32KHZ) != 0 {
|
let status = self.status & !BitFlags::EN32KHZ | BitFlags::ALARM2F | BitFlags::ALARM1F;
|
||||||
self.iface.write_register(Register::STATUS, status & !BitFlags::EN32KHZ)?;
|
self.iface.write_register(Register::STATUS, status)?;
|
||||||
}
|
self.status = status;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/lib.rs
14
src/lib.rs
|
@ -401,9 +401,12 @@ impl BitFlags {
|
||||||
const RS2 : u8 = 0b0001_0000;
|
const RS2 : u8 = 0b0001_0000;
|
||||||
const RS1 : u8 = 0b0000_1000;
|
const RS1 : u8 = 0b0000_1000;
|
||||||
const INTCN : u8 = 0b0000_0100;
|
const INTCN : u8 = 0b0000_0100;
|
||||||
const BUSY : u8 = 0b0000_0100;
|
|
||||||
const EN32KHZ : u8 = 0b0000_1000;
|
|
||||||
const OSC_STOP : u8 = 0b1000_0000;
|
const OSC_STOP : u8 = 0b1000_0000;
|
||||||
|
const BB32KHZ : u8 = 0b0100_0000;
|
||||||
|
const EN32KHZ : u8 = 0b0000_1000;
|
||||||
|
const BUSY : u8 = 0b0000_0100;
|
||||||
|
const ALARM2F : u8 = 0b0000_0010;
|
||||||
|
const ALARM1F : u8 = 0b0000_0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEVICE_ADDRESS : u8 = 0b110_1000;
|
const DEVICE_ADDRESS : u8 = 0b110_1000;
|
||||||
|
@ -426,6 +429,7 @@ use interface::{ I2cInterface, SpiInterface };
|
||||||
pub struct Ds323x<DI, IC> {
|
pub struct Ds323x<DI, IC> {
|
||||||
iface: DI,
|
iface: DI,
|
||||||
control: u8,
|
control: u8,
|
||||||
|
status : u8,
|
||||||
_ic: PhantomData<IC>
|
_ic: PhantomData<IC>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,11 +439,13 @@ where
|
||||||
{
|
{
|
||||||
/// 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;
|
||||||
Ds323x {
|
Ds323x {
|
||||||
iface: I2cInterface {
|
iface: I2cInterface {
|
||||||
i2c,
|
i2c,
|
||||||
},
|
},
|
||||||
control: CONTROL_POR_VALUE,
|
control: CONTROL_POR_VALUE,
|
||||||
|
status: STATUS_POR_VALUE,
|
||||||
_ic: PhantomData
|
_ic: PhantomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,11 +462,13 @@ where
|
||||||
{
|
{
|
||||||
/// 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;
|
||||||
Ds323x {
|
Ds323x {
|
||||||
iface: I2cInterface {
|
iface: I2cInterface {
|
||||||
i2c,
|
i2c,
|
||||||
},
|
},
|
||||||
control: CONTROL_POR_VALUE,
|
control: CONTROL_POR_VALUE,
|
||||||
|
status: STATUS_POR_VALUE,
|
||||||
_ic: PhantomData
|
_ic: PhantomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,12 +486,14 @@ where
|
||||||
{
|
{
|
||||||
/// 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 {
|
||||||
|
const STATUS_POR_VALUE : u8 = BitFlags::OSC_STOP | BitFlags::BB32KHZ | BitFlags::EN32KHZ;
|
||||||
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,
|
||||||
_ic: PhantomData
|
_ic: PhantomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,10 @@ use hal::spi::{ Mock as SpiMock, Transaction as SpiTrans };
|
||||||
pub const DEVICE_ADDRESS : u8 = 0b110_1000;
|
pub const DEVICE_ADDRESS : u8 = 0b110_1000;
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub const CONTROL_POR_VALUE: u8 = 0b0001_1100;
|
pub const CONTROL_POR_VALUE: u8 = 0b0001_1100;
|
||||||
|
#[allow(unused)]
|
||||||
|
pub const DS3231_POR_STATUS: u8 = BitFlags::OSC_STOP | BitFlags::EN32KHZ;
|
||||||
|
#[allow(unused)]
|
||||||
|
pub const DS323X_POR_STATUS: u8 = BitFlags::OSC_STOP | BitFlags::BB32KHZ | BitFlags::EN32KHZ;
|
||||||
|
|
||||||
pub struct Register;
|
pub struct Register;
|
||||||
|
|
||||||
|
@ -34,9 +38,12 @@ impl BitFlags {
|
||||||
pub const RS2 : u8 = 0b0001_0000;
|
pub const RS2 : u8 = 0b0001_0000;
|
||||||
pub const RS1 : u8 = 0b0000_1000;
|
pub const RS1 : u8 = 0b0000_1000;
|
||||||
pub const INTCN : u8 = 0b0000_0100;
|
pub const INTCN : u8 = 0b0000_0100;
|
||||||
pub const BUSY : u8 = 0b0000_0100;
|
|
||||||
pub const EN32KHZ : u8 = 0b0000_1000;
|
|
||||||
pub const OSC_STOP : u8 = 0b1000_0000;
|
pub const OSC_STOP : u8 = 0b1000_0000;
|
||||||
|
pub const BB32KHZ : u8 = 0b0100_0000;
|
||||||
|
pub const EN32KHZ : u8 = 0b0000_1000;
|
||||||
|
pub const BUSY : u8 = 0b0000_0100;
|
||||||
|
pub const ALARM2F : u8 = 0b0000_0010;
|
||||||
|
pub const ALARM1F : u8 = 0b0000_0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DummyOutputPin;
|
pub struct DummyOutputPin;
|
||||||
|
|
|
@ -10,7 +10,8 @@ use ds323x::SqWFreq;
|
||||||
mod common;
|
mod common;
|
||||||
use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, new_ds3231,
|
use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, new_ds3231,
|
||||||
new_ds3232, new_ds3234, destroy_ds3231, destroy_ds3232,
|
new_ds3232, new_ds3234, destroy_ds3231, destroy_ds3232,
|
||||||
destroy_ds3234, BitFlags as BF, CONTROL_POR_VALUE };
|
destroy_ds3234, BitFlags as BF, CONTROL_POR_VALUE,
|
||||||
|
DS3231_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) => {
|
||||||
|
@ -31,6 +32,19 @@ macro_rules! call_method_test {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! call_method_status_test {
|
||||||
|
($name:ident, $method:ident, $value_ds3231:expr, $value_ds323x:expr) => {
|
||||||
|
mod $name {
|
||||||
|
use super::*;
|
||||||
|
call_test!(can_call_ds3231, $method, new_ds3231, destroy_ds3231,
|
||||||
|
[ 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]) ]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! change_if_necessary_test {
|
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) => {
|
||||||
|
@ -52,8 +66,12 @@ macro_rules! change_if_necessary_test {
|
||||||
|
|
||||||
call_method_test!(enable, enable, CONTROL, CONTROL_POR_VALUE & !BF::EOSC);
|
call_method_test!(enable, enable, CONTROL, CONTROL_POR_VALUE & !BF::EOSC);
|
||||||
call_method_test!(disable, disable, CONTROL, CONTROL_POR_VALUE | BF::EOSC);
|
call_method_test!(disable, disable, CONTROL, CONTROL_POR_VALUE | BF::EOSC);
|
||||||
change_if_necessary_test!(en_32khz_out, enable_32khz_output, STATUS, BF::EN32KHZ, 0);
|
call_method_status_test!(en_32khz_out, enable_32khz_output,
|
||||||
change_if_necessary_test!(dis_32khz_out, disable_32khz_output, STATUS, 0xFF & !BF::EN32KHZ, 0xFF);
|
DS3231_POR_STATUS | BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F,
|
||||||
|
DS323X_POR_STATUS | BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F);
|
||||||
|
call_method_status_test!(dis_32khz_out, disable_32khz_output,
|
||||||
|
DS3231_POR_STATUS & !BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F,
|
||||||
|
DS323X_POR_STATUS & !BF::EN32KHZ | BF::ALARM2F | BF::ALARM1F);
|
||||||
change_if_necessary_test!(clr_stop, clear_has_been_stopped_flag, STATUS, 0xFF & !BF::OSC_STOP, 0xFF);
|
change_if_necessary_test!(clr_stop, clear_has_been_stopped_flag, STATUS, 0xFF & !BF::OSC_STOP, 0xFF);
|
||||||
change_if_necessary_test!(conv_temp, convert_temperature, CONTROL, CONTROL_POR_VALUE | BF::TEMP_CONV, CONTROL_POR_VALUE & !BF::TEMP_CONV);
|
change_if_necessary_test!(conv_temp, convert_temperature, CONTROL, CONTROL_POR_VALUE | BF::TEMP_CONV, CONTROL_POR_VALUE & !BF::TEMP_CONV);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue