use crate::ChannelMode;
#[derive(Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
#[allow(missing_docs)]
pub enum Register {
Status = 0x00,
Out = 0x01,
Data0Lsb = 0x02,
Data0Msb = 0x03,
Data1Lsb = 0x04,
Data1Msb = 0x05,
Data2Lsb = 0x06,
Data2Msb = 0x07,
Data3Lsb = 0x08,
Data3Msb = 0x09,
Reset = 0x0A,
En = 0x0C,
NpScanRate = 0x0D,
Gain0 = 0x0E,
LpScanRate = 0x0F,
Gain1 = 0x10,
IntPol = 0x11,
Gain2 = 0x12,
LpBaseInc = 0x13,
Gain3 = 0x14,
NpBaseInc = 0x15,
BtPauseMaxWin = 0x16,
LcDivider = 0x17,
Hyst = 0x18,
Twist = 0x19,
CommonDeform = 0x1A,
OpolDpol = 0x1C,
Cntsc = 0x1E,
Sensor0Config = 0x20,
Sensor1Config = 0x22,
Sensor2Config = 0x24,
Ftf0 = 0x25,
Sensor3Config = 0x26,
Ftf1_2 = 0x28,
Ftf3 = 0x2B,
RawData0_3 = 0x59,
RawData0_2 = 0x5A,
RawData0_1 = 0x5B,
RawData1_3 = 0x5C,
RawData1_2 = 0x5D,
RawData1_1 = 0x5E,
RawData2_3 = 0x5F,
RawData2_2 = 0x60,
RawData2_1 = 0x61,
RawData3_3 = 0x62,
RawData3_2 = 0x63,
RawData3_1 = 0x64,
ManufacturerIdLsb = 0xFC,
ManufacturerIdMsb = 0xFD,
DeviceIdLsb = 0xFE,
DeviceIdMsb = 0xFF,
}
impl Register {
pub fn addr(self) -> u8 {
self as u8
}
pub fn is_read_only(self) -> bool {
matches!(
self,
Register::Status
| Register::Out
| Register::Data0Lsb
| Register::Data0Msb
| Register::Data1Lsb
| Register::Data1Msb
| Register::Data2Lsb
| Register::Data2Msb
| Register::Data3Lsb
| Register::Data3Msb
| Register::RawData0_1
| Register::RawData0_2
| Register::RawData0_3
| Register::RawData1_1
| Register::RawData1_2
| Register::RawData1_3
| Register::RawData2_1
| Register::RawData2_2
| Register::RawData2_3
| Register::RawData3_1
| Register::RawData3_2
| Register::RawData3_3
| Register::DeviceIdLsb
| Register::DeviceIdMsb
| Register::ManufacturerIdLsb
| Register::ManufacturerIdMsb
)
}
}
pub(crate) const OUT_STATUS: u8 = 0x80;
pub(crate) const CHIP_READY: u8 = 0x40;
pub(crate) const RDY_TO_WRITE: u8 = 0x20;
pub(crate) const MAXOUT: u8 = 0x10;
pub(crate) const FSM_WD: u8 = 0x08;
pub(crate) const LC_WD: u8 = 0x04;
pub(crate) const TIMEOUT: u8 = 0x02;
pub(crate) const REGISTER_FLAG: u8 = 0x01;
pub(crate) const DATA_RDY: u8 = 0x10;
pub(crate) const OUT3: u8 = 0x08;
pub(crate) const OUT2: u8 = 0x04;
pub(crate) const OUT1: u8 = 0x02;
pub(crate) const OUT0: u8 = 0x01;
pub(crate) const FULL_RESET: u8 = 0x10;
pub(crate) const CONFIG_MODE: u8 = 0x01;
pub(crate) const LPEN3: u8 = 0x80;
pub(crate) const LPEN2: u8 = 0x40;
pub(crate) const LPEN1: u8 = 0x20;
pub(crate) const LPEN0: u8 = 0x10;
pub(crate) const EN3: u8 = 0x08;
pub(crate) const EN2: u8 = 0x04;
pub(crate) const EN1: u8 = 0x02;
pub(crate) const EN0: u8 = 0x01;
pub(crate) const BTSRT_EN: u8 = 0x10;
pub(crate) const BTN_ALG_EN: u8 = 0x08;
pub(crate) const INTPOL: u8 = 0x04;
pub(crate) const DIS_BTN_TO: u8 = 0x02;
pub(crate) const DIS_BTB_MO: u8 = 0x01;
pub(crate) const BTPAUSE3: u8 = 0x80;
pub(crate) const BTPAUSE2: u8 = 0x40;
pub(crate) const BTPAUSE1: u8 = 0x20;
pub(crate) const BTPAUSE0: u8 = 0x10;
pub(crate) const MAXWIN3: u8 = 0x08;
pub(crate) const MAXWIN2: u8 = 0x04;
pub(crate) const MAXWIN1: u8 = 0x02;
pub(crate) const MAXWIN0: u8 = 0x01;
pub(crate) const OPOL3: u8 = 0x80;
pub(crate) const OPOL2: u8 = 0x40;
pub(crate) const OPOL1: u8 = 0x20;
pub(crate) const OPOL0: u8 = 0x10;
pub(crate) const DPOL3: u8 = 0x08;
pub(crate) const DPOL2: u8 = 0x04;
pub(crate) const DPOL1: u8 = 0x02;
pub(crate) const DPOL0: u8 = 0x01;
pub(crate) const ANTICOM3: u8 = 0x80;
pub(crate) const ANTICOM2: u8 = 0x40;
pub(crate) const ANTICOM1: u8 = 0x20;
pub(crate) const ANTICOM0: u8 = 0x10;
pub(crate) const ANTIDFORM3: u8 = 0x08;
pub(crate) const ANTIDFORM2: u8 = 0x04;
pub(crate) const ANTIDFORM1: u8 = 0x02;
pub(crate) const ANTIDFORM0: u8 = 0x01;
pub(crate) const CNTSC3_MASK: u8 = 0xC0;
pub(crate) const CNTSC2_MASK: u8 = 0x30;
pub(crate) const CNTSC1_MASK: u8 = 0x0C;
pub(crate) const CNTSC0_MASK: u8 = 0x03;
pub(crate) const CNTSC3_OFFSET: u8 = 6;
pub(crate) const CNTSC2_OFFSET: u8 = 4;
pub(crate) const CNTSC1_OFFSET: u8 = 2;
pub(crate) const CNTSC0_OFFSET: u8 = 0;
pub(crate) const FTF0_MASK: u8 = 0x06;
pub(crate) const FTF0_OFFSET: u8 = 1;
pub(crate) const FTF2_MASK: u8 = 0xC0;
pub(crate) const FTF1_MASK: u8 = 0x30;
pub(crate) const FTF2_OFFSET: u8 = 6;
pub(crate) const FTF1_OFFSET: u8 = 4;
pub(crate) const FTF3_MASK: u8 = 0x03;
pub(crate) const FTF3_OFFSET: u8 = 0;
pub trait ChannelRegisters: Copy {
const CH: u8;
const EN_BIT: u8;
const LPEN_BIT: u8;
const BTPAUSE_BIT: u8;
const MAXWIN_BIT: u8;
const OPOL_BIT: u8;
const DPOL_BIT: u8;
const ANTICOM_BIT: u8;
const ANTIDFORM_BIT: u8;
const CNTSC_MASK: u8;
const CNTSC_OFFSET: u8;
const FTF_MASK: u8;
const FTF_OFFSET: u8;
const DEFAULT_MODE: super::ChannelMode;
fn data_lsb(&self) -> Register;
fn raw_data_lsb(&self) -> Register;
fn gain(&self) -> Register;
fn sensor_config(&self) -> Register;
fn ftf(&self) -> Register;
}
#[derive(Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Channel0;
#[derive(Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Channel1;
#[derive(Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Channel2;
#[derive(Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Channel3;
macro_rules! impl_channel_registers {
($ChType:ident: $Ch:expr, $Data:ident, $RawData:ident, $Gain:ident, $Sensor:ident, $Ftf:ident, $En:expr, $Lpen:expr, $Btpause:expr, $Maxwin:expr, $Opol:expr, $Dpol:expr, $Anticom:expr, $Antidform:expr, $CntscMask:expr, $CntscOffset:expr, $FtfMask:expr, $FtfOffset:expr, $DefaultMode:ident) => {
impl ChannelRegisters for $ChType {
const CH: u8 = $Ch;
const EN_BIT: u8 = $En;
const LPEN_BIT: u8 = $Lpen;
const BTPAUSE_BIT: u8 = $Btpause;
const MAXWIN_BIT: u8 = $Maxwin;
const OPOL_BIT: u8 = $Opol;
const DPOL_BIT: u8 = $Dpol;
const ANTICOM_BIT: u8 = $Anticom;
const ANTIDFORM_BIT: u8 = $Antidform;
const CNTSC_MASK: u8 = $CntscMask;
const CNTSC_OFFSET: u8 = $CntscOffset;
const FTF_MASK: u8 = $FtfMask;
const FTF_OFFSET: u8 = $FtfOffset;
const DEFAULT_MODE: super::ChannelMode = ChannelMode::$DefaultMode;
fn data_lsb(&self) -> Register {
Register::$Data
}
fn raw_data_lsb(&self) -> Register {
Register::$RawData
}
fn gain(&self) -> Register {
Register::$Gain
}
fn sensor_config(&self) -> Register {
Register::$Sensor
}
fn ftf(&self) -> Register {
Register::$Ftf
}
}
};
}
impl_channel_registers!(Channel0: 0, Data0Lsb, RawData0_3, Gain0, Sensor0Config, Ftf0, EN0, LPEN0, BTPAUSE0, MAXWIN0, OPOL0, DPOL0, ANTICOM0, ANTIDFORM0, CNTSC0_MASK, CNTSC0_OFFSET, FTF0_MASK, FTF0_OFFSET, NormalAndLowPowerMode);
impl_channel_registers!(Channel1: 1, Data1Lsb, RawData1_3, Gain1, Sensor1Config, Ftf1_2, EN1, LPEN1, BTPAUSE1, MAXWIN1, OPOL1, DPOL1, ANTICOM1, ANTIDFORM1, CNTSC1_MASK, CNTSC1_OFFSET, FTF1_MASK, FTF1_OFFSET, NormalMode);
impl_channel_registers!(Channel2: 2, Data2Lsb, RawData2_3, Gain2, Sensor2Config, Ftf1_2, EN2, LPEN2, BTPAUSE2, MAXWIN2, OPOL2, DPOL2, ANTICOM2, ANTIDFORM2, CNTSC2_MASK, CNTSC2_OFFSET, FTF2_MASK, FTF2_OFFSET, NormalMode);
impl_channel_registers!(Channel3: 3, Data3Lsb, RawData3_3, Gain3, Sensor3Config, Ftf3, EN3, LPEN3, BTPAUSE3, MAXWIN3, OPOL3, DPOL3, ANTICOM3, ANTIDFORM3, CNTSC3_MASK, CNTSC3_OFFSET, FTF3_MASK, FTF3_OFFSET, NormalMode);