Compare commits

...

3 Commits

Author SHA1 Message Date
Astro d40a038c2f config: switch to postcard encoding 2020-09-24 02:06:53 +02:00
Astro 5d0d75d395 config: encode with serde_cbor 2020-09-24 01:18:33 +02:00
Astro 93f14523d7 command_parser: parse load/save 2020-09-24 01:17:50 +02:00
8 changed files with 160 additions and 4 deletions

62
Cargo.lock generated
View File

@ -173,6 +173,28 @@ dependencies = [
"typenum",
]
[[package]]
name = "hash32"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
dependencies = [
"byteorder",
]
[[package]]
name = "heapless"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74911a68a1658cfcfb61bc0ccfbd536e3b6e906f8c2f7883ee50157e3e2184f1"
dependencies = [
"as-slice",
"generic-array 0.13.2",
"hash32",
"serde",
"stable_deref_trait",
]
[[package]]
name = "libm"
version = "0.2.1"
@ -251,6 +273,23 @@ dependencies = [
"cortex-m-semihosting",
]
[[package]]
name = "postcard"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e3f5c2e9a91383c6594ec68aa2dfdfe19a3c86f34b088ba7203f2483d2682f"
dependencies = [
"heapless",
"postcard-cobs",
"serde",
]
[[package]]
name = "postcard-cobs"
version = "0.1.5-pre"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c68cb38ed13fd7bc9dd5db8f165b7c8d9c1a315104083a2b10f11354c2af97f"
[[package]]
name = "proc-macro2"
version = "1.0.20"
@ -305,6 +344,26 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "smoltcp"
version = "0.6.0"
@ -404,6 +463,8 @@ dependencies = [
"num-traits",
"panic-abort",
"panic-semihosting",
"postcard",
"serde",
"smoltcp",
"stm32-eth",
"stm32f4xx-hal",
@ -431,6 +492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bb593f5252356bfb829112f8fca2d0982d48588d2d6bb5a92553b0dfc4c9aba"
dependencies = [
"num-traits",
"serde",
"typenum",
]

View File

@ -31,8 +31,10 @@ num-traits = { version = "0.2", default-features = false, features = ["libm"] }
usb-device = "0.2"
usbd-serial = "0.1"
nb = "0.1"
uom = { version = "0.29", default-features = false, features = ["autoconvert", "si", "f64"] }
uom = { version = "0.29", default-features = false, features = ["autoconvert", "si", "f64", "use_serde"] }
eeprom24x = "0.3"
serde = { version = "1.0", default-features = false, features = ["derive"] }
postcard = "0.5.1"
[patch.crates-io]
stm32f4xx-hal = { git = "https://github.com/stm32-rs/stm32f4xx-hal.git" }

View File

@ -71,3 +71,5 @@ The scope of this setting is per TCP session.
| `s-h` | Show Steinhart-Hart equation parameters |
| `s-h <0/1> <t/b/r0> <value>` | Set Steinhart-Hart parameter for a channel |
| `postfilter <0/1> rate <rate>` | Set postfilter output data rate |
| `load` | Restore configuration from EEPROM |
| `save` | Save configuration to EEPROM |

View File

@ -12,6 +12,7 @@ use nom::{
error::ErrorKind,
};
use num_traits::{Num, ParseFloatError};
use serde::{Serialize, Deserialize};
#[derive(Clone, Debug, PartialEq)]
@ -122,7 +123,7 @@ pub enum PwmPin {
MaxV,
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum CenterPoint {
Vref,
Override(f64),
@ -131,6 +132,8 @@ pub enum CenterPoint {
#[derive(Debug, Clone, PartialEq)]
pub enum Command {
Quit,
Load,
Save,
Show(ShowCommand),
Reporting(bool),
/// PWM parameter setting
@ -405,6 +408,8 @@ fn postfilter(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
fn command(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
alt((value(Ok(Command::Quit), tag("quit")),
value(Ok(Command::Load), tag("load")),
value(Ok(Command::Save), tag("save")),
map(report, Ok),
pwm,
center_point,
@ -437,6 +442,18 @@ mod test {
assert_eq!(command, Ok(Command::Quit));
}
#[test]
fn parse_load() {
let command = Command::parse(b"load");
assert_eq!(command, Ok(Command::Load));
}
#[test]
fn parse_save() {
let command = Command::parse(b"save");
assert_eq!(command, Ok(Command::Save));
}
#[test]
fn parse_report() {
let command = Command::parse(b"report");

55
src/config.rs Normal file
View File

@ -0,0 +1,55 @@
use serde::{Serialize, Deserialize};
use postcard::to_slice;
use crate::{
channel_state::ChannelState,
channels::{CHANNELS, Channels},
command_parser::CenterPoint,
pid,
steinhart_hart,
};
/// Just for encoding/decoding, actual state resides in ChannelState
#[derive(Serialize, Deserialize)]
pub struct Config {
channels: [ChannelConfig; CHANNELS],
}
impl Config {
pub fn new(channels: &mut Channels) -> Self {
Config {
channels: [
ChannelConfig::new(channels.channel_state(0usize)),
ChannelConfig::new(channels.channel_state(1usize)),
],
}
}
pub fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], postcard::Error> {
to_slice(self, buffer)
}
pub fn decode(buffer: &[u8]) -> Result<Self, postcard::Error> {
from_bytes(buffer)
}
}
#[derive(Serialize, Deserialize)]
pub struct ChannelConfig {
center: CenterPoint,
pid: pid::Parameters,
pid_target: f64,
sh: steinhart_hart::Parameters,
// TODO: pwm limits
}
impl ChannelConfig {
pub fn new(state: &ChannelState) -> Self {
ChannelConfig {
center: state.center.clone(),
pid: state.pid.parameters.clone(),
pid_target: state.pid.target,
sh: state.sh.clone(),
}
}
}

View File

@ -63,6 +63,8 @@ mod channels;
use channels::{CHANNELS, Channels};
mod channel;
mod channel_state;
mod config;
use config::Config;
const HSE: MegaHertz = MegaHertz(8);
@ -427,6 +429,19 @@ 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);
}
Err(e) => {
let _ = writeln!(socket, "Error encoding configuration: {}", e);
}
}
}
}
Ok(SessionOutput::Error(e)) => {
let _ = writeln!(socket, "Command error: {:?}", e);

View File

@ -1,4 +1,6 @@
#[derive(Clone, Copy)]
use serde::{Serialize, Deserialize};
#[derive(Clone, Serialize, Deserialize)]
pub struct Parameters {
pub kp: f64,
pub ki: f64,

View File

@ -8,9 +8,10 @@ use uom::si::{
ratio::ratio,
thermodynamic_temperature::{degree_celsius, kelvin},
};
use serde::{Serialize, Deserialize};
/// Steinhart-Hart equation parameters
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Parameters {
/// Base temperature
pub t0: ThermodynamicTemperature,