use arduino_hal::{adc::AdcChannel, hal::Atmega, pac::ADC, Adc}; use ufmt::derive::uDebug; use crate::{DEBOUNCE_DEPTH, KEYBOARD_ADC_THRESHOLD}; #[derive(uDebug, Clone, Copy, PartialEq, Eq)] pub enum KeyPress { Up, C, Num(u8), Mul, Div, Plus, Minus, Down, E, } impl KeyPress { fn map(display_no: usize, kn: bool, ko: bool) -> Option { match (display_no, kn, ko) { (0, true, false) => Some(KeyPress::Num(1)), (0, false, true) => Some(KeyPress::C), (1, true, false) => Some(KeyPress::Num(5)), (1, false, true) => Some(KeyPress::Div), (2, true, false) => Some(KeyPress::Num(6)), (2, false, true) => Some(KeyPress::Mul), (3, true, false) => Some(KeyPress::Num(7)), (3, false, true) => Some(KeyPress::Up), (4, true, false) => Some(KeyPress::Num(8)), (4, false, true) => Some(KeyPress::E), (5, true, false) => Some(KeyPress::Num(9)), (5, false, true) => Some(KeyPress::Num(0)), (6, true, false) => Some(KeyPress::Num(2)), (6, false, true) => Some(KeyPress::Down), (7, true, false) => Some(KeyPress::Num(3)), (7, false, true) => Some(KeyPress::Plus), (8, true, false) => Some(KeyPress::Num(4)), (8, false, true) => Some(KeyPress::Minus), _ => None, } } } #[derive(uDebug, Clone, Copy, PartialEq, Eq)] pub struct KeyReadout { display_no: usize, kn: bool, ko: bool, } pub struct Keyboard { kn: KN, ko: KO, } impl, KO: AdcChannel> Keyboard { pub fn new(kn: KN, ko: KO) -> Keyboard { Keyboard { kn, ko } } pub fn read(&self, adc: &mut Adc, display_no: usize) -> Option { let kn = adc.read_blocking(&self.kn); let ko = adc.read_blocking(&self.ko); if kn > KEYBOARD_ADC_THRESHOLD || ko > KEYBOARD_ADC_THRESHOLD { Some(KeyReadout { display_no, kn: kn > KEYBOARD_ADC_THRESHOLD, ko: ko > KEYBOARD_ADC_THRESHOLD, }) } else { None } } } #[derive(Default)] pub struct Debounce { record: [Option; DEBOUNCE_DEPTH], pos: usize, last: Option, } impl Debounce { pub fn input(&mut self, key: Option) -> Option { self.record[self.pos] = key; self.pos += 1; if self.pos >= self.record.len() { self.pos = 0; } if self.record.iter().all(|hist| hist == &key) && self.last != key { self.last = key; key.and_then(|key_readout| { KeyPress::map(key_readout.display_no, key_readout.kn, key_readout.ko) }) } else if self.record.iter().all(|hist| hist == &None) { self.last = None; None } else { None } } }