From 5b0251f4c95f86f6edef2d4402aa9be59fe3ac76 Mon Sep 17 00:00:00 2001 From: ju6ge Date: Thu, 26 Feb 2026 20:45:34 +0100 Subject: [PATCH] add new types for charge window info to bms protocol these type add support for reading how much the charge state of the battery has changed according to the configured charge window --- lib-bms-protocol/src/lib.rs | 91 +++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/lib-bms-protocol/src/lib.rs b/lib-bms-protocol/src/lib.rs index ca92124..95f8d90 100644 --- a/lib-bms-protocol/src/lib.rs +++ b/lib-bms-protocol/src/lib.rs @@ -171,6 +171,89 @@ impl BmsReadable for BatteryState { } } +#[derive(Debug, Clone)] +pub struct ChargeInfoWindowSec(pub u32); + +impl BmsReadable for ChargeInfoWindowSec { + fn read_from_i2c(i2c_dev: &mut I) -> Result + where + Self: Sized, + I: I2c, + { + let cmd = BmsRegisterMap::ChargoInfoWindowTotalSecs; + let mut charge_info_window_sec: [u8; 4] = [0x00; 4]; + i2c_dev.transaction( + BMS_I2C_ADDRESS, + &mut [ + Operation::Write(&(cmd as u32).to_be_bytes()), + Operation::Read(&mut charge_info_window_sec), + ], + )?; + Ok(ChargeInfoWindowSec(u32::from_be_bytes( + charge_info_window_sec, + ))) + } +} + +impl BmsWriteable for ChargeInfoWindowSec { + fn write_to_device(&self, i2c_dev: &mut I) -> Result<(), BmsProtocolError> + where + I: I2c, + { + let cmd = BmsRegisterMap::ChargoInfoWindowTotalSecs; + i2c_dev.transaction( + BMS_I2C_ADDRESS, + &mut [ + Operation::Write(&(cmd as u32).to_be_bytes()), + Operation::Write(&self.0.to_be_bytes()), + ], + )?; + Ok(()) + } +} + +#[derive(Debug, Clone, Copy)] +pub struct ChargeInfo { + pub total_charge_ma: u32, + pub total_discharge_ma: u32, + pub max_charge_mw: u32, + pub max_discharge_mw: u32, + pub avg_voltage_mv: u32, +} + +impl BmsReadable for ChargeInfo { + fn read_from_i2c(i2c_dev: &mut I) -> Result + where + Self: Sized, + I: I2c, + { + let cmd = BmsRegisterMap::ChargoInfoTotalChargeMilliAmpere; + let mut total_charge_ma: [u8; 4] = [0x00; 4]; + let mut total_discharge_ma: [u8; 4] = [0x00; 4]; + let mut max_charge_mw: [u8; 4] = [0x00; 4]; + let mut max_discharge_mw: [u8; 4] = [0x00; 4]; + let mut avg_voltage_mv: [u8; 4] = [0x00; 4]; + i2c_dev.transaction( + BMS_I2C_ADDRESS, + &mut [ + Operation::Write(&(cmd as u32).to_be_bytes()), + Operation::Read(&mut total_charge_ma), + Operation::Read(&mut total_discharge_ma), + Operation::Read(&mut max_charge_mw), + Operation::Read(&mut max_discharge_mw), + Operation::Read(&mut avg_voltage_mv), + ], + )?; + Ok(ChargeInfo { + total_charge_ma: u32::from_be_bytes(total_charge_ma), + total_discharge_ma: u32::from_be_bytes(total_discharge_ma), + max_charge_mw: u32::from_be_bytes(max_charge_mw), + max_discharge_mw: u32::from_be_bytes(max_discharge_mw), + avg_voltage_mv: u32::from_be_bytes(avg_voltage_mv), + }) + } +} + #[repr(u32)] #[non_exhaustive] pub enum BmsRegisterMap { @@ -190,4 +273,12 @@ pub enum BmsRegisterMap { BatteryCurrentVoltageMilliVolt = 0x00020008, BatteryTemperatureCelcius = 0x0002000c, BatteryHealthPercent = 0x00020010, + // Charge Window Read/Write Address + ChargoInfoWindowTotalSecs = 0x0003000, + // Charge Info Value Start Here + ChargoInfoTotalChargeMilliAmpere = 0x0003004, + ChargoInfoTotalDischargeMilliAmpere = 0x0003008, + ChargoInfoMaxChargeMilliWatt = 0x000300c, + ChargoInfoMaxDischargeMilliWatt = 0x0003010, + ChargoInfoAvgVoltageMilliVolt = 0x0003014, }