oxstack_cardputer/
keyboard.rs1use esp_hal::gpio::{Input, InputConfig, Pull};
8use esp_hal::peripherals::GPIO11;
9use oxstack_drivers::tca8418::{self, Event, FIFO_DEPTH, Matrix, Tca8418};
10use oxstack_input::{KeyEvent, KeyboardState, cardputer};
11
12use crate::i2c::{SysI2cBus, SysI2cDevice, device};
13
14pub type Error = embassy_embedded_hal::shared_bus::I2cDeviceError<esp_hal::i2c::master::Error>;
16
17const MATRIX: Matrix = Matrix::new(cardputer::ADV_MATRIX_ROWS, cardputer::ADV_MATRIX_COLS);
18
19#[allow(missing_docs)]
21pub struct KeyboardResources<'d> {
22 pub int: GPIO11<'d>,
23}
24reborrow_group!(KeyboardResources { int });
25
26impl<'d> KeyboardResources<'d> {
27 pub async fn init(&mut self, bus: &'static SysI2cBus) -> Result<Keyboard<'_>, Error> {
30 let int = Input::new(
33 self.int.reborrow(),
34 InputConfig::default().with_pull(Pull::Up),
35 );
36 let mut scanner = Tca8418::new(device(bus), tca8418::DEFAULT_ADDRESS);
37 scanner.configure(MATRIX).await?;
38 Ok(Keyboard {
39 scanner,
40 int,
41 state: KeyboardState::new(),
42 fifo: [0; FIFO_DEPTH],
43 pos: 0,
44 len: 0,
45 })
46 }
47}
48
49pub struct Keyboard<'d> {
51 scanner: Tca8418<SysI2cDevice>,
52 int: Input<'d>,
53 state: KeyboardState,
54 fifo: [u8; FIFO_DEPTH],
56 pos: u8,
57 len: u8,
58}
59
60impl Keyboard<'_> {
61 pub async fn next_event(&mut self) -> Result<KeyEvent, Error> {
68 loop {
69 while self.pos < self.len {
70 let raw = self.fifo[usize::from(self.pos)];
71 self.pos += 1;
72 if let Some(Event::Key(k)) = Event::decode(raw)
73 && let Some(key) = cardputer::from_adv_matrix(k.row, k.col)
74 {
75 return Ok(self.state.apply(key, k.pressed));
76 }
77 }
78 self.int.wait_for_low().await;
81 let n = self.scanner.drain(&mut self.fifo).await?.len();
82 self.scanner.clear_interrupts().await?;
83 (self.pos, self.len) = (0, n as u8);
84 }
85 }
86
87 pub fn state(&self) -> &KeyboardState {
89 &self.state
90 }
91}