ds323x/ds323x/
status.rs

1//! Device status
2
3use crate::{
4    interface::{ReadData, WriteData},
5    BitFlags, Ds323x, Error, Register,
6};
7
8impl<DI, IC, E> Ds323x<DI, IC>
9where
10    DI: ReadData<Error = Error<E>> + WriteData<Error = Error<E>>,
11{
12    /// Read whether the oscillator is running
13    pub fn running(&mut self) -> Result<bool, Error<E>> {
14        let control = self.iface.read_register(Register::CONTROL)?;
15        Ok((control & BitFlags::EOSC) == 0)
16    }
17
18    /// Read the busy status
19    pub fn busy(&mut self) -> Result<bool, Error<E>> {
20        let status = self.iface.read_register(Register::STATUS)?;
21        Ok((status & BitFlags::BUSY) != 0)
22    }
23
24    /// Read whether the oscillator is stopped or has been stopped at
25    /// some point.
26    ///
27    /// This allows a better assessment of the validity of the timekeeping data.
28    ///
29    /// Once this is true, it will stay as such until cleared with
30    /// [`clear_has_been_stopped_flag()`](#method.clear_has_been_stopped_flag)
31    pub fn has_been_stopped(&mut self) -> Result<bool, Error<E>> {
32        let status = self.iface.read_register(Register::STATUS)?;
33        Ok((status & BitFlags::OSC_STOP) != 0)
34    }
35
36    /// Clear flag signalling whether the oscillator is stopped or has been
37    /// stopped at some point.
38    ///
39    /// See also: [`has_been_stopped()`](#method.has_been_stopped)
40    pub fn clear_has_been_stopped_flag(&mut self) -> Result<(), Error<E>> {
41        let status = self.status & !BitFlags::OSC_STOP;
42        self.write_status_without_clearing_alarm(status)
43    }
44
45    /// Read whether the Alarm1 has matched at some point.
46    ///
47    /// Once this is true, it will stay as such until cleared with
48    /// [`clear_alarm1_matched_flag()`](#method.clear_alarm1_matched_flag)
49    pub fn has_alarm1_matched(&mut self) -> Result<bool, Error<E>> {
50        let status = self.iface.read_register(Register::STATUS)?;
51        Ok((status & BitFlags::ALARM1F) != 0)
52    }
53
54    /// Clear flag signalling whether the Alarm1 has matched at some point.
55    ///
56    /// See also: [`has_alarm1_matched()`](#method.has_alarm1_matched)
57    pub fn clear_alarm1_matched_flag(&mut self) -> Result<(), Error<E>> {
58        let status = self.status | BitFlags::ALARM2F;
59        self.iface.write_register(Register::STATUS, status)
60    }
61
62    /// Read whether the Alarm2 has matched at some point.
63    ///
64    /// Once this is true, it will stay as such until cleared with
65    /// [`clear_alarm2_matched_flag()`](#method.clear_alarm2_matched_flag)
66    pub fn has_alarm2_matched(&mut self) -> Result<bool, Error<E>> {
67        let status = self.iface.read_register(Register::STATUS)?;
68        Ok((status & BitFlags::ALARM2F) != 0)
69    }
70
71    /// Clear flag signalling whether the Alarm2 has matched at some point.
72    ///
73    /// See also: [`has_alarm2_matched()`](#method.has_alarm2_matched)
74    pub fn clear_alarm2_matched_flag(&mut self) -> Result<(), Error<E>> {
75        let status = self.status | BitFlags::ALARM1F;
76        self.iface.write_register(Register::STATUS, status)
77    }
78
79    /// Read the temperature.
80    ///
81    /// Note: It is possible to manually force a temperature conversion with
82    /// [`convert_temperature()`](#method.convert_temperature)
83    pub fn temperature(&mut self) -> Result<f32, Error<E>> {
84        let mut data = [Register::TEMP_MSB, 0, 0];
85        self.iface.read_data(&mut data)?;
86        let is_negative = (data[1] & 0b1000_0000) != 0;
87        let temp = (u16::from(data[1]) << 2) | u16::from(data[2] >> 6);
88        if is_negative {
89            let temp_sign_extended = temp | 0b1111_1100_0000_0000;
90            Ok(f32::from(temp_sign_extended as i16) * 0.25)
91        } else {
92            Ok(f32::from(temp) * 0.25)
93        }
94    }
95}