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}