pamoja_sensors/tmp117/sim.rs
1//! A TMP117 that is not there.
2//!
3//! [`part`] answers the way a TMP117 at 21.25 C does, and [`reporting`] at any temperature.
4//! Its configuration register keeps the four flags the part sets for itself, HIGH_Alert,
5//! LOW_Alert, Data_Ready, and EEPROM_Busy, whatever a driver writes there, with Data_Ready
6//! set, so every conversion reads as finished.
7
8use pamoja_hal::sim::WordPart;
9
10use super::{raw_from_celsius, register, DEVICE_ID};
11
12/// The temperature [`part`] reports.
13pub const CELSIUS: f32 = 21.25;
14
15/// The configuration register's flags, bits 15 to 12, which a write leaves alone.
16const FLAGS: u16 = 0xF000;
17
18/// Data_Ready, bit 13.
19const DATA_READY: u16 = 1 << 13;
20
21/// A TMP117 answering at an address, reading [`CELSIUS`].
22///
23/// # Arguments
24///
25/// * `address` - the address it answers to, 0x48 with ADD0 to ground.
26///
27/// # Returns
28///
29/// The part.
30#[must_use]
31pub fn part(address: u8) -> WordPart {
32 reporting(address, CELSIUS)
33}
34
35/// A TMP117 that reads what it is asked to.
36///
37/// # Arguments
38///
39/// * `address` - the address it answers to.
40/// * `celsius` - the temperature it reports, which lands on the nearest 7.8125 m°C.
41///
42/// # Returns
43///
44/// The part.
45///
46/// # Examples
47///
48/// ```
49/// use pamoja_hal::script::DelayLog;
50/// use pamoja_sensors::tmp117::{address, sim, Tmp117};
51///
52/// // A cold room at -18.5 °C.
53/// let part = sim::reporting(address::ADD0_GND, -18.5);
54/// let mut thermometer = Tmp117::new(part, address::ADD0_GND, DelayLog::new());
55/// let reading = thermometer.measure().expect("the part answers");
56/// assert_eq!(reading.celsius(), -18.5);
57/// ```
58#[must_use]
59pub fn reporting(address: u8, celsius: f32) -> WordPart {
60 WordPart::new(address)
61 .holding(register::DEVICE_ID, DEVICE_ID)
62 .holding(register::CONFIGURATION, DATA_READY)
63 .read_only(register::CONFIGURATION, FLAGS)
64 .holding(register::TEMP_RESULT, raw_from_celsius(celsius) as u16)
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use crate::tmp117::{data_ready, eeprom_busy, Tmp117};
71 use pamoja_hal::script::DelayLog;
72
73 #[test]
74 fn the_flags_are_the_ones_the_decoder_reads() {
75 assert!(data_ready(DATA_READY));
76 assert!(eeprom_busy(FLAGS));
77 }
78
79 #[test]
80 fn the_driver_reads_the_temperature_the_part_holds() {
81 let mut thermometer = Tmp117::new(part(0x48), 0x48, DelayLog::new());
82 assert_eq!(thermometer.measure().expect("a reading").celsius(), CELSIUS);
83
84 let mut cold = Tmp117::new(reporting(0x49, -40.0), 0x49, DelayLog::new());
85 assert_eq!(cold.measure().expect("a reading").celsius(), -40.0);
86 }
87}