Move away from matrix-based key layout

This commit is contained in:
2023-03-17 23:37:43 +01:00
parent 4e83970cc3
commit 5c154141d0
12 changed files with 384 additions and 269 deletions

View File

@ -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);
}

View File

@ -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]

View File

@ -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());
}
}