1#[allow(unused_imports)]
3#[warn(dead_code)]
4use libm::{exp, round, trunc};
5
6#[allow(unused_imports)] use bitfield::bitfield;
11
12pub const DEFAULT_ADDRESS: u8 = 0x52;
14pub const SECONDARY_ADDRESS: u8 = 0x53;
16
17#[derive(Debug, PartialEq, Clone, Copy)]
19pub struct Measurements {
20 pub co2eq_ppm: ECO2,
22 pub tvoc_ppb: u16,
24 pub air_quality_index: AirQualityIndex,
26 pub etoh: u16,
28 pub raw_resistance: f32,
30}
31
32#[derive(Debug, Clone, Copy, Eq, PartialEq)]
34#[repr(u8)] pub enum AirQualityIndex {
36 Unavailable = 0,
37 Excellent = 1,
38 Good = 2,
39 Moderate = 3,
40 Poor = 4,
41 Unhealthy = 5,
42 InvalidRange = 6,
43}
44
45impl From<u8> for AirQualityIndex {
46 fn from(i: u8) -> Self {
47 match i {
48 0 => Self::Unavailable,
49 1 => Self::Excellent,
50 2 => Self::Good,
51 3 => Self::Moderate,
52 4 => Self::Poor,
53 5 => Self::Unhealthy,
54 _ => Self::InvalidRange,
55 }
56 }
57}
58
59#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
61pub struct ECO2 {
62 pub value: u16,
63}
64
65impl ECO2 {
66 pub fn get_value(&self) -> u16 {
67 self.value
68 }
69}
70
71impl From<u16> for ECO2 {
72 fn from(v: u16) -> Self {
73 ECO2 { value: v }
74 }
75}
76
77#[derive(Debug, PartialEq)]
79#[repr(u8)]
80pub enum OperationMode {
81 Sleep = 0x00,
83 Idle = 0x01,
85 Standard = 0x02,
87 Reset = 0xf0,
91}
92
93impl From<u8> for OperationMode {
94 fn from(value: u8) -> Self {
95 match value {
96 0x00 => OperationMode::Sleep,
97 0x01 => OperationMode::Idle,
98 0x02 => OperationMode::Standard,
99 0xf0 => OperationMode::Reset, _ => unreachable!(),
101 }
102 }
103}
104
105#[repr(u8)]
107pub enum ENS160Command {
108 Nop = 0x00,
110 GetAppVersion = 0x0e,
112 ClearGPR = 0xcc,
114}
115
116#[derive(Debug, Clone, Copy)]
118pub enum ValidityFlag {
119 NormalOperation,
120 WarmupPhase,
121 InitialStartupPhase,
122 InvalidOutput,
123}
124
125impl From<u8> for ValidityFlag {
127 fn from(v: u8) -> Self {
128 match v {
129 0x00 => Self::NormalOperation,
130 0x01 => Self::WarmupPhase,
131 0x02 => Self::InitialStartupPhase,
132 0x03 => Self::InvalidOutput,
133 _ => unreachable!(), }
135 }
136}
137
138bitfield! {
139 pub struct Status(u8);
141 impl Debug;
142
143 pub bool, new_group_data_ready, _: 0;
144 pub bool, new_data_ready, _: 1;
145 pub into ValidityFlag, validity_flag, _: 3,2; pub bool, error, _: 6; pub bool, running_mode, _: 7;
149}
150
151#[derive(Debug)]
152pub struct InterruptPinConfig(pub u8);
154
155impl InterruptPinConfig {
156 pub fn builder() -> InterruptPinConfig {
158 InterruptPinConfig(0x00)
159 }
160 pub fn get_value(&self) -> u8 {
162 self.0
163 }
164 pub fn active_high(mut self) -> Self {
166 self.0 |= 0b01000000;
167 self
168 }
169 pub fn active_low(mut self) -> Self {
171 self.0 &= 0b10111111;
172 self
173 }
174 pub fn push_pull(mut self) -> Self {
176 self.0 |= 0b00100000;
177 self
178 }
179 pub fn open_drain(mut self) -> Self {
181 self.0 &= 0b11011111;
182 self
183 }
184 pub fn on_new_group_data(mut self) -> Self {
186 self.0 |= 0b00000100;
187 self
188 }
189 pub fn not_new_group_data(mut self) -> Self {
191 self.0 &= 0b11111011;
192 self
193 }
194 pub fn on_new_data(mut self) -> Self {
196 self.0 |= 0b00000010;
197 self
198 }
199 pub fn not_new_data(mut self) -> Self {
201 self.0 &= 0b11111101;
202 self
203 }
204 pub fn enable_interrupt(mut self) -> Self {
206 self.0 |= 0b00000001;
207 self
208 }
209 pub fn disable_interrupt(mut self) -> Self {
211 self.0 &= 0b11111110;
212 self
213 }
214 pub fn build(&self) -> u8 { self.0
217 }
218
219}