Some cleanup
This commit is contained in:
@ -41,7 +41,7 @@ pub mod button {
|
||||
|
||||
/// 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.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Event {
|
||||
|
||||
@ -51,8 +51,13 @@ struct State {
|
||||
lights: Lights<PIO1, SWITCH_COUNT>,
|
||||
}
|
||||
|
||||
/// Number of [KbEvents] returned by [KeyboardConfig::create].
|
||||
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 KB_EVENT_CAP: usize = 128;
|
||||
static KB_EVENTS: PubSubChannel<CS, Event, KB_EVENT_CAP, ACTUAL_KB_SUBSCRIBERS, 0> =
|
||||
PubSubChannel::new();
|
||||
@ -115,7 +120,9 @@ impl KeyboardConfig {
|
||||
spawner.must_spawn(layer_switch_task(
|
||||
KbEvents {
|
||||
publisher: KB_EVENTS.immediate_publisher(),
|
||||
subscriber: KB_EVENTS.subscriber().unwrap(),
|
||||
subscriber: KB_EVENTS
|
||||
.subscriber()
|
||||
.expect("Not enough KbEvents allocated"),
|
||||
},
|
||||
state,
|
||||
));
|
||||
@ -123,14 +130,20 @@ impl KeyboardConfig {
|
||||
spawner.must_spawn(lights::task(
|
||||
KbEvents {
|
||||
publisher: KB_EVENTS.immediate_publisher(),
|
||||
subscriber: KB_EVENTS.subscriber().unwrap(),
|
||||
subscriber: KB_EVENTS
|
||||
.subscriber()
|
||||
.expect("Not enough KbEvents allocated"),
|
||||
},
|
||||
state,
|
||||
));
|
||||
|
||||
Some([(); KB_SUBSCRIBERS].map(|_| KbEvents {
|
||||
publisher: KB_EVENTS.immediate_publisher(),
|
||||
subscriber: KB_EVENTS.subscriber().unwrap(),
|
||||
Some([(); KB_SUBSCRIBERS].map(|_| {
|
||||
KbEvents {
|
||||
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
|
||||
let (x, y) = state.current_layer.load(Ordering::Relaxed);
|
||||
|
||||
let Some(Layer { buttons }) = state.layers.get(usize::from(y))
|
||||
.and_then(|row| row.get(usize::from(x))) else {
|
||||
let Some(Layer { buttons }) = state
|
||||
.layers
|
||||
.get(usize::from(y))
|
||||
.and_then(|row| row.get(usize::from(x)))
|
||||
else {
|
||||
// currently layer is null, do nothing
|
||||
pin.wait_for_high().await;
|
||||
continue;
|
||||
|
||||
@ -22,21 +22,15 @@ use usbd_hid::descriptor::SerializedDescriptor;
|
||||
use crate::{
|
||||
event::button,
|
||||
keyboard::KbEvents,
|
||||
keypress_handler::keypress_handler,
|
||||
usb::keyboard::report::{KeyboardReport, EMPTY_KEYBOARD_REPORT},
|
||||
util::CS, keypress_handler::keypress_handler,
|
||||
util::CS,
|
||||
};
|
||||
|
||||
use super::MAX_PACKET_SIZE;
|
||||
|
||||
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 {
|
||||
/// The report to be sent to the host machine.
|
||||
actual: KeyboardReport,
|
||||
@ -50,13 +44,26 @@ struct Context {
|
||||
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) {
|
||||
log::info!("setting up usb hid");
|
||||
|
||||
let context = CONTEXT.init(Context {
|
||||
handler: Handler,
|
||||
state: hid::State::new(),
|
||||
});
|
||||
let context = {
|
||||
static CONTEXT: StaticCell<Context> = StaticCell::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 {
|
||||
//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;
|
||||
|
||||
spawner.must_spawn(task(stream, &context.handler));
|
||||
spawner.must_spawn(listen_to_events(events));
|
||||
spawner.must_spawn(report_task(stream, &context.handler, reports));
|
||||
spawner.must_spawn(event_listener_task(events, reports));
|
||||
|
||||
log::info!("done setting up usb keyboard");
|
||||
}
|
||||
@ -103,7 +110,7 @@ impl RequestHandler for Handler {
|
||||
type HidStream = HidReaderWriter<'static, Driver<'static, USB>, 256, 256>;
|
||||
|
||||
#[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 mut button_pub = button_events.publisher().unwrap();
|
||||
let mut button_sub = button_events.subscriber().unwrap();
|
||||
@ -117,7 +124,7 @@ async fn listen_to_events(mut events: KbEvents) {
|
||||
};
|
||||
|
||||
loop {
|
||||
let mut r = KB_REPORT.lock().await;
|
||||
let mut r = reports.lock().await;
|
||||
match event {
|
||||
button::Event::PressKey(k) => {
|
||||
r.actual.press_key(k);
|
||||
@ -154,21 +161,29 @@ async fn listen_to_events(mut events: KbEvents) {
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn task(stream: HidStream, handler: &'static Handler) {
|
||||
if let Err(e) = keyboard_report(stream, handler).await {
|
||||
async fn report_task(
|
||||
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:?}");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
loop {
|
||||
Timer::after(Duration::from_millis(2)).await;
|
||||
|
||||
let report = {
|
||||
let mut reports = KB_REPORT.lock().await;
|
||||
let mut reports = reports.lock().await;
|
||||
reports.unsent = EMPTY_KEYBOARD_REPORT;
|
||||
reports.actual.clone()
|
||||
reports.actual
|
||||
};
|
||||
|
||||
if report.keycodes != EMPTY_KEYBOARD_REPORT.keycodes {
|
||||
|
||||
@ -50,9 +50,9 @@ fn key_to_byte_mask(key: Key) -> (usize, u8) {
|
||||
impl KeyboardReport {
|
||||
#[inline(always)]
|
||||
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 {
|
||||
*k |= mask;
|
||||
} else {
|
||||
@ -75,8 +75,8 @@ impl KeyboardReport {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn key_pressed(&mut self, key: Key) -> bool {
|
||||
let (byte, mask) = key_to_byte_mask(key);
|
||||
if let Some(k) = self.keycodes.get_mut(byte as usize) {
|
||||
let (byte_i, mask) = key_to_byte_mask(key);
|
||||
if let Some(k) = self.keycodes.get_mut(byte_i) {
|
||||
(*k & mask) != 0
|
||||
} else {
|
||||
log::warn!("Tried to get out-of-range keycode: 0x{:x}", u8::from(key));
|
||||
|
||||
Reference in New Issue
Block a user