From 0655fb272490f5544765e446b559492ec6daac14 Mon Sep 17 00:00:00 2001 From: Hexa Dust Date: Fri, 18 Jul 2025 20:31:23 +0100 Subject: [PATCH] better error handling and debugging --- Cargo.lock | 1 + Cargo.toml | 2 +- src/main.rs | 147 ++++++++++++++++++++++++++++++++-------------------- 3 files changed, 93 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4183d70..c8501b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,6 +92,7 @@ name = "calc-math" version = "0.1.0" dependencies = [ "num-traits", + "ufmt", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9e0784c..a8c1929 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ bench = false ufmt = "0.2.0" nb = "1.1.0" embedded-hal = "1.0" -calc-math = { path = "../calc-math" } +calc-math = { path = "../calc-math", features = ["ufmt"] } [dependencies.arduino-hal] git = "https://github.com/rahix/avr-hal" diff --git a/src/main.rs b/src/main.rs index db3a157..42985fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,10 @@ mod display; mod keyboard; mod panic; -use calc_math::{calc::StackCalc, Decimal}; +use calc_math::{ + calc::{StackCalc, StackCalcError}, + Decimal, +}; use display::{DispalyState, SegmentPins, SegmentState, Show}; use keyboard::{Debounce, KeyPress, KeyReadout, Keyboard}; @@ -13,7 +16,6 @@ use arduino_hal::{ adc::channel::{ADC6, ADC7}, hal::port::{PB3, PB4, PC1, PC2, PC3, PD2, PD3, PD4, PD7}, port::{mode::Output, Pin}, - prelude::*, Adc, }; use ufmt::derive::uDebug; @@ -89,6 +91,12 @@ impl IOPins { } } +#[derive(uDebug)] +pub enum NumberInputError { + SignificantOverflow, + ExponentOverflow, +} + #[derive(Default)] pub struct NumberInput { minus: bool, @@ -105,31 +113,31 @@ impl NumberInput { *self = Self::default(); } - pub fn input_significant(&mut self, val: u8) -> Result<(), ()> { + pub fn input_significant(&mut self, val: u8) -> Result<(), NumberInputError> { if val > 9 { panic!("Bad significatn val"); } if self.significant_pos >= DISPLAY_SEGMENTS_SIG { - return Err(()); + return Err(NumberInputError::SignificantOverflow); } self.significant[self.significant_pos] = val; self.significant_pos += 1; return Ok(()); } - pub fn input_exponent(&mut self, val: u8) -> Result<(), ()> { + pub fn input_exponent(&mut self, val: u8) -> Result<(), NumberInputError> { if val > 9 { panic!("Bad exponent val"); } if self.exponent_pos >= DISPLAY_SEGMENTS_EXP { - return Err(()); + return Err(NumberInputError::ExponentOverflow); } self.exponent[self.exponent_pos] = val; self.exponent_pos += 1; Ok(()) } - pub fn input(&mut self, val: u8) -> Result<(), ()> { + pub fn input(&mut self, val: u8) -> Result<(), NumberInputError> { if self.enter_exponent { self.input_exponent(val) } else { @@ -165,13 +173,13 @@ impl NumberInput { ) } - pub fn set_result(&mut self, dec: Decimal<5, u8>) -> Result<(), ()> { + pub fn set_result(&mut self, dec: Decimal<5, u8>) -> Result<(), NumberInputError> { let (minus, significant, minus_exponent, exponent) = dec.into_parts(); self.minus = minus; self.significant = significant; self.minus_exponent = minus_exponent; if exponent > 99 { - return Err(()); + return Err(NumberInputError::ExponentOverflow); } self.exponent[0] = exponent / 10; self.exponent[1] = exponent - (self.exponent[0] * 10); @@ -235,6 +243,26 @@ impl TransientState { } } +#[derive(uDebug)] +enum CalcluclatorError { + NumberInputError(NumberInputError), + StackCalcError(StackCalcError), + StackOverflow, + InvalidOperation, +} + +impl From for CalcluclatorError { + fn from(value: NumberInputError) -> Self { + CalcluclatorError::NumberInputError(value) + } +} + +impl From for CalcluclatorError { + fn from(value: StackCalcError) -> Self { + CalcluclatorError::StackCalcError(value) + } +} + #[derive(uDebug)] enum CalcluclatorState { EnterSignificant, @@ -248,7 +276,7 @@ impl CalcluclatorState { key: KeyPress, number_input: &mut NumberInput, calc: &mut Calc, - ) -> Result { + ) -> Result { match self { CalcluclatorState::EnterSignificant => match key { KeyPress::C => { @@ -268,7 +296,7 @@ impl CalcluclatorState { number_input.enter_exponent(); Ok(CalcluclatorState::EnterExponent) } - _ => Ok(CalcluclatorState::EnterSignificant), + _ => Err(CalcluclatorError::InvalidOperation), }, CalcluclatorState::EnterExponent => match key { KeyPress::C => { @@ -286,58 +314,46 @@ impl CalcluclatorState { } KeyPress::E => { number_input.done(); - match calc.push(number_input.to_decimal()) { - Ok(()) => Ok(CalcluclatorState::EnterOperation), - Err(_) => Err(()), - } + calc.push(number_input.to_decimal())?; + Ok(CalcluclatorState::EnterOperation) } - _ => Ok(CalcluclatorState::EnterExponent), + _ => Err(CalcluclatorError::InvalidOperation), }, CalcluclatorState::EnterOperation => match key { - KeyPress::Up => todo!(), KeyPress::C => { number_input.reset(); calc.reset(); Ok(CalcluclatorState::EnterSignificant) } - KeyPress::Num(_) => todo!(), - KeyPress::Mul => match calc.mul() { - Ok(dec) => { - number_input.set_result(dec)?; - Ok(CalcluclatorState::EnterOperation) - } - Err(_) => Err(()), - }, - KeyPress::Div => match calc.div() { - Ok(dec) => { - number_input.set_result(dec)?; - Ok(CalcluclatorState::EnterOperation) - } - Err(_) => Err(()), - }, - KeyPress::Plus => match calc.add() { - Ok(dec) => { - number_input.set_result(dec)?; - Ok(CalcluclatorState::EnterOperation) - } - Err(_) => Err(()), - }, - KeyPress::Minus => match calc.sub() { - Ok(dec) => { - number_input.set_result(dec)?; - Ok(CalcluclatorState::EnterOperation) - } - Err(_) => Err(()), - }, - KeyPress::Down => todo!(), + KeyPress::Mul => { + let dec = calc.mul()?; + number_input.set_result(dec)?; + Ok(CalcluclatorState::EnterOperation) + } + KeyPress::Div => { + let dec = calc.div()?; + number_input.set_result(dec)?; + Ok(CalcluclatorState::EnterOperation) + } + KeyPress::Plus => { + let dec = calc.add()?; + number_input.set_result(dec)?; + Ok(CalcluclatorState::EnterOperation) + } + KeyPress::Minus => { + let dec = calc.sub()?; + number_input.set_result(dec)?; + Ok(CalcluclatorState::EnterOperation) + } KeyPress::E => { if calc.is_full() { - Err(()) + Err(CalcluclatorError::StackOverflow) } else { number_input.reset(); Ok(CalcluclatorState::EnterSignificant) } } + _ => Err(CalcluclatorError::InvalidOperation), }, } } @@ -350,7 +366,7 @@ fn main() -> ! { let mut serial = arduino_hal::default_serial!(dp, pins, SERIAL_BAUD); - ufmt::uwriteln!(&mut serial, "Hello from Arduino!").unwrap_infallible(); + ufmt::uwriteln!(&mut serial, "Hello from Arduino!").ok(); let mut io = IOPins::new( pins.d2.into_output(), @@ -406,22 +422,41 @@ fn main() -> ! { let key = debounce.input(last_key_readout); - if let Some(key) = &key { - ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible(); - } - if let TransientState::Done = state.transient { if let Some(key) = key { + ufmt::uwriteln!( + &mut serial, + "-> key: {:?} state: {:?}", + key, + state.calculator + ) + .ok(); match state.calculator.on_key(key, &mut number_input, &mut calc) { Ok(new_state) => state.calculator = new_state, - Err(()) => { + Err(err) => { + match err { + CalcluclatorError::StackCalcError(_) => { + number_input.reset(); + state.calculator = CalcluclatorState::EnterSignificant; + } + _ => (), + } + ufmt::uwriteln!(&mut serial, "!! error: {:?}", err).ok(); state.transient = TransientState::Err { timeout: ERROR_TIMEOUT, }; } } - ufmt::uwriteln!(&mut serial, "state: {:?} stack: {}", state, calc.len()) - .unwrap_infallible(); + ufmt::uwriteln!( + &mut serial, + "<- state: {:?} stack: {}", + state.calculator, + calc.len() + ) + .ok(); + for (i, dec) in calc.iter().enumerate() { + ufmt::uwriteln!(&mut serial, "[{}] {}", i, dec).ok(); + } } } else { state.transient.on_frame(key)