Some cleanup

This commit is contained in:
2023-12-20 16:34:25 +01:00
parent 00b3b51b36
commit 7f6971b329
4 changed files with 64 additions and 33 deletions

View File

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

View File

@ -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(|_| {
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"),
}
})) }))
} }
} }
@ -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;

View File

@ -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 = {
static CONTEXT: StaticCell<Context> = StaticCell::new();
// this panics if the functon is called twice
CONTEXT.init(Context {
handler: Handler, handler: Handler,
state: hid::State::new(), 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 {

View File

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