From f376e1b1c59e89e8f1872e2096fe5ade6034abe3 Mon Sep 17 00:00:00 2001 From: Empire Date: Wed, 23 Oct 2024 22:01:25 +0200 Subject: [PATCH] rtc com and reinit i2c --- rust/src/main.rs | 62 +++++++++---- rust/src/plant_hal.rs | 155 ++++++-------------------------- rust/src/webserver/webserver.rs | 10 ++- 3 files changed, 83 insertions(+), 144 deletions(-) diff --git a/rust/src/main.rs b/rust/src/main.rs index cee943e..093f9f5 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -1,14 +1,14 @@ -use std::{ - fmt::Display, - sync::{atomic::AtomicBool, Arc, Mutex}, -}; +use std:: + sync::{atomic::AtomicBool, Arc, Mutex} +; use anyhow::Result; +use bq34z100::{Bq34Z100Error, Bq34z100g1, Bq34z100g1Driver}; use chrono::{DateTime, Datelike, TimeDelta, Timelike, Utc}; use chrono_tz::{Europe::Berlin, Tz}; use config::Mode; -use esp_idf_hal::delay::Delay; +use esp_idf_hal::{delay::Delay, i2c::I2cError}; use esp_idf_sys::{ esp_deep_sleep, esp_ota_get_app_partition_count, esp_ota_get_running_partition, esp_ota_get_state_partition, esp_ota_img_states_t, esp_ota_img_states_t_ESP_OTA_IMG_ABORTED, @@ -491,7 +491,12 @@ fn safe_main() -> anyhow::Result<()> { config.night_lamp_hour_end, ); - let state_of_charge = board.state_charge_percent().unwrap_or(0); + let mut battery_driver = Bq34z100g1Driver { + i2c: &mut board.driver, + delay: Delay::new(0), + flash_block_data: [0; 32], + }; + let state_of_charge = battery_driver.state_of_charge().unwrap_or(0); if state_of_charge < 30 { board.set_low_voltage_in_cycle(); } else if state_of_charge > 50 { @@ -590,15 +595,24 @@ fn publish_battery_state( board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>, config: &Config, ) { - let bat = BatteryState { - voltage_milli_volt: &to_string(&board.voltage_milli_volt()), - current_milli_ampere: &to_string(&board.average_current_milli_ampere()), - cycle_count: &to_string(&board.cycle_count()), - design_milli_ampere: &to_string(&board.design_milli_ampere_hour()), - remaining_milli_ampere: &to_string(&board.remaining_milli_ampere_hour()), - state_of_charge: &to_string(&board.state_charge_percent()), - state_of_health: &to_string(&board.state_health_percent()), + let bat = { + + let mut battery_driver = Bq34z100g1Driver { + i2c: &mut board.driver, + delay: Delay::new(0), + flash_block_data: [0; 32], + }; + BatteryState { + voltage_milli_volt: &to_string_u16(&battery_driver.voltage()), + current_milli_ampere: &to_string_i16(&battery_driver.average_current()), + cycle_count: &to_string_u16(&battery_driver.cycle_count()), + design_milli_ampere: &to_string_u16(&battery_driver.design_capacity()), + remaining_milli_ampere: &to_string_u16(&battery_driver.remaining_capacity()), + state_of_charge: &to_string_u8(&battery_driver.state_of_charge()), + state_of_health: &to_string_u16(&battery_driver.state_of_health()), + } }; + match serde_json::to_string(&bat) { Ok(state) => { let _ = board.mqtt_publish(&config, "/battery", state.as_bytes()); @@ -1035,7 +1049,25 @@ fn sensor_to_string(value: &Option, error: &Option, enabled: bo }; } -fn to_string(value: &Result) -> String { +fn to_string_i16(value: &Result>) -> String { + return match value { + Ok(v) => v.to_string(), + Err(err) => { + format!("{:?}", err) + } + }; +} + +fn to_string_u16(value: &Result>) -> String { + return match value { + Ok(v) => v.to_string(), + Err(err) => { + format!("{:?}", err) + } + }; +} + +fn to_string_u8(value: &Result>) -> String { return match value { Ok(v) => v.to_string(), Err(err) => { diff --git a/rust/src/plant_hal.rs b/rust/src/plant_hal.rs index c15839f..2093f07 100644 --- a/rust/src/plant_hal.rs +++ b/rust/src/plant_hal.rs @@ -1,8 +1,7 @@ use bq34z100::{Bq34Z100Error, Bq34z100g1, Bq34z100g1Driver}; use chrono_tz::Europe::Berlin; -use ds323x::Ds323x; -use embedded_hal_bus::i2c::MutexDevice; +use ds323x::{Ds323x, DateTimeAccess}; use embedded_svc::wifi::{ AccessPointConfiguration, AccessPointInfo, AuthMethod, ClientConfiguration, Configuration, }; @@ -26,7 +25,6 @@ use anyhow::anyhow; use anyhow::{bail, Ok, Result}; use std::ffi::CString; use std::fs::File; -use std::ops::Deref; use std::path::Path; use chrono::{DateTime, Utc}; @@ -145,15 +143,6 @@ pub trait PlantCtrlBoardInteraction { fn mount_file_system(&mut self) -> Result<()>; fn file_system_size(&mut self) -> Result; - fn state_charge_percent(&mut self) -> Result; - fn remaining_milli_ampere_hour(&mut self) -> Result; - fn max_milli_ampere_hour(&mut self) -> Result; - fn design_milli_ampere_hour(&mut self) -> Result; - fn voltage_milli_volt(&mut self) -> Result; - fn average_current_milli_ampere(&mut self) -> Result; - fn cycle_count(&mut self) -> Result; - fn state_health_percent(&mut self) -> Result; - fn general_fault(&mut self, enable: bool); fn is_day(&self) -> bool; @@ -194,7 +183,6 @@ pub trait PlantCtrlBoardInteraction { fn mqtt_publish(&mut self, config: &Config, subtopic: &str, message: &[u8]) -> Result<()>; fn sensor_multiplexer(&mut self, n: u8) -> Result<()>; - fn flash_bq34_z100(&mut self, line: &str, dryrun: bool) -> Result<()>; } pub trait CreatePlantHal<'a> { @@ -222,8 +210,7 @@ pub struct PlantCtrlBoard<'a> { pub wifi_driver: EspWifi<'a>, one_wire_bus: OneWire>, mqtt_client: Option>, - battery_driver: Option>, Delay>>, - rtc: Option>>, ds323x::ic::DS3231>> + pub driver: I2cDriver<'a> } impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { @@ -894,86 +881,6 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { } } - fn state_charge_percent(&mut self) -> Result { - match &mut self.battery_driver { - Some(driver) => match driver.state_of_charge() { - OkStd(r) => Ok(r), - Err(err) => bail!("Error reading SoC {:?}", err), - }, - None => bail!("Error reading SoC bq34z100 not found"), - } - } - - fn remaining_milli_ampere_hour(&mut self) -> Result { - match &mut self.battery_driver { - Some(driver) => match driver.remaining_capacity() { - OkStd(r) => Ok(r), - Err(err) => bail!("Error reading Remaining Capacity {:?}", err), - }, - None => bail!("Error reading Remaining Capacity bq34z100 not found"), - } - } - - fn max_milli_ampere_hour(&mut self) -> Result { - match &mut self.battery_driver { - Some(driver) => match driver.full_charge_capacity() { - OkStd(r) => Ok(r), - Err(err) => bail!("Error reading Full Charge Capacity {:?}", err), - }, - None => bail!("Error reading Full Charge Capacity bq34z100 not found"), - } - } - - fn design_milli_ampere_hour(&mut self) -> Result { - match &mut self.battery_driver { - Some(driver) => match driver.design_capacity() { - OkStd(r) => Ok(r), - Err(err) => bail!("Error reading Design Capacity {:?}", err), - }, - None => bail!("Error reading Design Capacity bq34z100 not found"), - } - } - - fn voltage_milli_volt(&mut self) -> Result { - match &mut self.battery_driver { - Some(driver) => match driver.voltage() { - OkStd(r) => Ok(r), - Err(err) => bail!("Error reading voltage {:?}", err), - }, - None => bail!("Error reading voltage bq34z100 not found"), - } - } - - fn average_current_milli_ampere(&mut self) -> Result { - match &mut self.battery_driver { - Some(driver) => match driver.average_current() { - OkStd(r) => Ok(r), - Err(err) => bail!("Error reading Average Current {:?}", err), - }, - None => bail!("Error reading Average Current bq34z100 not found"), - } - } - - fn cycle_count(&mut self) -> Result { - match &mut self.battery_driver { - Some(driver) => match driver.cycle_count() { - OkStd(r) => Ok(r), - Err(err) => bail!("Error reading Cycle Count {:?}", err), - }, - None => bail!("Error reading Cycle Count bq34z100 not found"), - } - } - - fn state_health_percent(&mut self) -> Result { - match &mut self.battery_driver { - Some(driver) => match driver.state_of_health() { - OkStd(r) => Ok(r as u8), - Err(err) => bail!("Error reading State of Health {:?}", err), - }, - None => bail!("Error reading State of Health bq34z100 not found"), - } - } - fn sensor_multiplexer(&mut self, n: u8) -> Result<()> { assert!(n < 16); let is_bit_set = |b: u8| -> bool { n & (1 << b) != 0 }; @@ -1004,20 +911,10 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { } Ok(()) } - - fn flash_bq34_z100(&mut self, line: &str, dryrun: bool) -> Result<()> { - match &mut self.battery_driver { - Some(driver) => match driver.write_flash_stream_i2c(line, dryrun) { - OkStd(r) => Ok(r), - Err(err) => bail!("Error reading SoC {:?}", err), - }, - None => bail!("Error reading SoC bq34z100 not found"), - } - } } fn print_battery( - battery_driver: &mut Bq34z100g1Driver>, Delay>, + battery_driver: &mut Bq34z100g1Driver<&mut I2cDriver<'_>, Delay>, ) -> Result<(), Bq34Z100Error> { println!("Try communicating with battery"); let fwversion = battery_driver.fw_version().unwrap_or_else(|e| { @@ -1074,6 +971,7 @@ fn print_battery( return Result::Ok(()); } + impl CreatePlantHal<'_> for PlantHal { fn create() -> Result>> { let peripherals = Peripherals::take()?; @@ -1093,19 +991,6 @@ impl CreatePlantHal<'_> for PlantHal { esp!(unsafe { esp_idf_sys::i2c_get_timeout(i2c_port, &mut timeout) }).unwrap(); println!("init i2c timeout is {}", timeout); - let i2c_mutex = Arc::new(Mutex::new(driver)); - - let i2c_battery_device = MutexDevice::new(&i2c_mutex); - - let mut battery_driver: Bq34z100g1Driver, Delay> = Bq34z100g1Driver { - i2c: i2c_battery_device, - delay: Delay::new(0), - flash_block_data: [0; 32], - }; - - let i2c_rtc_device = MutexDevice::new(&i2c_mutex); - let rtc = Ds323x::new_ds3231(i2c_rtc_device); - let mut clock = PinDriver::input_output(peripherals.pins.gpio15.downgrade())?; clock.set_pull(Pull::Floating).unwrap(); let mut latch = PinDriver::input_output(peripherals.pins.gpio3.downgrade())?; @@ -1252,12 +1137,7 @@ impl CreatePlantHal<'_> for PlantHal { println!("After stuff"); - let status = print_battery(&mut battery_driver); - if status.is_err() { - println!("Error communicating with battery!! {:?}", status.err()); - } else { - println!("Managed to comunnicate with battery"); - } + let shift_register_enable_invert = PinDriver::output(peripherals.pins.gpio21.downgrade())?; @@ -1275,17 +1155,38 @@ impl CreatePlantHal<'_> for PlantHal { signal_counter: counter_unit1, wifi_driver, mqtt_client: None, - battery_driver: Some(battery_driver), - rtc: Some(rtc) + driver }); let _ = rv.lock().is_ok_and(|mut board| { + let mut battery_driver = Bq34z100g1Driver { + i2c: &mut board.driver, + delay: Delay::new(0), + flash_block_data: [0; 32], + }; + let status = print_battery(&mut battery_driver); + match status { + OkStd(_) => { + println!("Managed to comunnicate with battery"); + return true; + }, + Err(err) => { + println!("Error communicating with battery!! {:?}", err); + }, + } unsafe { gpio_hold_dis(board.shift_register_enable_invert.pin()) }; board.shift_register_enable_invert.set_low().unwrap(); unsafe { gpio_hold_en(board.shift_register_enable_invert.pin()) }; return true; }); + let _ = rv.lock().is_ok_and(|mut board| { + let mut rtc = Ds323x::new_ds3231(&mut board.driver); + let dt = rtc.datetime().unwrap(); + println!("Rtc Currently returned {}", dt); + return true; + }); + Ok(rv) } } diff --git a/rust/src/webserver/webserver.rs b/rust/src/webserver/webserver.rs index 835ea3d..e26e815 100644 --- a/rust/src/webserver/webserver.rs +++ b/rust/src/webserver/webserver.rs @@ -9,6 +9,7 @@ use std::{ use crate::{espota::OtaUpdate, BOARD_ACCESS}; use core::result::Result::Ok; +use bq34z100::{Bq34z100g1, Bq34z100g1Driver}; use embedded_svc::http::Method; use esp_idf_hal::delay::Delay; use esp_idf_svc::http::server::{Configuration, EspHttpServer}; @@ -326,6 +327,11 @@ pub fn shared() -> Box> { board.general_fault(toggle); toggle = !toggle; + let mut battery_driver = Bq34z100g1Driver { + i2c: &mut board.driver, + delay: Delay::new(0), + flash_block_data: [0; 32], + }; loop { let has_line = line_buffer.contains(&b'\n'); if !has_line { @@ -335,12 +341,12 @@ pub fn shared() -> Box> { line_buffer.read_line(&mut line)?; let line2 = &line[0..line.len()-1]; println!("Processing dry:{} line {}", is_dry_run, line2); - let validate = board.flash_bq34_z100(&line2, is_dry_run); + let validate = battery_driver.write_flash_stream_i2c(&line2, is_dry_run); delay.delay_us(2); if validate.is_err() { let mut response = request.into_status_response(400_u16).unwrap(); let err = validate.unwrap_err(); - let err_str = err.to_string(); + let err_str = format!("{:?}", err); let err_msg = err_str.as_bytes(); println!("Error writing {}", err_str); response