#[derive(Default, Debug, Copy, Clone)]
pub struct Config {
pub clkout_en: bool,
pub pwrdwn_en: bool,
pub temp_en: bool,
pub adc_freq: AdcFreqVal,
pub swrst: bool,
pub bw: bool,
}
#[repr(u8)]
#[derive(Default, Debug, Copy, Clone)]
pub enum AdcFreqVal {
#[default]
KHz8 = 0x00,
KHz4 = 0x01,
KHz2 = 0x02,
KHz1 = 0x03,
}
impl From<u8> for Config {
fn from(x: u8) -> Self {
Self {
clkout_en: (x & 0x01) != 0,
pwrdwn_en: (x & 0x04) != 0,
temp_en: (x & 0x08) != 0,
adc_freq: AdcFreqVal::from((x & 0x30) >> 4),
swrst: (x & 0x40) != 0,
bw: (x & 0x80) != 0,
}
}
}
impl From<Config> for u8 {
fn from(x: Config) -> Self {
(x.bw as u8) << 7
| (x.swrst as u8) << 6
| (x.adc_freq as u8) << 4
| (x.temp_en as u8) << 3
| (x.pwrdwn_en as u8) << 2
| (x.clkout_en as u8)
}
}
impl From<u8> for AdcFreqVal {
fn from(x: u8) -> Self {
match x & 0x03 {
0x00 => AdcFreqVal::KHz8,
0x01 => AdcFreqVal::KHz4,
0x02 => AdcFreqVal::KHz2,
_ => AdcFreqVal::KHz1,
}
}
}
#[derive(Default, Debug, Copy, Clone)]
pub struct Status0 {
pub reset_on: bool,
pub crc_stat: bool,
pub ic_prot: bool,
}
impl From<u8> for Status0 {
fn from(x: u8) -> Self {
Status0 {
reset_on: (x & 0x01) != 0,
crc_stat: (x & 0x02) != 0,
ic_prot: (x & 0x04) != 0,
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct EmiCtrl {
pub slot0: bool,
pub slot1: bool,
pub slot2: bool,
pub slot3: bool,
pub slot4: bool,
pub slot5: bool,
pub slot6: bool,
pub slot7: bool,
}
impl Default for EmiCtrl {
fn default() -> Self {
Self::from(0xFF)
}
}
impl From<u8> for EmiCtrl {
fn from(x: u8) -> Self {
Self {
slot0: (x & 0x01) != 0,
slot1: (x & (0x01 << 1)) != 0,
slot2: (x & (0x01 << 2)) != 0,
slot3: (x & (0x01 << 3)) != 0,
slot4: (x & (0x01 << 4)) != 0,
slot5: (x & (0x01 << 5)) != 0,
slot6: (x & (0x01 << 6)) != 0,
slot7: (x & (0x01 << 7)) != 0,
}
}
}
impl From<EmiCtrl> for u8 {
fn from(x: EmiCtrl) -> Self {
(x.slot7 as u8) << 7
| (x.slot6 as u8) << 6
| (x.slot5 as u8) << 5
| (x.slot4 as u8) << 4
| (x.slot3 as u8) << 3
| (x.slot2 as u8) << 2
| (x.slot1 as u8) << 1
| (x.slot0 as u8)
}
}
pub(crate) struct SyncSnap {
pub sync: bool,
pub snap: bool,
}
impl From<SyncSnap> for u8 {
fn from(x: SyncSnap) -> Self {
(x.snap as u8) << 1 | (x.sync as u8)
}
}
#[allow(dead_code)]
pub(crate) struct BurstRead {
pub iwv: i32,
pub v1wv: i32,
pub v2wv: i32,
pub adc_crc: u16,
pub status0: Status0,
pub cnt_snapshot: u16,
}
impl From<[u8; 15]> for BurstRead {
fn from(x: [u8; 15]) -> Self {
Self {
iwv: (i32::from_be_bytes(x[0..4].try_into().unwrap()) << 8) >> 8,
v1wv: (i32::from_be_bytes(x[3..7].try_into().unwrap()) << 8) >> 8,
v2wv: (i32::from_be_bytes(x[6..10].try_into().unwrap()) << 8) >> 8,
adc_crc: u16::from_be_bytes(x[10..12].try_into().unwrap()),
status0: Status0::from(x[12]),
cnt_snapshot: u16::from_be_bytes(x[13..].try_into().unwrap()),
}
}
}
#[repr(u8)]
#[allow(dead_code)]
#[derive(PartialEq, Copy, Clone)]
pub(crate) enum Register {
Iwv,
V1wv,
V2wv,
AdcCrc,
CtrlCrc,
CntSnapshot,
Config,
Status0,
Lock,
SyncSnap,
Counter0,
Counter1,
EmiCtrl,
Status1,
Tempos,
}
impl Register {
pub fn addr(&self) -> u8 {
match self {
Register::Iwv => 0x00,
Register::V1wv => 0x01,
Register::V2wv => 0x02,
Register::AdcCrc => 0x04,
Register::CtrlCrc => 0x05,
Register::CntSnapshot => 0x07,
Register::Config => 0x08,
Register::Status0 => 0x09,
Register::Lock => 0x0A,
Register::SyncSnap => 0x0B,
Register::Counter0 => 0x0C,
Register::Counter1 => 0x0D,
Register::EmiCtrl => 0x0E,
Register::Status1 => 0x0F,
Register::Tempos => 0x18,
}
}
pub fn is_read_only(&self) -> bool {
*self != Register::Config
&& *self != Register::Lock
&& *self != Register::SyncSnap
&& *self != Register::Counter0
&& *self != Register::Counter1
&& *self != Register::EmiCtrl
}
pub fn is_write_only(&self) -> bool {
*self == Register::Lock || *self == Register::SyncSnap
}
}
#[repr(u8)]
pub(crate) enum SpiOp {
Read = 0x04,
Write = 0x00,
}
#[repr(u8)]
pub(crate) enum LockOp {
Enable = 0xCA,
Disable = 0x9C,
}