inital structure for bms communication protocol implemented
This commit is contained in:
Generated
+3
@@ -535,6 +535,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "lib-bms-protocol"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"embedded-hal 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
|
||||
@@ -4,6 +4,7 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
embedded-hal = "1.0.0"
|
||||
|
||||
|
||||
[profile.dev]
|
||||
|
||||
+169
-8
@@ -1,29 +1,190 @@
|
||||
#![no_std]
|
||||
|
||||
use embedded_hal::i2c::{I2c, Operation, SevenBitAddress};
|
||||
|
||||
pub const BMS_I2C_ADDRESS: u8 = 0x55;
|
||||
|
||||
pub trait BmsReadable {
|
||||
fn read_from_i2c<I>(i2c_dev: &mut I) -> Result<Self, BmsProtocolError>
|
||||
where
|
||||
Self: Sized,
|
||||
I: I2c<SevenBitAddress>;
|
||||
}
|
||||
|
||||
pub trait BmsWriteable {
|
||||
fn write_to_device<I>(&self, i2c_dev: &mut I) -> Result<(), BmsProtocolError>
|
||||
where
|
||||
I: I2c<SevenBitAddress>;
|
||||
}
|
||||
|
||||
pub enum BmsProtocolError {
|
||||
I2cCommunicationError,
|
||||
}
|
||||
|
||||
impl<E> From<E> for BmsProtocolError
|
||||
where
|
||||
E: embedded_hal::i2c::Error,
|
||||
{
|
||||
fn from(_value: E) -> Self {
|
||||
Self::I2cCommunicationError
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BmsSoftwareReset;
|
||||
|
||||
impl BmsWriteable for BmsSoftwareReset {
|
||||
fn write_to_device<I>(&self, i2c_dev: &mut I) -> Result<(), BmsProtocolError>
|
||||
where
|
||||
I: I2c<SevenBitAddress>,
|
||||
{
|
||||
i2c_dev.write(
|
||||
BMS_I2C_ADDRESS,
|
||||
&(BmsRegisterMap::Reset as u32).to_be_bytes(),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct Version(u32);
|
||||
pub struct ProtocolVersion(u32);
|
||||
|
||||
impl BmsReadable for ProtocolVersion {
|
||||
fn read_from_i2c<I>(i2c_dev: &mut I) -> Result<Self, BmsProtocolError>
|
||||
where
|
||||
Self: Sized,
|
||||
I: I2c<SevenBitAddress>,
|
||||
{
|
||||
let cmd = BmsRegisterMap::ProtocolVersion;
|
||||
let mut version: [u8; 4] = [0x00; 4];
|
||||
i2c_dev.transaction(
|
||||
BMS_I2C_ADDRESS,
|
||||
&mut [
|
||||
Operation::Write(&(cmd as u32).to_be_bytes()),
|
||||
Operation::Read(&mut version),
|
||||
],
|
||||
)?;
|
||||
Ok(ProtocolVersion(u32::from_be_bytes(version)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct FirmwareVersion(u32);
|
||||
|
||||
impl BmsReadable for FirmwareVersion {
|
||||
fn read_from_i2c<I>(i2c_dev: &mut I) -> Result<Self, BmsProtocolError>
|
||||
where
|
||||
Self: Sized,
|
||||
I: I2c<SevenBitAddress>,
|
||||
{
|
||||
let cmd = BmsRegisterMap::FirmwareVersion;
|
||||
let mut version: [u8; 4] = [0x00; 4];
|
||||
i2c_dev.transaction(
|
||||
BMS_I2C_ADDRESS,
|
||||
&mut [
|
||||
Operation::Write(&(cmd as u32).to_be_bytes()),
|
||||
Operation::Read(&mut version),
|
||||
],
|
||||
)?;
|
||||
Ok(FirmwareVersion(u32::from_be_bytes(version)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
pub capacity_mah: u32,
|
||||
pub v_full_mv: u32,
|
||||
pub v_full_mv: u32,
|
||||
pub v_empty_mv: u32,
|
||||
}
|
||||
|
||||
impl BmsReadable for Config {
|
||||
fn read_from_i2c<I>(i2c_dev: &mut I) -> Result<Self, BmsProtocolError>
|
||||
where
|
||||
Self: Sized,
|
||||
I: I2c<SevenBitAddress>,
|
||||
{
|
||||
let cmd = BmsRegisterMap::ConfigCapacityMilliAmpereHours;
|
||||
let mut capacity_mah: [u8; 4] = [0x00; 4];
|
||||
let mut v_full_mv: [u8; 4] = [0x00; 4];
|
||||
let mut v_empty_mv: [u8; 4] = [0x00; 4];
|
||||
i2c_dev.transaction(
|
||||
BMS_I2C_ADDRESS,
|
||||
&mut [
|
||||
Operation::Write(&(cmd as u32).to_be_bytes()),
|
||||
Operation::Read(&mut capacity_mah),
|
||||
Operation::Read(&mut v_full_mv),
|
||||
Operation::Read(&mut v_empty_mv),
|
||||
],
|
||||
)?;
|
||||
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),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct BatteryState {
|
||||
pub lifetime_capacity_mah: u32,
|
||||
pub remaining_capacity_mah: u32,
|
||||
pub current_mv: u16,
|
||||
pub current_mv: u32,
|
||||
pub temperature_celcius: i32,
|
||||
pub health_percent: u8
|
||||
pub health_percent: u32,
|
||||
}
|
||||
|
||||
pub enum BmsCommand {
|
||||
GetVersion,
|
||||
GetConfig,
|
||||
GetBatteryState,
|
||||
impl BmsReadable for BatteryState {
|
||||
fn read_from_i2c<I>(i2c_dev: &mut I) -> Result<Self, BmsProtocolError>
|
||||
where
|
||||
Self: Sized,
|
||||
I: I2c<SevenBitAddress>,
|
||||
{
|
||||
let cmd = BmsRegisterMap::BatteryLifetimeCapacityMilliAmpereHours;
|
||||
let mut lifetime_capacity_mah: [u8; 4] = [0x00; 4];
|
||||
let mut remaining_capacity_mah: [u8; 4] = [0x00; 4];
|
||||
let mut current_mv: [u8; 4] = [0x00; 4];
|
||||
let mut temperature_celcius: [u8; 4] = [0x00; 4];
|
||||
let mut health_percent: [u8; 4] = [0x00; 4];
|
||||
i2c_dev.transaction(
|
||||
BMS_I2C_ADDRESS,
|
||||
&mut [
|
||||
Operation::Write(&(cmd as u32).to_be_bytes()),
|
||||
Operation::Read(&mut lifetime_capacity_mah),
|
||||
Operation::Read(&mut remaining_capacity_mah),
|
||||
Operation::Read(&mut current_mv),
|
||||
Operation::Read(&mut temperature_celcius),
|
||||
Operation::Read(&mut health_percent),
|
||||
],
|
||||
)?;
|
||||
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),
|
||||
temperature_celcius: i32::from_be_bytes(temperature_celcius),
|
||||
health_percent: u32::from_be_bytes(health_percent),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[non_exhaustive]
|
||||
pub enum BmsRegisterMap {
|
||||
// software reset register
|
||||
Reset = 0x00000000,
|
||||
// bms protocol revesion as u32 value
|
||||
ProtocolVersion = 0x00000001,
|
||||
// bms firmware revesion as u32 value
|
||||
FirmwareVersion = 0x00000002,
|
||||
// Configuration Values Start Here
|
||||
ConfigCapacityMilliAmpereHours = 0x00010000,
|
||||
ConfigFullMilliVolt = 0x00010004,
|
||||
ConfigEmptyMilliVolt = 0x00010008,
|
||||
// Battery State Values Start Here
|
||||
BatteryLifetimeCapacityMilliAmpereHours = 0x00020000,
|
||||
BatteryRemainingCapacityMilliAmpereHours = 0x00020004,
|
||||
BatteryCurrentVoltageMilliVolt = 0x00020008,
|
||||
BatteryTemperatureCelcius = 0x0002000c,
|
||||
BatteryHealthPercent = 0x00020010,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user