Compare commits
4 Commits
master
...
shorter_ma
Author | SHA1 | Date |
---|---|---|
topquark12 | 2731df7813 | |
topquark12 | 677cdbdc12 | |
topquark12 | 31f7e7eead | |
topquark12 | 6473b27539 |
|
@ -0,0 +1,373 @@
|
||||||
|
use smoltcp::socket::TcpSocket;
|
||||||
|
use log::{error, warn};
|
||||||
|
use core::fmt::Write;
|
||||||
|
use super::{
|
||||||
|
net,
|
||||||
|
command_parser::{
|
||||||
|
Ipv4Config,
|
||||||
|
Command,
|
||||||
|
ShowCommand,
|
||||||
|
CenterPoint,
|
||||||
|
PidParameter,
|
||||||
|
PwmPin,
|
||||||
|
ShParameter
|
||||||
|
},
|
||||||
|
leds::Leds,
|
||||||
|
ad7172,
|
||||||
|
CHANNEL_CONFIG_KEY,
|
||||||
|
channels::{
|
||||||
|
Channels,
|
||||||
|
CHANNELS
|
||||||
|
},
|
||||||
|
config::ChannelConfig,
|
||||||
|
dfu,
|
||||||
|
flash_store::FlashStore,
|
||||||
|
session::Session
|
||||||
|
};
|
||||||
|
|
||||||
|
use uom::{
|
||||||
|
si::{
|
||||||
|
f64::{
|
||||||
|
ElectricCurrent,
|
||||||
|
ElectricPotential,
|
||||||
|
ElectricalResistance,
|
||||||
|
ThermodynamicTemperature,
|
||||||
|
},
|
||||||
|
electric_current::ampere,
|
||||||
|
electric_potential::volt,
|
||||||
|
electrical_resistance::ohm,
|
||||||
|
thermodynamic_temperature::degree_celsius,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum Handler {
|
||||||
|
Handled,
|
||||||
|
CloseSocket,
|
||||||
|
NewIPV4(Ipv4Config),
|
||||||
|
Reset,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum Error {
|
||||||
|
ReportError,
|
||||||
|
PostFilterRateError,
|
||||||
|
FlashError
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_line(socket: &mut TcpSocket, data: &[u8]) -> bool {
|
||||||
|
let send_free = socket.send_capacity() - socket.send_queue();
|
||||||
|
if data.len() > send_free + 1 {
|
||||||
|
// Not enough buffer space, skip report for now,
|
||||||
|
// instead of sending incomplete line
|
||||||
|
warn!(
|
||||||
|
"TCP socket has only {}/{} needed {}",
|
||||||
|
send_free + 1, socket.send_capacity(), data.len(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
match socket.send_slice(&data) {
|
||||||
|
Ok(sent) if sent == data.len() => {
|
||||||
|
let _ = socket.send_slice(b"\n");
|
||||||
|
// success
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
Ok(sent) =>
|
||||||
|
warn!("sent only {}/{} bytes", sent, data.len()),
|
||||||
|
Err(e) =>
|
||||||
|
error!("error sending line: {:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not success
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Handler {
|
||||||
|
|
||||||
|
fn reporting(socket: &mut TcpSocket) -> Result<Handler, Error> {
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_report_mode(socket: &mut TcpSocket, session: &Session) -> Result<Handler, Error> {
|
||||||
|
let _ = writeln!(socket, "{{ \"report\": {:?} }}", session.reporting());
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_report(socket: &mut TcpSocket, channels: &mut Channels) -> Result<Handler, Error> {
|
||||||
|
match channels.reports_json() {
|
||||||
|
Ok(buf) => {
|
||||||
|
send_line(socket, &buf[..]);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("unable to serialize report: {:?}", e);
|
||||||
|
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
||||||
|
return Err(Error::ReportError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_pid(socket: &mut TcpSocket, channels: &mut Channels) -> Result<Handler, Error> {
|
||||||
|
match channels.pid_summaries_json() {
|
||||||
|
Ok(buf) => {
|
||||||
|
send_line(socket, &buf);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("unable to serialize pid summary: {:?}", e);
|
||||||
|
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
||||||
|
return Err(Error::ReportError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_pwm(socket: &mut TcpSocket, channels: &mut Channels) -> Result<Handler, Error> {
|
||||||
|
match channels.pwm_summaries_json() {
|
||||||
|
Ok(buf) => {
|
||||||
|
send_line(socket, &buf);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("unable to serialize pwm summary: {:?}", e);
|
||||||
|
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
||||||
|
return Err(Error::ReportError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_steinhart_hart(socket: &mut TcpSocket, channels: &mut Channels) -> Result<Handler, Error> {
|
||||||
|
match channels.steinhart_hart_summaries_json() {
|
||||||
|
Ok(buf) => {
|
||||||
|
send_line(socket, &buf);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("unable to serialize steinhart-hart summaries: {:?}", e);
|
||||||
|
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
||||||
|
return Err(Error::ReportError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_post_filter (socket: &mut TcpSocket, channels: &mut Channels) -> Result<Handler, Error> {
|
||||||
|
match channels.postfilter_summaries_json() {
|
||||||
|
Ok(buf) => {
|
||||||
|
send_line(socket, &buf);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("unable to serialize postfilter summary: {:?}", e);
|
||||||
|
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
||||||
|
return Err(Error::ReportError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_ipv4 (socket: &mut TcpSocket, ipv4_config: &mut Ipv4Config) -> Result<Handler, Error> {
|
||||||
|
let (cidr, gateway) = net::split_ipv4_config(ipv4_config.clone());
|
||||||
|
let _ = write!(socket, "{{\"addr\":\"{}\"", cidr);
|
||||||
|
gateway.map(|gateway| write!(socket, ",\"gateway\":\"{}\"", gateway));
|
||||||
|
let _ = writeln!(socket, "}}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn engage_pid (socket: &mut TcpSocket, channels: &mut Channels, leds: &mut Leds, channel: usize) -> Result<Handler, Error> {
|
||||||
|
channels.channel_state(channel).pid_engaged = true;
|
||||||
|
leds.g3.on();
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_pwm (socket: &mut TcpSocket, channels: &mut Channels, leds: &mut Leds, channel: usize, pin: PwmPin, value: f64) -> Result<Handler, Error> {
|
||||||
|
match pin {
|
||||||
|
PwmPin::ISet => {
|
||||||
|
channels.channel_state(channel).pid_engaged = false;
|
||||||
|
leds.g3.off();
|
||||||
|
let current = ElectricCurrent::new::<ampere>(value);
|
||||||
|
channels.set_i(channel, current);
|
||||||
|
channels.power_up(channel);
|
||||||
|
}
|
||||||
|
PwmPin::MaxV => {
|
||||||
|
let voltage = ElectricPotential::new::<volt>(value);
|
||||||
|
channels.set_max_v(channel, voltage);
|
||||||
|
}
|
||||||
|
PwmPin::MaxIPos => {
|
||||||
|
let current = ElectricCurrent::new::<ampere>(value);
|
||||||
|
channels.set_max_i_pos(channel, current);
|
||||||
|
}
|
||||||
|
PwmPin::MaxINeg => {
|
||||||
|
let current = ElectricCurrent::new::<ampere>(value);
|
||||||
|
channels.set_max_i_neg(channel, current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_center_point(socket: &mut TcpSocket, channels: &mut Channels, channel: usize, center: CenterPoint) -> Result<Handler, Error> {
|
||||||
|
let i_tec = channels.get_i(channel);
|
||||||
|
let state = channels.channel_state(channel);
|
||||||
|
state.center = center;
|
||||||
|
if !state.pid_engaged {
|
||||||
|
channels.set_i(channel, i_tec);
|
||||||
|
}
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_pid (socket: &mut TcpSocket, channels: &mut Channels, channel: usize, parameter: PidParameter, value: f64) -> Result<Handler, Error> {
|
||||||
|
let pid = &mut channels.channel_state(channel).pid;
|
||||||
|
use super::command_parser::PidParameter::*;
|
||||||
|
match parameter {
|
||||||
|
Target =>
|
||||||
|
pid.target = value,
|
||||||
|
KP =>
|
||||||
|
pid.parameters.kp = value as f32,
|
||||||
|
KI =>
|
||||||
|
pid.update_ki(value as f32),
|
||||||
|
KD =>
|
||||||
|
pid.parameters.kd = value as f32,
|
||||||
|
OutputMin =>
|
||||||
|
pid.parameters.output_min = value as f32,
|
||||||
|
OutputMax =>
|
||||||
|
pid.parameters.output_max = value as f32,
|
||||||
|
IntegralMin =>
|
||||||
|
pid.parameters.integral_min = value as f32,
|
||||||
|
IntegralMax =>
|
||||||
|
pid.parameters.integral_max = value as f32,
|
||||||
|
}
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_steinhart_hart (socket: &mut TcpSocket, channels: &mut Channels, channel: usize, parameter: ShParameter, value: f64) -> Result<Handler, Error> {
|
||||||
|
let sh = &mut channels.channel_state(channel).sh;
|
||||||
|
use super::command_parser::ShParameter::*;
|
||||||
|
match parameter {
|
||||||
|
T0 => sh.t0 = ThermodynamicTemperature::new::<degree_celsius>(value),
|
||||||
|
B => sh.b = value,
|
||||||
|
R0 => sh.r0 = ElectricalResistance::new::<ohm>(value),
|
||||||
|
}
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset_post_filter (socket: &mut TcpSocket, channels: &mut Channels, channel: usize) -> Result<Handler, Error> {
|
||||||
|
channels.adc.set_postfilter(channel as u8, None).unwrap();
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_post_filter (socket: &mut TcpSocket, channels: &mut Channels, channel: usize, rate: f32) -> Result<Handler, Error> {
|
||||||
|
let filter = ad7172::PostFilter::closest(rate);
|
||||||
|
match filter {
|
||||||
|
Some(filter) => {
|
||||||
|
channels.adc.set_postfilter(channel as u8, Some(filter)).unwrap();
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
error!("unable to choose postfilter for rate {:.3}", rate);
|
||||||
|
send_line(socket, b"{{\"error\": \"unable to choose postfilter rate\"}}");
|
||||||
|
return Err(Error::PostFilterRateError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_channel (socket: &mut TcpSocket, channels: &mut Channels, store: &mut FlashStore, channel: Option<usize>) -> Result<Handler, Error> {
|
||||||
|
for c in 0..CHANNELS {
|
||||||
|
if channel.is_none() || channel == Some(c) {
|
||||||
|
match store.read_value::<ChannelConfig>(CHANNEL_CONFIG_KEY[c]) {
|
||||||
|
Ok(Some(config)) => {
|
||||||
|
config.apply(channels, c);
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
error!("flash config not found");
|
||||||
|
send_line(socket, b"{{\"error\": \"flash config not found\"}}");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("unable to load config from flash: {:?}", e);
|
||||||
|
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
||||||
|
return Err(Error::FlashError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_channel (socket: &mut TcpSocket, channels: &mut Channels, channel: Option<usize>, store: &mut FlashStore) -> Result<Handler, Error> {
|
||||||
|
for c in 0..CHANNELS {
|
||||||
|
let mut store_value_buf = [0u8; 256];
|
||||||
|
if channel.is_none() || channel == Some(c) {
|
||||||
|
let config = ChannelConfig::new(channels, c);
|
||||||
|
match store.write_value(CHANNEL_CONFIG_KEY[c], &config, &mut store_value_buf) {
|
||||||
|
Ok(()) => {
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("unable to save channel {} config to flash: {:?}", c, e);
|
||||||
|
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
||||||
|
return Err(Error::FlashError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_ipv4 (socket: &mut TcpSocket, store: &mut FlashStore, config: Ipv4Config) -> Result<Handler, Error> {
|
||||||
|
let _ = store
|
||||||
|
.write_value("ipv4", &config, [0; 16])
|
||||||
|
.map_err(|e| error!("unable to save ipv4 config to flash: {:?}", e));
|
||||||
|
let new_ipv4_config = Some(config);
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::NewIPV4(new_ipv4_config.unwrap()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset (channels: &mut Channels) -> Result<Handler, Error> {
|
||||||
|
for i in 0..CHANNELS {
|
||||||
|
channels.power_down(i);
|
||||||
|
}
|
||||||
|
// should_reset = true;
|
||||||
|
Ok(Handler::Reset)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dfu (channels: &mut Channels) -> Result<Handler, Error> {
|
||||||
|
for i in 0..CHANNELS {
|
||||||
|
channels.power_down(i);
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
dfu::set_dfu_trigger();
|
||||||
|
}
|
||||||
|
// should_reset = true;
|
||||||
|
Ok(Handler::Reset)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_command (command: Command, socket: &mut TcpSocket, channels: &mut Channels, session: &Session, leds: &mut Leds, store: &mut FlashStore, ipv4_config: &mut Ipv4Config) -> Result<Self, Error> {
|
||||||
|
match command {
|
||||||
|
Command::Quit => Ok(Handler::CloseSocket),
|
||||||
|
Command::Reporting(_reporting) => Handler::reporting(socket),
|
||||||
|
Command::Show(ShowCommand::Reporting) => Handler::show_report_mode(socket, session),
|
||||||
|
Command::Show(ShowCommand::Input) => Handler::show_report(socket, channels),
|
||||||
|
Command::Show(ShowCommand::Pid) => Handler::show_pid(socket, channels),
|
||||||
|
Command::Show(ShowCommand::Pwm) => Handler::show_pwm(socket, channels),
|
||||||
|
Command::Show(ShowCommand::SteinhartHart) => Handler::show_steinhart_hart(socket, channels),
|
||||||
|
Command::Show(ShowCommand::PostFilter) => Handler::show_post_filter(socket, channels),
|
||||||
|
Command::Show(ShowCommand::Ipv4) => Handler::show_ipv4(socket, ipv4_config),
|
||||||
|
Command::PwmPid { channel } => Handler::engage_pid(socket, channels, leds, channel),
|
||||||
|
Command::Pwm { channel, pin, value } => Handler::set_pwm(socket, channels, leds, channel, pin, value),
|
||||||
|
Command::CenterPoint { channel, center } => Handler::set_center_point(socket, channels, channel, center),
|
||||||
|
Command::Pid { channel, parameter, value } => Handler::set_pid(socket, channels, channel, parameter, value),
|
||||||
|
Command::SteinhartHart { channel, parameter, value } => Handler::set_steinhart_hart(socket, channels, channel, parameter, value),
|
||||||
|
Command::PostFilter { channel, rate: None } => Handler::reset_post_filter(socket, channels, channel),
|
||||||
|
Command::PostFilter { channel, rate: Some(rate) } => Handler::set_post_filter(socket, channels, channel, rate),
|
||||||
|
Command::Load { channel } => Handler::load_channel(socket, channels, store, channel),
|
||||||
|
Command::Save { channel } => Handler::save_channel(socket, channels, channel, store),
|
||||||
|
Command::Ipv4(config) => Handler::set_ipv4(socket, store, config),
|
||||||
|
Command::Reset => Handler::reset(channels),
|
||||||
|
Command::Dfu => Handler::dfu(channels)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
245
src/main.rs
245
src/main.rs
|
@ -11,7 +11,6 @@ use panic_semihosting as _;
|
||||||
|
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
|
|
||||||
use core::fmt::Write;
|
|
||||||
use cortex_m::asm::wfi;
|
use cortex_m::asm::wfi;
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use stm32f4xx_hal::{
|
use stm32f4xx_hal::{
|
||||||
|
@ -26,20 +25,6 @@ use smoltcp::{
|
||||||
socket::TcpSocket,
|
socket::TcpSocket,
|
||||||
wire::EthernetAddress,
|
wire::EthernetAddress,
|
||||||
};
|
};
|
||||||
use uom::{
|
|
||||||
si::{
|
|
||||||
f64::{
|
|
||||||
ElectricCurrent,
|
|
||||||
ElectricPotential,
|
|
||||||
ElectricalResistance,
|
|
||||||
ThermodynamicTemperature,
|
|
||||||
},
|
|
||||||
electric_current::ampere,
|
|
||||||
electric_potential::volt,
|
|
||||||
electrical_resistance::ohm,
|
|
||||||
thermodynamic_temperature::degree_celsius,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
mod init_log;
|
mod init_log;
|
||||||
use init_log::init_log;
|
use init_log::init_log;
|
||||||
|
@ -55,7 +40,7 @@ use server::Server;
|
||||||
mod session;
|
mod session;
|
||||||
use session::{Session, SessionInput};
|
use session::{Session, SessionInput};
|
||||||
mod command_parser;
|
mod command_parser;
|
||||||
use command_parser::{Command, Ipv4Config, PwmPin, ShowCommand};
|
use command_parser::Ipv4Config;
|
||||||
mod timer;
|
mod timer;
|
||||||
mod pid;
|
mod pid;
|
||||||
mod steinhart_hart;
|
mod steinhart_hart;
|
||||||
|
@ -67,6 +52,8 @@ mod config;
|
||||||
use config::ChannelConfig;
|
use config::ChannelConfig;
|
||||||
mod flash_store;
|
mod flash_store;
|
||||||
mod dfu;
|
mod dfu;
|
||||||
|
mod command_handler;
|
||||||
|
use command_handler::Handler;
|
||||||
|
|
||||||
const HSE: MegaHertz = MegaHertz(8);
|
const HSE: MegaHertz = MegaHertz(8);
|
||||||
#[cfg(not(feature = "semihosting"))]
|
#[cfg(not(feature = "semihosting"))]
|
||||||
|
@ -149,7 +136,7 @@ fn main() -> ! {
|
||||||
usb::State::setup(usb);
|
usb::State::setup(usb);
|
||||||
|
|
||||||
let mut store = flash_store::store(dp.FLASH);
|
let mut store = flash_store::store(dp.FLASH);
|
||||||
let mut store_value_buf = [0u8; 256];
|
|
||||||
|
|
||||||
let mut channels = Channels::new(pins);
|
let mut channels = Channels::new(pins);
|
||||||
for c in 0..CHANNELS {
|
for c in 0..CHANNELS {
|
||||||
|
@ -218,223 +205,13 @@ fn main() -> ! {
|
||||||
// socket RX ring buffer wraps around, or when the command is sent as seperate TCP packets etc.
|
// socket RX ring buffer wraps around, or when the command is sent as seperate TCP packets etc.
|
||||||
// Do nothing and feed more data to the line reader in the next loop cycle.
|
// Do nothing and feed more data to the line reader in the next loop cycle.
|
||||||
Ok(SessionInput::Nothing) => {}
|
Ok(SessionInput::Nothing) => {}
|
||||||
Ok(SessionInput::Command(command)) => match command {
|
Ok(SessionInput::Command(command)) => {
|
||||||
Command::Quit =>
|
match Handler::handle_command(command, &mut socket, &mut channels, session, &mut leds, &mut store, &mut ipv4_config) {
|
||||||
socket.close(),
|
Ok(Handler::NewIPV4(ip)) => new_ipv4_config = Some(ip),
|
||||||
Command::Reporting(_reporting) => {
|
Ok(Handler::Handled) => {},
|
||||||
// handled by session
|
Ok(Handler::CloseSocket) => socket.close(),
|
||||||
send_line(&mut socket, b"{}");
|
Ok(Handler::Reset) => should_reset = true,
|
||||||
}
|
Err(_) => {},
|
||||||
Command::Show(ShowCommand::Reporting) => {
|
|
||||||
let _ = writeln!(socket, "{{ \"report\": {:?} }}", session.reporting());
|
|
||||||
}
|
|
||||||
Command::Show(ShowCommand::Input) => {
|
|
||||||
match channels.reports_json() {
|
|
||||||
Ok(buf) => {
|
|
||||||
send_line(&mut socket, &buf[..]);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("unable to serialize report: {:?}", e);
|
|
||||||
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Show(ShowCommand::Pid) => {
|
|
||||||
match channels.pid_summaries_json() {
|
|
||||||
Ok(buf) => {
|
|
||||||
send_line(&mut socket, &buf);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("unable to serialize pid summary: {:?}", e);
|
|
||||||
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Show(ShowCommand::Pwm) => {
|
|
||||||
match channels.pwm_summaries_json() {
|
|
||||||
Ok(buf) => {
|
|
||||||
send_line(&mut socket, &buf);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("unable to serialize pwm summary: {:?}", e);
|
|
||||||
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Show(ShowCommand::SteinhartHart) => {
|
|
||||||
match channels.steinhart_hart_summaries_json() {
|
|
||||||
Ok(buf) => {
|
|
||||||
send_line(&mut socket, &buf);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("unable to serialize steinhart-hart summaries: {:?}", e);
|
|
||||||
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Show(ShowCommand::PostFilter) => {
|
|
||||||
match channels.postfilter_summaries_json() {
|
|
||||||
Ok(buf) => {
|
|
||||||
send_line(&mut socket, &buf);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("unable to serialize postfilter summary: {:?}", e);
|
|
||||||
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Show(ShowCommand::Ipv4) => {
|
|
||||||
let (cidr, gateway) = net::split_ipv4_config(ipv4_config.clone());
|
|
||||||
let _ = write!(socket, "{{\"addr\":\"{}\"", cidr);
|
|
||||||
gateway.map(|gateway| write!(socket, ",\"gateway\":\"{}\"", gateway));
|
|
||||||
let _ = writeln!(socket, "}}");
|
|
||||||
}
|
|
||||||
Command::PwmPid { channel } => {
|
|
||||||
channels.channel_state(channel).pid_engaged = true;
|
|
||||||
leds.g3.on();
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Command::Pwm { channel, pin, value } => {
|
|
||||||
match pin {
|
|
||||||
PwmPin::ISet => {
|
|
||||||
channels.channel_state(channel).pid_engaged = false;
|
|
||||||
leds.g3.off();
|
|
||||||
let current = ElectricCurrent::new::<ampere>(value);
|
|
||||||
channels.set_i(channel, current);
|
|
||||||
channels.power_up(channel);
|
|
||||||
}
|
|
||||||
PwmPin::MaxV => {
|
|
||||||
let voltage = ElectricPotential::new::<volt>(value);
|
|
||||||
channels.set_max_v(channel, voltage);
|
|
||||||
}
|
|
||||||
PwmPin::MaxIPos => {
|
|
||||||
let current = ElectricCurrent::new::<ampere>(value);
|
|
||||||
channels.set_max_i_pos(channel, current);
|
|
||||||
}
|
|
||||||
PwmPin::MaxINeg => {
|
|
||||||
let current = ElectricCurrent::new::<ampere>(value);
|
|
||||||
channels.set_max_i_neg(channel, current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Command::CenterPoint { channel, center } => {
|
|
||||||
let i_tec = channels.get_i(channel);
|
|
||||||
let state = channels.channel_state(channel);
|
|
||||||
state.center = center;
|
|
||||||
if !state.pid_engaged {
|
|
||||||
channels.set_i(channel, i_tec);
|
|
||||||
}
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Command::Pid { channel, parameter, value } => {
|
|
||||||
let pid = &mut channels.channel_state(channel).pid;
|
|
||||||
use command_parser::PidParameter::*;
|
|
||||||
match parameter {
|
|
||||||
Target =>
|
|
||||||
pid.target = value,
|
|
||||||
KP =>
|
|
||||||
pid.parameters.kp = value as f32,
|
|
||||||
KI =>
|
|
||||||
pid.update_ki(value as f32),
|
|
||||||
KD =>
|
|
||||||
pid.parameters.kd = value as f32,
|
|
||||||
OutputMin =>
|
|
||||||
pid.parameters.output_min = value as f32,
|
|
||||||
OutputMax =>
|
|
||||||
pid.parameters.output_max = value as f32,
|
|
||||||
IntegralMin =>
|
|
||||||
pid.parameters.integral_min = value as f32,
|
|
||||||
IntegralMax =>
|
|
||||||
pid.parameters.integral_max = value as f32,
|
|
||||||
}
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Command::SteinhartHart { channel, parameter, value } => {
|
|
||||||
let sh = &mut channels.channel_state(channel).sh;
|
|
||||||
use command_parser::ShParameter::*;
|
|
||||||
match parameter {
|
|
||||||
T0 => sh.t0 = ThermodynamicTemperature::new::<degree_celsius>(value),
|
|
||||||
B => sh.b = value,
|
|
||||||
R0 => sh.r0 = ElectricalResistance::new::<ohm>(value),
|
|
||||||
}
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Command::PostFilter { channel, rate: None } => {
|
|
||||||
channels.adc.set_postfilter(channel as u8, None).unwrap();
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Command::PostFilter { channel, rate: Some(rate) } => {
|
|
||||||
let filter = ad7172::PostFilter::closest(rate);
|
|
||||||
match filter {
|
|
||||||
Some(filter) => {
|
|
||||||
channels.adc.set_postfilter(channel as u8, Some(filter)).unwrap();
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
error!("unable to choose postfilter for rate {:.3}", rate);
|
|
||||||
send_line(&mut socket, b"{{\"error\": \"unable to choose postfilter rate\"}}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Load { channel } => {
|
|
||||||
for c in 0..CHANNELS {
|
|
||||||
if channel.is_none() || channel == Some(c) {
|
|
||||||
match store.read_value::<ChannelConfig>(CHANNEL_CONFIG_KEY[c]) {
|
|
||||||
Ok(Some(config)) => {
|
|
||||||
config.apply(&mut channels, c);
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Ok(None) => {
|
|
||||||
error!("flash config not found");
|
|
||||||
send_line(&mut socket, b"{{\"error\": \"flash config not found\"}}");
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("unable to load config from flash: {:?}", e);
|
|
||||||
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Save { channel } => {
|
|
||||||
for c in 0..CHANNELS {
|
|
||||||
if channel.is_none() || channel == Some(c) {
|
|
||||||
let config = ChannelConfig::new(&mut channels, c);
|
|
||||||
match store.write_value(CHANNEL_CONFIG_KEY[c], &config, &mut store_value_buf) {
|
|
||||||
Ok(()) => {
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("unable to save channel {} config to flash: {:?}", c, e);
|
|
||||||
let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Ipv4(config) => {
|
|
||||||
let _ = store
|
|
||||||
.write_value("ipv4", &config, [0; 16])
|
|
||||||
.map_err(|e| error!("unable to save ipv4 config to flash: {:?}", e));
|
|
||||||
new_ipv4_config = Some(config);
|
|
||||||
send_line(&mut socket, b"{}");
|
|
||||||
}
|
|
||||||
Command::Reset => {
|
|
||||||
for i in 0..CHANNELS {
|
|
||||||
channels.power_down(i);
|
|
||||||
}
|
|
||||||
should_reset = true;
|
|
||||||
}
|
|
||||||
Command::Dfu => {
|
|
||||||
for i in 0..CHANNELS {
|
|
||||||
channels.power_down(i);
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
dfu::set_dfu_trigger();
|
|
||||||
}
|
|
||||||
should_reset = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(SessionInput::Error(e)) => {
|
Ok(SessionInput::Error(e)) => {
|
||||||
|
|
Loading…
Reference in New Issue