Implement modifiers and modtap
This commit is contained in:
@ -97,24 +97,25 @@ async fn switch_task(switch_num: usize, pin: AnyPin, layers: &'static [Layer]) -
|
||||
KB_REPORT.lock().await.release_key(key);
|
||||
continue;
|
||||
}
|
||||
Button::Mod(modifier) => {
|
||||
// TODO
|
||||
//KB_REPORT.lock().await.press_mod(modifier);
|
||||
//pin.wait_for_high().await;
|
||||
//KB_REPORT.lock().await.release_mod(modifier);
|
||||
//continue;
|
||||
&Button::Mod(modifier) => {
|
||||
KB_REPORT.lock().await.press_modifier(modifier);
|
||||
wait_for_release.await;
|
||||
KB_REPORT.lock().await.release_modifier(modifier);
|
||||
continue;
|
||||
}
|
||||
Button::ModTap { keycode, modifier } => {
|
||||
&Button::ModTap { keycode, modifier } => {
|
||||
select_biased! {
|
||||
_ = Timer::after(MOD_TAP_TIME).fuse() => {
|
||||
// TODO: Modifier
|
||||
KB_REPORT.lock().await.press_modifier(modifier);
|
||||
pin.wait_for_high().await;
|
||||
KB_REPORT.lock().await.release_modifier(modifier);
|
||||
debug!("switch {switch_num} button {button:?} released");
|
||||
continue;
|
||||
}
|
||||
_ = wait_for_release.fuse() => {
|
||||
KB_REPORT.lock().await.press_key(*keycode);
|
||||
KB_REPORT.lock().await.press_key(keycode);
|
||||
Timer::after(Duration::from_millis(10)).await;
|
||||
KB_REPORT.lock().await.release_key(*keycode);
|
||||
KB_REPORT.lock().await.release_key(keycode);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -122,10 +123,12 @@ async fn switch_task(switch_num: usize, pin: AnyPin, layers: &'static [Layer]) -
|
||||
Button::NextLayer => {
|
||||
let next_layer = (current_layer + 1) % layer_count;
|
||||
CURRENT_LAYER.store(next_layer, Ordering::Relaxed);
|
||||
debug!("switched to layer {next_layer}");
|
||||
}
|
||||
Button::PrevLayer => {
|
||||
let prev_layer = current_layer.checked_sub(1).unwrap_or(layer_count - 1);
|
||||
CURRENT_LAYER.store(prev_layer, Ordering::Relaxed);
|
||||
debug!("switched to layer {prev_layer}");
|
||||
}
|
||||
Button::None => {}
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ async fn keyboard_test(mut stream: HidStream, _handler: &'static Handler) -> Res
|
||||
}
|
||||
|
||||
#[cfg(feature = "n-key-rollover")]
|
||||
stream.write(&report.serialized()).await?;
|
||||
stream.write(report.as_bytes()).await?;
|
||||
|
||||
#[cfg(not(feature = "n-key-rollover"))]
|
||||
stream.write_serialize(&report).await?;
|
||||
|
||||
@ -7,21 +7,24 @@
|
||||
/// Unlike usbd_hids KeyboardReport, this one supports N-key rollover.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[cfg(feature = "n-key-rollover")]
|
||||
#[repr(C, packed)]
|
||||
pub struct KeyboardReport {
|
||||
pub modifier: u8,
|
||||
|
||||
/// Bitmap representing all keycodes from 0 to 104
|
||||
pub keycodes: [u8; 13],
|
||||
/// Bitmap representing all keycodes from 0 to 215
|
||||
pub keycodes: [u8; 27],
|
||||
}
|
||||
|
||||
use tgnt::keys::Key;
|
||||
use core::mem::{size_of, transmute};
|
||||
use tgnt::{button::Modifier, keys::Key};
|
||||
|
||||
#[cfg(not(feature = "n-key-rollover"))]
|
||||
pub use usbd_hid::descriptor::KeyboardReport;
|
||||
pub use ::usbd_hid::descriptor::KeyboardReport;
|
||||
|
||||
#[cfg(feature = "n-key-rollover")]
|
||||
pub const EMPTY_KEYBOARD_REPORT: KeyboardReport = KeyboardReport {
|
||||
modifier: 0,
|
||||
keycodes: [0; 13],
|
||||
keycodes: [0; 27],
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "n-key-rollover"))]
|
||||
@ -34,6 +37,7 @@ pub const EMPTY_KEYBOARD_REPORT: KeyboardReport = KeyboardReport {
|
||||
|
||||
#[cfg(feature = "n-key-rollover")]
|
||||
impl KeyboardReport {
|
||||
#[inline(always)]
|
||||
pub fn set_key(&mut self, key: Key, pressed: bool) {
|
||||
let keycode = u8::from(key);
|
||||
let byte = keycode >> 3;
|
||||
@ -51,29 +55,43 @@ impl KeyboardReport {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn press_key(&mut self, key: Key) {
|
||||
self.set_key(key, true)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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]
|
||||
#[inline(always)]
|
||||
pub fn set_modifier(&mut self, modifier: Modifier, pressed: bool) {
|
||||
if pressed {
|
||||
self.modifier |= u8::from(modifier);
|
||||
} else {
|
||||
self.modifier &= !u8::from(modifier);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn press_modifier(&mut self, modifier: Modifier) {
|
||||
self.set_modifier(modifier, true)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn release_modifier(&mut self, modifier: Modifier) {
|
||||
self.set_modifier(modifier, false)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_bytes(&self) -> &[u8; size_of::<KeyboardReport>()] {
|
||||
// SAFETY: KeyboardReport is repr(C, packed) and contains only u8s.
|
||||
unsafe { transmute(self) }
|
||||
}
|
||||
}
|
||||
|
||||
// bitmasks for the `modifier` field
|
||||
pub const MOD_LCTRL: u8 = 0x01;
|
||||
pub const MOD_LSHIFT: u8 = 0x02;
|
||||
pub const MOD_LALT: u8 = 0x04;
|
||||
pub const MOD_LSUPER: u8 = 0x08;
|
||||
pub const MOD_RCTRL: u8 = 0x10;
|
||||
pub const MOD_RSHIFT: u8 = 0x20;
|
||||
pub const MOD_RALT: u8 = 0x40;
|
||||
pub const MOD_RSUPER: u8 = 0x80;
|
||||
|
||||
#[cfg(feature = "n-key-rollover")]
|
||||
impl usbd_hid::descriptor::SerializedDescriptor for KeyboardReport {
|
||||
@ -95,8 +113,10 @@ impl usbd_hid::descriptor::SerializedDescriptor for KeyboardReport {
|
||||
0x81, 0x02, // input (variable)
|
||||
//
|
||||
0x19, 0x00, // local usage minimum
|
||||
0x29, 0x67, // local usage maximum
|
||||
0x95, 0x68, // report count
|
||||
//0x29, 0x67, // local usage maximum (0x67)
|
||||
//0x95, 0x68, // report count (0x68)
|
||||
0x29, 215, // local usage maximum (215)
|
||||
0x95, 216, // report count (216)
|
||||
0x81, 0x02, // input (variable)
|
||||
//
|
||||
0x05, 0x08, // usage page 8 (led page)
|
||||
|
||||
Reference in New Issue
Block a user