1use crate::hw_def::*;
2
3use core::fmt;
4
5#[derive(Debug)]
7pub struct Hdc302x<I2C, Delay> {
8 pub(crate) i2c: I2C,
9 pub(crate) delay: Delay,
10 pub(crate) i2c_addr: crate::hw_def::I2cAddr,
11}
12
13#[derive(Debug)]
15pub enum Error<E> {
16 I2c(E),
18 InvalidInputData,
20 CrcMismatch,
22}
23
24#[derive(Debug)]
26pub enum RawDatum {
27 TempAndRelHumid(RawTempAndRelHumid),
29 MinTemp(u16),
31 MaxTemp(u16),
33 MinRelHumid(u16),
35 MaxRelHumid(u16),
37}
38impl RawDatum {
39 pub fn fahrenheit(&self) -> Option<f32> {
41 match self {
42 Self::TempAndRelHumid(RawTempAndRelHumid{temperature, ..}) => Some(raw_temp_to_fahrenheit(*temperature)),
43 Self::MinTemp(u16) => Some(raw_temp_to_fahrenheit(*u16)),
44 Self::MaxTemp(u16) => Some(raw_temp_to_fahrenheit(*u16)),
45 Self::MinRelHumid(_) => None,
46 Self::MaxRelHumid(_) => None,
47 }
48 }
49 pub fn centigrade(&self) -> Option<f32> {
51 match self {
52 Self::TempAndRelHumid(RawTempAndRelHumid{temperature, ..}) => Some(raw_temp_to_centigrade(*temperature)),
53 Self::MinTemp(u16) => Some(raw_temp_to_centigrade(*u16)),
54 Self::MaxTemp(u16) => Some(raw_temp_to_centigrade(*u16)),
55 Self::MinRelHumid(_) => None,
56 Self::MaxRelHumid(_) => None,
57 }
58 }
59 pub fn humidity_percent(&self) -> Option<f32> {
61 match self {
62 Self::TempAndRelHumid(_) => None,
63 Self::MinTemp(_) => None,
64 Self::MaxTemp(_) => None,
65 Self::MinRelHumid(u16) => Some(raw_rel_humid_to_percent(*u16)),
66 Self::MaxRelHumid(u16) => Some(raw_rel_humid_to_percent(*u16)),
67 }
68 }
69}
70
71#[derive(Debug)]
73pub struct RawTempAndRelHumid{
74 pub temperature: u16,
76 pub humidity: u16,
78}
79impl RawTempAndRelHumid {
80 pub fn fahrenheit(&self) -> f32 {
82 raw_temp_to_fahrenheit(self.temperature)
83 }
84 pub fn centigrade(&self) -> f32 {
86 raw_temp_to_centigrade(self.temperature)
87 }
88 pub fn humidity_percent(&self) -> f32 {
90 raw_rel_humid_to_percent(self.humidity)
91 }
92}
93
94#[derive(Debug)]
96pub enum Datum {
97 TempAndRelHumid(TempAndRelHumid),
99 MinTemp(Temp),
101 MaxTemp(Temp),
103 MinRelHumid(f32),
105 MaxRelHumid(f32),
107}
108impl From<&RawDatum> for Datum {
109 fn from(raw: &RawDatum) -> Self {
110 match raw {
111 RawDatum::TempAndRelHumid(raw) => Datum::TempAndRelHumid(raw.into()),
112 RawDatum::MinTemp(raw) => Datum::MinTemp((*raw).into()),
113 RawDatum::MaxTemp(raw) => Datum::MaxTemp((*raw).into()),
114 RawDatum::MinRelHumid(raw) => Datum::MinRelHumid(raw_rel_humid_to_percent(*raw)),
115 RawDatum::MaxRelHumid(raw) => Datum::MaxRelHumid(raw_rel_humid_to_percent(*raw)),
116 }
117 }
118}
119
120#[derive(Debug)]
122pub struct TempAndRelHumid {
123 pub centigrade: f32,
125 pub fahrenheit: f32,
127 pub humidity_percent: f32,
129}
130impl From<&RawTempAndRelHumid> for TempAndRelHumid {
131 fn from(raw: &RawTempAndRelHumid) -> Self {
132 Self {
133 centigrade: raw_temp_to_centigrade(raw.temperature),
134 fahrenheit: raw_temp_to_fahrenheit(raw.temperature),
135 humidity_percent: raw_rel_humid_to_percent(raw.humidity),
136 }
137 }
138}
139#[derive(Debug)]
141pub struct Temp{
142 pub centigrade: f32,
144 pub fahrenheit: f32,
146}
147impl From<u16> for Temp {
148 fn from(raw: u16) -> Self {
149 Self {
150 centigrade: raw_temp_to_centigrade(raw),
151 fahrenheit: raw_temp_to_fahrenheit(raw),
152 }
153 }
154}
155
156#[derive(Clone, Copy, Debug, Eq, PartialEq)]
158pub struct StatusBits {
159 raw: u16,
160 pub at_least_one_alert: bool,
162 pub heater_enabled: bool,
164 pub rh_tracking_alert: bool,
166 pub t_tracking_alert: bool,
168 pub rh_high_tracking_alert: bool,
170 pub rh_low_tracking_alert: bool,
172 pub t_high_tracking_alert: bool,
174 pub t_low_tracking_alert: bool,
176 pub reset_since_clear: bool,
178 pub checksum_failure: bool,
180}
181impl From<u16> for StatusBits {
182 fn from(raw: u16) -> Self {
183 Self {
184 raw,
185 at_least_one_alert: (raw >> STATUS_FIELD_LSBIT_AT_LEAST_ONE_ALERT) & ((1 << STATUS_FIELD_WIDTH_AT_LEAST_ONE_ALERT) - 1) != 0,
186 heater_enabled: (raw >> STATUS_FIELD_LSBIT_HEATER_ENABLED) & ((1 << STATUS_FIELD_WIDTH_HEATER_ENABLED) - 1) != 0,
187 rh_tracking_alert: (raw >> STATUS_FIELD_LSBIT_RH_TRACKING_ALERT) & ((1 << STATUS_FIELD_WIDTH_RH_TRACKING_ALERT) - 1) != 0,
188 t_tracking_alert: (raw >> STATUS_FIELD_LSBIT_T_TRACKING_ALERT) & ((1 << STATUS_FIELD_WIDTH_T_TRACKING_ALERT) - 1) != 0,
189 rh_high_tracking_alert: (raw >> STATUS_FIELD_LSBIT_RH_HIGH_TRACKING_ALERT) & ((1 << STATUS_FIELD_WIDTH_RH_HIGH_TRACKING_ALERT) - 1) != 0,
190 rh_low_tracking_alert: (raw >> STATUS_FIELD_LSBIT_RH_LOW_TRACKING_ALERT) & ((1 << STATUS_FIELD_WIDTH_RH_LOW_TRACKING_ALERT) - 1) != 0,
191 t_high_tracking_alert: (raw >> STATUS_FIELD_LSBIT_T_HIGH_TRACKING_ALERT) & ((1 << STATUS_FIELD_WIDTH_T_HIGH_TRACKING_ALERT) - 1) != 0,
192 t_low_tracking_alert: (raw >> STATUS_FIELD_LSBIT_T_LOW_TRACKING_ALERT) & ((1 << STATUS_FIELD_WIDTH_T_LOW_TRACKING_ALERT) - 1) != 0,
193 reset_since_clear: (raw >> STATUS_FIELD_LSBIT_RESET_SINCE_CLEAR) & ((1 << STATUS_FIELD_WIDTH_RESET_SINCE_CLEAR) - 1) != 0,
194 checksum_failure: (raw >> STATUS_FIELD_LSBIT_CHECKSUM_FAILURE) & ((1 << STATUS_FIELD_WIDTH_CHECKSUM_FAILURE) - 1) != 0,
195 }
196 }
197}
198impl StatusBits {
199 pub fn raw(&self) -> u16 {
201 self.raw
202 }
203}
204impl fmt::Display for StatusBits {
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 write!(f, "StatusBits {{ 0x{:02x}; ", self.raw)?;
207 if self.at_least_one_alert {
208 write!(f, "at_least_one_alert ")?;
209 }
210 if self.heater_enabled {
211 write!(f, "heater_enabled ")?;
212 }
213 if self.rh_tracking_alert {
214 write!(f, "rh_tracking_alert ")?;
215 }
216 if self.t_tracking_alert {
217 write!(f, "t_tracking_alert ")?;
218 }
219 if self.rh_high_tracking_alert {
220 write!(f, "rh_high_tracking_alert ")?;
221 }
222 if self.rh_low_tracking_alert {
223 write!(f, "rh_low_tracking_alert ")?;
224 }
225 if self.t_high_tracking_alert {
226 write!(f, "t_high_tracking_alert ")?;
227 }
228 if self.t_low_tracking_alert {
229 write!(f, "t_low_tracking_alert ")?;
230 }
231 if self.reset_since_clear {
232 write!(f, "reset_since_clear ")?;
233 }
234 if self.checksum_failure {
235 write!(f, "checksum_failure ")?;
236 }
237 write!(f, "}}")
238 }
239}
240
241
242pub struct SerialNumber(pub [u8; 6]);
244impl fmt::Display for SerialNumber {
245 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246 for byte in self.0.iter().rev() {
247 write!(f, "{:02X}", byte)?;
248 }
249 Ok(())
250 }
251}
252
253#[derive(Clone, Copy)]
255pub enum ManufacturerId {
256 TexasInstruments,
258 Other(u16),
260}
261impl From<u16> for ManufacturerId {
262 fn from(raw: u16) -> Self {
263 match raw {
264 MANUFACTURER_ID_TEXAS_INSTRUMENTS => ManufacturerId::TexasInstruments,
265 _ => ManufacturerId::Other(raw),
266 }
267 }
268}
269impl Into<u16> for ManufacturerId {
270 fn into(self) -> u16 {
271 match self {
272 ManufacturerId::TexasInstruments => MANUFACTURER_ID_TEXAS_INSTRUMENTS,
273 ManufacturerId::Other(id) => id,
274 }
275 }
276}
277impl fmt::Display for ManufacturerId {
278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279 match self {
280 ManufacturerId::TexasInstruments => {
281 let mid_u16: u16 = (*self).into();
282 write!(f, "Texas Instruments (0x{mid_u16:04X})")
283 }
284 ManufacturerId::Other(mid_u16) => write!(f, "Unknown (0x{mid_u16:04X})"),
285 }
286 }
287}