split rtc module out to reduce repreated exactly same code

This commit is contained in:
2025-06-24 20:59:12 +02:00
parent e57e87af3f
commit 5fb8705d9a
12 changed files with 318 additions and 416 deletions

View File

@@ -1,9 +1,11 @@
pub(crate) mod battery;
mod esp;
mod initial_hal;
mod rtc;
mod v3_hal;
mod v4_hal;
use crate::hal::rtc::{DS3231Module, RTCModuleInteraction};
use crate::{
config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig},
hal::{
@@ -15,7 +17,8 @@ use crate::{
use anyhow::{Ok, Result};
use battery::BQ34Z100G1;
use bq34z100::Bq34z100g1Driver;
use chrono::{DateTime, Utc};
use ds323x::{DateTimeAccess, Ds323x};
use eeprom24x::{Eeprom24x, SlaveAddr};
use embedded_hal_bus::i2c::MutexDevice;
use esp_idf_hal::{
adc::ADC1,
@@ -39,7 +42,6 @@ use esp_idf_sys::{
use esp_ota::mark_app_valid;
use measurements::{Current, Voltage};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::result::Result::Ok as OkStd;
use std::sync::Mutex;
use std::time::Duration;
@@ -52,8 +54,6 @@ const TANK_MULTI_SAMPLE: usize = 11;
pub static I2C_DRIVER: Lazy<Mutex<I2cDriver<'static>>> = Lazy::new(PlantHal::create_i2c);
const X25: crc::Crc<u16> = crc::Crc::<u16>::new(&crc::CRC_16_IBM_SDLC);
fn deep_sleep(duration_in_ms: u64) -> ! {
unsafe {
//if we don't do this here, we might just revert newly flashed firmware
@@ -84,22 +84,14 @@ pub struct HAL<'a> {
pub board_hal: Box<dyn BoardInteraction<'a> + Send>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Default)]
pub struct BackupHeader {
pub timestamp: i64,
crc16: u16,
pub size: usize,
}
pub trait BoardInteraction<'a> {
fn get_esp(&mut self) -> &mut Esp<'a>;
fn get_config(&mut self) -> &PlantControllerConfig;
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>;
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send>;
fn set_charge_indicator(&mut self, charging: bool) -> Result<()>;
fn deep_sleep(&mut self, duration_in_ms: u64) -> !;
fn get_backup_info(&mut self) -> Result<BackupHeader>;
fn get_backup_config(&mut self) -> Result<Vec<u8>>;
fn backup_config(&mut self, bytes: &[u8]) -> Result<()>;
fn is_day(&self) -> bool;
//should be multsampled
fn water_temperature_c(&mut self) -> Result<f32>;
@@ -110,9 +102,7 @@ pub trait BoardInteraction<'a> {
fn fault(&mut self, plant: usize, enable: bool) -> Result<()>;
fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> Result<f32>;
fn general_fault(&mut self, enable: bool);
fn factory_reset(&mut self) -> Result<()>;
fn get_rtc_time(&mut self) -> Result<DateTime<Utc>>;
fn set_rtc_time(&mut self, time: &DateTime<Utc>) -> Result<()>;
fn test_pump(&mut self, plant: usize) -> Result<()>;
fn test(&mut self) -> Result<()>;
fn set_config(&mut self, config: PlantControllerConfig) -> Result<()>;
@@ -120,6 +110,18 @@ pub trait BoardInteraction<'a> {
fn get_mptt_current(&mut self) -> anyhow::Result<Current>;
}
impl dyn BoardInteraction<'_> {
//the counter is just some arbitrary number that increases whenever some progress was made, try to keep the updates < 10 per second for ux reasons
fn progress(&mut self, counter: u32) {
let even = counter % 2 == 0;
let current = counter / (PLANT_COUNT as u32);
for led in 0..PLANT_COUNT {
self.fault(led, current == led as u32).unwrap();
}
let _ = self.general_fault(even.into());
}
}
#[allow(dead_code)]
pub struct FreePeripherals {
pub gpio0: Gpio0,
@@ -259,6 +261,37 @@ impl PlantHal {
let config = esp.load_config();
println!("Init rtc driver");
let mut rtc = Ds323x::new_ds3231(MutexDevice::new(&I2C_DRIVER));
println!("Init rtc eeprom driver");
let mut eeprom = {
Eeprom24x::new_24x32(
MutexDevice::new(&I2C_DRIVER),
SlaveAddr::Alternative(true, true, true),
)
};
let rtc_time = rtc.datetime();
match rtc_time {
OkStd(tt) => {
println!("Rtc Module reports time at UTC {}", tt);
}
Err(err) => {
println!("Rtc Module could not be read {:?}", err);
}
}
match eeprom.read_byte(0) {
OkStd(byte) => {
println!("Read first byte with status {}", byte);
}
Err(err) => {
println!("Eeprom could not read first byte {:?}", err);
}
}
let rtc_module: Box<dyn RTCModuleInteraction + Send> =
Box::new(DS3231Module { rtc, eeprom }) as Box<dyn RTCModuleInteraction + Send>;
let hal = match config {
Result::Ok(config) => {
let battery_interaction: Box<dyn BatteryInteraction + Send> =
@@ -296,10 +329,10 @@ impl PlantHal {
initial_hal::create_initial_board(free_pins, fs_mount_error, config, esp)?
}
BoardVersion::V3 => {
v3_hal::create_v3(free_pins, esp, config, battery_interaction)?
v3_hal::create_v3(free_pins, esp, config, battery_interaction, rtc_module)?
}
BoardVersion::V4 => {
v4_hal::create_v4(free_pins, esp, config, battery_interaction)?
v4_hal::create_v4(free_pins, esp, config, battery_interaction, rtc_module)?
}
};