use packed_struct::prelude::*;
use register_derive::Register;
#[repr(u8)]
pub(crate) enum Address {
Refresh,
Ctrl,
AccCount,
Vaccn = 0x03,
Vbusn = 0x07,
Vsensen = 0x0B,
VbusnAvg = 0x0F,
VsensenAvg = 0x13,
Vpowern = 0x17,
SmbusSettings = 0x1C,
NegPwrFsr,
RefreshG,
RefreshV,
Slow,
CtrlAct,
NegPwrFsrAct,
CtrlLat,
NegPwrFsrLat,
AccumConfig,
AlertStatus,
SlowAlert1,
GpioAlert2,
AccFullnessLimits,
OcLimitn = 0x30,
UcLimitn = 0x34,
OpLimitn = 0x38,
OvLimitn = 0x3C,
UvLimitn = 0x40,
OcLimitNSamples = 0x44,
UcLimitNSamples,
OpLimitNSamples,
OvLimitNSamples,
UvLimitNSamples,
AlertEnable,
AccumConfigAct,
AccumConfigLat,
ProductId = 0xFD,
ManufacturerId,
RevisionId,
}
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
pub enum SampleMode {
_1024Adaptive,
_256Adaptive,
_64Adaptive,
_8Adaptive,
_1024,
_256,
_64,
_8,
SingleShot,
SingleShot8X,
Fast,
Burst,
Sleep = 0b1111,
}
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
pub enum GpioAlert {
Alert,
Input,
Output,
Slow,
}
#[derive(PackedStruct, Default, Debug, PartialEq)]
#[packed_struct(bit_numbering = "msb0")]
pub struct Channels {
#[packed_field(bits = "4")]
pub _1: bool,
pub _2: bool,
pub _3: bool,
pub _4: bool,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct Ctrl {
#[packed_field(bits = "15:12", ty = "enum")]
pub sample_mode: SampleMode,
#[packed_field(bits = "11:10", ty = "enum")]
pub gpio_alert2: GpioAlert,
#[packed_field(bits = "9:8", ty = "enum")]
pub slow_alert1: GpioAlert,
#[packed_field(bits = "7:4")]
pub channel_n_off: Channels,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "4", bit_numbering = "lsb0")]
pub struct AccCount {
#[packed_field(bits = "31:0", endian = "msb")]
pub count: u32,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "7", bit_numbering = "lsb0")]
pub struct Vaccn {
#[packed_field(bits = "55:0", endian = "msb")]
pub sum: u64,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct Vbusn {
#[packed_field(bits = "15:0", endian = "msb")]
pub voltage: u16,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct Vsensen {
#[packed_field(bits = "15:0", endian = "msb")]
pub voltage: u16,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct VbusnAvg {
#[packed_field(bits = "15:0", endian = "msb")]
pub voltage: u16,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct VsensenAvg {
#[packed_field(bits = "15:0", endian = "msb")]
pub voltage: u16,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "4", bit_numbering = "lsb0")]
pub struct Vpowern {
#[packed_field(bits = "31:2", endian = "msb")]
pub power: u32,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct SmbusSettings {
#[packed_field(bits = "7")]
pub gpio_data2: bool,
#[packed_field(bits = "6")]
pub gpio_data1: bool,
#[packed_field(bits = "5")]
pub any_alert: bool,
#[packed_field(bits = "4")]
pub por: bool,
#[packed_field(bits = "3")]
pub timeout: bool,
#[packed_field(bits = "2")]
pub byte_count: bool,
#[packed_field(bits = "1")]
pub no_skip: bool,
#[packed_field(bits = "0")]
pub i2c_hispeed: bool,
}
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
pub enum VSenseFSR {
Unipolar = 0,
BipolarHV = 1,
BipolarLV = 2,
}
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
pub enum VBusFSR {
Unipolar = 0,
BipolarHV = 1,
BipolarLV = 2,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct NegPwrFsr {
#[packed_field(bits = "15:14", ty = "enum")]
pub cfg_vs1: VSenseFSR,
#[packed_field(bits = "13:12", ty = "enum")]
pub cfg_vs2: VSenseFSR,
#[packed_field(bits = "11:10", ty = "enum")]
pub cfg_vs3: VSenseFSR,
#[packed_field(bits = "9:8", ty = "enum")]
pub cfg_vs4: VSenseFSR,
#[packed_field(bits = "7:6", ty = "enum")]
pub cfg_vb1: VBusFSR,
#[packed_field(bits = "5:4", ty = "enum")]
pub cfg_vb2: VBusFSR,
#[packed_field(bits = "3:2", ty = "enum")]
pub cfg_vb3: VBusFSR,
#[packed_field(bits = "1:0", ty = "enum")]
pub cfg_vb4: VBusFSR,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct Slow {
#[packed_field(bits = "7")]
pub slow: bool,
#[packed_field(bits = "6")]
pub slow_lh: bool,
#[packed_field(bits = "5")]
pub slow_hl: bool,
#[packed_field(bits = "4")]
pub r_rise: bool,
#[packed_field(bits = "3")]
pub r_v_rise: bool,
#[packed_field(bits = "2")]
pub r_fall: bool,
#[packed_field(bits = "1")]
pub r_v_fall: bool,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct CtrlAct {
#[packed_field(bits = "15:12", ty = "enum")]
pub sample_mode: SampleMode,
#[packed_field(bits = "11:10", ty = "enum")]
pub gpio_alert2: GpioAlert,
#[packed_field(bits = "9:8", ty = "enum")]
pub slow_alert1: GpioAlert,
#[packed_field(bits = "7:4")]
pub channel_n_off: Channels,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct NegPwrFsrAct {
#[packed_field(bits = "15:14", ty = "enum")]
pub cfg_vs1: VSenseFSR,
#[packed_field(bits = "13:12", ty = "enum")]
pub cfg_vs2: VSenseFSR,
#[packed_field(bits = "11:10", ty = "enum")]
pub cfg_vs3: VSenseFSR,
#[packed_field(bits = "9:8", ty = "enum")]
pub cfg_vs4: VSenseFSR,
#[packed_field(bits = "7:6", ty = "enum")]
pub cfg_vb1: VBusFSR,
#[packed_field(bits = "5:4", ty = "enum")]
pub cfg_vb2: VBusFSR,
#[packed_field(bits = "3:2", ty = "enum")]
pub cfg_vb3: VBusFSR,
#[packed_field(bits = "1:0", ty = "enum")]
pub cfg_vb4: VBusFSR,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct CtrlLat {
#[packed_field(bits = "15:12", ty = "enum")]
pub sample_mode: SampleMode,
#[packed_field(bits = "11:10", ty = "enum")]
pub gpio_alert2: GpioAlert,
#[packed_field(bits = "9:8", ty = "enum")]
pub slow_alert1: GpioAlert,
#[packed_field(bits = "7:4")]
pub channel_n_off: Channels,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct NegPwrFsrLat {
#[packed_field(bits = "15:14", ty = "enum")]
pub cfg_vs1: VSenseFSR,
#[packed_field(bits = "13:12", ty = "enum")]
pub cfg_vs2: VSenseFSR,
#[packed_field(bits = "11:10", ty = "enum")]
pub cfg_vs3: VSenseFSR,
#[packed_field(bits = "9:8", ty = "enum")]
pub cfg_vs4: VSenseFSR,
#[packed_field(bits = "7:6", ty = "enum")]
pub cfg_vb1: VBusFSR,
#[packed_field(bits = "5:4", ty = "enum")]
pub cfg_vb2: VBusFSR,
#[packed_field(bits = "3:2", ty = "enum")]
pub cfg_vb3: VBusFSR,
#[packed_field(bits = "1:0", ty = "enum")]
pub cfg_vb4: VBusFSR,
}
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
pub enum AccumSetting {
VPower = 0,
VSense = 1,
VBus = 2,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct AccumConfig {
#[packed_field(bits = "7:6", ty = "enum")]
pub acc1_config: AccumSetting,
#[packed_field(bits = "5:4", ty = "enum")]
pub acc2_config: AccumSetting,
#[packed_field(bits = "3:2", ty = "enum")]
pub acc3_config: AccumSetting,
#[packed_field(bits = "1:0", ty = "enum")]
pub acc4_config: AccumSetting,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "3", bit_numbering = "msb0")]
pub struct AlertStatus {
#[packed_field(bit = "0")]
pub ch1_oc: bool,
pub ch2_oc: bool,
pub ch3_oc: bool,
pub ch4_oc: bool,
pub ch1_uc: bool,
pub ch2_uc: bool,
pub ch3_uc: bool,
pub ch4_uc: bool,
pub ch1_ov: bool,
pub ch2_ov: bool,
pub ch3_ov: bool,
pub ch4_ov: bool,
pub ch1_uv: bool,
pub ch2_uv: bool,
pub ch3_uv: bool,
pub ch4_uv: bool,
pub ch1_op: bool,
pub ch2_op: bool,
pub ch3_op: bool,
pub ch4_op: bool,
pub acc_ovf: bool,
pub acc_count: bool,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "3", bit_numbering = "msb0")]
pub struct SlowAlert1 {
#[packed_field(bit = "0")]
pub ch1_oc: bool,
pub ch2_oc: bool,
pub ch3_oc: bool,
pub ch4_oc: bool,
pub ch1_uc: bool,
pub ch2_uc: bool,
pub ch3_uc: bool,
pub ch4_uc: bool,
pub ch1_ov: bool,
pub ch2_ov: bool,
pub ch3_ov: bool,
pub ch4_ov: bool,
pub ch1_uv: bool,
pub ch2_uv: bool,
pub ch3_uv: bool,
pub ch4_uv: bool,
pub ch1_op: bool,
pub ch2_op: bool,
pub ch3_op: bool,
pub ch4_op: bool,
pub acc_ovf: bool,
pub acc_count: bool,
pub alert_cc1: bool,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "3", bit_numbering = "msb0")]
pub struct GpioAlert2 {
#[packed_field(bit = "0")]
pub ch1_oc: bool,
pub ch2_oc: bool,
pub ch3_oc: bool,
pub ch4_oc: bool,
pub ch1_uc: bool,
pub ch2_uc: bool,
pub ch3_uc: bool,
pub ch4_uc: bool,
pub ch1_ov: bool,
pub ch2_ov: bool,
pub ch3_ov: bool,
pub ch4_ov: bool,
pub ch1_uv: bool,
pub ch2_uv: bool,
pub ch3_uv: bool,
pub ch4_uv: bool,
pub ch1_op: bool,
pub ch2_op: bool,
pub ch3_op: bool,
pub ch4_op: bool,
pub acc_ovf: bool,
pub acc_count: bool,
pub alert_cc2: bool,
}
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
pub enum AccFullness {
Full = 0,
Mostly = 1,
Somewhat = 2,
Partially = 3,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct AccFullnessLimits {
#[packed_field(bits = "15:14", ty = "enum")]
pub ch1_acc_full: AccFullness,
#[packed_field(bits = "13:12", ty = "enum")]
pub ch2_acc_full: AccFullness,
#[packed_field(bits = "11:10", ty = "enum")]
pub ch3_acc_full: AccFullness,
#[packed_field(bits = "9:8", ty = "enum")]
pub ch4_acc_full: AccFullness,
#[packed_field(bits = "7:6", ty = "enum")]
pub acc_count_full: AccFullness,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct OcLimitn {
#[packed_field(bits = "15:0", endian = "msb")]
pub limit: i16,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct UcLimitn {
#[packed_field(bits = "15:0", endian = "msb")]
pub limit: i16,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "3", bit_numbering = "lsb0")]
pub struct OpLimitn {
#[packed_field(bits = "23:0", endian = "msb")]
pub limit: i32,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct OvLimitn {
#[packed_field(bits = "15:0", endian = "msb")]
pub limit: i16,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "2", bit_numbering = "lsb0")]
pub struct UvLimitn {
#[packed_field(bits = "15:0", endian = "msb")]
pub limit: i16,
}
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq)]
pub enum SampleCount {
_1 = 0,
_4 = 1,
_8 = 2,
_16 = 3,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct OcLimitNSamples {
#[packed_field(bits = "7:6", ty = "enum")]
pub n_samples_ch1: SampleCount,
#[packed_field(bits = "5:4", ty = "enum")]
pub n_samples_ch2: SampleCount,
#[packed_field(bits = "3:2", ty = "enum")]
pub n_samples_ch3: SampleCount,
#[packed_field(bits = "1:0", ty = "enum")]
pub n_samples_ch4: SampleCount,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct UcLimitNSamples {
#[packed_field(bits = "7:6", ty = "enum")]
pub n_samples_ch1: SampleCount,
#[packed_field(bits = "5:4", ty = "enum")]
pub n_samples_ch2: SampleCount,
#[packed_field(bits = "3:2", ty = "enum")]
pub n_samples_ch3: SampleCount,
#[packed_field(bits = "1:0", ty = "enum")]
pub n_samples_ch4: SampleCount,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct OpLimitNSamples {
#[packed_field(bits = "7:6", ty = "enum")]
pub n_samples_ch1: SampleCount,
#[packed_field(bits = "5:4", ty = "enum")]
pub n_samples_ch2: SampleCount,
#[packed_field(bits = "3:2", ty = "enum")]
pub n_samples_ch3: SampleCount,
#[packed_field(bits = "1:0", ty = "enum")]
pub n_samples_ch4: SampleCount,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct OvLimitNSamples {
#[packed_field(bits = "7:6", ty = "enum")]
pub n_samples_ch1: SampleCount,
#[packed_field(bits = "5:4", ty = "enum")]
pub n_samples_ch2: SampleCount,
#[packed_field(bits = "3:2", ty = "enum")]
pub n_samples_ch3: SampleCount,
#[packed_field(bits = "1:0", ty = "enum")]
pub n_samples_ch4: SampleCount,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct UvLimitNSamples {
#[packed_field(bits = "7:6", ty = "enum")]
pub n_samples_ch1: SampleCount,
#[packed_field(bits = "5:4", ty = "enum")]
pub n_samples_ch2: SampleCount,
#[packed_field(bits = "3:2", ty = "enum")]
pub n_samples_ch3: SampleCount,
#[packed_field(bits = "1:0", ty = "enum")]
pub n_samples_ch4: SampleCount,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "3", bit_numbering = "msb0")]
pub struct AlertEnable {
#[packed_field(bit = "0")]
pub ch1_oc: bool,
pub ch2_oc: bool,
pub ch3_oc: bool,
pub ch4_oc: bool,
pub ch1_uc: bool,
pub ch2_uc: bool,
pub ch3_uc: bool,
pub ch4_uc: bool,
pub ch1_ov: bool,
pub ch2_ov: bool,
pub ch3_ov: bool,
pub ch4_ov: bool,
pub ch1_uv: bool,
pub ch2_uv: bool,
pub ch3_uv: bool,
pub ch4_uv: bool,
pub ch1_op: bool,
pub ch2_op: bool,
pub ch3_op: bool,
pub ch4_op: bool,
pub acc_ovf: bool,
pub acc_count: bool,
pub alert_cc: bool,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct AccumConfigAct {
#[packed_field(bits = "7:6", ty = "enum")]
pub acc1_config: AccumSetting,
#[packed_field(bits = "5:4", ty = "enum")]
pub acc2_config: AccumSetting,
#[packed_field(bits = "3:2", ty = "enum")]
pub acc3_config: AccumSetting,
#[packed_field(bits = "1:0", ty = "enum")]
pub acc4_config: AccumSetting,
}
#[derive(PackedStruct, Debug, PartialEq, Register)]
#[packed_struct(size_bytes = "1", bit_numbering = "lsb0")]
pub struct AccumConfigLat {
#[packed_field(bits = "7:6", ty = "enum")]
pub acc1_config: AccumSetting,
#[packed_field(bits = "5:4", ty = "enum")]
pub acc2_config: AccumSetting,
#[packed_field(bits = "3:2", ty = "enum")]
pub acc3_config: AccumSetting,
#[packed_field(bits = "1:0", ty = "enum")]
pub acc4_config: AccumSetting,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn round_trip_ctrl() {
let ctrl = Ctrl {
sample_mode: SampleMode::_256,
gpio_alert2: GpioAlert::Input,
slow_alert1: GpioAlert::Output,
channel_n_off: Channels {
_1: false,
_2: true,
_3: false,
_4: false,
},
};
let bytes = ctrl.pack().unwrap();
assert_eq!(ctrl, Ctrl::unpack(&bytes).unwrap());
}
#[test]
fn round_trip_acc_count() {
let acc_count = AccCount { count: 2459526763 };
let bytes = acc_count.pack().unwrap();
assert_eq!(acc_count, AccCount::unpack(&bytes).unwrap());
}
}