diff --git a/src/keyboard.rs b/src/keyboard.rs index e787964717dc95473171e989ebab861c5cc2d878..2a11aef065d5d5ebf43296a733c29addbd8ed74a 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -1,11 +1,96 @@ -use core::convert::Infallible; +use core::{convert::Infallible, fmt::Display}; use embedded_hal::{ blocking::delay::{DelayMs, DelayUs}, digital::v2::{InputPin, OutputPin}, }; use rp2040_hal::Timer; -use rtt_target::rprintln; +use rtt_target::{rprint, rprintln}; + +const NONE: char = '\0'; +const CALL_END: char = '\x01'; +const L_SHIFT: char = '\x02'; +const R_SHIFT: char = '\x03'; +const ALT: char = '\x04'; +const SYM: char = '\x05'; +const BACK: char = '\x06'; +const MENU: char = '\x07'; +const BACKSPACE: char = '\x08'; +const CALL_START: char = '\x09'; +const TOUCHPAD_BUTTON: char = '\x0B'; +const ENTER: char = '\n'; +const KEYMAP: [[char; 8]; 6] = [ + [CALL_END, ENTER, 'b', 'y', 'n', 'j', 'u', 'h'], + [NONE, BACKSPACE, '$', 'i', 'm', 'k', 'o', 'l'], + [NONE, 'p', 'x', 'd', 'z', L_SHIFT, 'e', 's'], + [NONE, R_SHIFT, 'v', 't', 'c', 'f', 'r', 'g'], + [NONE, 'a', ALT, SYM, ' ', '0', 'q', 'w'], + [ + NONE, + NONE, + BACK, + MENU, + NONE, + CALL_START, + NONE, + TOUCHPAD_BUTTON, + ], +]; + +enum KeyCode { + CallStart, + Menu, + Touchpad, + Back, + CallEnd, + Backspace, + Enter, + LeftShift, + RightShift, + Alt, + Sym, + Char(char), +} + +impl KeyCode { + fn from_keyboard(c: char, alt: bool, shift: bool) -> Self { + match (alt, shift, c) { + (_, _, CALL_END) => KeyCode::CallEnd, + (_, _, L_SHIFT) => KeyCode::LeftShift, + (_, _, R_SHIFT) => KeyCode::RightShift, + (_, _, ALT) => KeyCode::Alt, + (_, _, SYM) => KeyCode::Sym, + (_, _, BACK) => KeyCode::Back, + (_, _, MENU) => KeyCode::Menu, + (_, _, BACKSPACE) => KeyCode::Backspace, + (_, _, CALL_START) => KeyCode::CallStart, + (_, _, TOUCHPAD_BUTTON) => KeyCode::Touchpad, + (_, _, ENTER) => KeyCode::Enter, + (false, false, _) => KeyCode::Char(c), + (true, _, _) => KeyCode::Char(altify(c)), + (false, true, _) => KeyCode::Char(c.to_ascii_uppercase()), + } + } +} + +impl Display for KeyCode { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + KeyCode::CallEnd => write!(f, "<CALLEND>"), + KeyCode::Backspace => write!(f, "<BACKSPACE>"), + KeyCode::Enter => write!(f, "\n"), + KeyCode::CallStart => write!(f, "<CALLSTART>"), + KeyCode::Menu => write!(f, "<MENU>"), + KeyCode::Touchpad => write!(f, "<TOUCHPAD>"), + KeyCode::Back => write!(f, "<BACK>"), + KeyCode::LeftShift => write!(f, "<LEFTSHIFT>"), + KeyCode::RightShift => write!(f, "<RIGHTSHIFT>"), + KeyCode::Alt => write!(f, "<ALT>"), + KeyCode::Sym => write!(f, "<SYM>"), + KeyCode::Char(c) => write!(f, "{c}"), + } + } +} pub struct Keyboard< // col @@ -24,6 +109,7 @@ pub struct Keyboard< row_clk: RCLK, row_ser: RSER, row_ld: RLD, + last_state: u64, } impl< @@ -54,11 +140,13 @@ impl< row_clk, row_ser, row_ld, + + last_state: 0, } } pub fn read_state(&mut self) -> u64 { - let mut out = 0; + let mut state = 0; for x in 0..6 { // +2 gets us to QF (col 6) @@ -66,15 +154,37 @@ impl< self.timer.delay_ms(1); - out |= u64::from(read_rows( + let y = read_rows( &mut self.timer, &mut self.row_clk, &mut self.row_ser, &mut self.row_ld, - )) << (x * 8); + ); + + state |= u64::from(y) << (x * 8); + } + + let delta = (!self.last_state) & state; + for x in 0..6 { + for y in 0..8 { + if delta & (1 << (x * 8 + y)) > 0 { + let key = KEYMAP[usize::try_from(x).unwrap()][usize::try_from(y).unwrap()]; + if key != NONE { + let keycode = KeyCode::from_keyboard( + key, + is_alt_pressed(state), + is_shift_pressed(state), + ); + rprint!("{}", keycode); + } else { + rprint!("\n({}, {})", x, y); + } + } + } } - out + self.last_state = state; + state } // 1s in val are low @@ -122,3 +232,46 @@ fn read_rows< out } + +fn is_alt_pressed(state: u64) -> bool { + (state & (1 << (4 * 8 + 2))) > 0 +} + +fn is_shift_pressed(state: u64) -> bool { + let left = (state & (1 << (2 * 8 + 5))) > 0; + let right = (state & (1 << (3 * 8 + 1))) > 0; + + left || right +} + +fn altify(c: char) -> char { + match c { + 'q' => '#', + 'w' => '1', + 'e' => '2', + 'r' => '3', + 't' => '(', + 'y' => ')', + 'u' => '_', + 'i' => '-', + 'o' => '+', + 'p' => '@', + 'a' => '*', + 's' => '4', + 'd' => '5', + 'f' => '6', + 'g' => '/', + 'h' => ':', + 'j' => ';', + 'k' => ',', + 'l' => '"', + 'z' => '7', + 'x' => '8', + 'c' => '9', + 'v' => '?', + 'b' => '!', + 'n' => ',', + 'm' => '.', + _ => c, + } +} diff --git a/src/main.rs b/src/main.rs index 868b3deeb8361d34e308b498a0a84252bf8a0e13..a4a5ae2a6e16e6bb44c6c1a5a958571cebd377f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -277,7 +277,6 @@ mod app { let state = keyboard.read_state(); if state > 0 { - rprintln!("{:x}", state); write!(&mut buf, "KB: {state:x}\r\n").unwrap(); //serial.write(&buf.as_bytes()); keyboard_bl.set_duty(max_duty);