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 if self.deboune_only_pressed {
42 return event.pressed;
43 } else {
44 return true;
45 }
46 }
47 self.last[event.row as usize][event.col as usize] = Some(now);
48 false
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use embassy_time::{Duration, Instant};
55 use rktk::drivers::interface::{debounce::DebounceDriver as _, keyscan::KeyChangeEvent};
56
57 use super::EagerDebounceDriver;
58
59 #[test]
60 fn eager_debouncer_only_pressed() {
61 let mut d = EagerDebounceDriver::new(Duration::from_millis(10), true);
72
73 assert!(
74 !d.should_ignore_event(
75 &KeyChangeEvent {
76 row: 0,
77 col: 0,
78 pressed: true,
79 },
80 Instant::from_millis(0),
81 ),
82 "Key press event should not be ignored"
83 );
84
85 assert!(
86 !d.should_ignore_event(
87 &KeyChangeEvent {
88 row: 0,
89 col: 0,
90 pressed: false,
91 },
92 Instant::from_millis(5),
93 ),
94 "Key release event before debounce_time should not be ignored"
95 );
96
97 assert!(
98 d.should_ignore_event(
99 &KeyChangeEvent {
100 row: 0,
101 col: 0,
102 pressed: true,
103 },
104 Instant::from_millis(8),
105 ),
106 "Key press event before debounce_time should be ignored"
107 );
108
109 assert!(
110 !d.should_ignore_event(
111 &KeyChangeEvent {
112 row: 0,
113 col: 0,
114 pressed: true,
115 },
116 Instant::from_millis(100),
117 ),
118 "Key press event after debounce_time should not be ignored"
119 );
120 }
121}