Map Usb Keycodes to Enum

This commit is contained in:
2026-07-25 16:45:58 -05:00
committed by Nick Mello
parent 189a8c463f
commit 59a3ab1596
3 changed files with 131 additions and 24 deletions

View File

@@ -4,14 +4,126 @@ use embassy_sync::blocking_mutex::raw::RawMutex;
use embassy_sync::channel::Sender; use embassy_sync::channel::Sender;
use futures_util::stream::{FuturesUnordered, StreamExt}; use futures_util::stream::{FuturesUnordered, StreamExt};
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(dead_code)]
pub enum UsbKeycodes {
A = 4,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Zero,
Enter,
Escape,
BackSpace,
Tab,
Space,
Hyphen,
Equal,
SquareBracketLeft,
SquareBracketRight,
BackSlash,
Semicolon = 51,
SingleQuote,
Backtick,
Comma,
Period,
ForwardSlash,
CapsLock,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
PrintScreen,
ScrollLock,
Pause,
Insert,
Home,
PageUp,
Delete,
End,
PageDown,
Right,
Left,
Down,
Up,
NumLock,
F13 = 104,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
Execute,
Help,
Menu,
Select,
Again,
Undo,
Cut,
Copy,
Paste,
Find,
Mute,
VolumeUp,
VolumeDown,
}
pub struct Key<'a> { pub struct Key<'a> {
button: Input<'a>, button: Input<'a>,
value: char, value: UsbKeycodes,
} }
impl Key<'_> { impl Key<'_> {
#[allow(unused)] #[allow(unused)]
pub async fn set_value(mut self, value: char) { pub async fn set_value(mut self, value: UsbKeycodes) {
self.value = value; self.value = value;
} }
} }
@@ -34,7 +146,7 @@ impl<'d, const KEY_N: usize> Keyboard<'d, KEY_N> {
} }
} }
pub fn add_key(&mut self, button: Input<'d>, value: char) -> Result<(), KeyboardError> { pub fn add_key(&mut self, button: Input<'d>, value: UsbKeycodes) -> Result<(), KeyboardError> {
let key = self let key = self
.keys .keys
.get_mut(self.num_keys) .get_mut(self.num_keys)
@@ -46,8 +158,10 @@ impl<'d, const KEY_N: usize> Keyboard<'d, KEY_N> {
Ok(()) Ok(())
} }
pub async fn process<'ch, M, const N: usize>(mut self, sender: Sender<'ch, M, Vec<char>, N>) pub async fn process<'ch, M, const N: usize>(
where mut self,
sender: Sender<'ch, M, Vec<UsbKeycodes>, N>,
) where
M: RawMutex, M: RawMutex,
{ {
loop { loop {
@@ -58,7 +172,7 @@ impl<'d, const KEY_N: usize> Keyboard<'d, KEY_N> {
.next() .next()
.await; .await;
let mut pressed: Vec<char> = Vec::new(); let mut pressed: Vec<UsbKeycodes> = Vec::new();
for key in self.keys.iter_mut().filter_map(|opt| opt.as_mut()) { for key in self.keys.iter_mut().filter_map(|opt| opt.as_mut()) {
if key.button.is_low() { if key.button.is_low() {
pressed.push(key.value); pressed.push(key.value);

View File

@@ -7,7 +7,7 @@ mod usb;
extern crate alloc; extern crate alloc;
use crate::heartbeat::heartbeat; use crate::heartbeat::heartbeat;
use crate::keyboard::Keyboard; use crate::keyboard::{Keyboard, UsbKeycodes};
use alloc::vec::Vec; use alloc::vec::Vec;
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
@@ -39,7 +39,7 @@ async fn main(_spawner: Spawner) {
); );
} }
let keyboard_events: Channel<ThreadModeRawMutex, Vec<char>, 64> = Channel::new(); let keyboard_events: Channel<ThreadModeRawMutex, Vec<UsbKeycodes>, 64> = Channel::new();
let p = embassy_rp::init(Default::default()); let p = embassy_rp::init(Default::default());
@@ -51,7 +51,7 @@ async fn main(_spawner: Spawner) {
let mut signal_pin = Input::new(p.PIN_15, Pull::None); let mut signal_pin = Input::new(p.PIN_15, Pull::None);
signal_pin.set_schmitt(true); signal_pin.set_schmitt(true);
match keyboard.add_key(signal_pin, 'a') { match keyboard.add_key(signal_pin, UsbKeycodes::Left) {
Ok(()) => info!("Key 'a' registered"), Ok(()) => info!("Key 'a' registered"),
Err(e) => { Err(e) => {
defmt::panic!("Failed to register key! {:?}", e); defmt::panic!("Failed to register key! {:?}", e);
@@ -59,7 +59,7 @@ async fn main(_spawner: Spawner) {
} }
let mut signal_pin = Input::new(p.PIN_16, Pull::None); let mut signal_pin = Input::new(p.PIN_16, Pull::None);
signal_pin.set_schmitt(true); signal_pin.set_schmitt(true);
match keyboard.add_key(signal_pin, 's') { match keyboard.add_key(signal_pin, UsbKeycodes::Down) {
Ok(()) => info!("Key 's' registered"), Ok(()) => info!("Key 's' registered"),
Err(e) => { Err(e) => {
defmt::panic!("Failed to register key! {:?}", e); defmt::panic!("Failed to register key! {:?}", e);
@@ -67,7 +67,7 @@ async fn main(_spawner: Spawner) {
} }
let mut signal_pin = Input::new(p.PIN_17, Pull::None); let mut signal_pin = Input::new(p.PIN_17, Pull::None);
signal_pin.set_schmitt(true); signal_pin.set_schmitt(true);
match keyboard.add_key(signal_pin, 'x') { match keyboard.add_key(signal_pin, UsbKeycodes::X) {
Ok(()) => info!("Key 'x' registered"), Ok(()) => info!("Key 'x' registered"),
Err(e) => { Err(e) => {
defmt::panic!("Failed to register key! {:?}", e); defmt::panic!("Failed to register key! {:?}", e);
@@ -75,7 +75,7 @@ async fn main(_spawner: Spawner) {
} }
let mut signal_pin = Input::new(p.PIN_18, Pull::None); let mut signal_pin = Input::new(p.PIN_18, Pull::None);
signal_pin.set_schmitt(true); signal_pin.set_schmitt(true);
match keyboard.add_key(signal_pin, 'd') { match keyboard.add_key(signal_pin, UsbKeycodes::Right) {
Ok(()) => info!("Key 'd' registered"), Ok(()) => info!("Key 'd' registered"),
Err(e) => { Err(e) => {
defmt::panic!("Failed to register key! {:?}", e); defmt::panic!("Failed to register key! {:?}", e);
@@ -83,7 +83,7 @@ async fn main(_spawner: Spawner) {
} }
let mut signal_pin = Input::new(p.PIN_19, Pull::None); let mut signal_pin = Input::new(p.PIN_19, Pull::None);
signal_pin.set_schmitt(true); signal_pin.set_schmitt(true);
match keyboard.add_key(signal_pin, 'c') { match keyboard.add_key(signal_pin, UsbKeycodes::C) {
Ok(()) => info!("Key 'c' registered"), Ok(()) => info!("Key 'c' registered"),
Err(e) => { Err(e) => {
defmt::panic!("Failed to register key! {:?}", e); defmt::panic!("Failed to register key! {:?}", e);
@@ -91,7 +91,7 @@ async fn main(_spawner: Spawner) {
} }
let mut signal_pin = Input::new(p.PIN_20, Pull::None); let mut signal_pin = Input::new(p.PIN_20, Pull::None);
signal_pin.set_schmitt(true); signal_pin.set_schmitt(true);
match keyboard.add_key(signal_pin, 'w') { match keyboard.add_key(signal_pin, UsbKeycodes::Up) {
Ok(()) => info!("Key 'w' registered"), Ok(()) => info!("Key 'w' registered"),
Err(e) => { Err(e) => {
defmt::panic!("Failed to register key! {:?}", e); defmt::panic!("Failed to register key! {:?}", e);

View File

@@ -1,3 +1,4 @@
use crate::keyboard::UsbKeycodes;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::cell::OnceCell; use core::cell::OnceCell;
use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
@@ -107,7 +108,7 @@ impl<'d> UsbKeyboard<'d> {
} }
} }
pub async fn run<'ch, M, const N: usize>(self, receiver: Receiver<'ch, M, Vec<char>, N>) pub async fn run<'ch, M, const N: usize>(self, receiver: Receiver<'ch, M, Vec<UsbKeycodes>, N>)
where where
M: RawMutex, M: RawMutex,
{ {
@@ -130,15 +131,7 @@ impl<'d> UsbKeyboard<'d> {
let mut boot_keys = [0, 0, 0, 0, 0, 0, 0, 0]; let mut boot_keys = [0, 0, 0, 0, 0, 0, 0, 0];
for (&key, idx) in event.iter().zip(2usize..) { for (&key, idx) in event.iter().zip(2usize..) {
let boot_key = match key { boot_keys[idx] = key as u8;
'd' => 79,
'a' => 80,
's' => 81,
'w' => 82,
('a'..='z') => (key as u8) - b'a' + 4,
_ => defmt::panic!("Not supported key: {}", key),
};
boot_keys[idx] = boot_key;
} }
if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 { if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {