debounce key readout

This commit is contained in:
2025-07-18 20:31:23 +01:00
parent 7467f41c30
commit b597bedc0b
2 changed files with 15 additions and 18 deletions

View File

@@ -42,17 +42,13 @@ impl KeyPress {
} }
} }
#[derive(uDebug, Clone, Copy, PartialEq, Eq)]
pub struct KeyReadout { pub struct KeyReadout {
display_no: usize,
kn: bool, kn: bool,
ko: 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> { pub struct Keyboard<KN, KO> {
kn: KN, kn: KN,
ko: KO, ko: KO,
@@ -63,11 +59,12 @@ impl<KN: AdcChannel<Atmega, ADC>, KO: AdcChannel<Atmega, ADC>> Keyboard<KN, KO>
Keyboard { kn, ko } Keyboard { kn, ko }
} }
pub fn read(&self, adc: &mut Adc) -> Option<KeyReadout> { pub fn read(&self, adc: &mut Adc, display_no: usize) -> Option<KeyReadout> {
let kn = adc.read_blocking(&self.kn); let kn = adc.read_blocking(&self.kn);
let ko = adc.read_blocking(&self.ko); let ko = adc.read_blocking(&self.ko);
if kn > KEYBOARD_ADC_THRESHOLD || ko > KEYBOARD_ADC_THRESHOLD { if kn > KEYBOARD_ADC_THRESHOLD || ko > KEYBOARD_ADC_THRESHOLD {
Some(KeyReadout { Some(KeyReadout {
display_no,
kn: kn > KEYBOARD_ADC_THRESHOLD, kn: kn > KEYBOARD_ADC_THRESHOLD,
ko: ko > KEYBOARD_ADC_THRESHOLD, ko: ko > KEYBOARD_ADC_THRESHOLD,
}) })
@@ -79,13 +76,13 @@ impl<KN: AdcChannel<Atmega, ADC>, KO: AdcChannel<Atmega, ADC>> Keyboard<KN, KO>
#[derive(Default)] #[derive(Default)]
pub struct Debounce { pub struct Debounce {
record: [Option<KeyPress>; DEBOUNCE_DEPTH], record: [Option<KeyReadout>; DEBOUNCE_DEPTH],
pos: usize, pos: usize,
last: Option<KeyPress>, last: Option<KeyReadout>,
} }
impl Debounce { impl Debounce {
pub fn input(&mut self, key: Option<KeyPress>) -> Option<KeyPress> { pub fn input(&mut self, key: Option<KeyReadout>) -> Option<KeyPress> {
self.record[self.pos] = key; self.record[self.pos] = key;
self.pos += 1; self.pos += 1;
if self.pos >= self.record.len() { if self.pos >= self.record.len() {
@@ -93,7 +90,9 @@ impl Debounce {
} }
if self.record.iter().all(|hist| hist == &key) && self.last != key { if self.record.iter().all(|hist| hist == &key) && self.last != key {
self.last = key; self.last = key;
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) { } else if self.record.iter().all(|hist| hist == &None) {
self.last = None; self.last = None;
None None

View File

@@ -480,7 +480,7 @@ fn main() -> ! {
); );
let mut adc = Adc::new(dp.ADC, Default::default()); let mut adc = Adc::new(dp.ADC, Default::default());
let input = Keyboard::new(ADC7, ADC6); let keyboard = Keyboard::new(ADC7, ADC6);
let mut debounce = Debounce::default(); let mut debounce = Debounce::default();
let mut number_input = NumberInput::default(); let mut number_input = NumberInput::default();
@@ -491,7 +491,7 @@ fn main() -> ! {
let mut state = State::EnterSignificant; let mut state = State::EnterSignificant;
loop { loop {
let mut last_key_readout: Option<(usize, KeyReadout)> = None; let mut last_key_readout: Option<KeyReadout> = None;
for (mut io_select, ss) in io.iter_mut().zip(display.0.iter()) { for (mut io_select, ss) in io.iter_mut().zip(display.0.iter()) {
ss.apply(&mut seg); ss.apply(&mut seg);
io_select.set_on(); io_select.set_on();
@@ -499,15 +499,13 @@ fn main() -> ! {
io_select.set_off(); io_select.set_off();
seg.set_off(); seg.set_off();
io_select.set_on(); io_select.set_on();
if let Some(key_readout) = input.read(&mut adc) { if let key_readout @ Some(_) = keyboard.read(&mut adc, io_select.display_no()) {
last_key_readout = Some((io_select.display_no(), key_readout)); last_key_readout = key_readout;
} }
io_select.set_off(); io_select.set_off();
} }
let key_press = last_key_readout if let Some(key) = debounce.input(last_key_readout) {
.and_then(|(display_no, key_readout)| key_readout.to_keypress(display_no));
if let Some(key) = debounce.input(key_press) {
ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible();
let res = match state { let res = match state {
State::EnterSignificant => match key { State::EnterSignificant => match key {