From b5121ce7f40af51afad5370461553f84aef68fe6 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Mon, 13 Jan 2025 12:14:53 +1100 Subject: [PATCH] ccs: tristar: parse dip switches --- .../src/controller/tristar.rs | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/charge-controller-supervisor/src/controller/tristar.rs b/charge-controller-supervisor/src/controller/tristar.rs index 2148da4..5b533d6 100644 --- a/charge-controller-supervisor/src/controller/tristar.rs +++ b/charge-controller-supervisor/src/controller/tristar.rs @@ -426,6 +426,7 @@ pub struct TristarState { pub alarms_daily: Alarms, pub faults_daily: Faults, pub flags_daily: DailyFlags, + pub dip_switches: DipSwitch, } fn signed(val: u16) -> i16 { @@ -466,6 +467,9 @@ impl TristarState { ), faults_daily: Faults::from_bits_retain(ram[TristarRamAddress::FaultDaily]), flags_daily: DailyFlags::from_bits_retain(ram[TristarRamAddress::FlagsDaily]), + dip_switches: DipSwitch::parse_byte( + (ram[TristarRamAddress::Dip] & 0xFF).try_into().unwrap_or(0), + ), } } } @@ -536,6 +540,99 @@ impl Alarms { } } +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub struct DipSwitch { + sw1_reserved: bool, + system_voltage: SystemVoltage, + battery_config: BatteryConfig, + battery_equalization: BatteryEqualization, + ethernet_security: bool, +} + +trait Bit { + fn bit(&self, num: u8) -> bool; +} + +impl Bit for u8 { + fn bit(&self, num: u8) -> bool { + ((*self >> num) & 0b1) != 0 + } +} + +impl DipSwitch { + fn parse_byte(value: u8) -> Self { + let sw1_reserved = value.bit(0); + let system_voltage = SystemVoltage::from_dip(value.bit(1), value.bit(2)); + let battery_config = BatteryConfig::from_dip(value.bit(3), value.bit(4), value.bit(5)); + let battery_equalization = if value.bit(6) { + BatteryEqualization::Automatic + } else { + BatteryEqualization::Manual + }; + let ethernet_security = value.bit(7); + + Self { + sw1_reserved, + system_voltage, + battery_config, + battery_equalization, + ethernet_security, + } + } +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +enum SystemVoltage { + Auto, + V12, + V24, + V48, +} + +impl SystemVoltage { + const fn from_dip(switch2: bool, switch3: bool) -> Self { + match (switch2, switch3) { + (false, false) => Self::Auto, + (false, true) => Self::V12, + (true, false) => Self::V24, + (true, true) => Self::V48, + } + } +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +enum BatteryConfig { + Gel, + Sealed2, + Sealed3, + AgmFlooded, + Flooded5, + Flooded6, + Flooded7, + Custom, +} + +impl BatteryConfig { + const fn from_dip(switch4: bool, switch5: bool, switch6: bool) -> Self { + match (switch4, switch5, switch6) { + (false, false, false) => Self::Gel, + (false, false, true) => Self::Sealed2, + (false, true, false) => Self::Sealed3, + (false, true, true) => Self::AgmFlooded, + (true, false, false) => Self::Flooded5, + (true, false, true) => Self::Flooded6, + (true, true, false) => Self::Flooded7, + (true, true, true) => Self::Custom, + } + } +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +enum BatteryEqualization { + Manual, + Automatic, +} + #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum ChargeState { Start,