1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! Device configuration

extern crate embedded_hal as hal;
use super::super::{ Ds323x, SqWFreq, Register, BitFlags, Error };
use interface::{ ReadData, WriteData };

impl<DI, IC, E> Ds323x<DI, IC>
where
    DI: ReadData<Error = E> + WriteData<Error = E>
{
    /// Enable the oscillator (set the clock running) (default).
    pub fn enable(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control & !BitFlags::EOSC)
    }

    /// Disable the oscillator (stops the clock).
    pub fn disable(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control | BitFlags::EOSC)
    }

    /// Force a temperature conversion and time compensation with TXCO algorithm.
    ///
    /// The *busy* status should be checked before doing this. See [`is_busy()`](#method.is_busy)
    pub fn convert_temperature(&mut self) -> Result<(), Error<E>> {
        let control = self.iface.read_register(Register::CONTROL)?;
        // do not overwrite if a conversion is in progress
        if (control & BitFlags::TEMP_CONV) == 0 {
            self.iface.write_register(Register::CONTROL, control | BitFlags::TEMP_CONV)?;
        }
        Ok(())
    }

    /// Enable the 32kHz output. (enabled per default)
    pub fn enable_32khz_output(&mut self) -> Result<(), Error<E>> {
        let status = self.status | BitFlags::EN32KHZ;
        self.write_status_without_clearing_alarm(status)
    }

    /// Disable the 32kHz output.
    pub fn disable_32khz_output(&mut self) -> Result<(), Error<E>> {
        let status = self.status & !BitFlags::EN32KHZ;
        self.write_status_without_clearing_alarm(status)
    }

    /// Set the aging offset.
    pub fn set_aging_offset(&mut self, offset: i8) -> Result<(), Error<E>> {
        self.iface.write_register(Register::AGING_OFFSET, offset as u8)
    }

    /// Read the aging offset.
    pub fn get_aging_offset(&mut self) -> Result<i8, Error<E>> {
        let offset = self.iface.read_register(Register::AGING_OFFSET)?;
        Ok(offset as i8)
    }

    /// Set the interrupt/square-wave output to be used as interrupt output.
    pub fn use_int_sqw_output_as_interrupt(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control | BitFlags::INTCN)
    }

    /// Set the interrupt/square-wave output to be used as square-wave output. (default)
    pub fn use_int_sqw_output_as_square_wave(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control & !BitFlags::INTCN)
    }

    /// Enable battery-backed square wave generation.
    pub fn enable_square_wave(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control | BitFlags::BBSQW)
    }

    /// Disable battery-backed square wave generation.
    pub fn disable_square_wave(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control & !BitFlags::BBSQW)
    }

    /// Set the square-wave output frequency.
    pub fn set_square_wave_frequency(&mut self, freq: SqWFreq) -> Result<(), Error<E>> {
        let new_control;
        match freq {
            SqWFreq::_1Hz     => new_control = self.control & !BitFlags::RS2 & !BitFlags::RS1,
            SqWFreq::_1_024Hz => new_control = self.control & !BitFlags::RS2 |  BitFlags::RS1,
            SqWFreq::_4_096Hz => new_control = self.control |  BitFlags::RS2 & !BitFlags::RS1,
            SqWFreq::_8_192Hz => new_control = self.control |  BitFlags::RS2 |  BitFlags::RS1,
        }
        self.write_control(new_control)
    }

    /// Enable Alarm1 interrupts.
    pub fn enable_alarm1_interrupts(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control | BitFlags::ALARM1_INT_EN)
    }

    /// Disable Alarm1 interrupts.
    pub fn disable_alarm1_interrupts(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control & !BitFlags::ALARM1_INT_EN)
    }

    /// Enable Alarm2 interrupts.
    pub fn enable_alarm2_interrupts(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control | BitFlags::ALARM2_INT_EN)
    }

    /// Disable Alarm2 interrupts.
    pub fn disable_alarm2_interrupts(&mut self) -> Result<(), Error<E>> {
        let control = self.control;
        self.write_control(control & !BitFlags::ALARM2_INT_EN)
    }

    fn write_control(&mut self, control: u8) -> Result<(), Error<E>> {
        self.iface.write_register(Register::CONTROL, control)?;
        self.control = control;
        Ok(())
    }

    pub(crate) fn write_status_without_clearing_alarm(&mut self, status: u8) -> Result<(), Error<E>> {
        // avoid clearing alarm flags
        let new_status = status | BitFlags::ALARM2F | BitFlags::ALARM1F;
        self.iface.write_register(Register::STATUS, new_status)?;
        self.status = status;
        Ok(())
    }
}