1#![no_std]
2
3#[cfg(not(feature = "async"))]
4use embedded_hal::i2c::I2c;
5#[cfg(feature = "async")]
6use embedded_hal_async::i2c::I2c;
7
8static CONVERSION_REGISTER : u8 = 0b00;
9static CONFIG_REGISTER : u8 = 0b01;
10static LO_THRESH_REGISTER : u8 = 0b10;
11static HI_THRESH_REGISTER : u8 = 0b11;
12
13#[derive(Debug)]
14pub enum ADSError{
15 WrongAddress,
16 ModeSetToSingle,
17}
18
19#[derive(Debug)]
20enum OSW{
21 StartConversion,
22 Idle,
23}
24
25#[derive(Debug,PartialEq)]
26enum OSR{
27 PerformingConversion,
28 DeviceIdle,
29}
30
31impl OSW {
32 fn bits(&self) -> u16{
33 match self {
34 OSW::StartConversion => 1<<15,
35 OSW::Idle => 0,
36 }
37 }
38}
39
40impl Default for OSW{
41 fn default() -> Self {
42 OSW::Idle
43 }
44}
45
46impl OSR {
47 fn from_bits(bits: u16) -> Self{
48 match bits >> 15 & 0b01 {
49 0 => OSR::PerformingConversion,
50 _ => OSR::DeviceIdle,
51 }
52 }
53}
54
55impl Default for OSR{
56 fn default() -> Self {
57 OSR::DeviceIdle
58 }
59}
60
61#[derive(Debug)]
62pub enum InputMultiplexer{
63 AIN0AIN1,
64 AIN0AIN3,
65 AIN1AIN3,
66 AIN2AIN3,
67 AIN0GND,
68 AIN1GND,
69 AIN2GND,
70 AIN3GND,
71}
72
73impl InputMultiplexer {
74 fn bits(&self) -> u16{
75 match self {
76 InputMultiplexer::AIN0AIN1 => 0b000 << 12,
77 InputMultiplexer::AIN0AIN3 => 0b001 << 12,
78 InputMultiplexer::AIN1AIN3 => 0b010 << 12,
79 InputMultiplexer::AIN2AIN3 => 0b011 << 12,
80 InputMultiplexer::AIN0GND => 0b100 << 12,
81 InputMultiplexer::AIN1GND => 0b101 << 12,
82 InputMultiplexer::AIN2GND => 0b110 << 12,
83 InputMultiplexer::AIN3GND => 0b111 << 12,
84 }
85 }
86
87 fn from_bits(bits: u16) -> Self{
88 match bits >> 12 & 0b111{
89 0b000 => InputMultiplexer::AIN0AIN1,
90 0b001 => InputMultiplexer::AIN0AIN3,
91 0b010 => InputMultiplexer::AIN1AIN3,
92 0b011 => InputMultiplexer::AIN2AIN3,
93 0b100 => InputMultiplexer::AIN0GND,
94 0b101 => InputMultiplexer::AIN1GND,
95 0b110 => InputMultiplexer::AIN2GND,
96 _ => InputMultiplexer::AIN3GND,
97 }
98 }
99}
100
101impl Default for InputMultiplexer{
102 fn default() -> Self {
103 InputMultiplexer::AIN0AIN1
104 }
105}
106
107#[derive(Debug)]
108pub enum ProgramableGainAmplifier{
109 V6_144,
110 V4_096,
111 V2_048,
112 V1_024,
113 V0_512,
114 V0_256,
115}
116
117impl ProgramableGainAmplifier{
118 fn bits(&self) -> u16{
119 match self {
120 ProgramableGainAmplifier::V6_144 => 0b000 << 9,
121 ProgramableGainAmplifier::V4_096 => 0b001 << 9,
122 ProgramableGainAmplifier::V2_048 => 0b010 << 9,
123 ProgramableGainAmplifier::V1_024 => 0b011 << 9,
124 ProgramableGainAmplifier::V0_512 => 0b100 << 9,
125 ProgramableGainAmplifier::V0_256 => 0b101 << 9,
126 }
127 }
128
129 fn from_bits(bits: u16) -> Self{
130 match bits >> 9 & 0b111 {
131 0b000 => ProgramableGainAmplifier::V6_144,
132 0b001 => ProgramableGainAmplifier::V4_096,
133 0b010 => ProgramableGainAmplifier::V2_048,
134 0b011 => ProgramableGainAmplifier::V1_024,
135 0b100 => ProgramableGainAmplifier::V0_512,
136 _ => ProgramableGainAmplifier::V0_256,
137 }
138 }
139}
140
141impl Default for ProgramableGainAmplifier{
142 fn default() -> Self {
143 ProgramableGainAmplifier::V2_048
144 }
145}
146
147#[derive(Debug, PartialEq)]
148pub enum Mode{
149 Continuous,
150 Signle,
151}
152
153impl Mode {
154 fn bits(&self) -> u16{
155 match self {
156 Mode::Continuous => 0,
157 Mode::Signle => 1<<8,
158 }
159 }
160
161 fn from_bits(bits: u16) -> Self{
162 match bits >> 8 & 0b01 {
163 1 => Mode::Signle,
164 _ => Mode::Continuous,
165 }
166 }
167}
168
169impl Default for Mode {
170 fn default() -> Self {
171 Mode::Signle
172 }
173}
174
175#[derive(Debug)]
176pub enum DataRate{
177 SPS8,
178 SPS16,
179 SPS32,
180 SPS64,
181 SPS128,
182 SPS250,
183 SPS475,
184 SPS860,
185}
186
187impl DataRate{
188 fn bits(&self) -> u16{
189 match self {
190 DataRate::SPS8 => 0b000,
191 DataRate::SPS16 => 0b001 << 5,
192 DataRate::SPS32 => 0b010 << 5,
193 DataRate::SPS64 => 0b011 << 5,
194 DataRate::SPS128 => 0b100 << 5,
195 DataRate::SPS250 => 0b101 << 5,
196 DataRate::SPS475 => 0b110 << 5,
197 DataRate::SPS860 => 0b111 << 5,
198 }
199 }
200
201 fn from_bits(bits: u16) -> Self{
202 match bits >> 5 & 0b111 {
203 0b000 => DataRate::SPS8,
204 0b001 => DataRate::SPS16,
205 0b010 => DataRate::SPS32,
206 0b011 => DataRate::SPS64,
207 0b100 => DataRate::SPS128,
208 0b101 => DataRate::SPS250,
209 0b110 => DataRate::SPS475,
210 _ => DataRate::SPS860,
211 }
212 }
213}
214
215impl Default for DataRate{
216 fn default() -> Self {
217 DataRate::SPS128
218 }
219}
220
221#[derive(Debug)]
222pub enum ComparatorMode{
223 Traditional,
224 Window,
225}
226
227impl ComparatorMode{
228 fn bits(&self) -> u16{
229 match self {
230 ComparatorMode::Traditional => 0,
231 ComparatorMode::Window => 1<<4,
232 }
233 }
234
235 fn from_bits(bits: u16) -> Self{
236 match bits >> 4 & 0b01 {
237 1 => ComparatorMode::Window,
238 _ => ComparatorMode::Traditional,
239 }
240 }
241}
242
243impl Default for ComparatorMode{
244 fn default() -> Self {
245 ComparatorMode::Traditional
246 }
247}
248
249#[derive(Debug)]
250pub enum ComparatorPolarity{
251 ActiveLow,
252 ActiveHigh,
253}
254
255impl ComparatorPolarity{
256 fn bits(&self) -> u16{
257 match self {
258 ComparatorPolarity::ActiveLow => 0,
259 ComparatorPolarity::ActiveHigh => 1<<3,
260 }
261 }
262
263 fn from_bits(bits: u16) -> Self{
264 match bits >> 3 & 0b01 {
265 1 => ComparatorPolarity::ActiveHigh,
266 _ => ComparatorPolarity::ActiveLow,
267 }
268 }
269}
270
271impl Default for ComparatorPolarity{
272 fn default() -> Self {
273 ComparatorPolarity::ActiveLow
274 }
275}
276
277#[derive(Debug)]
278pub enum LatchingComparator{
279 NonLatching,
280 Latching,
281}
282
283impl LatchingComparator{
284 fn bits(&self) -> u16{
285 match self {
286 LatchingComparator::NonLatching => 0,
287 LatchingComparator::Latching => 1<<2,
288 }
289 }
290
291 fn from_bits(bits: u16) -> Self{
292 match bits >> 2 & 0b01 {
293 1 => LatchingComparator::Latching,
294 _ => LatchingComparator::NonLatching,
295 }
296 }
297}
298
299impl Default for LatchingComparator{
300 fn default() -> Self {
301 LatchingComparator::NonLatching
302 }
303}
304
305#[derive(Debug)]
306pub enum ComparatorQueue{
307 AsserAfterOne,
308 AsserAfterTwo,
309 AsserAfterFour,
310 Disable,
311}
312
313impl ComparatorQueue{
314 fn bits(&self) -> u16{
315 match self {
316 ComparatorQueue::AsserAfterOne => 0b00,
317 ComparatorQueue::AsserAfterTwo => 0b01,
318 ComparatorQueue::AsserAfterFour => 0b10,
319 ComparatorQueue::Disable => 0b11,
320 }
321 }
322
323 fn from_bits(bits: u16) -> Self{
324 match bits & 0b11 {
325 0b00 => ComparatorQueue::AsserAfterOne,
326 0b01 => ComparatorQueue::AsserAfterTwo,
327 0b10 => ComparatorQueue::AsserAfterFour,
328 _ => ComparatorQueue::Disable,
329 }
330 }
331}
332
333impl Default for ComparatorQueue{
334 fn default() -> Self {
335 ComparatorQueue::Disable
336 }
337}
338
339#[derive(Default, Debug)]
340pub struct ADS111xConfig{
341 osw: OSW,
342 osr: OSR,
343 mux: InputMultiplexer,
344 pga: ProgramableGainAmplifier,
345 mode: Mode,
346 dr: DataRate,
347 comp_mode: ComparatorMode,
348 comp_pol: ComparatorPolarity,
349 comp_lat: LatchingComparator,
350 comp_que: ComparatorQueue,
351}
352
353impl ADS111xConfig{
354 fn bits(&self) -> u16{
355 self.osw.bits() |
356 self.mux.bits() |
357 self.pga.bits() |
358 self.mode.bits() |
359 self.dr.bits() |
360 self.comp_mode.bits() |
361 self.comp_pol.bits() |
362 self.comp_lat.bits() |
363 self.comp_que.bits()
364 }
365
366 fn from_bits(bits: u16) -> Self{
367 ADS111xConfig {
368 osr: OSR::from_bits(bits),
369 osw: OSW::default(),
370 mux: InputMultiplexer::from_bits(bits),
371 pga: ProgramableGainAmplifier::from_bits(bits),
372 mode: Mode::from_bits(bits),
373 dr: DataRate::from_bits(bits),
374 comp_mode: ComparatorMode::from_bits(bits),
375 comp_pol: ComparatorPolarity::from_bits(bits),
376 comp_lat: LatchingComparator::from_bits(bits),
377 comp_que: ComparatorQueue::from_bits(bits)}
378 }
379
380 pub fn mux(mut self, mux: InputMultiplexer) -> Self{
381 self.mux = mux;
382 self
383 }
384
385 pub fn pga(mut self, pga: ProgramableGainAmplifier) -> Self{
386 self.pga = pga;
387 self
388 }
389
390 pub fn mode(mut self, mode: Mode) -> Self{
391 self.mode = mode;
392 self
393 }
394
395 pub fn dr(mut self, dr: DataRate) -> Self{
396 self.dr = dr;
397 self
398 }
399
400 pub fn comp_mode(mut self, cm: ComparatorMode) -> Self{
401 self.comp_mode = cm;
402 self
403 }
404
405 pub fn comp_pol(mut self, cp: ComparatorPolarity) -> Self{
406 self.comp_pol = cp;
407 self
408 }
409
410 pub fn comp_lat(mut self, cl: LatchingComparator) -> Self{
411 self.comp_lat = cl;
412 self
413 }
414
415 pub fn comp_que(mut self, cq: ComparatorQueue) -> Self{
416 self.comp_que = cq;
417 self
418 }
419}
420
421#[maybe_async_cfg::maybe(
422 sync(cfg(not(feature = "async")),),
423 async(feature="async"),
424 keep_self
425)]
426pub struct ADS111x<I2C> {
427 i2c: I2C,
428 address: u8,
429 config: ADS111xConfig,
430}
431
432#[maybe_async_cfg::maybe(
433 sync(cfg(not(feature = "async")),),
434 async(feature="async"),
435 keep_self
436)]
437impl<I2C, E> ADS111x<I2C>
438where
439 I2C: I2c<Error = E>,
440{
441 pub fn new(i2c: I2C, address: u8, config: ADS111xConfig) -> Result<Self, ADSError>{
444 match address {
445 0b1001000 => {},
446 0b1001001 => {},
447 0b1001010 => {},
448 0b1001011 => {},
449 _ => return Err(ADSError::WrongAddress),
450 }
451 Ok(ADS111x{ i2c, address, config} )
452 }
453
454 pub fn destroy(self) -> I2C {
456 self.i2c
457 }
458
459 pub async fn write_config(&mut self, config: Option<ADS111xConfig>) -> Result<(), E>{
463 if let Some(conf) = config{
464 self.config = conf;
465 }
466 self.config.osw = OSW::Idle;
467 let conf = self.config.bits().to_be_bytes();
468 self.i2c.write(self.address, &[CONFIG_REGISTER, conf[0], conf[1]]).await
469 }
470
471 pub async fn read_config(&mut self) -> Result<ADS111xConfig, E>{
472 self.config.osw = OSW::Idle;
473 let mut conf = [0, 0];
474
475 self.i2c.write_read(self.address, &[CONFIG_REGISTER], &mut conf).await.and(Ok(ADS111xConfig::from_bits(u16::from_be_bytes(conf))))
476 }
477
478 pub async fn read_single_voltage(&mut self, mux: Option<InputMultiplexer>) -> Result<f32, E>{
483 if let Some(m) = mux{
484 self.config.mux = m;
485 }
486 self.config.osw = OSW::StartConversion;
487 let config = self.config.bits().to_be_bytes();
488 let mut conf = [0, 0];
489
490 self.i2c.write_read(self.address, &[CONFIG_REGISTER, config[0], config[1]], &mut conf).await?;
491
492 while OSR::from_bits(u16::from_be_bytes(conf)) == OSR::PerformingConversion{
493 self.i2c.write_read(self.address, &[CONFIG_REGISTER], &mut conf).await?;
494 }
495
496 self.read_voltage().await
497 }
498
499 pub async fn check_cnversion_ready(&mut self) -> Result<bool, E>{
500 Ok(self.read_config().await?.osr == OSR::DeviceIdle)
501 }
502
503 pub async fn read_voltage(&mut self) -> Result<f32, E> {
509 let mut voltage = [0, 0];
510 self.i2c.write_read(self.address, &[CONVERSION_REGISTER], &mut voltage).await?;
511 let val = i16::from_be_bytes(voltage);
512 let pga = match self.config.pga{
513 ProgramableGainAmplifier::V0_256 => 0.256f32,
514 ProgramableGainAmplifier::V0_512 => 0.512f32,
515 ProgramableGainAmplifier::V1_024 => 1.024f32,
516 ProgramableGainAmplifier::V2_048 => 2.048f32,
517 ProgramableGainAmplifier::V4_096 => 4.096f32,
518 ProgramableGainAmplifier::V6_144 => 6.144f32,
519 };
520
521 Ok(f32::from(val) * pga / 32768f32)
522 }
523
524 pub async fn set_low_treshold(&mut self, low_tresh: i16) -> Result<(), E>{
525 let lt = low_tresh.to_be_bytes();
526 self.i2c.write(self.address, &[LO_THRESH_REGISTER, lt[0], lt[1]]).await
527 }
528
529 pub async fn set_high_treshold(&mut self, high_tresh: i16) -> Result<(), E>{
530 let ht = high_tresh.to_be_bytes();
531 self.i2c.write(self.address, &[HI_THRESH_REGISTER, ht[0], ht[1]]).await
532 }
533}