diff --git a/README.md b/README.md index e0c3a9a..6388cd8 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ This driver allows you to: - Enable and disable the square-wave generation. See `enable_square_wave`. - Select the square-wave frequency. See `set_square_wave_frequency`. - Enable and disable the 32kHz output when battery powered. See `enable_32khz_output_on_battery`. +- Set the temperature conversion rate. See `set_temperature_conversion_rate`. ## The devices diff --git a/src/ds3232.rs b/src/ds3232.rs index 434a280..22232dc 100644 --- a/src/ds3232.rs +++ b/src/ds3232.rs @@ -2,7 +2,7 @@ extern crate embedded_hal as hal; use hal::blocking; -use super::{ Ds323x, BitFlags, Error, ic }; +use super::{ Ds323x, TempConvRate, BitFlags, Error, ic }; use interface::I2cInterface; impl Ds323x, ic::DS3232> @@ -30,4 +30,22 @@ where let status = self.status & !BitFlags::BB32KHZ; self.write_status_without_clearing_alarm(status) } + + /// Set the temperature conversion rate. + /// + /// Set how often the temperature is measured and applies compensation to + /// the oscillator. This can be used to reduce power consumption but sudden + /// temperature changes will not be compensated for. + /// + /// Note: This is only available for DS3232 and DS3234 devices. + pub fn set_temperature_conversion_rate(&mut self, rate: TempConvRate) -> Result<(), Error> { + let status; + match rate { + TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0, + TempConvRate::_128s => status = self.status & !BitFlags::CRATE1 | BitFlags::CRATE0, + TempConvRate::_256s => status = self.status | BitFlags::CRATE1 & !BitFlags::CRATE0, + TempConvRate::_512s => status = self.status | BitFlags::CRATE1 | BitFlags::CRATE0, + } + self.write_status_without_clearing_alarm(status) + } } diff --git a/src/ds3234.rs b/src/ds3234.rs index f406afd..07b3a96 100644 --- a/src/ds3234.rs +++ b/src/ds3234.rs @@ -2,7 +2,7 @@ extern crate embedded_hal as hal; use hal::blocking; -use super::{ Ds323x, BitFlags, Error, ic }; +use super::{ Ds323x, TempConvRate, BitFlags, Error, ic }; use interface::SpiInterface; impl Ds323x, ic::DS3234> @@ -31,4 +31,22 @@ where let status = self.status & !BitFlags::BB32KHZ; self.write_status_without_clearing_alarm(status) } + + /// Set the temperature conversion rate. + /// + /// Set how often the temperature is measured and applies compensation to + /// the oscillator. This can be used to reduce power consumption but sudden + /// temperature changes will not be compensated for. + /// + /// Note: This is only available for DS3232 and DS3234 devices. + pub fn set_temperature_conversion_rate(&mut self, rate: TempConvRate) -> Result<(), Error> { + let status; + match rate { + TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0, + TempConvRate::_128s => status = self.status & !BitFlags::CRATE1 | BitFlags::CRATE0, + TempConvRate::_256s => status = self.status | BitFlags::CRATE1 & !BitFlags::CRATE0, + TempConvRate::_512s => status = self.status | BitFlags::CRATE1 | BitFlags::CRATE0, + } + self.write_status_without_clearing_alarm(status) + } } diff --git a/src/lib.rs b/src/lib.rs index bfa358f..9a34f89 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,7 @@ //! - Enable and disable the square-wave generation. See [`enable_square_wave`]. //! - Select the square-wave frequency. See [`set_square_wave_frequency`]. //! - Enable and disable the 32kHz output when battery powered. See [`enable_32khz_output_on_battery`]. +//! - Set the temperature conversion rate. See [`set_temperature_conversion_rate`]. //! //! [`get_datetime`]: struct.Ds323x.html#method.get_datetime //! [`get_year`]: struct.Ds323x.html#method.get_year @@ -33,6 +34,7 @@ //! [`enable_square_wave`]: Struct.Ds323x.html#method.enable_square_wave //! [`set_square_wave_frequency`]: Struct.Ds323x.html#method.set_square_wave_frequency //! [`enable_32khz_output_on_battery`]: Struct.Ds323x.html#method.enable_32khz_output_on_battery +//! [`set_temperature_conversion_rate`]: Struct.Ds323x.html#method.set_temperature_conversion_rate //! //! ## The devices //! @@ -361,6 +363,21 @@ //! # } //! ``` //! +//! ### Set the temperature conversion rate to once every 128 seconds +//! +//! This is only available for the devices DS3232 and DS3234. +//! +//! ```no_run +//! extern crate linux_embedded_hal as hal; +//! extern crate ds323x; +//! use ds323x::{ Ds323x, TempConvRate }; +//! +//! # fn main() { +//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap(); +//! let mut rtc = Ds323x::new_ds3232(dev); +//! rtc.set_temperature_conversion_rate(TempConvRate::_128s).unwrap(); +//! # } +//! ``` #![deny(unsafe_code)] #![deny(missing_docs)] @@ -393,6 +410,21 @@ pub enum SqWFreq { _8_192Hz, } +/// Temperature conversion rate +/// +/// This is only available on the DS3232 and DS3234 devices. +#[derive(Debug, Clone, PartialEq)] +pub enum TempConvRate { + /// Once every 64 seconds + _64s, + /// Once every 128 seconds + _128s, + /// Once every 256 seconds + _256s, + /// Once every 512 seconds + _512s, +} + struct Register; impl Register { @@ -423,6 +455,8 @@ impl BitFlags { const INTCN : u8 = 0b0000_0100; const OSC_STOP : u8 = 0b1000_0000; const BB32KHZ : u8 = 0b0100_0000; + const CRATE1 : u8 = 0b0010_0000; + const CRATE0 : u8 = 0b0001_0000; const EN32KHZ : u8 = 0b0000_1000; const BUSY : u8 = 0b0000_0100; const ALARM2F : u8 = 0b0000_0010; diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 43c876d..f82d05c 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -40,6 +40,8 @@ impl BitFlags { pub const INTCN : u8 = 0b0000_0100; pub const OSC_STOP : u8 = 0b1000_0000; pub const BB32KHZ : u8 = 0b0100_0000; + pub const CRATE1 : u8 = 0b0010_0000; + pub const CRATE0 : u8 = 0b0001_0000; pub const EN32KHZ : u8 = 0b0000_1000; pub const BUSY : u8 = 0b0000_0100; pub const ALARM2F : u8 = 0b0000_0010; diff --git a/tests/ds3232_4.rs b/tests/ds3232_4.rs index 0f2b170..4da3273 100644 --- a/tests/ds3232_4.rs +++ b/tests/ds3232_4.rs @@ -4,6 +4,9 @@ extern crate embedded_hal_mock as hal; use hal::i2c::Transaction as I2cTrans; use hal::spi::Transaction as SpiTrans; +extern crate ds323x; +use ds323x::TempConvRate; + #[allow(unused)] mod common; use common::{ DEVICE_ADDRESS as DEV_ADDR, Register, @@ -22,6 +25,26 @@ macro_rules! call_method_status_test { }; } +#[macro_export] +macro_rules! _set_param_test_2_4 { + ($name:ident, $method:ident, $value:expr, $i2c_transactions:expr, $spi_transactions:expr) => { + mod $name { + use super::*; + 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); + } + }; +} + +#[macro_export] +macro_rules! set_param_test_2_4 { + ($name:ident, $method:ident, $register:ident, $value:expr, $binary_value:expr) => { + _set_param_test_2_4!($name, $method, $value, + [ I2cTrans::write(DEV_ADDR, vec![Register::$register, $binary_value]) ], + [ SpiTrans::write(vec![Register::$register + 0x80, $binary_value]) ]); + }; +} + #[test] fn can_create_and_destroy_ds3232() { let dev = new_ds3232(&[]); @@ -41,3 +64,12 @@ call_method_status_test!(can_en_32khz_bat, enable_32khz_output_on_battery, call_method_status_test!(can_dis_32khz_bat, disable_32khz_output_on_battery, DEFAULT_WRITE_STATUS & !BF::BB32KHZ); +set_param_test_2_4!(can_set_cr_64s, set_temperature_conversion_rate, STATUS, TempConvRate::_64s, + DEFAULT_WRITE_STATUS & !BF::CRATE1 & !BF::CRATE0); +set_param_test_2_4!(can_set_cr_128s, set_temperature_conversion_rate, STATUS, TempConvRate::_128s, + DEFAULT_WRITE_STATUS & !BF::CRATE1 | BF::CRATE0); +set_param_test_2_4!(can_set_cr_256s, set_temperature_conversion_rate, STATUS, TempConvRate::_256s, + DEFAULT_WRITE_STATUS | BF::CRATE1 & !BF::CRATE0); +set_param_test_2_4!(can_set_cr_512s, set_temperature_conversion_rate, STATUS, TempConvRate::_512s, + DEFAULT_WRITE_STATUS | BF::CRATE1 | BF::CRATE0); +