embedded_devices/devices/bosch/bme280/
registers.rs

1use embedded_interfaces::codegen::interface_objects;
2use embedded_interfaces::registers::{i2c::codecs::OneByteRegAddrCodec, spi::codecs::standard_codec::StandardCodec};
3
4pub type BME280SpiCodec = StandardCodec<1, 6, 0, 7, true, 0>;
5pub type BME280I2cCodec = OneByteRegAddrCodec;
6
7interface_objects! {
8    register_defaults {
9        codec_error = (),
10        i2c_codec = BME280I2cCodec,
11        spi_codec = BME280SpiCodec,
12    }
13
14    register_devices [ super::BME280Common ]
15
16    /// Known chip ids
17    enum Chip: u8{8} {
18        /// A BMP280 production sample
19        0x56 BMP280Sample1,
20        /// A BMP280 production sample
21        0x57 BMP280Sample2,
22        /// A mass-produced BMP280
23        0x58 BMP280,
24        /// A mass-produced BME280
25        0x60 BME280,
26        /// Unknown chip id
27        _ Invalid(u8),
28    }
29
30    /// Reset magic values
31    enum ResetMagic: u8{8} {
32        /// Magic value to reset the device
33        0xb6 Reset,
34        /// Invalid reset magic
35        _ Invalid(u8),
36    }
37
38    /// Oversampling settings for temperature, pressure, and humidity measurements.
39    /// See sections 3.4ff of the manual for measurement flow and recommended values.
40    #[allow(non_camel_case_types)]
41    enum Oversampling: u8{3} {
42        /// Disables this output. Measurement data will be returned as 0x80000.
43        0b000 Disabled,
44        /// Disables oversampling.
45        /// Without IIR filtering, this sets the resolution of temperature and pressure measurements
46        /// to 16 bits.
47        0b001 X_1,
48        /// Configures 2x oversampling.
49        /// This increases the resolution of temperature and pressure measurements to 17 bits without
50        /// IIR filtering.
51        0b010 X_2,
52        /// Configures 4x oversampling.
53        /// This increases the resolution of temperature and pressure measurements to 18 bits without
54        /// IIR filtering.
55        0b011 X_4,
56        /// Configures 8x oversampling.
57        /// This increases the resolution of temperature and pressure measurements to 19 bits without
58        /// IIR filtering.
59        0b100 X_8,
60        /// Configures 16x oversampling.
61        /// This increases the resolution of temperature and pressure measurements to 20 bits,
62        /// regardless of IIR filtering.
63        0b101 X_16,
64        /// Unknown oversampling setting.
65        _ Invalid(u8),
66    }
67
68    /// Sensor operating mode
69    enum SensorMode: u8{2} {
70        /// Sleep mode is entered by default after power on reset. In sleep mode, no measurements are
71        /// performed and power consumption is at a minimum. All registers are accessible.
72        /// There are no special restrictions on interface timings.
73        0b00 Sleep,
74        /// In forced mode, a single measurement is performed in accordance to the selected measurement and
75        /// filter options. When the measurement is finished, the sensor returns to sleep mode and the
76        /// measurement results can be obtained from the data registers. For a next measurement, forced mode
77        /// needs to be selected again. Using forced mode is recommended
78        /// for applications which require low sampling rate or host-based synchronization.
79        0b01 Forced,
80        /// Normal mode comprises an automated perpetual cycling between an (active) measurement period
81        /// and an (inactive) standby period. The measurements are performed in accordance to the selected
82        /// measurement and filter options. The standby time is determined by the standby_time setting
83        /// in the Config register and can be set to between 0.5 and 1000 ms.
84        0b11 Normal,
85        /// Invalid sensor mode
86        _ Invalid(u8),
87    }
88
89    /// The standby time between measurements in Normal sensor mode.
90    #[allow(non_camel_case_types)]
91    enum StandbyTime: u8{3} {
92        /// 0.5ms
93        0b000 T_0_5,
94        /// 62.5ms
95        0b001 T_62_5,
96        /// 125ms
97        0b010 T_125,
98        /// 250ms
99        0b011 T_250,
100        /// 500ms
101        0b100 T_500,
102        /// 1000ms
103        0b101 T_1000,
104        /// 10ms (BME280 only)
105        0b110 T_10,
106        /// 20ms (BME280 only)
107        0b111 T_20,
108    }
109
110    /// Lowpass filter settings for pressure and temperature values.
111    /// Enabling any filter option increases the resolution of the
112    /// respective measured quantity to 20 bits.
113    enum IIRFilter: u8{3} {
114        /// Disables the IIR filter (default).
115        /// The resolution of pressure and temperature measurements is dictated by their respective
116        /// oversampling settings.
117        0b000 Disabled,
118        /// Sets the IIR filter coefficient to 2.
119        0b001 Coefficient2,
120        /// Sets the IIR filter coefficient to 4.
121        0b010 Coefficient4,
122        /// Sets the IIR filter coefficient to 8.
123        0b011 Coefficient8,
124        /// Sets the IIR filter coefficient to 16.
125        0b100 Coefficient16,
126        /// Invalid coefficient
127        _ Invalid(u8),
128    }
129
130    /// The chip identification number. This number can
131    /// be read as soon as the device finished the power-on-reset.
132    register Id(addr = 0xd0, mode = r, size = 1) {
133        chip: Chip = Chip::Invalid(0),
134    }
135
136    /// The reset register. If the value 0xB6 is written to the register,
137    /// the device is reset using the complete power-on-reset procedure.
138    /// Writing other values than 0xB6 has no effect.
139    register Reset(addr = 0xe0, mode = w, size = 1) {
140        magic: ResetMagic = ResetMagic::Reset,
141    }
142
143    /// The humidity control register. Changes to this register only become effective
144    /// after a write to the ControlMeasurement register!
145    register ControlHumidity(addr = 0xf2, mode = rw, size = 1) {
146        /// Reserved bits
147        _: u8{5},
148        /// Controls oversampling of humidity data.
149        /// The default is 1x, i.e., no oversampling.
150        oversampling: Oversampling = Oversampling::X_1,
151    }
152
153    /// The status register.
154    register Status(addr = 0xf3, mode = r, size = 1) {
155        /// Reserved bits
156        _: u8{4},
157        /// Automatically set to `1` whenever a conversion is running and back to `0` when the results have been transferred to the data registers.
158        measuring: bool = false,
159        /// Reserved bits
160        _: u8{2},
161        /// Automatically set to `1` when the NVM data is being copied to image registers and back to `0` when the
162        /// copying is done. The data are copied at power-on-reset and before every conversion.
163        update: bool = false,
164    }
165
166    /// The measurement control register sets the pressure and temperature
167    /// data acquisition options of the device. The register needs to be written
168    /// after changing ControlHumidity for those changes to become effective.
169    register ControlMeasurement(addr = 0xf4, mode = rw, size = 1) {
170        /// Controls oversampling of temperature data.
171        temperature_oversampling: Oversampling = Oversampling::Disabled,
172        /// Controls oversampling of pressure data.
173        pressure_oversampling: Oversampling = Oversampling::Disabled,
174        /// Controls operating mode of the sensor.
175        sensor_mode: SensorMode = SensorMode::Sleep,
176    }
177
178    /// The config register sets the rate, filter and interface options of the device.
179    /// Writes to this register in Normal mode may be ignored.
180    /// In Sleep mode writes are not ignored.
181    register Config(addr = 0xf5, mode = rw, size = 1) {
182        /// Controls inactive duration t_standby in Normal sensor mode.
183        standby_time: StandbyTime = StandbyTime::T_0_5,
184        /// Controls the time constant of the IIR filter.
185        filter: IIRFilter = IIRFilter::Disabled,
186        /// Reserved bit
187        _: bool,
188        /// Whether to enable the SPI 3-wire interface.
189        spi_3wire: bool = false,
190    }
191
192    /// Device-internal calibration registers (section 1)
193    register TrimmingParameters1(addr = 0x88, mode = r, size = 26) {
194        dig_t1: u16{le},
195        dig_t2: i16{le},
196        dig_t3: i16{le},
197        dig_p1: u16{le},
198        dig_p2: i16{le},
199        dig_p3: i16{le},
200        dig_p4: i16{le},
201        dig_p5: i16{le},
202        dig_p6: i16{le},
203        dig_p7: i16{le},
204        dig_p8: i16{le},
205        dig_p9: i16{le},
206        /// Reserved byte
207        _: u8,
208        dig_h1: u8,
209    }
210
211    /// Device-internal calibration registers (section 2)
212    register TrimmingParameters2(addr = 0xe1, mode = r, size = 7) {
213        dig_h2: i16{le},
214        dig_h3: u8,
215        dig_h4_msb: i8,
216        dig_h5_lsn_h4_lsn: i8,
217        dig_h5_msb: i8,
218        dig_h6: i8,
219    }
220
221    /// This register contains the raw pressure measurement
222    register Pressure(addr = 0xf7, mode = r, size = 3) {
223        /// The raw pressure measurement
224        value: u32{20} = 1 << 19,
225        /// Reserved bits
226        _: u8{4},
227    }
228
229    /// This register contains the raw temperature measurement
230    register Temperature(addr = 0xfa, mode = r, size = 3) {
231        /// The raw temperature measurement
232        value: u32{20} = 1 << 19,
233        /// Reserved bits
234        _: u8{4},
235    }
236
237    /// This register contains the raw humidity measurement
238    register Humidity(addr = 0xfd, mode = r, size = 2) {
239        /// The raw humidity measurement
240        value: u16 = 1 << 15,
241    }
242
243    /// Burst register read of pressure and temperature
244    register BurstMeasurementsPT(addr = 0xf7, mode = r, size = 6) {
245        pressure: PressureUnpacked,
246        temperature: TemperatureUnpacked,
247    }
248
249    /// Burst register read of pressure, temperature and humidity
250    register BurstMeasurementsPTH(addr = 0xf7, mode = r, size = 8) {
251        pressure: PressureUnpacked,
252        temperature: TemperatureUnpacked,
253        humidity: HumidityUnpacked,
254    }
255}
256
257impl Oversampling {
258    /// Returns the oversampling factor (1 for X_1, 16 for X_16)
259    pub fn factor(&self) -> u32 {
260        match self {
261            Oversampling::Disabled => 0,
262            Oversampling::X_1 => 1,
263            Oversampling::X_2 => 2,
264            Oversampling::X_4 => 4,
265            Oversampling::X_8 => 8,
266            Oversampling::X_16 => 16,
267            Oversampling::Invalid(_) => 0,
268        }
269    }
270}
271
272impl StandbyTime {
273    /// Standby time in microseconds.
274    pub fn time_us(&self) -> u32 {
275        match self {
276            StandbyTime::T_0_5 => 500,
277            StandbyTime::T_62_5 => 62_500,
278            StandbyTime::T_125 => 125_000,
279            StandbyTime::T_250 => 250_000,
280            StandbyTime::T_500 => 500_000,
281            StandbyTime::T_1000 => 1_000_000,
282            StandbyTime::T_10 => 10_000,
283            StandbyTime::T_20 => 20_000,
284        }
285    }
286}