diff --git a/src/config.rs b/src/config.rs index 7ed198e..42f77fd 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,18 +1,40 @@ -use serde::{Serialize, Deserialize}; use postcard::{from_bytes, to_slice}; +use serde::{Serialize, Deserialize}; +use stm32f4xx_hal::i2c; use uom::si::{ electric_potential::volt, electric_current::ampere, electrical_resistance::ohm, + f64::{ElectricCurrent, ElectricPotential, ElectricalResistance, ThermodynamicTemperature}, thermodynamic_temperature::degree_celsius, }; use crate::{ channels::{CHANNELS, Channels}, command_parser::CenterPoint, + EEPROM_SIZE, EEPROM_PAGE_SIZE, pid, + pins, steinhart_hart, }; +#[derive(Debug)] +pub enum Error { + Eeprom(eeprom24x::Error), + Encode(postcard::Error), +} + +impl From> for Error { + fn from(e: eeprom24x::Error) -> Self { + Error::Eeprom(e) + } +} + +impl From for Error { + fn from(e: postcard::Error) -> Self { + Error::Encode(e) + } +} + /// Just for encoding/decoding, actual state resides in ChannelState #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct Config { @@ -60,6 +82,14 @@ impl ChannelConfig { } } + pub fn apply(&self, channels: &mut Channels, channel: usize) { + let state = channels.channel_state(channel); + state.center = self.center.clone(); + state.pid.parameters = self.pid.clone(); + state.pid.target = self.pid_target.into(); + state.sh = (&self.sh).into(); + self.pwm.apply(channels, channel); + } } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -79,6 +109,16 @@ impl From<&steinhart_hart::Parameters> for SteinhartHartConfig { } } +impl Into for &SteinhartHartConfig { + fn into(self) -> steinhart_hart::Parameters { + steinhart_hart::Parameters { + t0: ThermodynamicTemperature::new::(self.t0.into()), + r0: ElectricalResistance::new::(self.r0.into()), + b: self.b.into(), + } + } +} + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] struct PwmLimits { max_v: f32, @@ -97,6 +137,12 @@ impl PwmLimits { max_i_neg: max_i_neg.get::() as f32, } } + + pub fn apply(&self, channels: &mut Channels, channel: usize) { + channels.set_max_v(channel, ElectricPotential::new::(self.max_v.into())); + channels.set_max_i_pos(channel, ElectricCurrent::new::(self.max_i_pos.into())); + channels.set_max_i_neg(channel, ElectricCurrent::new::(self.max_i_neg.into())); + } } #[cfg(test)] @@ -123,7 +169,6 @@ mod test { ], }; - const EEPROM_SIZE: usize = 0x80; let mut buffer = [0; EEPROM_SIZE]; let buffer = config.encode(&mut buffer).unwrap(); assert!(buffer.len() <= EEPROM_SIZE); @@ -149,7 +194,6 @@ mod test { ], }; - const EEPROM_SIZE: usize = 0x80; let mut buffer = [0; EEPROM_SIZE]; config.encode(&mut buffer).unwrap(); let decoded = Config::decode(&buffer).unwrap(); diff --git a/src/main.rs b/src/main.rs index a9f78f4..20eee14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,6 +73,9 @@ const WATCHDOG_INTERVAL: u32 = 1_000; #[cfg(feature = "semihosting")] const WATCHDOG_INTERVAL: u32 = 30_000; +pub const EEPROM_PAGE_SIZE: usize = 8; +pub const EEPROM_SIZE: usize = 128; + const TCP_PORT: u16 = 23; @@ -429,16 +432,25 @@ fn main() -> ! { } } } - Command::Load => {} - Command::Save => { - let config = Config::new(&mut channels); - let mut buf = [0; 128]; - match config.encode(&mut buf) { - Ok(buf) => { - let _ = writeln!(socket, "Encoded {}: {:?}", buf.len(), buf); + Command::Load => { + match Config::load(&mut eeprom) { + Ok(config) => { + config.apply(&mut channels); + let _ = writeln!(socket, "Config loaded from EEPROM."); } Err(e) => { - let _ = writeln!(socket, "Error encoding configuration: {}", e); + let _ = writeln!(socket, "Error: {:?}", e); + } + } + } + Command::Save => { + let config = Config::new(&mut channels); + match config.save(&mut eeprom) { + Ok(()) => { + let _ = writeln!(socket, "Config saved to EEPROM."); + } + Err(e) => { + let _ = writeln!(socket, "Error saving config: {:?}", e); } } }