Some cleanup
This commit is contained in:
@ -41,7 +41,7 @@ pub mod button {
|
|||||||
|
|
||||||
/// A usb keyboard button was pressed or released.
|
/// A usb keyboard button was pressed or released.
|
||||||
///
|
///
|
||||||
/// This is a lower-level event than a [SwitchEvent], as things like ModTap and Compose are
|
/// This is a lower-level event than a [switch::Event], as things like ModTap and Compose are
|
||||||
/// converted to Presses and Releases.
|
/// converted to Presses and Releases.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
|
|||||||
@ -51,8 +51,13 @@ struct State {
|
|||||||
lights: Lights<PIO1, SWITCH_COUNT>,
|
lights: Lights<PIO1, SWITCH_COUNT>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Number of [KbEvents] returned by [KeyboardConfig::create].
|
||||||
pub const KB_SUBSCRIBERS: usize = 2;
|
pub const KB_SUBSCRIBERS: usize = 2;
|
||||||
|
|
||||||
|
/// Max number of subscribers for [KB_EVENTS]. Equals [KB_SUBSCRIBERS] plus the two used by
|
||||||
|
/// [layer_switch_task] and [lights::task].
|
||||||
const ACTUAL_KB_SUBSCRIBERS: usize = KB_SUBSCRIBERS + 2;
|
const ACTUAL_KB_SUBSCRIBERS: usize = KB_SUBSCRIBERS + 2;
|
||||||
|
|
||||||
const KB_EVENT_CAP: usize = 128;
|
const KB_EVENT_CAP: usize = 128;
|
||||||
static KB_EVENTS: PubSubChannel<CS, Event, KB_EVENT_CAP, ACTUAL_KB_SUBSCRIBERS, 0> =
|
static KB_EVENTS: PubSubChannel<CS, Event, KB_EVENT_CAP, ACTUAL_KB_SUBSCRIBERS, 0> =
|
||||||
PubSubChannel::new();
|
PubSubChannel::new();
|
||||||
@ -115,7 +120,9 @@ impl KeyboardConfig {
|
|||||||
spawner.must_spawn(layer_switch_task(
|
spawner.must_spawn(layer_switch_task(
|
||||||
KbEvents {
|
KbEvents {
|
||||||
publisher: KB_EVENTS.immediate_publisher(),
|
publisher: KB_EVENTS.immediate_publisher(),
|
||||||
subscriber: KB_EVENTS.subscriber().unwrap(),
|
subscriber: KB_EVENTS
|
||||||
|
.subscriber()
|
||||||
|
.expect("Not enough KbEvents allocated"),
|
||||||
},
|
},
|
||||||
state,
|
state,
|
||||||
));
|
));
|
||||||
@ -123,14 +130,20 @@ impl KeyboardConfig {
|
|||||||
spawner.must_spawn(lights::task(
|
spawner.must_spawn(lights::task(
|
||||||
KbEvents {
|
KbEvents {
|
||||||
publisher: KB_EVENTS.immediate_publisher(),
|
publisher: KB_EVENTS.immediate_publisher(),
|
||||||
subscriber: KB_EVENTS.subscriber().unwrap(),
|
subscriber: KB_EVENTS
|
||||||
|
.subscriber()
|
||||||
|
.expect("Not enough KbEvents allocated"),
|
||||||
},
|
},
|
||||||
state,
|
state,
|
||||||
));
|
));
|
||||||
|
|
||||||
Some([(); KB_SUBSCRIBERS].map(|_| KbEvents {
|
Some([(); KB_SUBSCRIBERS].map(|_| {
|
||||||
publisher: KB_EVENTS.immediate_publisher(),
|
KbEvents {
|
||||||
subscriber: KB_EVENTS.subscriber().unwrap(),
|
publisher: KB_EVENTS.immediate_publisher(),
|
||||||
|
subscriber: KB_EVENTS
|
||||||
|
.subscriber()
|
||||||
|
.expect("Not enough KbEvents allocated"),
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,8 +200,11 @@ async fn switch_task(switch_num: usize, pin: AnyPin, state: &'static State) -> !
|
|||||||
// get current layer
|
// get current layer
|
||||||
let (x, y) = state.current_layer.load(Ordering::Relaxed);
|
let (x, y) = state.current_layer.load(Ordering::Relaxed);
|
||||||
|
|
||||||
let Some(Layer { buttons }) = state.layers.get(usize::from(y))
|
let Some(Layer { buttons }) = state
|
||||||
.and_then(|row| row.get(usize::from(x))) else {
|
.layers
|
||||||
|
.get(usize::from(y))
|
||||||
|
.and_then(|row| row.get(usize::from(x)))
|
||||||
|
else {
|
||||||
// currently layer is null, do nothing
|
// currently layer is null, do nothing
|
||||||
pin.wait_for_high().await;
|
pin.wait_for_high().await;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -22,21 +22,15 @@ use usbd_hid::descriptor::SerializedDescriptor;
|
|||||||
use crate::{
|
use crate::{
|
||||||
event::button,
|
event::button,
|
||||||
keyboard::KbEvents,
|
keyboard::KbEvents,
|
||||||
|
keypress_handler::keypress_handler,
|
||||||
usb::keyboard::report::{KeyboardReport, EMPTY_KEYBOARD_REPORT},
|
usb::keyboard::report::{KeyboardReport, EMPTY_KEYBOARD_REPORT},
|
||||||
util::CS, keypress_handler::keypress_handler,
|
util::CS,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::MAX_PACKET_SIZE;
|
use super::MAX_PACKET_SIZE;
|
||||||
|
|
||||||
struct Handler;
|
struct Handler;
|
||||||
|
|
||||||
static CONTEXT: StaticCell<Context> = StaticCell::new();
|
|
||||||
|
|
||||||
static KB_REPORT: Mutex<CS, Reports> = Mutex::new(Reports {
|
|
||||||
actual: EMPTY_KEYBOARD_REPORT,
|
|
||||||
unsent: EMPTY_KEYBOARD_REPORT,
|
|
||||||
});
|
|
||||||
|
|
||||||
struct Reports {
|
struct Reports {
|
||||||
/// The report to be sent to the host machine.
|
/// The report to be sent to the host machine.
|
||||||
actual: KeyboardReport,
|
actual: KeyboardReport,
|
||||||
@ -50,13 +44,26 @@ struct Context {
|
|||||||
state: hid::State<'static>,
|
state: hid::State<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set up a USB HID keyboard. This function panics if called more than once.
|
||||||
pub async fn setup(builder: &mut Builder<'static, Driver<'static, USB>>, events: KbEvents) {
|
pub async fn setup(builder: &mut Builder<'static, Driver<'static, USB>>, events: KbEvents) {
|
||||||
log::info!("setting up usb hid");
|
log::info!("setting up usb hid");
|
||||||
|
|
||||||
let context = CONTEXT.init(Context {
|
let context = {
|
||||||
handler: Handler,
|
static CONTEXT: StaticCell<Context> = StaticCell::new();
|
||||||
state: hid::State::new(),
|
// this panics if the functon is called twice
|
||||||
});
|
CONTEXT.init(Context {
|
||||||
|
handler: Handler,
|
||||||
|
state: hid::State::new(),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let reports = {
|
||||||
|
static KB_REPORT: Mutex<CS, Reports> = Mutex::new(Reports {
|
||||||
|
actual: EMPTY_KEYBOARD_REPORT,
|
||||||
|
unsent: EMPTY_KEYBOARD_REPORT,
|
||||||
|
});
|
||||||
|
&KB_REPORT
|
||||||
|
};
|
||||||
|
|
||||||
let config = hid::Config {
|
let config = hid::Config {
|
||||||
//report_descriptor: MouseReport::desc(),
|
//report_descriptor: MouseReport::desc(),
|
||||||
@ -70,8 +77,8 @@ pub async fn setup(builder: &mut Builder<'static, Driver<'static, USB>>, events:
|
|||||||
|
|
||||||
let spawner = Spawner::for_current_executor().await;
|
let spawner = Spawner::for_current_executor().await;
|
||||||
|
|
||||||
spawner.must_spawn(task(stream, &context.handler));
|
spawner.must_spawn(report_task(stream, &context.handler, reports));
|
||||||
spawner.must_spawn(listen_to_events(events));
|
spawner.must_spawn(event_listener_task(events, reports));
|
||||||
|
|
||||||
log::info!("done setting up usb keyboard");
|
log::info!("done setting up usb keyboard");
|
||||||
}
|
}
|
||||||
@ -103,7 +110,7 @@ impl RequestHandler for Handler {
|
|||||||
type HidStream = HidReaderWriter<'static, Driver<'static, USB>, 256, 256>;
|
type HidStream = HidReaderWriter<'static, Driver<'static, USB>, 256, 256>;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn listen_to_events(mut events: KbEvents) {
|
async fn event_listener_task(mut events: KbEvents, reports: &'static Mutex<CS, Reports>) {
|
||||||
let button_events = PubSubChannel::<NoopRawMutex, button::Event, 10, 1, 1>::new();
|
let button_events = PubSubChannel::<NoopRawMutex, button::Event, 10, 1, 1>::new();
|
||||||
let mut button_pub = button_events.publisher().unwrap();
|
let mut button_pub = button_events.publisher().unwrap();
|
||||||
let mut button_sub = button_events.subscriber().unwrap();
|
let mut button_sub = button_events.subscriber().unwrap();
|
||||||
@ -117,7 +124,7 @@ async fn listen_to_events(mut events: KbEvents) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut r = KB_REPORT.lock().await;
|
let mut r = reports.lock().await;
|
||||||
match event {
|
match event {
|
||||||
button::Event::PressKey(k) => {
|
button::Event::PressKey(k) => {
|
||||||
r.actual.press_key(k);
|
r.actual.press_key(k);
|
||||||
@ -154,21 +161,29 @@ async fn listen_to_events(mut events: KbEvents) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn task(stream: HidStream, handler: &'static Handler) {
|
async fn report_task(
|
||||||
if let Err(e) = keyboard_report(stream, handler).await {
|
stream: HidStream,
|
||||||
|
handler: &'static Handler,
|
||||||
|
reports: &'static Mutex<CS, Reports>,
|
||||||
|
) {
|
||||||
|
if let Err(e) = keyboard_report(stream, handler, reports).await {
|
||||||
log::error!("keyboard error: {e:?}");
|
log::error!("keyboard error: {e:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn keyboard_report(mut stream: HidStream, _handler: &'static Handler) -> Result<(), Error> {
|
async fn keyboard_report(
|
||||||
|
mut stream: HidStream,
|
||||||
|
_handler: &'static Handler,
|
||||||
|
reports: &'static Mutex<CS, Reports>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
stream.ready().await;
|
stream.ready().await;
|
||||||
loop {
|
loop {
|
||||||
Timer::after(Duration::from_millis(2)).await;
|
Timer::after(Duration::from_millis(2)).await;
|
||||||
|
|
||||||
let report = {
|
let report = {
|
||||||
let mut reports = KB_REPORT.lock().await;
|
let mut reports = reports.lock().await;
|
||||||
reports.unsent = EMPTY_KEYBOARD_REPORT;
|
reports.unsent = EMPTY_KEYBOARD_REPORT;
|
||||||
reports.actual.clone()
|
reports.actual
|
||||||
};
|
};
|
||||||
|
|
||||||
if report.keycodes != EMPTY_KEYBOARD_REPORT.keycodes {
|
if report.keycodes != EMPTY_KEYBOARD_REPORT.keycodes {
|
||||||
|
|||||||
@ -50,9 +50,9 @@ fn key_to_byte_mask(key: Key) -> (usize, u8) {
|
|||||||
impl KeyboardReport {
|
impl KeyboardReport {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_key(&mut self, key: Key, pressed: bool) {
|
pub fn set_key(&mut self, key: Key, pressed: bool) {
|
||||||
let (byte, mask) = key_to_byte_mask(key);
|
let (byte_i, mask) = key_to_byte_mask(key);
|
||||||
|
|
||||||
if let Some(k) = self.keycodes.get_mut(byte as usize) {
|
if let Some(k) = self.keycodes.get_mut(byte_i) {
|
||||||
if pressed {
|
if pressed {
|
||||||
*k |= mask;
|
*k |= mask;
|
||||||
} else {
|
} else {
|
||||||
@ -75,8 +75,8 @@ impl KeyboardReport {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn key_pressed(&mut self, key: Key) -> bool {
|
pub fn key_pressed(&mut self, key: Key) -> bool {
|
||||||
let (byte, mask) = key_to_byte_mask(key);
|
let (byte_i, mask) = key_to_byte_mask(key);
|
||||||
if let Some(k) = self.keycodes.get_mut(byte as usize) {
|
if let Some(k) = self.keycodes.get_mut(byte_i) {
|
||||||
(*k & mask) != 0
|
(*k & mask) != 0
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Tried to get out-of-range keycode: 0x{:x}", u8::from(key));
|
log::warn!("Tried to get out-of-range keycode: 0x{:x}", u8::from(key));
|
||||||
|
|||||||
Reference in New Issue
Block a user