rktk_drivers_common/
debounce.rs1use rktk::{
4 config::CONST_CONFIG,
5 drivers::interface::debounce::{DebounceDriver, KeyChangeEvent},
6};
7
8pub struct EagerDebounceDriver {
14 last: [[Option<embassy_time::Instant>; CONST_CONFIG.keyboard.cols as usize];
15 CONST_CONFIG.keyboard.rows as usize],
16 debounce_time: embassy_time::Duration,
17 deboune_only_pressed: bool,
18}
19
20impl EagerDebounceDriver {
21 pub const fn new(debounce_time: embassy_time::Duration, deboune_only_pressed: bool) -> Self {
27 Self {
28 last: [[None; CONST_CONFIG.keyboard.cols as usize];
29 CONST_CONFIG.keyboard.rows as usize],
30 debounce_time,
31 deboune_only_pressed,
32 }
33 }
34}
35
36impl DebounceDriver for EagerDebounceDriver {
37 fn should_ignore_event(&mut self, event: &KeyChangeEvent, now: embassy_time::Instant) -> bool {
38 let last = self.last[event.row as usize][event.col as usize];
39 if let Some(last) = last
40 && now - last < self.debounce_time
41 {
42 if self.deboune_only_pressed {
43 return event.pressed;
44 } else {
45 return true;
46 }
47 }
48 self.last[event.row as usize][event.col as usize] = Some(now);
49 false
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use embassy_time::{Duration, Instant};
56 use rktk::drivers::interface::{debounce::DebounceDriver as _, keyscan::KeyChangeEvent};
57
58 use super::EagerDebounceDriver;
59
60 #[test]
61 fn eager_debouncer_only_pressed() {
62 let mut d = EagerDebounceDriver::new(Duration::from_millis(10), true);
73
74 assert!(
75 !d.should_ignore_event(
76 &KeyChangeEvent { row: 0, col: 0, pressed: true },
77 Instant::from_millis(0),
78 ),
79 "Key press event should not be ignored"
80 );
81
82 assert!(
83 !d.should_ignore_event(
84 &KeyChangeEvent { row: 0, col: 0, pressed: false },
85 Instant::from_millis(5),
86 ),
87 "Key release event before debounce_time should not be ignored"
88 );
89
90 assert!(
91 d.should_ignore_event(
92 &KeyChangeEvent { row: 0, col: 0, pressed: true },
93 Instant::from_millis(8),
94 ),
95 "Key press event before debounce_time should be ignored"
96 );
97
98 assert!(
99 !d.should_ignore_event(
100 &KeyChangeEvent { row: 0, col: 0, pressed: true },
101 Instant::from_millis(100),
102 ),
103 "Key press event after debounce_time should not be ignored"
104 );
105 }
106}