diff --git a/Cargo.lock b/Cargo.lock index 16ec191..04df67e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,11 +25,18 @@ dependencies = [ "avr-hal-generic", ] +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + [[package]] name = "avr-calc" version = "0.1.0" dependencies = [ "arduino-hal", + "calc-math", "embedded-hal 1.0.0", "nb 1.1.0", "proc-macro2", @@ -81,6 +88,13 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" +[[package]] +name = "calc-math" +version = "0.1.0" +dependencies = [ + "num-traits", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -140,6 +154,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "paste" version = "1.0.15" diff --git a/Cargo.toml b/Cargo.toml index db7d960..2dcceeb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ bench = false ufmt = "0.2.0" nb = "1.1.0" embedded-hal = "1.0" +calc-math = { path = "../calc-math" } [dependencies.arduino-hal] git = "https://github.com/rahix/avr-hal" diff --git a/src/main.rs b/src/main.rs index e700625..d34fc0d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ #![no_std] #![no_main] +use calc_math::calc::StackCalc; +use calc_math::Decimal; use core::ops::{Index, IndexMut}; use arduino_hal::{ @@ -476,7 +478,31 @@ impl NumberInput { } } - fn apply(&self, display: &mut DispalyState) { + fn to_decimal(&self) -> Decimal<5, u8> { + Decimal { + minus: self.minus, + significant: self.significant, + minus_exponent: self.minus_exponent, + exponent: self.exponent[0] * 10 + self.exponent[1], + } + } + + fn set_decimal(&mut self, dec: Decimal<5, u8>) { + self.minus = dec.minus; + self.significant = dec.significant; + self.minus_exponent = dec.minus_exponent; + self.exponent[0] = dec.exponent / 10; + self.exponent[1] = dec.exponent - dec.exponent / 10; + } +} + +// Show data on segment display +trait Show { + fn show(&self, display: &mut DispalyState); +} + +impl Show for NumberInput { + fn show(&self, display: &mut DispalyState) { display[0] = if self.minus { SegmentState::Minus } else { @@ -497,6 +523,13 @@ impl NumberInput { } } +enum State { + EnterSignificant, + EnterExponent, + EnterOperation, + Err, +} + #[arduino_hal::entry] fn main() -> ! { let dp = arduino_hal::Peripherals::take().unwrap(); @@ -539,7 +572,10 @@ fn main() -> ! { let mut number_input = NumberInput::default(); let mut display = DispalyState::default(); - number_input.apply(&mut display); + number_input.show(&mut display); + + let mut calc = StackCalc::<2, 5, u8>::default(); + let mut state = State::EnterSignificant; loop { let mut key: Option<(usize, bool, bool)> = None; @@ -558,25 +594,84 @@ fn main() -> ! { } let key = key.and_then(|(no, kn, ko)| InputKey::map(no, kn, ko)); - // TODO: impl main state - let mut err = Ok(()); if let Some(key) = debounce.input(key) { ufmt::uwriteln!(&mut serial, "key: {:?}", key).unwrap_infallible(); - match key { - InputKey::Up => todo!(), - InputKey::C => number_input.reset(), - InputKey::Num(val) => { - err = number_input.input(val); - } - InputKey::Mul => todo!(), - InputKey::Div => todo!(), - InputKey::Plus => todo!(), - InputKey::Minus => number_input.toggle_minus(), - InputKey::Down => todo!(), - InputKey::E => number_input.toggle_enter_exponent(), + let res = match state { + State::EnterSignificant => match key { + InputKey::C => Ok(number_input.reset()), + InputKey::Num(val) => number_input.input(val), + InputKey::Minus => Ok(number_input.toggle_minus()), + InputKey::E => { + number_input.toggle_enter_exponent(); + state = State::EnterExponent; + Ok(()) + } + _ => Ok(()), + }, + State::EnterExponent => match key { + InputKey::C => { + number_input.reset(); + state = State::EnterSignificant; + Ok(()) + } + InputKey::Num(val) => number_input.input(val), + InputKey::Minus => Ok(number_input.toggle_minus()), + InputKey::E => { + number_input.toggle_enter_exponent(); + match calc.push(number_input.to_decimal()) { + Ok(()) => { + number_input.reset(); + state = State::EnterSignificant; + } + Err(_) => { + state = State::EnterOperation; + } + } + Ok(()) + } + _ => Ok(()), + }, + State::EnterOperation => match key { + InputKey::Up => todo!(), + InputKey::C => { + number_input.reset(); + state = State::EnterSignificant; + Ok(()) + } + InputKey::Num(_) => todo!(), + InputKey::Mul => todo!(), + InputKey::Div => todo!(), + InputKey::Plus => match calc.add() { + Ok(dec) => { + number_input.set_decimal(dec); + Ok(()) + } + Err(_) => Err(()), + }, + InputKey::Minus => todo!(), + InputKey::Down => todo!(), + InputKey::E => todo!(), + }, + State::Err => match key { + InputKey::C => { + number_input.reset(); + state = State::EnterSignificant; + Ok(()) + } + _ => Ok(()), + }, + }; + if res.is_err() { + state = State::Err + } + + match state { + State::EnterSignificant | State::EnterExponent | State::EnterOperation => { + number_input.show(&mut display) + } + State::Err => todo!("display error"), } - number_input.apply(&mut display); } arduino_hal::delay_ms(1); }