config: finalize load/save

pull/20/head
Astro 2020-09-24 23:04:29 +02:00
parent 3b050347d4
commit 8d70c03520
2 changed files with 67 additions and 11 deletions

View File

@ -1,18 +1,40 @@
use serde::{Serialize, Deserialize};
use postcard::{from_bytes, to_slice}; use postcard::{from_bytes, to_slice};
use serde::{Serialize, Deserialize};
use stm32f4xx_hal::i2c;
use uom::si::{ use uom::si::{
electric_potential::volt, electric_potential::volt,
electric_current::ampere, electric_current::ampere,
electrical_resistance::ohm, electrical_resistance::ohm,
f64::{ElectricCurrent, ElectricPotential, ElectricalResistance, ThermodynamicTemperature},
thermodynamic_temperature::degree_celsius, thermodynamic_temperature::degree_celsius,
}; };
use crate::{ use crate::{
channels::{CHANNELS, Channels}, channels::{CHANNELS, Channels},
command_parser::CenterPoint, command_parser::CenterPoint,
EEPROM_SIZE, EEPROM_PAGE_SIZE,
pid, pid,
pins,
steinhart_hart, steinhart_hart,
}; };
#[derive(Debug)]
pub enum Error {
Eeprom(eeprom24x::Error<i2c::Error>),
Encode(postcard::Error),
}
impl From<eeprom24x::Error<i2c::Error>> for Error {
fn from(e: eeprom24x::Error<i2c::Error>) -> Self {
Error::Eeprom(e)
}
}
impl From<postcard::Error> for Error {
fn from(e: postcard::Error) -> Self {
Error::Encode(e)
}
}
/// Just for encoding/decoding, actual state resides in ChannelState /// Just for encoding/decoding, actual state resides in ChannelState
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Config { 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)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -79,6 +109,16 @@ impl From<&steinhart_hart::Parameters> for SteinhartHartConfig {
} }
} }
impl Into<steinhart_hart::Parameters> for &SteinhartHartConfig {
fn into(self) -> steinhart_hart::Parameters {
steinhart_hart::Parameters {
t0: ThermodynamicTemperature::new::<degree_celsius>(self.t0.into()),
r0: ElectricalResistance::new::<ohm>(self.r0.into()),
b: self.b.into(),
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct PwmLimits { struct PwmLimits {
max_v: f32, max_v: f32,
@ -97,6 +137,12 @@ impl PwmLimits {
max_i_neg: max_i_neg.get::<ampere>() as f32, max_i_neg: max_i_neg.get::<ampere>() as f32,
} }
} }
pub fn apply(&self, channels: &mut Channels, channel: usize) {
channels.set_max_v(channel, ElectricPotential::new::<volt>(self.max_v.into()));
channels.set_max_i_pos(channel, ElectricCurrent::new::<ampere>(self.max_i_pos.into()));
channels.set_max_i_neg(channel, ElectricCurrent::new::<ampere>(self.max_i_neg.into()));
}
} }
#[cfg(test)] #[cfg(test)]
@ -123,7 +169,6 @@ mod test {
], ],
}; };
const EEPROM_SIZE: usize = 0x80;
let mut buffer = [0; EEPROM_SIZE]; let mut buffer = [0; EEPROM_SIZE];
let buffer = config.encode(&mut buffer).unwrap(); let buffer = config.encode(&mut buffer).unwrap();
assert!(buffer.len() <= EEPROM_SIZE); assert!(buffer.len() <= EEPROM_SIZE);
@ -149,7 +194,6 @@ mod test {
], ],
}; };
const EEPROM_SIZE: usize = 0x80;
let mut buffer = [0; EEPROM_SIZE]; let mut buffer = [0; EEPROM_SIZE];
config.encode(&mut buffer).unwrap(); config.encode(&mut buffer).unwrap();
let decoded = Config::decode(&buffer).unwrap(); let decoded = Config::decode(&buffer).unwrap();

View File

@ -73,6 +73,9 @@ const WATCHDOG_INTERVAL: u32 = 1_000;
#[cfg(feature = "semihosting")] #[cfg(feature = "semihosting")]
const WATCHDOG_INTERVAL: u32 = 30_000; const WATCHDOG_INTERVAL: u32 = 30_000;
pub const EEPROM_PAGE_SIZE: usize = 8;
pub const EEPROM_SIZE: usize = 128;
const TCP_PORT: u16 = 23; const TCP_PORT: u16 = 23;
@ -429,16 +432,25 @@ fn main() -> ! {
} }
} }
} }
Command::Load => {} Command::Load => {
Command::Save => { match Config::load(&mut eeprom) {
let config = Config::new(&mut channels); Ok(config) => {
let mut buf = [0; 128]; config.apply(&mut channels);
match config.encode(&mut buf) { let _ = writeln!(socket, "Config loaded from EEPROM.");
Ok(buf) => {
let _ = writeln!(socket, "Encoded {}: {:?}", buf.len(), buf);
} }
Err(e) => { 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);
} }
} }
} }