1#![no_std]
2#![doc = include_str!("../README.md")]
3#![warn(missing_docs)]
4
5use core::fmt;
6#[cfg(feature = "defmt")]
7use defmt::Format;
8use embedded_hal_async::delay::DelayNs;
9use embedded_hal_async::i2c::I2c;
10use ux::i24;
11
12#[derive(Debug, Clone, Copy)]
14#[cfg_attr(feature = "defmt", derive(Format))]
15pub enum FDC1004Error<E>{
16 UnableToFindCapdacSetting,
18 MeasurementNotComplete,
20 InvalidMeasurementChannel,
22 I2CError(E)
24}
25
26#[derive(Default, Copy, Clone, Debug)]
31pub enum OutputRate {
32 #[default]
34 SPS100,
35 SPS200,
37 SPS400,
39}
40
41impl OutputRate {
42 fn delay_ns(&self) -> u32 {
43 match self {
44 OutputRate::SPS100 => 11_000_000, OutputRate::SPS200 => 6_000_000, OutputRate::SPS400 => 3_000_000, }
48 }
49}
50
51static CAPDAC_MAX: u8 = 0x1F;
52
53#[derive(Copy, Clone, Debug)]
58pub enum Channel {
59 CIN1,
61 CIN2,
63 CIN3,
65 CIN4,
67 CAPDAC,
69 DISABLED
71}
72
73#[derive(Copy, Clone)]
79pub enum Measurement {
80 Measurement1,
82 Measurement2,
84 Measurement3,
86 Measurement4,
88}
89
90impl Measurement {
91 fn msb_register(&self) -> RegisterAddress {
92 match self {
93 Measurement::Measurement1 => RegisterAddress::Measurement1MSB,
94 Measurement::Measurement2 => RegisterAddress::Measurement2MSB,
95 Measurement::Measurement3 => RegisterAddress::Measurement3MSB,
96 Measurement::Measurement4 => RegisterAddress::Measurement4MSB,
97 }
98 }
99
100 fn lsb_register(&self) -> RegisterAddress {
101 match self {
102 Measurement::Measurement1 => RegisterAddress::Measurement1LSB,
103 Measurement::Measurement2 => RegisterAddress::Measurement2LSB,
104 Measurement::Measurement3 => RegisterAddress::Measurement3LSB,
105 Measurement::Measurement4 => RegisterAddress::Measurement4LSB,
106 }
107 }
108
109 fn config_register(&self) -> RegisterAddress {
110 match self {
111 Measurement::Measurement1 => RegisterAddress::Measurement1Config,
112 Measurement::Measurement2 => RegisterAddress::Measurement2Config,
113 Measurement::Measurement3 => RegisterAddress::Measurement3Config,
114 Measurement::Measurement4 => RegisterAddress::Measurement4Config,
115 }
116 }
117
118 fn ready_according_to_config(&self, config: &FDCConfiguration) -> bool {
119 match self {
120 Measurement::Measurement1 => config.measurement1_done,
121 Measurement::Measurement2 => config.measurement2_done,
122 Measurement::Measurement3 => config.measurement3_done,
123 Measurement::Measurement4 => config.measurement4_done,
124 }
125 }
126}
127
128#[derive(Copy, Clone, Debug)]
134pub enum RegisterAddress {
135 Measurement1MSB,
137 Measurement1LSB,
139 Measurement2MSB,
141 Measurement2LSB,
143 Measurement3MSB,
145 Measurement3LSB,
147 Measurement4MSB,
149 Measurement4LSB,
151 Measurement1Config,
153 Measurement2Config,
155 Measurement3Config,
157 Measurement4Config,
159 FdcConf,
161 OffsetCalCIN1,
163 OffsetCalCIN2,
165 OffsetCalCIN3,
167 OffsetCalCIN4,
169 GainCalCIN1,
171 GainCalCIN2,
173 GainCalCIN3,
175 GainCalCIN4,
177 ManufacturerId,
179 DeviceId,
181}
182
183impl RegisterAddress {
184 pub(crate) fn to_u8(&self) -> u8 {
185 match self {
186 RegisterAddress::Measurement1MSB => 0x00,
187 RegisterAddress::Measurement1LSB => 0x01,
188 RegisterAddress::Measurement2MSB => 0x02,
189 RegisterAddress::Measurement2LSB => 0x03,
190 RegisterAddress::Measurement3MSB => 0x04,
191 RegisterAddress::Measurement3LSB => 0x05,
192 RegisterAddress::Measurement4MSB => 0x06,
193 RegisterAddress::Measurement4LSB => 0x07,
194 RegisterAddress::Measurement1Config => 0x08,
195 RegisterAddress::Measurement2Config => 0x09,
196 RegisterAddress::Measurement3Config => 0x0A,
197 RegisterAddress::Measurement4Config => 0x0B,
198 RegisterAddress::FdcConf => 0x0C,
199 RegisterAddress::OffsetCalCIN1 => 0x0D,
200 RegisterAddress::OffsetCalCIN2 => 0x0E,
201 RegisterAddress::OffsetCalCIN3 => 0x0F,
202 RegisterAddress::OffsetCalCIN4 => 0x10,
203 RegisterAddress::GainCalCIN1 => 0x11,
204 RegisterAddress::GainCalCIN2 => 0x12,
205 RegisterAddress::GainCalCIN3 => 0x13,
206 RegisterAddress::GainCalCIN4 => 0x14,
207 RegisterAddress::ManufacturerId => 0xFE,
208 RegisterAddress::DeviceId => 0xFF,
209 }
210 }
211}
212
213static PICOFARADS_PER_CAPDAC: f32 = 3.125;
214
215#[derive(Debug, Clone, Copy)]
220#[cfg_attr(feature = "defmt", derive(Format))]
221pub enum SuccessfulMeasurement {
222 MeasurementInRange(MeasuredCapacitance),
224 Underflow,
226 Overflow,
228}
229
230#[derive(Debug, Clone, Copy)]
236pub struct MeasuredCapacitance {
237 pub(crate) value: i24,
238 pub(crate) capdac: u8,
239}
240
241#[cfg(feature = "defmt")]
242impl Format for MeasuredCapacitance {
243 fn format(&self, f: defmt::Formatter) {
244 defmt::write!(f, "MeasuredCapacitance {} pF", self.to_pf());
245 }
246}
247
248impl MeasuredCapacitance {
249 pub(crate) fn new(value: i24, capdac: u8) -> Self {
250 MeasuredCapacitance {
251 value,
252 capdac,
253 }
254 }
255
256 pub fn to_pf(&self) -> f32 {
258 let vali32 : i32 = self.value.into();
259 let val: f32 = vali32 as f32;
260
261 let mut pf = val / 524_288f32;
262
263 pf += PICOFARADS_PER_CAPDAC * (self.capdac as f32);
264 pf
265 }
266}
267
268#[derive(Debug)]
269struct MeasurementConfiguration {
270 channel_a: Channel,
271 channel_b: Channel,
272 offset_capacitance: u8,
273}
274
275impl MeasurementConfiguration {
276 pub(crate) fn new(channel_a: Channel, channel_b: Channel, offset_capacitance: u8) -> Self {
277 MeasurementConfiguration {
278 channel_a,
279 channel_b,
280 offset_capacitance,
281 }
282 }
283
284 pub(crate) fn to_u16(&self) -> u16 {
285 let mut val = 0;
286
287 val |= match self.channel_a {
288 Channel::CIN1 => 0x0000,
289 Channel::CIN2 => 0x2000,
290 Channel::CIN3 => 0x4000,
291 Channel::CIN4 => 0x6000,
292 _ => 0x0000,
293 };
294
295 val |= match self.channel_b {
296 Channel::CIN1 => 0x0000,
297 Channel::CIN2 => 0x0400,
298 Channel::CIN3 => 0x0800,
299 Channel::CIN4 => 0x0C00,
300 Channel::CAPDAC => 0x1000,
301 Channel::DISABLED => 0x1C00,
302 };
303
304 val |= (self.offset_capacitance as u16) << 5;
305
306 val
307 }
308}
309
310#[derive(Default, Debug)]
311struct FDCConfiguration {
312 reset: bool,
313 rate: OutputRate,
314 repeat: bool,
315 initiate_measurement1: bool,
316 initiate_measurement2: bool,
317 initiate_measurement3: bool,
318 initiate_measurement4: bool,
319 measurement1_done: bool,
320 measurement2_done: bool,
321 measurement3_done: bool,
322 measurement4_done: bool,
323}
324
325impl FDCConfiguration {
326 pub(crate) fn from_u16(d: u16) -> Self {
327 let mut config = FDCConfiguration::default();
328
329 config.reset = d & (1u16 << 15) != 0;
330 config.rate = match d & 0x0C00 {
331 0x0400 => OutputRate::SPS100,
332 0x0800 => OutputRate::SPS200,
333 0x0C00 => OutputRate::SPS400,
334 _ => OutputRate::SPS100,
335 };
336 config.repeat = d & (1u16 << 8) != 0;
337 config.initiate_measurement1 = d & (1u16 << 7) != 0;
338 config.initiate_measurement2 = d & (1u16 << 6) != 0;
339 config.initiate_measurement3 = d & (1u16 << 5) != 0;
340 config.initiate_measurement4 = d & (1u16 << 4) != 0;
341 config.measurement1_done = d & (1u16 << 3) != 0;
342 config.measurement2_done = d & (1u16 << 2) != 0;
343 config.measurement3_done = d & (1u16 << 1) != 0;
344 config.measurement4_done = d & (1u16 << 0) != 0;
345
346 config
347 }
348
349 pub(crate) fn rate(&mut self, rate: OutputRate) -> &mut Self {
350 self.rate = rate;
351 self
352 }
353
354 pub(crate) fn initiate_measurement1(&mut self, initiate: bool) -> &mut Self {
355 self.initiate_measurement1 = initiate;
356 self
357 }
358
359 pub(crate) fn initiate_measurement2(&mut self, initiate: bool) -> &mut Self {
360 self.initiate_measurement2 = initiate;
361 self
362 }
363
364 pub(crate) fn initiate_measurement3(&mut self, initiate: bool) -> &mut Self {
365 self.initiate_measurement3 = initiate;
366 self
367 }
368
369 pub(crate) fn initiate_measurement4(&mut self, initiate: bool) -> &mut Self {
370 self.initiate_measurement4 = initiate;
371 self
372 }
373
374 #[allow(unused)]
375 pub(crate) fn reset(&mut self, reset: bool) -> &mut Self {
376 self.reset = reset;
377 self
378 }
379
380 #[allow(unused)]
381 pub(crate) fn repeat(&mut self, repeat: bool) -> &mut Self {
382 self.repeat = repeat;
383 self
384 }
385
386 pub(crate) fn to_u16(&self) -> u16 {
387 let mut val = 0;
388
389 val |= if self.reset { 1u16 << 15 } else { 0x0000 };
390 val |= match self.rate {
391 OutputRate::SPS100 => 0x0400,
392 OutputRate::SPS200 => 0x0800,
393 OutputRate::SPS400 => 0x0C00,
394 };
395 val |= if self.repeat { 1u16 << 8 } else { 0x0000 };
396 val |= if self.initiate_measurement1 { 1u16 << 7 } else { 0x0000 };
397 val |= if self.initiate_measurement2 { 1u16 << 6 } else { 0x0000 };
398 val |= if self.initiate_measurement3 { 1u16 << 5 } else { 0x0000 };
399 val |= if self.initiate_measurement4 { 1u16 << 4 } else { 0x0000 };
400 val |= if self.measurement1_done { 1u16 << 3 } else { 0x0000 };
401 val |= if self.measurement2_done { 1u16 << 2 } else { 0x0000 };
402 val |= if self.measurement3_done { 1u16 << 1 } else { 0x0000 };
403 val |= if self.measurement4_done { 1u16 << 0 } else { 0x0000 };
404
405 val
406 }
407}
408
409pub struct FDC1004<I2C: I2c, D: DelayNs> {
427 i2c: I2C,
428 address: u8,
429 output_rate: OutputRate,
430 delay: D,
431}
432
433impl<I2C: I2c, D: DelayNs> FDC1004<I2C, D>
434where
435 I2C::Error: fmt::Debug,
436{
437 pub fn new(i2c: I2C, address: u8, output_rate: OutputRate, delay: D) -> Self {
446 FDC1004 {
447 i2c,
448 address,
449 output_rate,
450 delay,
451 }
452 }
453
454 pub async fn read_capacitance(&mut self, channel: Channel) -> Result<SuccessfulMeasurement, FDC1004Error<I2C::Error>> {
471 let mut capdac: u8 = 0x00;
472
473 for _ in 0..33 {
474 let m = self.measure_channel(channel, capdac).await?;
475 if m < i24::max_value() && m > i24::min_value() {
476 return Ok(SuccessfulMeasurement::MeasurementInRange(MeasuredCapacitance::new(m, capdac)));
477 }
478
479 if m == i24::max_value() && capdac < CAPDAC_MAX {
480 capdac += 1;
481 } else if m == i24::min_value() && capdac > 0 {
482 capdac -= 1;
483 } else {
484 return match capdac {
485 0 => Ok(SuccessfulMeasurement::Underflow),
486 _ => Ok(SuccessfulMeasurement::Overflow)
487 };
488 }
489 }
490
491 Err(FDC1004Error::UnableToFindCapdacSetting)
492 }
493
494 pub async fn measure_channel(&mut self, channel: Channel, capdac: u8) -> Result<i24, FDC1004Error<I2C::Error>> {
509 let measurement = match channel {
511 Channel::CIN1 => Measurement::Measurement1,
512 Channel::CIN2 => Measurement::Measurement2,
513 Channel::CIN3 => Measurement::Measurement3,
514 Channel::CIN4 => Measurement::Measurement4,
515 Channel::CAPDAC | Channel::DISABLED => return Err(FDC1004Error::InvalidMeasurementChannel),
517 };
518
519 self.configure_single_measurement(channel, measurement.clone(), capdac).await?;
520 self.trigger_single_measurement(measurement.clone()).await?;
521 self.delay.delay_ns(self.output_rate.delay_ns()).await;
522
523 return self.read_measurement(measurement).await;
524 }
525
526 pub async fn configure_single_measurement(&mut self, channel: Channel, measurement: Measurement, capdac: u8) -> Result<(), FDC1004Error<I2C::Error>> {
537 let config = MeasurementConfiguration::new(channel, Channel::CAPDAC, capdac);
538
539 self.write_u16(measurement.config_register(), config.to_u16()).await
540 }
541
542 pub async fn trigger_single_measurement(&mut self, measurement: Measurement) -> Result<(), FDC1004Error<I2C::Error>> {
552 let mut config = FDCConfiguration::default();
553 let config = config.rate(self.output_rate);
554 let config = match measurement {
555 Measurement::Measurement1 => config.initiate_measurement1(true),
556 Measurement::Measurement2 => config.initiate_measurement2(true),
557 Measurement::Measurement3 => config.initiate_measurement3(true),
558 Measurement::Measurement4 => config.initiate_measurement4(true),
559 };
560
561 self.write_u16(RegisterAddress::FdcConf, config.to_u16()).await
562 }
563
564 pub async fn read_measurement(&mut self, measurement: Measurement) -> Result<i24, FDC1004Error<I2C::Error>> {
578 const MAX_WAIT_ATTEMPTS: u8 = 10;
580 let wait_delay_ns = self.output_rate.delay_ns();
581
582 for _ in 0..MAX_WAIT_ATTEMPTS {
583 let config = FDCConfiguration::from_u16(self.read_u16(RegisterAddress::FdcConf).await?);
584
585 if measurement.ready_according_to_config(&config) {
586 break;
587 }
588
589 self.delay.delay_ns(wait_delay_ns).await;
591 }
592
593 let config = FDCConfiguration::from_u16(self.read_u16(RegisterAddress::FdcConf).await?);
595 if !measurement.ready_according_to_config(&config) {
596 return Err(FDC1004Error::MeasurementNotComplete);
597 }
598
599 let msb = self.read_u16(measurement.msb_register()).await? as i32;
600 let lsb = self.read_u16(measurement.lsb_register()).await? as i32;
601
602 let mut val24 = i24::default();
603 val24 |= i24::new(msb) << 8;
604 val24 |= i24::new(lsb) >> 8;
605
606 Ok(val24)
607 }
608
609 pub(crate) async fn write_u16(&mut self, reg: RegisterAddress, data: u16) -> Result<(), FDC1004Error<I2C::Error>> {
610 let data = data.to_be_bytes();
611 self.i2c.write(self.address, &[reg.to_u8(), data[0], data[1]]).await.map_err(|e| FDC1004Error::I2CError(e))
612 }
613
614 pub(crate) async fn read_u16(&mut self, reg: RegisterAddress) -> Result<u16, FDC1004Error<I2C::Error>> {
615 let mut data: [u8; 2] = [0,0];
616 self.i2c.write_read(self.address, &[reg.to_u8()], &mut data).await.map_err(|e| FDC1004Error::I2CError(e))?;
617
618 let be = u16::from_be_bytes(data);
619
620 return Ok(be);
621 }
622}
623