Convert communication protocol to use Transit_U26 with built-in CRC calculation

This commit is contained in:
2026-03-26 22:26:50 +01:00
parent d69c468ebc
commit 0437d30d04
+28 -17
View File
@@ -8,6 +8,8 @@ mod types;
use embedded_hal::i2c::{I2c, Operation, SevenBitAddress}; use embedded_hal::i2c::{I2c, Operation, SevenBitAddress};
use thiserror::Error; use thiserror::Error;
use crate::types::Transit_U26;
pub const BMS_I2C_ADDRESS: u8 = 0x55; pub const BMS_I2C_ADDRESS: u8 = 0x55;
pub trait BmsReadable { pub trait BmsReadable {
@@ -38,6 +40,12 @@ where
} }
} }
impl From<crate::types::U26Error> for BmsProtocolError {
fn from(_error: crate::types::U26Error) -> Self {
Self::I2cCommunicationError
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct BmsSoftwareReset; pub struct BmsSoftwareReset;
@@ -73,7 +81,8 @@ impl BmsReadable for ProtocolVersion {
Operation::Read(&mut version), Operation::Read(&mut version),
], ],
)?; )?;
Ok(ProtocolVersion(u32::from_be_bytes(version))) let transit = Transit_U26::from_be_bytes(version)?;
Ok(ProtocolVersion(u32::from(transit)))
} }
} }
@@ -96,7 +105,8 @@ impl BmsReadable for FirmwareVersion {
Operation::Read(&mut version), Operation::Read(&mut version),
], ],
)?; )?;
Ok(FirmwareVersion(u32::from_be_bytes(version))) let transit = Transit_U26::from_be_bytes(version)?;
Ok(FirmwareVersion(u32::from(transit)))
} }
} }
@@ -127,9 +137,9 @@ impl BmsReadable for Config {
], ],
)?; )?;
Ok(Config { Ok(Config {
capacity_mah: u32::from_be_bytes(capacity_mah), capacity_mah: u32::from(Transit_U26::from_be_bytes(capacity_mah)?),
v_full_mv: u32::from_be_bytes(v_full_mv), v_full_mv: u32::from(Transit_U26::from_be_bytes(v_full_mv)?),
v_empty_mv: u32::from_be_bytes(v_empty_mv), v_empty_mv: u32::from(Transit_U26::from_be_bytes(v_empty_mv)?),
}) })
} }
} }
@@ -167,11 +177,11 @@ impl BmsReadable for BatteryState {
], ],
)?; )?;
Ok(BatteryState { Ok(BatteryState {
lifetime_capacity_mah: u32::from_be_bytes(lifetime_capacity_mah), lifetime_capacity_mah: u32::from(Transit_U26::from_be_bytes(lifetime_capacity_mah)?),
remaining_capacity_mah: u32::from_be_bytes(remaining_capacity_mah), remaining_capacity_mah: u32::from(Transit_U26::from_be_bytes(remaining_capacity_mah)?),
current_mv: u32::from_be_bytes(current_mv), current_mv: u32::from(Transit_U26::from_be_bytes(current_mv)?),
temperature_celcius: i32::from_be_bytes(temperature_celcius), temperature_celcius: i32::from_be_bytes(temperature_celcius),
health_percent: u32::from_be_bytes(health_percent), health_percent: u32::from(Transit_U26::from_be_bytes(health_percent)?),
}) })
} }
} }
@@ -194,9 +204,9 @@ impl BmsReadable for ChargeInfoWindowSec {
Operation::Read(&mut charge_info_window_sec), Operation::Read(&mut charge_info_window_sec),
], ],
)?; )?;
Ok(ChargeInfoWindowSec(u32::from_be_bytes( Ok(ChargeInfoWindowSec(u32::from(Transit_U26::from_be_bytes(
charge_info_window_sec, charge_info_window_sec,
))) )?)))
} }
} }
@@ -206,11 +216,12 @@ impl BmsWriteable for ChargeInfoWindowSec {
I: I2c<SevenBitAddress>, I: I2c<SevenBitAddress>,
{ {
let cmd = BmsRegisterMap::ChargoInfoWindowTotalSecs; let cmd = BmsRegisterMap::ChargoInfoWindowTotalSecs;
let transit = Transit_U26::try_from(self.0)?;
i2c_dev.transaction( i2c_dev.transaction(
BMS_I2C_ADDRESS, BMS_I2C_ADDRESS,
&mut [ &mut [
Operation::Write(&(cmd as u32).to_be_bytes()), Operation::Write(&(cmd as u32).to_be_bytes()),
Operation::Write(&self.0.to_be_bytes()), Operation::Write(&transit.to_be_bytes()),
], ],
)?; )?;
Ok(()) Ok(())
@@ -250,11 +261,11 @@ impl BmsReadable for ChargeInfo {
], ],
)?; )?;
Ok(ChargeInfo { Ok(ChargeInfo {
total_charge_ma: u32::from_be_bytes(total_charge_ma), total_charge_ma: u32::from(Transit_U26::from_be_bytes(total_charge_ma)?),
total_discharge_ma: u32::from_be_bytes(total_discharge_ma), total_discharge_ma: u32::from(Transit_U26::from_be_bytes(total_discharge_ma)?),
max_charge_mw: u32::from_be_bytes(max_charge_mw), max_charge_mw: u32::from(Transit_U26::from_be_bytes(max_charge_mw)?),
max_discharge_mw: u32::from_be_bytes(max_discharge_mw), max_discharge_mw: u32::from(Transit_U26::from_be_bytes(max_discharge_mw)?),
avg_voltage_mv: u32::from_be_bytes(avg_voltage_mv), avg_voltage_mv: u32::from(Transit_U26::from_be_bytes(avg_voltage_mv)?),
}) })
} }
} }