starting with library and measurment implementation
This commit is contained in:
Generated
+34
@@ -46,14 +46,18 @@ dependencies = [
|
|||||||
"ch32-metapac 0.0.6",
|
"ch32-metapac 0.0.6",
|
||||||
"embassy-executor",
|
"embassy-executor",
|
||||||
"embassy-futures",
|
"embassy-futures",
|
||||||
|
"embassy-sync 0.7.2",
|
||||||
"embassy-time 0.4.0",
|
"embassy-time 0.4.0",
|
||||||
"embassy-usb",
|
"embassy-usb",
|
||||||
"embedded-hal 1.0.0",
|
"embedded-hal 1.0.0",
|
||||||
"heapless",
|
"heapless",
|
||||||
|
"ina219",
|
||||||
|
"lib-bms-protocol",
|
||||||
"micromath",
|
"micromath",
|
||||||
"panic-halt",
|
"panic-halt",
|
||||||
"qingke",
|
"qingke",
|
||||||
"qingke-rt",
|
"qingke-rt",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -518,6 +522,16 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ina219"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "457a68120d2d0f0ca1b5c7f8e0ff3f77db9e34b1076a4e82f7097cbde7d2aaa4"
|
||||||
|
dependencies = [
|
||||||
|
"embedded-hal 1.0.0",
|
||||||
|
"embedded-hal-async",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lib-bms-protocol"
|
name = "lib-bms-protocol"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -804,6 +818,26 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ embassy-executor = { version = "0.7.0", features = [
|
|||||||
embassy-time = { version = "0.4.0" }
|
embassy-time = { version = "0.4.0" }
|
||||||
embassy-usb = { version = "0.3.0" }
|
embassy-usb = { version = "0.3.0" }
|
||||||
embassy-futures = { version = "0.1.0" }
|
embassy-futures = { version = "0.1.0" }
|
||||||
|
embassy-sync = { version = "0.7.2" }
|
||||||
|
|
||||||
# This is okay because we should automatically use whatever ch32-hal uses
|
# This is okay because we should automatically use whatever ch32-hal uses
|
||||||
qingke-rt = "*"
|
qingke-rt = "*"
|
||||||
@@ -32,6 +33,9 @@ embedded-hal = "1.0.0"
|
|||||||
heapless = "0.8.0"
|
heapless = "0.8.0"
|
||||||
micromath = { version = "2.1.0", features = ["num-traits"] }
|
micromath = { version = "2.1.0", features = ["num-traits"] }
|
||||||
ch32-metapac = { version = "0.0.6", features = ["ch32v203c8t6"] }
|
ch32-metapac = { version = "0.0.6", features = ["ch32v203c8t6"] }
|
||||||
|
ina219 = "0.2.0"
|
||||||
|
lib-bms-protocol = { path = "../lib-bms-protocol" }
|
||||||
|
thiserror = { version = "2.0.17", default-features = false }
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
#lto = true
|
#lto = true
|
||||||
|
|||||||
+22
-2
@@ -3,20 +3,40 @@
|
|||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(impl_trait_in_assoc_type)]
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
|
|
||||||
|
mod measurement;
|
||||||
|
|
||||||
|
use ch32_hal::i2c::mode::OperatingMode;
|
||||||
|
use ch32_hal::mode::Mode;
|
||||||
use ch32_hal::println;
|
use ch32_hal::println;
|
||||||
use ch32_hal::time::Hertz;
|
use ch32_hal::time::Hertz;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};
|
||||||
|
use embassy_sync::lazy_lock::LazyLock;
|
||||||
|
use embassy_sync::mutex::Mutex;
|
||||||
|
use embassy_sync::rwlock::RwLock;
|
||||||
//use embassy_time::{Duration, Timer};
|
//use embassy_time::{Duration, Timer};
|
||||||
use hal::bind_interrupts;
|
use hal::bind_interrupts;
|
||||||
use hal::i2c::{Config, I2c, SlaveAddress, SlaveConfig};
|
use hal::i2c::{Config, I2c, SlaveAddress, SlaveConfig};
|
||||||
use {ch32_hal as hal, panic_halt as _};
|
use {ch32_hal as hal, panic_halt as _};
|
||||||
|
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
I2C1_EV => ch32_hal::i2c::EventInterruptHandler<ch32_hal::peripherals::I2C1>;
|
I2C1_EV => ch32_hal::i2c::EventInterruptHandler<ch32_hal::peripherals::I2C1>;
|
||||||
I2C1_ER => ch32_hal::i2c::ErrorInterruptHandler<ch32_hal::peripherals::I2C1>;
|
I2C1_ER => ch32_hal::i2c::ErrorInterruptHandler<ch32_hal::peripherals::I2C1>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const MEASUREMENT_SAMPLES_CAPACITY: usize = 1024;
|
||||||
|
static MEASUREMENTS: LazyLock<
|
||||||
|
embassy_sync::mutex::Mutex<
|
||||||
|
CriticalSectionRawMutex,
|
||||||
|
heapless::Deque<lib_bms_protocol::BatteryState, MEASUREMENT_SAMPLES_CAPACITY>,
|
||||||
|
>,
|
||||||
|
> = LazyLock::new(|| Mutex::new(heapless::Deque::new()));
|
||||||
|
|
||||||
|
async fn measurement_task<'m, M: Mode, O: OperatingMode>(
|
||||||
|
i2c_dev: I2c<'m, ch32_hal::peripherals::I2C2, M, O>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
#[embassy_executor::main(entry = "qingke_rt::entry")]
|
#[embassy_executor::main(entry = "qingke_rt::entry")]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
let p = hal::init(Default::default());
|
let p = hal::init(Default::default());
|
||||||
@@ -44,7 +64,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
println!("received byte 0x{buf:x?}");
|
println!("received byte 0x{buf:x?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("{:?}", err)
|
println!("{:?}", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
use embassy_usb::msos::ConfigurationSubsetHeader;
|
||||||
|
use lib_bms_protocol::BatteryState;
|
||||||
|
|
||||||
|
use ina219::{address::Address, calibration::{IntCalibration, MicroAmpere, MicroWatt, UnCalibrated}, configuration::Configuration, errors::{ConfigurationReadError, InitializationError}, measurements::{CurrentRegister, Measurements, PowerRegister}, SyncIna219};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
pub(crate) const INA219_DEVICE_ADDR: u8 = 0b100_1011;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub(crate) enum MeasurementError {
|
||||||
|
#[error("ina219 sensor initialization failed")]
|
||||||
|
Ina219InitError,
|
||||||
|
#[error("ina219 configuration read error")]
|
||||||
|
Ina219ConfigReadErr,
|
||||||
|
#[error("ina219 measurement read error")]
|
||||||
|
Ina219MeasurementReadError,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<IE> From<ina219::errors::MeasurementError<IE>> for MeasurementError {
|
||||||
|
fn from(value: ina219::errors::MeasurementError<IE>) -> Self {
|
||||||
|
MeasurementError::Ina219MeasurementReadError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<IE> From<ConfigurationReadError<IE>> for MeasurementError {
|
||||||
|
fn from(value: ConfigurationReadError<IE>) -> Self {
|
||||||
|
MeasurementError::Ina219InitError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, IE> From<InitializationError<I, IE>> for MeasurementError {
|
||||||
|
fn from(value: InitializationError<I, IE>) -> Self {
|
||||||
|
MeasurementError::Ina219InitError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn read_ina219<T: embedded_hal::i2c::I2c>(i2c_dev: &mut T) -> Result<Option<BatteryState>, MeasurementError> {
|
||||||
|
let mut dev: SyncIna219<&mut T, _> = SyncIna219::new_calibrated(i2c_dev, Address::from_byte(INA219_DEVICE_ADDR).unwrap(), IntCalibration::default())?;
|
||||||
|
let config: Configuration = dev.configuration()?;
|
||||||
|
|
||||||
|
if let Some(ina_measurement) = dev.next_measurement()? {
|
||||||
|
let ina_measurement: Measurements<MicroAmpere, MicroWatt> = ina_measurement;
|
||||||
|
}
|
||||||
|
let measurement = todo!();
|
||||||
|
Ok(measurement)
|
||||||
|
}
|
||||||
@@ -2,22 +2,24 @@
|
|||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct Version(u32);
|
pub struct Version(u32);
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
capacity_mah: u32,
|
pub capacity_mah: u32,
|
||||||
v_full_mv: u32,
|
pub v_full_mv: u32,
|
||||||
v_empty_mv: u32,
|
pub v_empty_mv: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct BatteryState {
|
pub struct BatteryState {
|
||||||
lifetime_capacity_mAh: u32,
|
pub lifetime_capacity_mah: u32,
|
||||||
remaining_capacity_mAh: u32,
|
pub remaining_capacity_mah: u32,
|
||||||
current_milli_volts: u16,
|
pub current_mv: u16,
|
||||||
temperature_celcius: i32,
|
pub temperature_celcius: i32,
|
||||||
health_percent: u8
|
pub health_percent: u8
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BmsCommand {
|
pub enum BmsCommand {
|
||||||
|
|||||||
Reference in New Issue
Block a user