use num_traits::cast::FromPrimitive;
use num_traits::ToPrimitive;
#[cfg(feature = "use-defmt")]
use defmt::Format;
pub trait Register {
fn addr() -> u8;
fn parse(reg: u16) -> Self;
fn data(&self) -> u16;
}
#[derive(Copy, Clone, Primitive, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "use-defmt", derive(Format))]
pub enum CommOption {
Diode = 0,
Active = 1,
}
#[derive(Copy, Clone, Primitive, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "use-defmt", derive(Format))]
pub enum PwmMode {
Six = 0,
Three = 1,
One = 2,
}
#[derive(Copy, Clone, Primitive, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "use-defmt", derive(Format))]
pub enum VdsMode {
Latched = 0,
Report = 1,
Disabled = 2,
}
#[derive(Copy, Clone, Primitive, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "use-defmt", derive(Format))]
pub enum Flag {
Enabled = 1,
Disabled = 0,
}
impl Flag {
pub fn enabled(&self) -> bool {
matches!(self, Flag::Enabled)
}
}
macro_rules! register {
(struct $name: ident [$addr: expr] { $($var: ident: $kind: ty [$size: expr, $offset: expr]),+ }) => {
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "use-defmt", derive(Format))]
pub struct $name {
pub bits: u16,
$(pub $var: $kind,)*
}
impl $name {
$(
pub fn $var(mut self, $var: $kind) -> Self {
self.$var = $var;
self
}
)*
}
impl Register for $name {
fn addr() -> u8 {
return $addr;
}
fn parse(reg: u16) -> Self {
$name {
bits: reg,
$($var: <$kind>::from_u16((reg & ($size << $offset)) >> $offset).unwrap(),)*
}
}
fn data(&self) -> u16 {
let mut data = self.bits;
$(data = (data & !($size << $offset)) | (self.$var.to_u16().unwrap() << $offset);)*
data
}
}
};
}
register!(struct IcOperation [0x9]{
en_sns_clamp: Flag [0b1, 7],
wd_en: Flag [0b1, 3],
wd_dly: u8 [0b11, 5]
});
register!(struct VdsSenseControl [0xc] {
vds_level: u16 [0b1111, 3],
vds_mode: VdsMode [0b111, 0]
});
register!(struct ShuntAmplifierControl [0xa] {
dc_cal_ch3: Flag [0b1, 10],
dc_cal_ch2: Flag [0b1, 9],
dc_cal_ch1: Flag [0b1, 8],
cs_blank: u16 [0b11, 6],
gain_cs3: u16 [0b11, 4],
gain_cs2: u16 [0b11, 2],
gain_cs1: u16 [0b11, 0]
});
register!(
struct GateDriveControl [0x7] {
comm_option: CommOption [0b1, 9],
pwm_mode: PwmMode [0b11, 7],
dead_time: u8 [0b111, 4],
tblank: u8 [0b11, 2],
tvds: u8 [0b11, 0]
}
);
register!(
struct WarningAndWatchdog [0x1] {
fault: Flag [0b1, 10],
temp_flag4: Flag [0b1, 8],
pvdd_uv: Flag [0b1, 7],
pvdd_ov: Flag [0b1, 6],
vds_status: Flag [0b1, 5],
vchp_uvfl: Flag [0b1, 4],
temp_flag1: Flag [0b1, 3],
temp_flag2: Flag [0b1, 2],
temp_flag3: Flag [0b1, 1],
otw: Flag [0b1, 0]
}
);
register!(
struct OvVdsFaults [0x2] {
vds_ha: Flag [0b1, 10],
vds_la: Flag [0b1, 9],
vds_hb: Flag [0b1, 8],
vds_lb: Flag [0b1, 7],
vds_hc: Flag [0b1, 6],
vds_lc: Flag [0b1, 5],
sns_c_ocp: Flag [0b1, 2],
sns_b_ocp: Flag [0b1, 1],
sns_a_ocp: Flag [0b1, 0]
}
);
register!(
struct IcFaults [0x3] {
pvdd_uvlo2: Flag [0b1, 10],
wd_fault: Flag [0b1, 9],
otsd: Flag [0b1, 8],
vreg_uv: Flag [0b1, 6],
avdd_uvlo: Flag [0b1, 5],
vcp_lsd_uvlo2: Flag [0b1, 4],
vcph_uvlo2: Flag [0b1, 2],
vcph_uvlo: Flag [0b1, 1],
vcph_ovlo_abs: Flag [0b1, 0]
}
);
register!(
struct VgsFaults [0x4] {
vgs_ha: Flag [0b1, 10],
vgs_la: Flag [0b1, 9],
vgs_hb: Flag [0b1, 8],
vgs_lb: Flag [0b1, 7],
vgs_hc: Flag [0b1, 6],
vgs_lc: Flag [0b1, 5]
}
);