deeper stack support and state refactoring

This commit is contained in:
2025-07-18 20:31:23 +01:00
parent d3fcb507a0
commit 86b4b227bf
2 changed files with 121 additions and 148 deletions

View File

@@ -87,8 +87,6 @@ pub enum SegmentState {
Minus, Minus,
Prompt(bool), Prompt(bool),
Dot, Dot,
O,
P,
Off, Off,
} }
@@ -181,21 +179,6 @@ impl SegmentState {
seg.set_dp() seg.set_dp()
} }
} }
SegmentState::O => {
seg.set_a();
seg.set_b();
seg.set_c();
seg.set_d();
seg.set_e();
seg.set_f();
}
SegmentState::P => {
seg.set_a();
seg.set_b();
seg.set_g();
seg.set_e();
seg.set_f();
}
SegmentState::Off => (), SegmentState::Off => (),
} }
} }
@@ -271,20 +254,6 @@ impl DispalyState {
SegmentState::Off, SegmentState::Off,
]) ])
} }
pub fn operation(&mut self) {
self.set([
SegmentState::Off,
SegmentState::Off,
SegmentState::Off,
SegmentState::Off,
SegmentState::O,
SegmentState::P,
SegmentState::Off,
SegmentState::Off,
SegmentState::Off,
])
}
} }
// Show data on segment display // Show data on segment display

View File

