better error handling and debugging
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -92,6 +92,7 @@ name = "calc-math"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"ufmt",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ bench = false
|
|||||||
ufmt = "0.2.0"
|
ufmt = "0.2.0"
|
||||||
nb = "1.1.0"
|
nb = "1.1.0"
|
||||||
embedded-hal = "1.0"
|
embedded-hal = "1.0"
|
||||||
calc-math = { path = "../calc-math" }
|
calc-math = { path = "../calc-math", features = ["ufmt"] }
|
||||||
|
|
||||||
[dependencies.arduino-hal]
|
[dependencies.arduino-hal]
|
||||||
git = "https://github.com/rahix/avr-hal"
|
git = "https://github.com/rahix/avr-hal"
|
||||||
|
|||||||
147
src/main.rs
147
src/main.rs
@@ -5,7 +5,10 @@ mod display;
|
|||||||
mod keyboard;
|
mod keyboard;
|
||||||
mod panic;
|
mod panic;
|
||||||
|
|
||||||
use calc_math::{calc::StackCalc, Decimal};
|
use calc_math::{
|
||||||
|
calc::{StackCalc, StackCalcError},
|
||||||
|
Decimal,
|
||||||
|
};
|
||||||
use display::{DispalyState, SegmentPins, SegmentState, Show};
|
use display::{DispalyState, SegmentPins, SegmentState, Show};
|
||||||
use keyboard::{Debounce, KeyPress, KeyReadout, Keyboard};
|
use keyboard::{Debounce, KeyPress, KeyReadout, Keyboard};
|
||||||
|
|
||||||
@@ -13,7 +16,6 @@ use arduino_hal::{
|
|||||||
adc::channel::{ADC6, ADC7},
|
adc::channel::{ADC6, ADC7},
|
||||||
hal::port::{PB3, PB4, PC1, PC2, PC3, PD2, PD3, PD4, PD7},
|
hal::port::{PB3, PB4, PC1, PC2, PC3, PD2, PD3, PD4, PD7},
|
||||||
port::{mode::Output, Pin},
|
port::{mode::Output, Pin},
|
||||||
prelude::*,
|
|
||||||
Adc,
|
Adc,
|
||||||
};
|
};
|
||||||
use ufmt::derive::uDebug;
|
use ufmt::derive::uDebug;
|
||||||
@@ -89,6 +91,12 @@ impl IOPins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(uDebug)]
|
||||||
|
pub enum NumberInputError {
|
||||||
|
SignificantOverflow,
|
||||||
|
ExponentOverflow,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct NumberInput {
|
pub struct NumberInput {
|
||||||
minus: bool,
|
minus: bool,
|
||||||
@@ -105,31 +113,31 @@ impl NumberInput {
|
|||||||
*self = Self::default();
|
*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 {
|
if val > 9 {
|
||||||
panic!("Bad significatn val");
|
panic!("Bad significatn val");
|
||||||
}
|
}
|
||||||
if self.significant_pos >= DISPLAY_SEGMENTS_SIG {
|
if self.significant_pos >= DISPLAY_SEGMENTS_SIG {
|
||||||
return Err(());
|
return Err(NumberInputError::SignificantOverflow);
|
||||||
}
|
}
|
||||||
self.significant[self.significant_pos] = val;
|
self.significant[self.significant_pos] = val;
|
||||||
self.significant_pos += 1;
|
self.significant_pos += 1;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_exponent(&mut self, val: u8) -> Result<(), ()> {
|
pub fn input_exponent(&mut self, val: u8) -> Result<(), NumberInputError> {
|
||||||
if val > 9 {
|
if val > 9 {
|
||||||
panic!("Bad exponent val");
|
panic!("Bad exponent val");
|
||||||
}
|
}
|
||||||
if self.exponent_pos >= DISPLAY_SEGMENTS_EXP {
|
if self.exponent_pos >= DISPLAY_SEGMENTS_EXP {
|
||||||
return Err(());
|
return Err(NumberInputError::ExponentOverflow);
|
||||||
}
|
}
|
||||||
self.exponent[self.exponent_pos] = val;
|
self.exponent[self.exponent_pos] = val;
|
||||||
self.exponent_pos += 1;
|
self.exponent_pos += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input(&mut self, val: u8) -> Result<(), ()> {
|
pub fn input(&mut self, val: u8) -> Result<(), NumberInputError> {
|
||||||
if self.enter_exponent {
|
if self.enter_exponent {
|
||||||
self.input_exponent(val)
|
self.input_exponent(val)
|
||||||
} else {
|
} 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();
|
let (minus, significant, minus_exponent, exponent) = dec.into_parts();
|
||||||
self.minus = minus;
|
self.minus = minus;
|
||||||
self.significant = significant;
|
self.significant = significant;
|
||||||
self.minus_exponent = minus_exponent;
|
self.minus_exponent = minus_exponent;
|
||||||
if exponent > 99 {
|
if exponent > 99 {
|
||||||
return Err(());
|
return Err(NumberInputError::ExponentOverflow);
|
||||||
}
|
}
|
||||||
self.exponent[0] = exponent / 10;
|
self.exponent[0] = exponent / 10;
|
||||||
self.exponent[1] = exponent - (self.exponent[0] * 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<NumberInputError> for CalcluclatorError {
|
||||||
|
fn from(value: NumberInputError) -> Self {
|
||||||
|
CalcluclatorError::NumberInputError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<StackCalcError> for CalcluclatorError {
|
||||||
|
fn from(value: StackCalcError) -> Self {
|
||||||
|
CalcluclatorError::StackCalcError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(uDebug)]
|
#[derive(uDebug)]
|
||||||
enum CalcluclatorState {
|
enum CalcluclatorState {
|
||||||
EnterSignificant,
|
EnterSignificant,
|
||||||
@@ -248,7 +276,7 @@ impl CalcluclatorState {
|
|||||||
key: KeyPress,
|
key: KeyPress,
|
||||||
number_input: &mut NumberInput,
|
number_input: &mut NumberInput,
|
||||||
calc: &mut Calc,
|
calc: &mut Calc,
|
||||||
) -> Result<CalcluclatorState, ()> {
|
) -> Result<CalcluclatorState, CalcluclatorError> {
|
||||||
match self {
|
match self {
|
||||||
CalcluclatorState::EnterSignificant => match key {
|
CalcluclatorState::EnterSignificant => match key {
|
||||||
KeyPress::C => {
|
KeyPress::C => {
|
||||||
@@ -268,7 +296,7 @@ impl CalcluclatorState {
|
|||||||
number_input.enter_exponent();
|
number_input.enter_exponent();
|
||||||
Ok(CalcluclatorState::EnterExponent)
|
Ok(CalcluclatorState::EnterExponent)
|
||||||
}
|
}
|
||||||
_ => Ok(CalcluclatorState::EnterSignificant),
|
_ => Err(CalcluclatorError::InvalidOperation),
|
||||||
},
|
},
|
||||||
CalcluclatorState::EnterExponent => match key {
|
CalcluclatorState::EnterExponent => match key {
|
||||||
KeyPress::C => {
|
KeyPress::C => {
|
||||||
@@ -286,58 +314,46 @@ impl CalcluclatorState {
|
|||||||
}
|
}
|
||||||
KeyPress::E => {
|
KeyPress::E => {
|
||||||
number_input.done();
|
number_input.done();
|
||||||
match calc.push(number_input.to_decimal()) {
|
calc.push(number_input.to_decimal())?;
|
||||||
Ok(()) => Ok(CalcluclatorState::EnterOperation),
|
Ok(CalcluclatorState::EnterOperation)
|
||||||
Err(_) => Err(()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => Ok(CalcluclatorState::EnterExponent),
|
_ => Err(CalcluclatorError::InvalidOperation),
|
||||||
},
|
},
|
||||||
CalcluclatorState::EnterOperation => match key {
|
CalcluclatorState::EnterOperation => match key {
|
||||||
KeyPress::Up => todo!(),
|
|
||||||
KeyPress::C => {
|
KeyPress::C => {
|
||||||
number_input.reset();
|
number_input.reset();
|
||||||
calc.reset();
|
calc.reset();
|
||||||
Ok(CalcluclatorState::EnterSignificant)
|
Ok(CalcluclatorState::EnterSignificant)
|
||||||
}
|
}
|
||||||
KeyPress::Num(_) => todo!(),
|
KeyPress::Mul => {
|
||||||
KeyPress::Mul => match calc.mul() {
|
let dec = calc.mul()?;
|
||||||
Ok(dec) => {
|
number_input.set_result(dec)?;
|
||||||
number_input.set_result(dec)?;
|
Ok(CalcluclatorState::EnterOperation)
|
||||||
Ok(CalcluclatorState::EnterOperation)
|
}
|
||||||
}
|
KeyPress::Div => {
|
||||||
Err(_) => Err(()),
|
let dec = calc.div()?;
|
||||||
},
|
number_input.set_result(dec)?;
|
||||||
KeyPress::Div => match calc.div() {
|
Ok(CalcluclatorState::EnterOperation)
|
||||||
Ok(dec) => {
|
}
|
||||||
number_input.set_result(dec)?;
|
KeyPress::Plus => {
|
||||||
Ok(CalcluclatorState::EnterOperation)
|
let dec = calc.add()?;
|
||||||
}
|
number_input.set_result(dec)?;
|
||||||
Err(_) => Err(()),
|
Ok(CalcluclatorState::EnterOperation)
|
||||||
},
|
}
|
||||||
KeyPress::Plus => match calc.add() {
|
KeyPress::Minus => {
|
||||||
Ok(dec) => {
|
let dec = calc.sub()?;
|
||||||
number_input.set_result(dec)?;
|
number_input.set_result(dec)?;
|
||||||
Ok(CalcluclatorState::EnterOperation)
|
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::E => {
|
KeyPress::E => {
|
||||||
if calc.is_full() {
|
if calc.is_full() {
|
||||||
Err(())
|
Err(CalcluclatorError::StackOverflow)
|
||||||
} else {
|
} else {
|
||||||
number_input.reset();
|
number_input.reset();
|
||||||
Ok(CalcluclatorState::EnterSignificant)
|
Ok(CalcluclatorState::EnterSignificant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => Err(CalcluclatorError::InvalidOperation),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,7 +366,7 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let mut serial = arduino_hal::default_serial!(dp, pins, SERIAL_BAUD);
|
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(
|
let mut io = IOPins::new(
|
||||||
pins.d2.into_output(),
|
pins.d2.into_output(),
|
||||||
@@ -406,22 +422,41 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let key = debounce.input(last_key_readout);
|
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 TransientState::Done = state.transient {
|
||||||
if let Some(key) = key {
|
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) {
|
match state.calculator.on_key(key, &mut number_input, &mut calc) {
|
||||||
Ok(new_state) => state.calculator = new_state,
|
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 {
|
state.transient = TransientState::Err {
|
||||||
timeout: ERROR_TIMEOUT,
|
timeout: ERROR_TIMEOUT,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ufmt::uwriteln!(&mut serial, "state: {:?} stack: {}", state, calc.len())
|
ufmt::uwriteln!(
|
||||||
.unwrap_infallible();
|
&mut serial,
|
||||||
|
"<- state: {:?} stack: {}",
|
||||||
|
state.calculator,
|
||||||
|
calc.len()
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
for (i, dec) in calc.iter().enumerate() {
|
||||||
|
ufmt::uwriteln!(&mut serial, "[{}] {}", i, dec).ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state.transient.on_frame(key)
|
state.transient.on_frame(key)
|
||||||
|
|||||||
Reference in New Issue
Block a user