diff --git a/src/main.rs b/src/main.rs index a15cf4d..f0b878c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,12 +10,9 @@ mod thermostat; mod net; use device::{boot::bootup, log_setup, sys_timer}; -use uom::fmt::DisplayStyle::Abbreviation; -use uom::si::electric_potential::volt; -use uom::si::electric_current::{ampere, milliampere}; -use uom::si::f32::{ElectricPotential, ElectricCurrent}; - +use serde::{Deserialize, Serialize}; use stm32f4xx_hal::pac::SCB; + // If RTT is used, print panic info through RTT #[cfg(all(feature = "RTT", not(test)))] use {core::panic::PanicInfo, rtt_target::rprintln}; @@ -31,12 +28,15 @@ use panic_halt as _; static mut ETH_DATA_BUFFER: [u8; 1024] = [0; 1024]; +#[derive(Deserialize, Serialize, Clone, Copy, Debug)] pub struct DeviceSettings{ report_readings: bool, } +const CONFIG_KEY: [&str; 3] = ["Device", "Laser_0", "Thermostat_0"]; + #[derive(Default)] -enum State { +pub enum State { #[default] LoadFlashSettings, MainLoop, @@ -53,41 +53,7 @@ fn main() -> ! { let core_perif = CorePeripherals::take().unwrap(); let perif = Peripherals::take().unwrap(); - let (mut wd, mut _flash_store, mut laser, mut thermostat,) = bootup(core_perif, perif); - - // Demo Fns for reading and writing stm32 Internal Flash - /* - let key = "test"; - info!("Read the Flash Content Stored"); - match flash_store.read(key).unwrap() { - Some(val) => {info!("Flash Valued Read: {:?}", val)} - _ => {info!("Key does not match")} - } - - info!("Erasing Flash"); - flash_store.erase().unwrap(); - match flash_store.read(key).unwrap() { - Some(val) => {info!("Flash Valued Read: {:?}", val)} - _ => {info!("Key does not match")} - } - - info!("Writing Flash"); - let buf = [1, 2, 3, 4]; - flash_store.write(key, &buf).unwrap(); - - info!("Reading Flash"); - match flash_store.read(key).unwrap() { - Some(val) => {info!("Val: {:?}", val)} - _ => {info!("Key does not match")} - }; - */ - - // https://github.com/iliekturtles/uom/blob/master/examples/si.rs - let volt_fmt = ElectricPotential::format_args(volt, Abbreviation); - let amp_fmt = ElectricCurrent::format_args(ampere, Abbreviation); - let milli_amp_fmt = ElectricCurrent::format_args(milliampere, Abbreviation); - - let mut should_reset = false; + let (mut wd, mut flash_store, mut laser, mut thermostat,) = bootup(core_perif, perif); let mut device_settings = DeviceSettings { report_readings: false, @@ -100,10 +66,64 @@ fn main() -> ! { match state { State::LoadFlashSettings => { - wd.feed(); - // Todo // State Transition state = State::MainLoop; + + wd.feed(); + let device_settings_flash: DeviceSettings; + match flash_store.read_value(CONFIG_KEY[0]) { + Ok(Some(config)) => { + device_settings_flash = config; + debug!("Found Device Settings"); + } + Ok(None) => { + debug!("Flash does not have Device Settings"); + continue; + } + Err(e) => { + debug!("Cannot Store Flash: {:?}", e); + continue; + } + } + + wd.feed(); + let laser_settings: laser_diode::laser_diode::LdSettingsSummary; + match flash_store.read_value(CONFIG_KEY[1]) { + Ok(Some(config)) => { + laser_settings = config; + debug!("Found Laser Diode Settings"); + } + Ok(None) => { + debug!("Does not have laser diode Settings"); + continue; + } + Err(e) => { + debug!("Cannot Store Flash: {:?}", e); + continue; + } + } + + wd.feed(); + let thermostat_settings: thermostat::thermostat::ThermostatSettingsSummary; + match flash_store.read_value(CONFIG_KEY[2]) { + Ok(Some(config)) => { + thermostat_settings = config; + debug!("Found Thermostat Settings"); + } + Ok(None) => { + debug!("Does not have thermostat Settings"); + continue; + } + Err(e) => { + debug!("Cannot Store Flash: {:?}", e); + continue; + } + } + + wd.feed(); + device_settings = device_settings_flash; + thermostat.load_settings_from_summary(thermostat_settings); + laser.load_settings_from_summary(laser_settings); } State::MainLoop => { let mut eth_is_pending = false; @@ -145,7 +165,8 @@ fn main() -> ! { if bytes != 0 { info!("Ts: {:?}", sys_timer::now()); debug!("Number of bytes recv: {:?}", bytes); - (laser, thermostat, should_reset, device_settings) = net::cmd_handler::execute_cmd(&mut ETH_DATA_BUFFER, bytes, laser, thermostat, device_settings); + // State Transition + (laser, thermostat, state, device_settings) = net::cmd_handler::execute_cmd(&mut ETH_DATA_BUFFER, bytes, laser, thermostat, state, device_settings); } } } @@ -153,20 +174,41 @@ fn main() -> ! { thermostat.start_tec_readings_conversion(); } } - else { - device_settings.report_readings = false; - } - - // State Transition - if should_reset { - state = State::HardReset; - } } State::SaveFlashSettings => { - wd.feed(); - // Todo // State Transition state = State::MainLoop; + + wd.feed(); + let mut store_value_buf = [0u8; 1024]; + match flash_store.write_value(CONFIG_KEY[0], &device_settings, &mut store_value_buf) { + Ok(()) => { + debug!("Device Settings is stored in flash"); + } + Err(e) => { + debug!("Cannot Store Flash: {:?}", e); + } + } + + wd.feed(); + match flash_store.write_value(CONFIG_KEY[1], &laser.get_settings_summary(), &mut store_value_buf) { + Ok(()) => { + debug!("Laser Diode Settings is stored in flash"); + } + Err(e) => { + debug!("Cannot Store Flash: {:?}", e); + } + } + + wd.feed(); + match flash_store.write_value(CONFIG_KEY[2], &thermostat.get_settings_summary(), &mut store_value_buf) { + Ok(()) => { + debug!("Thermostat Settings is stored in flash"); + } + Err(e) => { + debug!("Cannot Store Flash: {:?}", e); + } + } } State::HardReset => { wd.feed(); diff --git a/src/net/cmd_handler.rs b/src/net/cmd_handler.rs index 1cbeb2b..9ce1014 100644 --- a/src/net/cmd_handler.rs +++ b/src/net/cmd_handler.rs @@ -19,7 +19,7 @@ use crate::thermostat::thermostat::{Thermostat, ThermostatSettingsSummary}; use crate::thermostat::pid_state::PidSettings::*; use crate::device::{dfu, sys_timer}; use log::info; -use crate::DeviceSettings; +use crate::{DeviceSettings, State}; #[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)] enum DeviceCmd { @@ -29,6 +29,9 @@ enum DeviceCmd { GetStatusReport, GetSettingsSummary, Dfu, + SaveFlashSettings, + LoadFlashSettings, + HardReset, } #[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)] @@ -160,16 +163,14 @@ pub struct TecSetICmd { /// Make sure kirdy's firmware is flashed with release builds. /// The received message must contain only one json cmd. TCP client should set TCP_NODELAY or equivalent flag in its TCP Socket /// Settings to avoid unwanted buffering on TX Data and minimize TX latency. -pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mut tec: Thermostat, mut device_settings: DeviceSettings)->(LdDrive, Thermostat, bool, DeviceSettings){ - let mut should_reset = false; - +pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mut tec: Thermostat, mut state: State, mut device_settings: DeviceSettings)->(LdDrive, Thermostat, State, DeviceSettings){ let mut cmd = TecSetICmd { json: TecSetICmdJson::default() }; match cmd.set_json("/json", &buffer[0..buffer_size]){ Ok(_) => { tec.set_i(ElectricCurrent::new::(cmd.json.tec_set_i)); - return (laser, tec, should_reset, device_settings); + return (laser, tec, state, device_settings); } Err(_) => { /* Do Nothing */} } @@ -188,7 +189,6 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu unsafe { dfu::set_dfu_trigger(); } - should_reset = true; } Some(DeviceCmd::SetActiveReportMode) => { match cmd.json.data_bool{ @@ -206,6 +206,15 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu Some(DeviceCmd::GetSettingsSummary) => { send_settings_summary(buffer, &mut laser, &mut tec); } + Some(DeviceCmd::SaveFlashSettings) => { + state = State::SaveFlashSettings; + } + Some(DeviceCmd::LoadFlashSettings) => { + state = State::LoadFlashSettings; + } + Some(DeviceCmd::HardReset) => { + state = State::HardReset; + } None => { /* Do Nothing */} _ => { info!("Unimplemented Command") @@ -536,5 +545,5 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu info!("Invalid Command: {:?}", err); } } - (laser, tec, should_reset, device_settings) + (laser, tec, state, device_settings) }