1#[derive(Clone, Debug, Default, Eq, PartialEq)]
13pub struct Configuration {
14 standby_time: StandbyTime,
16
17 filter: Filter,
19
20 spi3w: bool,
22
23 temperature_oversampling: Oversampling,
25
26 pressure_oversampling: Oversampling,
28
29 humidity_oversampling: Oversampling,
31
32 sensor_mode: SensorMode,
34}
35
36impl From<&Configuration> for (Config, ControlMeasurement, ControlHumidity) {
37 fn from(configuration: &Configuration) -> Self {
38 let config = (
39 configuration.standby_time,
40 configuration.filter,
41 configuration.spi3w,
42 )
43 .into();
44 let control_measurement = (
45 configuration.temperature_oversampling,
46 configuration.pressure_oversampling,
47 configuration.sensor_mode,
48 )
49 .into();
50 let control_humidity = configuration.humidity_oversampling.into();
51 (config, control_measurement, control_humidity)
52 }
53}
54
55impl Configuration {
56 #[doc(hidden)]
58 #[must_use]
59 pub(crate) fn to_lowlevel_configuration(
60 &self,
61 ) -> (Config, ControlMeasurement, ControlHumidity) {
62 self.into()
63 }
64
65 #[must_use]
67 pub fn with_standby_time(mut self, standby_time: StandbyTime) -> Self {
68 self.standby_time = standby_time;
69 self
70 }
71
72 #[must_use]
74 pub fn with_filter(mut self, filter: Filter) -> Self {
75 self.filter = filter;
76 self
77 }
78
79 #[doc(hidden)]
81 #[allow(unused)]
82 pub(crate) fn with_spi3w(mut self, spi3w: bool) -> Self {
83 self.spi3w = spi3w;
84 self
85 }
86
87 #[must_use]
89 pub fn with_temperature_oversampling(mut self, temperature_oversampling: Oversampling) -> Self {
90 self.temperature_oversampling = temperature_oversampling;
91 self
92 }
93
94 #[must_use]
96 pub fn with_pressure_oversampling(mut self, pressure_oversampling: Oversampling) -> Self {
97 self.pressure_oversampling = pressure_oversampling;
98 self
99 }
100
101 #[must_use]
103 pub fn with_humidity_oversampling(mut self, humidity_oversampling: Oversampling) -> Self {
104 self.humidity_oversampling = humidity_oversampling;
105 self
106 }
107
108 #[must_use]
110 pub fn with_sensor_mode(mut self, sensor_mode: SensorMode) -> Self {
111 self.sensor_mode = sensor_mode;
112 self
113 }
114
115 #[doc(hidden)]
117 pub(crate) fn is_forced(&self) -> bool {
118 self.sensor_mode == SensorMode::Forced
119 }
120}
121
122#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
124pub struct Status {
125 measuring: bool,
127
128 calibrating: bool,
130}
131
132impl Status {
133 #[must_use]
135 pub fn is_measuring(&self) -> bool {
136 self.measuring
137 }
138
139 #[must_use]
141 pub fn is_calibrating(&self) -> bool {
142 self.calibrating
143 }
144}
145
146impl core::fmt::Display for Status {
147 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
148 if self.calibrating && self.measuring {
149 write!(f, "calibrating and measuring")?;
150 } else if self.calibrating {
151 write!(f, "calibrating")?;
152 } else if self.measuring {
153 write!(f, "measuring")?;
154 } else {
155 write!(f, "ready")?;
156 }
157 Ok(())
158 }
159}
160
161impl From<u8> for Status {
162 fn from(arg: u8) -> Self {
163 Self {
164 measuring: (arg & 0b0000_0100) != 0,
165 calibrating: (arg & 0b0000_0001) != 0,
166 }
167 }
168}
169
170#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
172pub enum Oversampling {
173 #[default]
175 Skip,
176
177 Oversample1,
179
180 Oversample2,
182
183 Oversample4,
185
186 Oversample8,
188
189 Oversample16,
191}
192
193impl Oversampling {
194 #[doc(hidden)]
196 pub(crate) fn to_value(self) -> u8 {
197 match self {
198 Self::Skip => 0b000,
199 Self::Oversample1 => 0b001,
200 Self::Oversample2 => 0b010,
201 Self::Oversample4 => 0b011,
202 Self::Oversample8 => 0b100,
203 Self::Oversample16 => 0b101,
204 }
205 }
206}
207
208#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
210pub enum SensorMode {
211 #[default]
215 Sleep,
216
217 Forced,
221
222 Normal,
228}
229
230impl SensorMode {
231 #[doc(hidden)]
233 pub(crate) fn to_value(self) -> u8 {
234 match self {
235 Self::Sleep => 0b00,
236 Self::Forced => 0b01,
237 Self::Normal => 0b11,
238 }
239 }
240}
241
242#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
244pub enum StandbyTime {
245 #[default]
247 Millis0_5,
248
249 Millis10,
251
252 Millis20,
254
255 Millis62_5,
257
258 Millis125,
260
261 Millis250,
263
264 Millis500,
266
267 Millis1000,
269}
270
271impl StandbyTime {
272 #[doc(hidden)]
274 pub(crate) fn to_value(self) -> u8 {
275 match self {
276 Self::Millis0_5 => 0b000,
277 Self::Millis10 => 0b110,
278 Self::Millis20 => 0b111,
279 Self::Millis62_5 => 0b001,
280 Self::Millis125 => 0b010,
281 Self::Millis250 => 0b011,
282 Self::Millis500 => 0b100,
283 Self::Millis1000 => 0b101,
284 }
285 }
286}
287
288#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
290pub enum Filter {
291 #[default]
293 Off,
294
295 Filter2,
297
298 Filter4,
300
301 Filter8,
303
304 Filter16,
306}
307
308impl Filter {
309 #[doc(hidden)]
311 pub(crate) fn to_value(self) -> u8 {
312 match self {
313 Self::Off => 0b000,
314 Self::Filter2 => 0b001,
315 Self::Filter4 => 0b010,
316 Self::Filter8 => 0b011,
317 Self::Filter16 => 0b100,
318 }
319 }
320}
321
322#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
324pub(crate) struct Config(u8);
325
326impl From<(StandbyTime, Filter, bool)> for Config {
327 fn from((standby_time, filter, spi3w): (StandbyTime, Filter, bool)) -> Self {
328 let standby_time = standby_time.to_value() & 0b111;
329 let filter = filter.to_value() & 0b111;
330 let spi3w = u8::from(spi3w) & 0b1;
331 Self((standby_time << 5) | (filter << 2) | spi3w)
332 }
333}
334
335impl From<Config> for u8 {
336 fn from(config: Config) -> Self {
337 config.0
338 }
339}
340
341#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
343pub(crate) struct ControlHumidity(u8);
344
345impl From<Oversampling> for ControlHumidity {
346 fn from(humidity_oversampling: Oversampling) -> Self {
347 Self(humidity_oversampling.to_value() & 0b111)
348 }
349}
350
351impl From<ControlHumidity> for u8 {
352 fn from(ctrl_hum: ControlHumidity) -> Self {
353 ctrl_hum.0
354 }
355}
356
357#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
359pub(crate) struct ControlMeasurement(u8);
360
361impl From<(Oversampling, Oversampling, SensorMode)> for ControlMeasurement {
362 fn from(
363 (oversampling_temperature, oversampling_pressure, sensor_mode): (
364 Oversampling,
365 Oversampling,
366 SensorMode,
367 ),
368 ) -> Self {
369 let oversampling_temperature = oversampling_temperature.to_value() & 0b111;
370 let oversampling_pressure = oversampling_pressure.to_value() & 0b111;
371 let sensor_mode = sensor_mode.to_value() & 0b11;
372 Self((oversampling_temperature << 5) | (oversampling_pressure << 2) | sensor_mode)
373 }
374}
375
376impl From<ControlMeasurement> for u8 {
377 fn from(ctrl_meas: ControlMeasurement) -> Self {
378 ctrl_meas.0
379 }
380}
381
382#[cfg(test)]
383mod tests {
384 use super::*;
385
386 #[test]
387 fn test_status() {
388 let raw_status = 0b0000_0000;
389 let status: Status = raw_status.into();
390
391 let expected = Status {
392 measuring: false,
393 calibrating: false,
394 };
395
396 assert_eq!(status, expected);
397 }
398
399 #[test]
400 fn test_status_calibrating() {
401 let raw_status = 0b0000_0001;
402 let status: Status = raw_status.into();
403
404 let expected = Status {
405 measuring: false,
406 calibrating: true,
407 };
408
409 assert_eq!(status, expected);
410 }
411
412 #[test]
413 fn test_standby() {
414 let standby = StandbyTime::Millis125;
415
416 let expected = 0b010;
417 let actual = standby.to_value();
418
419 assert_eq!(actual, expected, "0b{actual:03b} == 0b{expected:03b}");
420 }
421
422 #[test]
423 fn test_config() {
424 let configuration = Configuration::default()
425 .with_standby_time(StandbyTime::Millis125)
426 .with_filter(Filter::Filter2)
427 .with_spi3w(true);
428 let (config, _ctrl_meas, _ctrl_hum) = configuration.to_lowlevel_configuration();
429 let actual: u8 = config.into();
430
431 let expected = 0b0100_0101;
432
433 assert_eq!(actual, expected, "0b{actual:08b} == 0b{expected:08b}");
434 }
435
436 #[test]
437 fn test_control_measurement() {
438 let configuration = Configuration::default()
439 .with_temperature_oversampling(Oversampling::Oversample8)
440 .with_pressure_oversampling(Oversampling::Oversample4)
441 .with_sensor_mode(SensorMode::Normal);
442 let (_config, ctrl_meas, _ctrl_hum) = configuration.to_lowlevel_configuration();
443 let actual: u8 = ctrl_meas.into();
444
445 let expected = 0b1000_1111;
446
447 assert_eq!(actual, expected, "0b{actual:08b} == 0b{expected:08b}");
448 }
449
450 #[test]
451 fn test_control_humidity() {
452 let configuration =
453 Configuration::default().with_humidity_oversampling(Oversampling::Oversample8);
454 let (_config, _ctrl_meas, ctrl_hum) = configuration.to_lowlevel_configuration();
455 let actual: u8 = ctrl_hum.into();
456
457 let expected = 0b100;
458
459 assert_eq!(actual, expected, "0b{actual:03b} == 0b{expected:03b}");
460 }
461}