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 thiserror::Error;
use crate::types::Transit_U26;
pub const BMS_I2C_ADDRESS: u8 = 0x55;
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)]
pub struct BmsSoftwareReset;
@@ -73,7 +81,8 @@ impl BmsReadable for ProtocolVersion {
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),
],
)?;
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 {
capacity_mah: u32::from_be_bytes(capacity_mah),
v_full_mv: u32::from_be_bytes(v_full_mv),
v_empty_mv: u32::from_be_bytes(v_empty_mv),
capacity_mah: u32::from(Transit_U26::from_be_bytes(capacity_mah)?),
v_full_mv: u32::from(Transit_U26::from_be_bytes(v_full_mv)?),
v_empty_mv: u32::from(Transit_U26::from_be_bytes(v_empty_mv)?),
})
}
}
@@ -167,11 +177,11 @@ impl BmsReadable for BatteryState {
],
)?;
Ok(BatteryState {
lifetime_capacity_mah: u32::from_be_bytes(lifetime_capacity_mah),
remaining_capacity_mah: u32::from_be_bytes(remaining_capacity_mah),
current_mv: u32::from_be_bytes(current_mv),
lifetime_capacity_mah: u32::from(Transit_U26::from_be_bytes(lifetime_capacity_mah)?),
remaining_capacity_mah: u32::from(Transit_U26::from_be_bytes(remaining_capacity_mah)?),
current_mv: u32::from(Transit_U26::from_be_bytes(current_mv)?),
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),
],
)?;
Ok(ChargeInfoWindowSec(u32::from_be_bytes(
Ok(ChargeInfoWindowSec(u32::from(Transit_U26::from_be_bytes(
charge_info_window_sec,
)))
)?)))
}
}
@@ -206,11 +216,12 @@ impl BmsWriteable for ChargeInfoWindowSec {
I: I2c<SevenBitAddress>,
{
let cmd = BmsRegisterMap::ChargoInfoWindowTotalSecs;
let transit = Transit_U26::try_from(self.0)?;
i2c_dev.transaction(
BMS_I2C_ADDRESS,
&mut [
Operation::Write(&(cmd as u32).to_be_bytes()),
Operation::Write(&self.0.to_be_bytes()),
Operation::Write(&transit.to_be_bytes()),
],
)?;
Ok(())
@@ -250,11 +261,11 @@ impl BmsReadable for ChargeInfo {
],
)?;
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),
total_charge_ma: u32::from(Transit_U26::from_be_bytes(total_charge_ma)?),
total_discharge_ma: u32::from(Transit_U26::from_be_bytes(total_discharge_ma)?),
max_charge_mw: u32::from(Transit_U26::from_be_bytes(max_charge_mw)?),
max_discharge_mw: u32::from(Transit_U26::from_be_bytes(max_discharge_mw)?),
avg_voltage_mv: u32::from(Transit_U26::from_be_bytes(avg_voltage_mv)?),
})
}
}