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
132
133
use crate::{
    BitFlagsHigh, ConfigHigh, ConversionRate, Error, Register, SlaveAddr, Tmp006,
    DEVICE_BASE_ADDRESS,
};
use embedded_hal::i2c;

impl ConfigHigh {
    fn with_high(self, mask: u8) -> Self {
        ConfigHigh {
            bits: self.bits | mask,
        }
    }
    fn with_low(self, mask: u8) -> Self {
        ConfigHigh {
            bits: self.bits & !mask,
        }
    }
}

impl Default for ConfigHigh {
    fn default() -> Self {
        ConfigHigh { bits: 0 }
            .with_high(BitFlagsHigh::MOD)
            .with_high(BitFlagsHigh::CR1)
    }
}

impl<I2C, E> Tmp006<I2C>
where
    I2C: i2c::I2c<Error = E>,
{
    /// Create new instance of the TMP006 device.
    pub fn new(i2c: I2C, address: SlaveAddr) -> Self {
        Tmp006 {
            i2c,
            address: address.addr(DEVICE_BASE_ADDRESS),
            config: ConfigHigh::default(),
        }
    }

    /// Destroy driver instance, return I²C bus instance.
    pub fn destroy(self) -> I2C {
        self.i2c
    }

    /// Enable the sensor (default state).
    ///
    /// Sensor and ambient continuous conversion.
    ///
    /// Note: calling this clears the data-ready bit.
    pub fn enable(&mut self) -> Result<(), Error<E>> {
        let config = self.config;
        self.write_config(config.with_high(BitFlagsHigh::MOD))
    }

    /// Disable the sensor (power-down).
    ///
    /// Note: calling this clears the data-ready bit.
    pub fn disable(&mut self) -> Result<(), Error<E>> {
        let config = self.config;
        self.write_config(config.with_low(BitFlagsHigh::MOD))
    }

    /// Reset the sensor (software reset).
    ///
    /// Note: calling this clears the data-ready bit.
    pub fn reset(&mut self) -> Result<(), Error<E>> {
        let config = self.config;
        self.write_config(config.with_high(BitFlagsHigh::SW_RESET))?;
        self.config = ConfigHigh::default();
        Ok(())
    }

    /// Enable DRDY pin.
    ///
    /// Note: calling this clears the data-ready bit.
    pub fn enable_drdy_pin(&mut self) -> Result<(), Error<E>> {
        let config = self.config;
        self.write_config(config.with_high(BitFlagsHigh::DRDY_EN))
    }

    /// Disable DRDY pin.
    ///
    /// Note: calling this clears the data-ready bit.
    pub fn disable_drdy_pin(&mut self) -> Result<(), Error<E>> {
        let config = self.config;
        self.write_config(config.with_low(BitFlagsHigh::DRDY_EN))
    }

    /// Set the ADC conversion rate.
    ///
    /// Note: calling this clears the data-ready bit.
    pub fn set_conversion_rate(&mut self, rate: ConversionRate) -> Result<(), Error<E>> {
        use crate::BitFlagsHigh as BF;
        use crate::ConversionRate as CR;
        let config = match rate {
            CR::Cps4 => self
                .config
                .with_low(BF::CR2)
                .with_low(BF::CR1)
                .with_low(BF::CR0),
            CR::Cps2 => self
                .config
                .with_low(BF::CR2)
                .with_low(BF::CR1)
                .with_high(BF::CR0),
            CR::Cps1 => self
                .config
                .with_low(BF::CR2)
                .with_high(BF::CR1)
                .with_low(BF::CR0),
            CR::Cps0_5 => self
                .config
                .with_low(BF::CR2)
                .with_high(BF::CR1)
                .with_high(BF::CR0),
            CR::Cps0_25 => self
                .config
                .with_high(BF::CR2)
                .with_low(BF::CR1)
                .with_low(BF::CR0),
        };
        self.write_config(config)
    }

    fn write_config(&mut self, config: ConfigHigh) -> Result<(), Error<E>> {
        self.i2c
            .write(self.address, &[Register::CONFIG, config.bits, 0])
            .map_err(Error::I2C)?;
        self.config = config;
        Ok(())
    }
}