Merge branch '10-system-is-starting-without-config' into 'dev'

Resolve "System is starting without config"

See merge request Steins7/fan_monitor!8
This commit is contained in:
Steins7 2022-01-28 10:32:04 +00:00
commit 07245df732
5 changed files with 124 additions and 37 deletions

View File

@ -52,8 +52,8 @@ impl SystemConfig {
}
#[allow(dead_code)]
pub fn load() -> Result<ConfigError, SystemConfig> {
unimplemented!();
pub fn load() -> Result<SystemConfig, ConfigError> {
Err(ConfigError::LoadError)
}
#[allow(dead_code)]

View File

@ -21,6 +21,12 @@ use crate::{
config::{Menu, SystemConfig, FanOutput},
};
//--------------------------------------------------------------------------------------------------
/* GUI config */
pub const GUI_TICK_SEC: f32 = 0.2;
const GUI_ERROR_SEC: f32 = 0.8;
//---Temp Enum--------------------------------------------------------------------------------------
/// A simple enum to handle displaying temps on the GUI. Temperatures can be valid or not. An
/// invalid temperature is displayed as "inval°C" whereas a valid temperature is displayed as
@ -75,6 +81,7 @@ pub enum GUIState {
Off,
Idle,
Menu,
Error (&'static str),
}
/// Manages the lcd screen and inputs (encoder + button) and display relevant information. Can also
@ -97,6 +104,7 @@ where
p1_deg: Temp,
p2_deg: Temp,
should_refresh: bool,
blink_counter: i32,
}
impl<L, Q, B> LCDGui<L, Q, B>
@ -126,6 +134,7 @@ where
p1_deg: Temp::Invalid,
p2_deg: Temp::Invalid,
should_refresh: true,
blink_counter: 0,
};
if let Some(bl) = &mut gui.backlight { let _ = bl.set_high(); };
@ -179,6 +188,11 @@ where
state.update_config(config);
self.menu.display(&mut self.lcd);
}
},
GUIState::Error (_) => {
self.state = GUIState::Idle;
self.lcd.clear();
self.should_refresh = true;
}}}
// manage encoder movement
@ -211,6 +225,18 @@ where
self.menu.movement_update(diff);
self.menu.display(&mut self.lcd);
}
},
GUIState::Error (err)=> {
self.blink_counter += 1;
if self.blink_counter as f32 * GUI_TICK_SEC >= 2.0*GUI_ERROR_SEC {
let _ = write!(self.lcd, "Erreur: ");
self.lcd.set_cursor_pos(0x40);
let _ = write!(self.lcd, "{}", err);
self.blink_counter = 0;
} else if self.blink_counter as f32 * GUI_TICK_SEC >= GUI_ERROR_SEC {
self.lcd.clear();
}
}}
input_update
@ -239,6 +265,11 @@ where
//TODO set display off ?
if let Some(bl) = &mut self.backlight { let _ = bl.set_low(); };
}
pub fn display_error(&mut self, error: &'static str) {
self.state = GUIState::Error (error);
self.blink_counter = 0;
}
}
fn display_idle_screen<L: LCDScreen>(screen: &mut L, ext_deg: &Temp, p1_deg: &Temp, p2_deg: &Temp,

View File

@ -27,7 +27,7 @@ use stm32f1xx_hal::{
};
mod lcd_gui;
use lcd_gui::LCDGui;
use lcd_gui::{LCDGui, GUI_TICK_SEC};
mod utils;
use utils::{
@ -43,7 +43,6 @@ use state::SystemState;
//--------------------------------------------------------------------------------------------------
/* system config */
const GUI_TICK_SEC: f32 = 0.2;
const AWAKE_TIMEOUT_SEC: f32 = 20.0;
const HEARTBEAT_SEC: f32 = 1.0;
@ -75,6 +74,14 @@ enum PowerState {
Sleeping,
}
//--------------------------------------------------------------------------------------------------
/* error management */
enum ErrorState {
NoError,
NewError (&'static str),
HandlingError,
}
//--------------------------------------------------------------------------------------------------
/* interrupt service routines */
#[interrupt]
@ -178,7 +185,13 @@ fn main() -> ! {
let mut afio = dp.AFIO.constrain();
// initialize system state
let config = SystemConfig::new();
let mut error_state = ErrorState::NoError;
let config = match SystemConfig::load() {
Ok(conf) => conf,
Err(_) => {
error_state = ErrorState::NewError("config invalide");
SystemConfig::new()
}};
let mut state = SystemState::new(config, gpiob.pb12.into_push_pull_output(&mut gpiob.crh));
// Setup display
@ -289,6 +302,8 @@ fn main() -> ! {
loop {
match error_state {
ErrorState::NoError => {
if TEMP_FLAG.swap(false, Ordering::AcqRel) {
// compute temps
@ -321,6 +336,22 @@ fn main() -> ! {
power_state = PowerState::Awake;
cp.SCB.clear_sleepdeep();
}}}
},
ErrorState::NewError (err) => {
gui.display_error(err);
state.stop();
error_state = ErrorState::HandlingError;
},
ErrorState::HandlingError => {
if gui.update(&mut state) {
error_state = ErrorState::NoError;
state.reset();
ext_probe.reset().unwrap();
p1_probe.reset().unwrap();
p2_probe.reset().unwrap();
timeout = 0;
}
}}
// put device in sleep mode until next interrupt (button or timer)
cortex_m::asm::wfi();

View File

@ -126,7 +126,17 @@ impl<O: OutputPin> SystemState<O> {
if (p - ext) > self.config.max_temp_diff {
self.fan.on();
}
},
}}
}
pub fn stop(&mut self) {
self.fan.off();
}
pub fn reset(&mut self) {
self.ext_temp = None;
self.p1_temp = None;
self.p2_temp = None;
self.fan.off();
}
}

View File

@ -121,5 +121,20 @@ where
},
}
}
pub fn reset(&mut self) -> Result<(), ProbeError>{
// re-compute first temp approximation to speed up stabilization
let mut temp = 0.0;
for _ in 0..10 {
temp += read_temp(self.adc, &mut self.pos_pin, &mut self.neg_pin)?;
}
temp /= 10.0;
self.filtered_temp = temp;
self.stabilized = false;
Ok(())
}
}