rktk_drivers_common/keyscan/
matrix.rs1use super::pressed::Pressed;
2use embedded_hal::digital::{InputPin, OutputPin};
3use embedded_hal_async::digital::Wait;
4use rktk::drivers::interface::keyscan::{KeyChangeEvent, KeyscanDriver};
5
6pub struct Matrix<
12 OP: OutputPin,
13 IP: InputPin + Wait,
14 T: Fn(usize, usize) -> Option<(usize, usize)>,
15 const OUTPUT_PIN_COUNT: usize,
16 const INPUT_PIN_COUNT: usize,
17 const ROWS: usize,
18 const COLS: usize,
19> {
20 output_pins: [OP; OUTPUT_PIN_COUNT],
21 input_pins: [IP; INPUT_PIN_COUNT],
22 pressed: Pressed<ROWS, COLS>,
23 map_key_pos: T,
24 scan_delay: embassy_time::Duration,
25}
26
27impl<
28 OP: OutputPin,
29 IP: InputPin + Wait,
30 T: Fn(usize, usize) -> Option<(usize, usize)>,
31 const OUTPUT_PIN_COUNT: usize,
32 const INPUT_PIN_COUNT: usize,
33 const ROWS: usize,
34 const COLS: usize,
35> Matrix<OP, IP, T, OUTPUT_PIN_COUNT, INPUT_PIN_COUNT, ROWS, COLS>
36{
37 pub fn new(
50 output_pins: [OP; OUTPUT_PIN_COUNT],
51 input_pins: [IP; INPUT_PIN_COUNT],
52 map_key_pos: T,
53 scan_delay: Option<embassy_time::Duration>,
54 ) -> Self {
55 Self {
56 output_pins,
57 input_pins,
58 pressed: Pressed::new(),
59 map_key_pos,
60 scan_delay: scan_delay.unwrap_or(embassy_time::Duration::from_micros(5)),
61 }
62 }
63}
64
65impl<
66 OP: OutputPin,
67 IP: InputPin + Wait,
68 T: Fn(usize, usize) -> Option<(usize, usize)>,
69 const OUTPUT_PIN_COUNT: usize,
70 const INPUT_PIN_COUNT: usize,
71 const ROWS: usize,
72 const COLS: usize,
73> KeyscanDriver for Matrix<OP, IP, T, OUTPUT_PIN_COUNT, INPUT_PIN_COUNT, ROWS, COLS>
74{
75 async fn scan(&mut self, mut cb: impl FnMut(KeyChangeEvent)) {
77 for output_idx in 0..OUTPUT_PIN_COUNT {
78 let _ = self.output_pins[output_idx].set_high();
79
80 embassy_time::Timer::after(self.scan_delay).await;
81
82 for (input_idx, input_pin) in self.input_pins.iter_mut().enumerate() {
83 if let Some((row, col)) = (self.map_key_pos)(input_idx, output_idx) {
84 if let Some(change) =
85 self.pressed
86 .set_pressed(input_pin.is_high().unwrap(), row, col)
87 {
88 cb(KeyChangeEvent {
89 row: row as u8,
90 col: col as u8,
91 pressed: change,
92 });
93 }
94 }
95 }
96
97 let _ = self.output_pins[output_idx].set_low();
98 }
99 }
100}