#![no_std]
#![no_main]
#[cfg(feature = "defmt")]
use defmt::Format;
use bitfield_struct::bitfield;
use embedded_hal::i2c::{Error as I2CError, I2c};
const MEAS1_MSB: u8 = 0x00; const MEAS1_LSB: u8 = 0x01; const MEAS2_MSB: u8 = 0x02; const MEAS2_LSB: u8 = 0x03; const MEAS3_MSB: u8 = 0x04; const MEAS3_LSB: u8 = 0x05; const MEAS4_MSB: u8 = 0x06; const MEAS4_LSB: u8 = 0x07; const CONF_MEAS1: u8 = 0x08; const CONF_MEAS2: u8 = 0x09; const CONF_MEAS3: u8 = 0x0A; const CONF_MEAS4: u8 = 0x0B; const FDC_CONF: u8 = 0x0C; const OFFSET_CAL_CIN1: u8 = 0x0D; const OFFSET_CAL_CIN2: u8 = 0x0E; const OFFSET_CAL_CIN3: u8 = 0x0F; const OFFSET_CAL_CIN4: u8 = 0x10; const GAIN_CAL_CIN1: u8 = 0x11; const GAIN_CAL_CIN2: u8 = 0x12; const GAIN_CAL_CIN3: u8 = 0x13; const GAIN_CAL_CIN4: u8 = 0x14; const MANUFACTURER_ID: u8 = 0xFE; const DEVICE_ID_TI: u8 = 0xFF; const ADDR: u8 = 80;
#[bitfield(u16, defmt = cfg(feature = "defmt"))]
pub struct MeasurementConfiguration {
#[bits(5)]
__: u8,
#[bits(3)]
pub channel_positive: CHANNEL,
#[bits(3)]
pub channel_negative: CHANNEL,
#[bits(5)]
pub offset_capacitance: u8,
}
#[repr(u8)]
pub enum Measurement {
CONF_MEAS1,
CONF_MEAS2,
CONF_MEAS3,
CONF_MEAS4,
}
#[repr(u8)]
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(Format))]
pub enum CHANNEL {
CIN1 = 0,
CIN2 = 1,
CIN3 = 2,
CIN4 = 3,
}
impl CHANNEL {
const fn into_bits(self) -> u16 {
self as _
}
const fn from_bits(value: u16) -> Self {
match value {
0 => Self::CIN1,
1 => Self::CIN2,
2 => Self::CIN3,
3 => Self::CIN4,
_ => panic!("Invalid channel"),
}
}
}
#[bitfield(u16, defmt = cfg(feature = "defmt"))]
pub struct FDCConfiguration {
#[bits(access = RO)]
pub done_4: bool,
#[bits(access = RO)]
pub done_3: bool,
#[bits(access = RO)]
pub done_2: bool,
#[bits(access = RO)]
pub done_1: bool,
pub meas_4: bool,
pub meas_3: bool,
pub meas_2: bool,
pub meas_1: bool,
pub repeat: bool,
#[bits(1)]
__: u8,
#[bits(2)]
pub rate: u8,
#[bits(3)]
__: u8,
pub reset: bool,
}
pub struct FDC1004<T: I2c> {
pub i2c: T,
}
impl<T: I2c> FDC1004<T> {
pub fn get_configuration(&mut self) -> FDCConfiguration {
let mut rx_buffer: [u8; 2] = [0; 2];
self.i2c
.write_read(ADDR, &[FDC_CONF], &mut rx_buffer)
.unwrap();
FDCConfiguration::from_bits(u16::from_be_bytes(rx_buffer))
}
pub fn set_configuration(&mut self, config: FDCConfiguration) {
let [config_msb, config_lsb] = config.into_bits().to_be_bytes();
self.i2c
.write(ADDR, &[FDC_CONF, config_msb, config_lsb])
.unwrap();
}
pub fn configure_measurement(
&mut self,
config: MeasurementConfiguration,
measurement: Measurement,
) {
let [config_msb, config_lsb] = config.into_bits().to_be_bytes();
self.i2c
.write(ADDR, &[measurement as u8, config_msb, config_lsb])
.unwrap();
}
fn read_measurement(&mut self, meas_msb: u8, meas_lsb: u8) -> u32 {
let mut buffer: [u8; 4] = [0; 4];
self.i2c
.write_read(ADDR, &[meas_msb], &mut buffer[0..2])
.unwrap();
self.i2c
.write_read(ADDR, &[meas_lsb], &mut buffer[2..4])
.unwrap();
u32::from_be_bytes(buffer)
}
pub fn read_measurement_1(&mut self) -> u32 {
self.read_measurement(MEAS1_MSB, MEAS1_LSB)
}
pub fn read_measurement_2(&mut self) -> u32 {
self.read_measurement(MEAS2_MSB, MEAS2_LSB)
}
pub fn read_measurement_3(&mut self) -> u32 {
self.read_measurement(MEAS3_MSB, MEAS3_LSB)
}
pub fn read_measurement_4(&mut self) -> u32 {
self.read_measurement(MEAS4_MSB, MEAS4_LSB)
}
}