Get a dummy keyboard working
This commit is contained in:
189
src/keyboard.rs
Normal file
189
src/keyboard.rs
Normal file
@ -0,0 +1,189 @@
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use embassy_time::{Duration, Timer};
|
||||
|
||||
pub const ROWS: usize = 3;
|
||||
pub const COLS: usize = 5;
|
||||
const NEW_SWITCH: Switch = Switch::new();
|
||||
const NEW_ROW: [Switch; COLS] = [NEW_SWITCH; COLS];
|
||||
pub static MATRIX: [[Switch; COLS]; ROWS] = [NEW_ROW; ROWS];
|
||||
|
||||
pub static TEST_KEYMAP: [[Button; COLS]; ROWS] = [
|
||||
[
|
||||
Button::KEY_A,
|
||||
Button::KEY_B,
|
||||
Button::KEY_C,
|
||||
Button::KEY_D,
|
||||
Button::KEY_E,
|
||||
],
|
||||
[
|
||||
Button::KEY_T,
|
||||
Button::KEY_R,
|
||||
Button::KEY_H,
|
||||
Button::KEY_I,
|
||||
Button::KEY_SPACE,
|
||||
],
|
||||
[
|
||||
Button::KEY_O,
|
||||
Button::KEY_L,
|
||||
Button::KEY_LSHIFT,
|
||||
Button::KEY_LCTRL,
|
||||
Button::KEY_LALT,
|
||||
],
|
||||
];
|
||||
|
||||
pub struct Switch {
|
||||
state: AtomicBool,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Switch {
|
||||
pub const fn new() -> Self {
|
||||
Switch {
|
||||
state: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn press(&self) {
|
||||
self.state.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
pub fn release(&self) {
|
||||
self.state.store(false, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
pub fn is_pressed(&self) -> bool {
|
||||
self.state.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Button {
|
||||
Key { keycode: u8 },
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Button {
|
||||
pub const fn key(keycode: u8) -> Self {
|
||||
Button::Key { keycode }
|
||||
}
|
||||
|
||||
// https://usb.org/sites/default/files/hut1_3_0.pdf
|
||||
pub const KEY_A: Button = Button::key(0x04);
|
||||
pub const KEY_B: Button = Button::key(0x05);
|
||||
pub const KEY_C: Button = Button::key(0x06);
|
||||
pub const KEY_D: Button = Button::key(0x07);
|
||||
pub const KEY_E: Button = Button::key(0x08);
|
||||
pub const KEY_F: Button = Button::key(0x09);
|
||||
pub const KEY_G: Button = Button::key(0x0A);
|
||||
pub const KEY_H: Button = Button::key(0x0B);
|
||||
pub const KEY_I: Button = Button::key(0x0C);
|
||||
pub const KEY_J: Button = Button::key(0x0D);
|
||||
pub const KEY_K: Button = Button::key(0x0E);
|
||||
pub const KEY_L: Button = Button::key(0x0F);
|
||||
pub const KEY_M: Button = Button::key(0x10);
|
||||
pub const KEY_N: Button = Button::key(0x11);
|
||||
pub const KEY_O: Button = Button::key(0x12);
|
||||
pub const KEY_P: Button = Button::key(0x13);
|
||||
pub const KEY_Q: Button = Button::key(0x14);
|
||||
pub const KEY_R: Button = Button::key(0x15);
|
||||
pub const KEY_S: Button = Button::key(0x16);
|
||||
pub const KEY_T: Button = Button::key(0x17);
|
||||
pub const KEY_U: Button = Button::key(0x18);
|
||||
pub const KEY_V: Button = Button::key(0x19);
|
||||
pub const KEY_W: Button = Button::key(0x1A);
|
||||
pub const KEY_X: Button = Button::key(0x1B);
|
||||
pub const KEY_Y: Button = Button::key(0x1C);
|
||||
pub const KEY_Z: Button = Button::key(0x1D);
|
||||
|
||||
pub const KEY_1: Button = Button::key(0x1E);
|
||||
pub const KEY_2: Button = Button::key(0x1F);
|
||||
pub const KEY_3: Button = Button::key(0x20);
|
||||
pub const KEY_4: Button = Button::key(0x21);
|
||||
pub const KEY_5: Button = Button::key(0x22);
|
||||
pub const KEY_6: Button = Button::key(0x23);
|
||||
pub const KEY_7: Button = Button::key(0x24);
|
||||
pub const KEY_8: Button = Button::key(0x25);
|
||||
pub const KEY_9: Button = Button::key(0x26);
|
||||
pub const KEY_0: Button = Button::key(0x27);
|
||||
|
||||
pub const KEY_SPACE: Button = Button::key(0x2C);
|
||||
pub const KEY_RETURN: Button = Button::key(0x28);
|
||||
|
||||
pub const KEY_LCTRL: Button = Button::key(0xE0);
|
||||
pub const KEY_RCTRL: Button = Button::key(0xE4);
|
||||
|
||||
pub const KEY_LSHIFT: Button = Button::key(0xE1);
|
||||
pub const KEY_RSHIFT: Button = Button::key(0xE5);
|
||||
|
||||
pub const KEY_LALT: Button = Button::key(0xE2);
|
||||
pub const KEY_RALT: Button = Button::key(0xE6);
|
||||
}
|
||||
|
||||
pub fn letter_to_key(c: char) -> Option<Button> {
|
||||
if !c.is_ascii() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let c = c.to_ascii_uppercase();
|
||||
|
||||
let key = match c {
|
||||
'A' => Button::KEY_A,
|
||||
'B' => Button::KEY_B,
|
||||
'C' => Button::KEY_C,
|
||||
'D' => Button::KEY_D,
|
||||
'E' => Button::KEY_E,
|
||||
'F' => Button::KEY_F,
|
||||
'G' => Button::KEY_G,
|
||||
'H' => Button::KEY_H,
|
||||
'I' => Button::KEY_I,
|
||||
'J' => Button::KEY_J,
|
||||
'K' => Button::KEY_K,
|
||||
'L' => Button::KEY_L,
|
||||
'M' => Button::KEY_M,
|
||||
'N' => Button::KEY_N,
|
||||
'O' => Button::KEY_O,
|
||||
'P' => Button::KEY_P,
|
||||
'Q' => Button::KEY_Q,
|
||||
'R' => Button::KEY_R,
|
||||
'S' => Button::KEY_S,
|
||||
'T' => Button::KEY_T,
|
||||
'U' => Button::KEY_U,
|
||||
'V' => Button::KEY_V,
|
||||
'W' => Button::KEY_W,
|
||||
'X' => Button::KEY_X,
|
||||
'Y' => Button::KEY_Y,
|
||||
'Z' => Button::KEY_Z,
|
||||
' ' => Button::KEY_SPACE,
|
||||
'\n' => Button::KEY_RETURN,
|
||||
_ => {
|
||||
log::info!("char {c:?} -> None");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
log::info!("char {c:?} -> {key:?}");
|
||||
|
||||
Some(key)
|
||||
}
|
||||
|
||||
pub async fn test_type(s: &str) {
|
||||
log::info!("typing {s:?}");
|
||||
|
||||
for c in s.chars() {
|
||||
let Some(key) = letter_to_key(c) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
for col in 0..COLS {
|
||||
for row in 0..ROWS {
|
||||
if TEST_KEYMAP[row][col] == key {
|
||||
MATRIX[row][col].press();
|
||||
Timer::after(Duration::from_millis(20)).await;
|
||||
MATRIX[row][col].release();
|
||||
Timer::after(Duration::from_millis(5)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user