diff --git a/src/main.rs b/src/main.rs index 8f11f0e..e700625 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ #![no_std] #![no_main] +use core::ops::{Index, IndexMut}; + use arduino_hal::{ adc::{ channel::{ADC6, ADC7}, @@ -179,9 +181,11 @@ impl IOPins { } } +#[derive(Clone, Copy, PartialEq, Eq)] enum SegmentState { Num(u8, bool), Minus, + Dot, Off, } @@ -267,12 +271,13 @@ impl SegmentState { } } SegmentState::Minus => seg.set_g(), + SegmentState::Dot => seg.set_dp(), SegmentState::Off => (), } } } -struct DispalyState(pub [SegmentState; 9]); +struct DispalyState([SegmentState; 9]); impl Default for DispalyState { fn default() -> DispalyState { @@ -290,6 +295,40 @@ impl Default for DispalyState { } } +impl Index for DispalyState { + type Output = SegmentState; + + fn index(&self, index: usize) -> &Self::Output { + &self.0[index] + } +} + +impl IndexMut for DispalyState { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + &mut self.0[index] + } +} + +impl DispalyState { + fn set(&mut self, seg: [SegmentState; 9]) { + self.0 = seg; + } + + fn busy(&mut self) { + self.set([ + SegmentState::Off, + SegmentState::Dot, + SegmentState::Off, + SegmentState::Off, + SegmentState::Off, + SegmentState::Off, + SegmentState::Off, + SegmentState::Off, + SegmentState::Off, + ]) + } +} + #[derive(uDebug, Clone, Copy, PartialEq, Eq)] enum InputKey { Up, @@ -376,6 +415,88 @@ impl Debounce { } } +#[derive(Default)] +struct NumberInput { + minus: bool, + significant: [u8; 5], + minus_exponent: bool, + exponent: [u8; 2], + enter_exponent: bool, + significant_pos: usize, + exponent_pos: usize, +} + +impl NumberInput { + fn reset(&mut self) { + *self = Self::default(); + } + fn input_significant(&mut self, val: u8) -> Result<(), ()> { + if val > 9 { + panic!("Bad significatn val"); + } + if self.significant_pos >= 5 { + return Err(()); + } + self.significant[self.significant_pos] = val; + self.significant_pos += 1; + return Ok(()); + } + + fn input_exponent(&mut self, val: u8) -> Result<(), ()> { + if val > 9 { + panic!("Bad exponent val"); + } + if self.exponent_pos >= 2 { + return Err(()); + } + self.exponent[self.exponent_pos] = val; + self.exponent_pos += 1; + Ok(()) + } + + fn input(&mut self, val: u8) -> Result<(), ()> { + if self.enter_exponent { + self.input_exponent(val) + } else { + self.input_significant(val) + } + } + + fn toggle_enter_exponent(&mut self) { + self.significant_pos = 0; + self.exponent_pos = 0; + self.enter_exponent = !self.enter_exponent; + } + + fn toggle_minus(&mut self) { + if self.enter_exponent { + self.minus_exponent = !self.minus_exponent; + } else { + self.minus = !self.minus; + } + } + + fn apply(&self, display: &mut DispalyState) { + display[0] = if self.minus { + SegmentState::Minus + } else { + SegmentState::Off + }; + display[1] = SegmentState::Num(self.significant[0], true); + display[2] = SegmentState::Num(self.significant[1], false); + display[3] = SegmentState::Num(self.significant[2], false); + display[4] = SegmentState::Num(self.significant[3], false); + display[5] = SegmentState::Num(self.significant[4], false); + display[6] = if self.minus_exponent { + SegmentState::Minus + } else { + SegmentState::Off + }; + display[7] = SegmentState::Num(self.exponent[0], false); + display[8] = SegmentState::Num(self.exponent[1], false); + } +} + #[arduino_hal::entry] fn main() -> ! { let dp = arduino_hal::Peripherals::take().unwrap(); @@ -415,17 +536,10 @@ fn main() -> ! { let mut adc = Adc::new(dp.ADC, Default::default()); let input = Input::new(ADC7, ADC6); let mut debounce = Debounce::default(); + let mut number_input = NumberInput::default(); let mut display = DispalyState::default(); - display.0[0] = SegmentState::Num(0, true); - display.0[1] = SegmentState::Num(1, false); - display.0[2] = SegmentState::Num(2, false); - display.0[3] = SegmentState::Num(3, false); - display.0[4] = SegmentState::Num(4, false); - display.0[5] = SegmentState::Num(5, false); - display.0[6] = SegmentState::Num(6, false); - display.0[7] = SegmentState::Num(7, false); - display.0[8] = SegmentState::Num(8, false); + number_input.apply(&mut display); loop { let mut key: Option<(usize, bool, bool)> = None; @@ -444,9 +558,25 @@ 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(), + } + number_input.apply(&mut display); } arduino_hal::delay_ms(1); }