@@ -34,6 +34,8 @@ pub const DISPLAY_SEGMENT_SIG_MINUS: usize = 0;
pub const DISPLAY_SEGMENTS_EXP: usize = 2; pub const DISPLAY_SEGMENTS_EXP: usize = 2;
pub const DISPLAY_SEGMENT_EXP_MINUS: usize = 6; pub const DISPLAY_SEGMENT_EXP_MINUS: usize = 6;
type Calc = StackCalc<f32, 3, 5, u8>;
struct IOSelect<'p> { struct IOSelect<'p> {
display_no: usize, display_no: usize,
pin: &'p mut Pin<Output>, pin: &'p mut Pin<Output>,
@@ -206,10 +208,118 @@ enum State {
EnterSignificant, EnterSignificant,
EnterExponent, EnterExponent,
EnterOperation, EnterOperation,
Result,
Err { timeout: usize }, Err { timeout: usize },
} }
impl State {
fn on_key(
&self,
key: KeyPress,
number_input: &mut NumberInput,
calc: &mut Calc,
) -> Result<State, ()> {
match self {
State::EnterSignificant => match key {
KeyPress::C => {
number_input.reset();
calc.reset();
Ok(State::EnterSignificant)
}
KeyPress::Num(val) => {
number_input.input(val)?;
Ok(State::EnterSignificant)
}
KeyPress::Minus => {
number_input.toggle_minus();
Ok(State::EnterSignificant)
}
KeyPress::E => {
number_input.enter_exponent();
Ok(State::EnterExponent)
}
_ => Ok(State::EnterSignificant),
},
State::EnterExponent => match key {
KeyPress::C => {
number_input.reset();
calc.reset();
Ok(State::EnterSignificant)
}
KeyPress::Num(val) => {
number_input.input(val)?;
Ok(State::EnterExponent)
}
KeyPress::Minus => {
number_input.toggle_minus();
Ok(State::EnterExponent)
}
KeyPress::E => {
number_input.done();
match calc.push(number_input.to_decimal()) {
Ok(()) => Ok(State::EnterOperation),
Err(_) => Err(()),
}
}
_ => Ok(State::EnterExponent),
},
State::EnterOperation => match key {
KeyPress::Up => todo!(),
KeyPress::C => {
number_input.reset();
calc.reset();
Ok(State::EnterSignificant)
}
KeyPress::Num(_) => todo!(),
KeyPress::Mul => match calc.mul() {
Ok(dec) => {
number_input.set_result(dec)?;
Ok(State::EnterOperation)
}
Err(_) => Err(()),
},
KeyPress::Div => match calc.div() {
Ok(dec) => {
number_input.set_result(dec)?;
Ok(State::EnterOperation)
}
Err(_) => Err(()),
},
KeyPress::Plus => match calc.add() {
Ok(dec) => {
number_input.set_result(dec)?;
Ok(State::EnterOperation)
}
Err(_) => Err(()),
},
KeyPress::Minus => match calc.sub() {
Ok(dec) => {
number_input.set_result(dec)?;
Ok(State::EnterOperation)
}
Err(_) => Err(()),
},
KeyPress::Down => todo!(),
KeyPress::E => {
if calc.is_full() {
Err(())
} else {
number_input.reset();
Ok(State::EnterSignificant)
}
}
},
State::Err { timeout } => match key {
KeyPress::C => {
number_input.reset();
calc.reset();
Ok(State::EnterSignificant)
}
_ => Ok(State::Err { timeout: *timeout }),
},
}
}
}
#[arduino_hal::entry] #[arduino_hal::entry]
fn main() -> ! { fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap(); let dp = arduino_hal::Peripherals::take().unwrap();
@@ -250,7 +360,7 @@ fn main() -> ! {
let mut display = DispalyState::default(); let mut display = DispalyState::default();
number_input.show(&mut display); number_input.show(&mut display);
let mut calc = StackCalc::<f32, 2, 5, u8>::default(); let mut calc = Calc::default();
let mut state = State::EnterSignificant; let mut state = State::EnterSignificant;
loop { loop {
@@ -284,132 +394,26 @@ fn main() -> ! {
if let Some(key) = debounce.input(last_key_readout) { if let Some(key) = debounce.input(last_key_readout) {
ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible();
let res = match &mut state { match state.on_key(key, &mut number_input, &mut calc) {
State::Result => match key { Ok(new_state) => state = new_state,
KeyPress::C => { Err(()) => {
number_input.reset();
calc.reset();
state = State::EnterSignificant;
Ok(())
}
KeyPress::E => {
number_input.reset();
state = State::EnterSignificant;
Ok(())
}
_ => Ok(()),
},
State::EnterSignificant => match key {
KeyPress::C => {
number_input.reset();
calc.reset();
Ok(())
}
KeyPress::Num(val) => number_input.input(val),
KeyPress::Minus => Ok(number_input.toggle_minus()),
KeyPress::E => {
number_input.enter_exponent();
state = State::EnterExponent;
Ok(())
}
_ => Ok(()),
},
State::EnterExponent => match key {
KeyPress::C => {
number_input.reset();
calc.reset();
state = State::EnterSignificant;
Ok(())
}
KeyPress::Num(val) => number_input.input(val),
KeyPress::Minus => Ok(number_input.toggle_minus()),
KeyPress::E => {
number_input.done();
match calc.push(number_input.to_decimal()) {
Ok(()) => {
number_input.reset();
state = if calc.is_full() {
State::EnterOperation
} else {
State::EnterSignificant
};
Ok(())
}
Err(_) => Err(()),
}
}
_ => Ok(()),
},
State::EnterOperation => match key {
KeyPress::Up => todo!(),
KeyPress::C => {
number_input.reset();
calc.reset();
state = State::EnterSignificant;
Ok(())
}
KeyPress::Num(_) => todo!(),
KeyPress::Mul => match calc.mul() {
Ok(dec) => {
state = State::Result;
number_input.set_result(dec)
}
Err(_) => Err(()),
},
KeyPress::Div => match calc.div() {
Ok(dec) => {
state = State::Result;
number_input.set_result(dec)
}
Err(_) => Err(()),
},
KeyPress::Plus => match calc.add() {
Ok(dec) => {
state = State::Result;
number_input.set_result(dec)
}
Err(_) => Err(()),
},
KeyPress::Minus => match calc.sub() {
Ok(dec) => {
state = State::Result;
number_input.set_result(dec)
}
Err(_) => Err(()),
},
KeyPress::Down => todo!(),
KeyPress::E => todo!(),
},
State::Err { .. } => match key {
KeyPress::C => {
number_input.reset();
calc.reset();
state = State::EnterSignificant;
Ok(())
}
_ => Ok(()),
},
};
if res.is_err() {
state = State::Err { state = State::Err {
timeout: ERROR_TIMEOUT, timeout: ERROR_TIMEOUT,
};
} }
}
}
ufmt::uwriteln!(&mut serial, "state: {:?} stack: {}", state, calc.len()) ufmt::uwriteln!(&mut serial, "state: {:?} stack: {}", state, calc.len())
.unwrap_infallible(); .unwrap_infallible();
match state { match &state {
State::Result | State::EnterSignificant | State::EnterExponent => { State::EnterSignificant | State::EnterExponent | State::EnterOperation => {
number_input.show(&mut display) number_input.show(&mut display)
} }
State::EnterOperation => {
display.operation();
}
State::Err { .. } => { State::Err { .. } => {
display.error(); display.error();
} }
} }
} }
arduino_hal::delay_ms(1); arduino_hal::delay_ms(1);
} }