Move away from matrix-based key layout
This commit is contained in:
@ -2,6 +2,7 @@ pub mod report;
|
||||
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_rp::{peripherals::USB, usb::Driver};
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embassy_usb::{
|
||||
class::hid::{self, HidReaderWriter, ReadError, ReportId, RequestHandler},
|
||||
@ -13,8 +14,8 @@ use static_cell::StaticCell;
|
||||
use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
|
||||
|
||||
use crate::{
|
||||
keyboard::{Button, COLS, MATRIX, ROWS, TEST_KEYMAP},
|
||||
usb::keyboard::report::{KeyboardReport, EMPTY_KEYBOARD_REPORT},
|
||||
util::CS,
|
||||
};
|
||||
|
||||
use super::MAX_PACKET_SIZE;
|
||||
@ -23,6 +24,8 @@ struct Handler;
|
||||
|
||||
static CONTEXT: StaticCell<Context> = StaticCell::new();
|
||||
|
||||
pub static KB_REPORT: Mutex<CS, KeyboardReport> = Mutex::new(EMPTY_KEYBOARD_REPORT);
|
||||
|
||||
struct Context {
|
||||
handler: Handler,
|
||||
state: hid::State<'static>,
|
||||
@ -94,36 +97,7 @@ async fn keyboard_test(mut stream: HidStream, _handler: &'static Handler) -> Res
|
||||
loop {
|
||||
Timer::after(Duration::from_millis(2)).await;
|
||||
|
||||
let keymap = &TEST_KEYMAP;
|
||||
|
||||
let mut report = EMPTY_KEYBOARD_REPORT;
|
||||
#[cfg(not(feature = "n-key-rollover"))]
|
||||
let mut i = 0;
|
||||
|
||||
#[allow(unused_labels)]
|
||||
'keyscan: for col in 0..COLS {
|
||||
for row in 0..ROWS {
|
||||
if !MATRIX[row][col].is_pressed() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let &Button::Key { keycode } = &keymap[row][col];
|
||||
// else { continue; };
|
||||
|
||||
#[cfg(feature = "n-key-rollover")]
|
||||
report.set_key(keycode);
|
||||
|
||||
#[cfg(not(feature = "n-key-rollover"))]
|
||||
{
|
||||
report.keycodes[i] = keycode;
|
||||
i += 1;
|
||||
if i >= report.keycodes.len() {
|
||||
break 'keyscan;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let report = KB_REPORT.lock().await.clone();
|
||||
if report.keycodes != EMPTY_KEYBOARD_REPORT.keycodes {
|
||||
log::debug!("keys: {:x?}", report.keycodes);
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
/// keyboard LEDs.
|
||||
///
|
||||
/// Unlike usbd_hids KeyboardReport, this one supports N-key rollover.
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[cfg(feature = "n-key-rollover")]
|
||||
pub struct KeyboardReport {
|
||||
pub modifier: u8,
|
||||
@ -14,6 +14,7 @@ pub struct KeyboardReport {
|
||||
pub keycodes: [u8; 13],
|
||||
}
|
||||
|
||||
use tgnt::keys::Key;
|
||||
#[cfg(not(feature = "n-key-rollover"))]
|
||||
pub use usbd_hid::descriptor::KeyboardReport;
|
||||
|
||||
@ -33,19 +34,32 @@ pub const EMPTY_KEYBOARD_REPORT: KeyboardReport = KeyboardReport {
|
||||
|
||||
#[cfg(feature = "n-key-rollover")]
|
||||
impl KeyboardReport {
|
||||
pub fn set_key(&mut self, keycode: u8) {
|
||||
log::info!("setting keycode: {keycode}");
|
||||
pub fn set_key(&mut self, key: Key, pressed: bool) {
|
||||
let keycode = u8::from(key);
|
||||
log::debug!("setting key: {key:?} ({keycode:x})");
|
||||
let byte = keycode >> 3;
|
||||
let bit = keycode & 0b111;
|
||||
let mask = 1 << bit;
|
||||
|
||||
if let Some(k) = self.keycodes.get_mut(byte as usize) {
|
||||
*k |= mask;
|
||||
if pressed {
|
||||
*k |= mask;
|
||||
} else {
|
||||
*k &= !mask;
|
||||
}
|
||||
} else {
|
||||
log::warn!("Tried to set out-of-range keycode: {keycode:x}");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn press_key(&mut self, key: Key) {
|
||||
self.set_key(key, true)
|
||||
}
|
||||
|
||||
pub fn release_key(&mut self, key: Key) {
|
||||
self.set_key(key, false)
|
||||
}
|
||||
|
||||
pub fn serialized(&self) -> [u8; 14] {
|
||||
let [a, b, c, d, e, f, g, h, i, j, k, l, m] = self.keycodes;
|
||||
[self.modifier, a, b, c, d, e, f, g, h, i, j, k, l, m]
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
use crate::util::CS;
|
||||
|
||||
use super::MAX_PACKET_SIZE;
|
||||
use core::fmt::Write as WriteFmt;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_rp::{peripherals::USB, usb::Driver};
|
||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe};
|
||||
use embassy_sync::pipe::Pipe;
|
||||
use embassy_time::Instant;
|
||||
use embassy_usb::{
|
||||
class::cdc_acm::{self, CdcAcmClass},
|
||||
@ -12,7 +14,7 @@ use log::{Metadata, Record};
|
||||
use static_cell::StaticCell;
|
||||
|
||||
pub const BUFFER_SIZE: usize = 16 * 1024;
|
||||
static BUFFER: Pipe<CriticalSectionRawMutex, BUFFER_SIZE> = Pipe::new();
|
||||
static BUFFER: Pipe<CS, BUFFER_SIZE> = Pipe::new();
|
||||
static STATE: StaticCell<cdc_acm::State<'static>> = StaticCell::new();
|
||||
|
||||
struct UsbLogger;
|
||||
@ -62,7 +64,7 @@ impl log::Log for UsbLogger {
|
||||
let s = now.as_secs();
|
||||
let ms = now.as_millis() % 1000;
|
||||
let level = record.metadata().level();
|
||||
let _ = write!(w, "[{s}.{ms:04}] ({level}) {}\n", record.args());
|
||||
let _ = writeln!(w, "[{s}.{ms:04}] ({level}) {}", record.args());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user