factored out keyboard file
This commit is contained in:
104
src/keyboard.rs
Normal file
104
src/keyboard.rs
Normal file
@@ -0,0 +1,104 @@
|
||||
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<KeyPress> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct KeyReadout {
|
||||
kn: bool,
|
||||
ko: bool,
|
||||
}
|
||||
|
||||
impl KeyReadout {
|
||||
pub fn to_keypress(&self, display_no: usize) -> Option<KeyPress> {
|
||||
KeyPress::map(display_no, self.kn, self.ko)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Keyboard<KN, KO> {
|
||||
kn: KN,
|
||||
ko: KO,
|
||||
}
|
||||
|
||||
impl<KN: AdcChannel<Atmega, ADC>, KO: AdcChannel<Atmega, ADC>> Keyboard<KN, KO> {
|
||||
pub fn new(kn: KN, ko: KO) -> Keyboard<KN, KO> {
|
||||
Keyboard { kn, ko }
|
||||
}
|
||||
|
||||
pub fn read(&self, adc: &mut Adc) -> Option<KeyReadout> {
|
||||
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 {
|
||||
kn: kn > KEYBOARD_ADC_THRESHOLD,
|
||||
ko: ko > KEYBOARD_ADC_THRESHOLD,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Debounce {
|
||||
record: [Option<KeyPress>; DEBOUNCE_DEPTH],
|
||||
pos: usize,
|
||||
last: Option<KeyPress>,
|
||||
}
|
||||
|
||||
impl Debounce {
|
||||
pub fn input(&mut self, key: Option<KeyPress>) -> Option<KeyPress> {
|
||||
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
|
||||
} else if self.record.iter().all(|hist| hist == &None) {
|
||||
self.last = None;
|
||||
None
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user