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 if now - last < self.debounce_time {
41 if self.deboune_only_pressed {
42 return event.pressed;
43 } else {
44 return true;
45 }
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 {
77 row: 0,
78 col: 0,
79 pressed: true,
80 },
81 Instant::from_millis(0),
82 ),
83 "Key press event should not be ignored"
84 );
85
86 assert!(
87 !d.should_ignore_event(
88 &KeyChangeEvent {
89 row: 0,
90 col: 0,
91 pressed: false,
92 },
93 Instant::from_millis(5),
94 ),
95 "Key release event before debounce_time should not be ignored"
96 );
97
98 assert!(
99 d.should_ignore_event(
100 &KeyChangeEvent {
101 row: 0,
102 col: 0,
103 pressed: true,
104 },
105 Instant::from_millis(8),
106 ),
107 "Key press event before debounce_time should be ignored"
108 );
109
110 assert!(
111 !d.should_ignore_event(
112 &KeyChangeEvent {
113 row: 0,
114 col: 0,
115 pressed: true,
116 },
117 Instant::from_millis(100),
118 ),
119 "Key press event after debounce_time should not be ignored"
120 );
121 }
122}