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