Added config error screen

+ added error management
+ added config error when failing to load
This commit is contained in:
Steins7 2022-01-25 14:09:16 +01:00
parent a3a2386dc2
commit 3fc3dbaae8
5 changed files with 124 additions and 37 deletions

View File

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

View File

@ -21,6 +21,12 @@ use crate::{
config::{Menu, SystemConfig, FanOutput}, config::{Menu, SystemConfig, FanOutput},
}; };
//--------------------------------------------------------------------------------------------------
/* GUI config */
pub const GUI_TICK_SEC: f32 = 0.2;
const GUI_ERROR_SEC: f32 = 0.8;
//---Temp Enum-------------------------------------------------------------------------------------- //---Temp Enum--------------------------------------------------------------------------------------
/// A simple enum to handle displaying temps on the GUI. Temperatures can be valid or not. An /// 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 /// invalid temperature is displayed as "inval°C" whereas a valid temperature is displayed as
@ -75,6 +81,7 @@ pub enum GUIState {
Off, Off,
Idle, Idle,
Menu, Menu,
Error (&'static str),
} }
/// Manages the lcd screen and inputs (encoder + button) and display relevant information. Can also /// Manages the lcd screen and inputs (encoder + button) and display relevant information. Can also
@ -97,6 +104,7 @@ where
p1_deg: Temp, p1_deg: Temp,
p2_deg: Temp, p2_deg: Temp,
should_refresh: bool, should_refresh: bool,
blink_counter: i32,
} }
impl<L, Q, B> LCDGui<L, Q, B> impl<L, Q, B> LCDGui<L, Q, B>
@ -126,6 +134,7 @@ where
p1_deg: Temp::Invalid, p1_deg: Temp::Invalid,
p2_deg: Temp::Invalid, p2_deg: Temp::Invalid,
should_refresh: true, should_refresh: true,
blink_counter: 0,
}; };
if let Some(bl) = &mut gui.backlight { let _ = bl.set_high(); }; if let Some(bl) = &mut gui.backlight { let _ = bl.set_high(); };
@ -179,6 +188,11 @@ where
state.update_config(config); state.update_config(config);
self.menu.display(&mut self.lcd); self.menu.display(&mut self.lcd);
} }
},
GUIState::Error (_) => {
self.state = GUIState::Idle;
self.lcd.clear();
self.should_refresh = true;
}}} }}}
// manage encoder movement // manage encoder movement
@ -211,6 +225,18 @@ where
self.menu.movement_update(diff); self.menu.movement_update(diff);
self.menu.display(&mut self.lcd); 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 input_update
@ -239,6 +265,11 @@ where
//TODO set display off ? //TODO set display off ?
if let Some(bl) = &mut self.backlight { let _ = bl.set_low(); }; 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, 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; mod lcd_gui;
use lcd_gui::LCDGui; use lcd_gui::{LCDGui, GUI_TICK_SEC};
mod utils; mod utils;
use utils::{ use utils::{
@ -43,7 +43,6 @@ use state::SystemState;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/* system config */ /* system config */
const GUI_TICK_SEC: f32 = 0.2;
const AWAKE_TIMEOUT_SEC: f32 = 20.0; const AWAKE_TIMEOUT_SEC: f32 = 20.0;
const HEARTBEAT_SEC: f32 = 1.0; const HEARTBEAT_SEC: f32 = 1.0;
@ -75,6 +74,14 @@ enum PowerState {
Sleeping, Sleeping,
} }
//--------------------------------------------------------------------------------------------------
/* error management */
enum ErrorState {
NoError,
NewError (&'static str),
HandlingError,
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/* interrupt service routines */ /* interrupt service routines */
#[interrupt] #[interrupt]
@ -178,7 +185,13 @@ fn main() -> ! {
let mut afio = dp.AFIO.constrain(); let mut afio = dp.AFIO.constrain();
// initialize system state // 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)); let mut state = SystemState::new(config, gpiob.pb12.into_push_pull_output(&mut gpiob.crh));
// Setup display // Setup display
@ -265,7 +278,7 @@ fn main() -> ! {
// configure stop mode (not working yet, probably due to fake chip) // configure stop mode (not working yet, probably due to fake chip)
//dp.PWR.cr.write(|w| w.pdds().stop_mode()); //dp.PWR.cr.write(|w| w.pdds().stop_mode());
//dp.PWR.cr.write(|w| w.lpds().set_bit()); //dp.PWR.cr.write(|w| w.lpds().set_bit());
// setup adc // setup adc
let mut adc = Adc::adc1(dp.ADC1, clocks); let mut adc = Adc::adc1(dp.ADC1, clocks);
adc.set_sample_time(SampleTime::T_71); adc.set_sample_time(SampleTime::T_71);
@ -283,45 +296,63 @@ fn main() -> ! {
let mut power_state = PowerState::Awake; let mut power_state = PowerState::Awake;
let mut timeout = 0; let mut timeout = 0;
/* run */ /* run */
let _ = TEMP_FLAG.swap(true, Ordering::Release); let _ = TEMP_FLAG.swap(true, Ordering::Release);
loop { loop {
if TEMP_FLAG.swap(false, Ordering::AcqRel) { match error_state {
ErrorState::NoError => {
if TEMP_FLAG.swap(false, Ordering::AcqRel) {
// compute temps // compute temps
let ext_temp = ext_probe.read().ok(); let ext_temp = ext_probe.read().ok();
let p1_temp = p1_probe.read().ok(); let p1_temp = p1_probe.read().ok();
let p2_temp = p2_probe.read().ok(); let p2_temp = p2_probe.read().ok();
state.update(ext_temp, p1_temp, p2_temp); state.update(ext_temp, p1_temp, p2_temp);
gui.update_temps(&mut state); gui.update_temps(&mut state);
} else { } else {
match gui.update(&mut state) { match gui.update(&mut state) {
true => timeout = 0, true => timeout = 0,
false => timeout += 1, false => timeout += 1,
}
// manage power state
match power_state {
PowerState::Awake => { // normal gui update
if timeout as f32 * GUI_TICK_SEC >= AWAKE_TIMEOUT_SEC {
// go to sleep
power_state = PowerState::Sleeping;
gui.sleep();
cp.SCB.set_sleepdeep();
} }
},
PowerState::Sleeping => { // button was pressed during sleep // manage power state
// wake up match power_state {
power_state = PowerState::Awake; PowerState::Awake => { // normal gui update
cp.SCB.clear_sleepdeep(); if timeout as f32 * GUI_TICK_SEC >= AWAKE_TIMEOUT_SEC {
}}} // go to sleep
power_state = PowerState::Sleeping;
gui.sleep();
cp.SCB.set_sleepdeep();
}
},
PowerState::Sleeping => { // button was pressed during sleep
// wake up
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) // put device in sleep mode until next interrupt (button or timer)
cortex_m::asm::wfi(); cortex_m::asm::wfi();
} }

View File

@ -126,7 +126,17 @@ impl<O: OutputPin> SystemState<O> {
if (p - ext) > self.config.max_temp_diff { if (p - ext) > self.config.max_temp_diff {
self.fan.on(); 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(())
}
} }