@@ -1,4 +1,4 @@
|
|||||||
use crate::usb::KeyboardEvent;
|
use alloc::vec::Vec;
|
||||||
use embassy_rp::gpio::Input;
|
use embassy_rp::gpio::Input;
|
||||||
use embassy_sync::blocking_mutex::raw::RawMutex;
|
use embassy_sync::blocking_mutex::raw::RawMutex;
|
||||||
use embassy_sync::channel::Sender;
|
use embassy_sync::channel::Sender;
|
||||||
@@ -46,7 +46,7 @@ impl<'d, const KEY_N: usize> Keyboard<'d, KEY_N> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn process<'ch, M, const N: usize>(mut self, sender: Sender<'ch, M, KeyboardEvent, N>)
|
pub async fn process<'ch, M, const N: usize>(mut self, sender: Sender<'ch, M, Vec<char>, N>)
|
||||||
where
|
where
|
||||||
M: RawMutex,
|
M: RawMutex,
|
||||||
{
|
{
|
||||||
@@ -57,14 +57,14 @@ impl<'d, const KEY_N: usize> Keyboard<'d, KEY_N> {
|
|||||||
.collect::<FuturesUnordered<_>>()
|
.collect::<FuturesUnordered<_>>()
|
||||||
.next()
|
.next()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
let mut pressed: Vec<char> = Vec::new();
|
||||||
for key in self.keys.iter_mut().filter_map(|opt| opt.as_mut()) {
|
for key in self.keys.iter_mut().filter_map(|opt| opt.as_mut()) {
|
||||||
sender
|
if key.button.is_low() {
|
||||||
.send(KeyboardEvent {
|
pressed.push(key.value);
|
||||||
key: key.value,
|
}
|
||||||
action: key.button.get_level().into(),
|
}
|
||||||
})
|
sender.send(pressed).await;
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/main.rs
24
src/main.rs
@@ -5,8 +5,10 @@ mod heartbeat;
|
|||||||
mod keyboard;
|
mod keyboard;
|
||||||
mod usb;
|
mod usb;
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
use crate::heartbeat::heartbeat;
|
use crate::heartbeat::heartbeat;
|
||||||
use crate::keyboard::Keyboard;
|
use crate::keyboard::Keyboard;
|
||||||
|
use alloc::vec::Vec;
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
@@ -37,7 +39,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let keyboard_events: Channel<ThreadModeRawMutex, usb::KeyboardEvent, 64> = Channel::new();
|
let keyboard_events: Channel<ThreadModeRawMutex, Vec<char>, 64> = Channel::new();
|
||||||
|
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
@@ -57,40 +59,40 @@ async fn main(_spawner: Spawner) {
|
|||||||
}
|
}
|
||||||
let mut signal_pin = Input::new(p.PIN_16, Pull::None);
|
let mut signal_pin = Input::new(p.PIN_16, Pull::None);
|
||||||
signal_pin.set_schmitt(true);
|
signal_pin.set_schmitt(true);
|
||||||
match keyboard.add_key(signal_pin, 'a') {
|
match keyboard.add_key(signal_pin, 's') {
|
||||||
Ok(()) => info!("Key 'a' registered"),
|
Ok(()) => info!("Key 's' registered"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
defmt::panic!("Failed to register key! {:?}", e);
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut signal_pin = Input::new(p.PIN_17, Pull::None);
|
let mut signal_pin = Input::new(p.PIN_17, Pull::None);
|
||||||
signal_pin.set_schmitt(true);
|
signal_pin.set_schmitt(true);
|
||||||
match keyboard.add_key(signal_pin, 'a') {
|
match keyboard.add_key(signal_pin, 'x') {
|
||||||
Ok(()) => info!("Key 'a' registered"),
|
Ok(()) => info!("Key 'x' registered"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
defmt::panic!("Failed to register key! {:?}", e);
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut signal_pin = Input::new(p.PIN_18, Pull::None);
|
let mut signal_pin = Input::new(p.PIN_18, Pull::None);
|
||||||
signal_pin.set_schmitt(true);
|
signal_pin.set_schmitt(true);
|
||||||
match keyboard.add_key(signal_pin, 'a') {
|
match keyboard.add_key(signal_pin, 'd') {
|
||||||
Ok(()) => info!("Key 'a' registered"),
|
Ok(()) => info!("Key 'd' registered"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
defmt::panic!("Failed to register key! {:?}", e);
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut signal_pin = Input::new(p.PIN_19, Pull::None);
|
let mut signal_pin = Input::new(p.PIN_19, Pull::None);
|
||||||
signal_pin.set_schmitt(true);
|
signal_pin.set_schmitt(true);
|
||||||
match keyboard.add_key(signal_pin, 'a') {
|
match keyboard.add_key(signal_pin, 'c') {
|
||||||
Ok(()) => info!("Key 'a' registered"),
|
Ok(()) => info!("Key 'c' registered"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
defmt::panic!("Failed to register key! {:?}", e);
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut signal_pin = Input::new(p.PIN_20, Pull::None);
|
let mut signal_pin = Input::new(p.PIN_20, Pull::None);
|
||||||
signal_pin.set_schmitt(true);
|
signal_pin.set_schmitt(true);
|
||||||
match keyboard.add_key(signal_pin, 'a') {
|
match keyboard.add_key(signal_pin, 'w') {
|
||||||
Ok(()) => info!("Key 'a' registered"),
|
Ok(()) => info!("Key 'w' registered"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
defmt::panic!("Failed to register key! {:?}", e);
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
}
|
}
|
||||||
|
|||||||
102
src/usb.rs
102
src/usb.rs
@@ -1,8 +1,8 @@
|
|||||||
|
use alloc::vec::Vec;
|
||||||
use core::cell::OnceCell;
|
use core::cell::OnceCell;
|
||||||
use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
|
use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_rp::gpio::Level;
|
|
||||||
use embassy_rp::peripherals::USB;
|
use embassy_rp::peripherals::USB;
|
||||||
use embassy_rp::usb::Driver;
|
use embassy_rp::usb::Driver;
|
||||||
use embassy_sync::blocking_mutex::raw::RawMutex;
|
use embassy_sync::blocking_mutex::raw::RawMutex;
|
||||||
@@ -18,27 +18,6 @@ use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
|
|||||||
|
|
||||||
pub static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
|
pub static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub enum KeyboardAction {
|
|
||||||
Press,
|
|
||||||
Depress,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Level> for KeyboardAction {
|
|
||||||
fn from(value: Level) -> Self {
|
|
||||||
match value {
|
|
||||||
Level::High => KeyboardAction::Depress,
|
|
||||||
Level::Low => KeyboardAction::Press,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct KeyboardEvent {
|
|
||||||
pub key: char,
|
|
||||||
pub action: KeyboardAction,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UsbKeyboardBuf<'d> {
|
pub struct UsbKeyboardBuf<'d> {
|
||||||
// Create embassy-usb DeviceBuilder using the driver and config.
|
// Create embassy-usb DeviceBuilder using the driver and config.
|
||||||
// It needs some buffers for building the descriptors.
|
// It needs some buffers for building the descriptors.
|
||||||
@@ -128,7 +107,7 @@ impl<'d> UsbKeyboard<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run<'ch, M, const N: usize>(self, receiver: Receiver<'ch, M, KeyboardEvent, N>)
|
pub async fn run<'ch, M, const N: usize>(self, receiver: Receiver<'ch, M, Vec<char>, N>)
|
||||||
where
|
where
|
||||||
M: RawMutex,
|
M: RawMutex,
|
||||||
{
|
{
|
||||||
@@ -148,58 +127,39 @@ impl<'d> UsbKeyboard<'d> {
|
|||||||
loop {
|
loop {
|
||||||
let event = receiver.receive().await;
|
let event = receiver.receive().await;
|
||||||
|
|
||||||
match event {
|
let mut boot_keys = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
KeyboardEvent {
|
|
||||||
key: 'a',
|
for (&key, idx) in event.iter().zip(2usize..) {
|
||||||
action: KeyboardAction::Press,
|
let boot_key = match key {
|
||||||
} => {
|
'd' => 79,
|
||||||
if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8
|
'a' => 80,
|
||||||
{
|
's' => 81,
|
||||||
match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
|
'w' => 82,
|
||||||
|
('a'..='z') => (key as u8) - b'a' + 4,
|
||||||
|
_ => defmt::panic!("Not supported key: {}", key),
|
||||||
|
};
|
||||||
|
boot_keys[idx] = boot_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
|
||||||
|
match writer.write(&boot_keys).await {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(e) => warn!("Failed to send boot report: {:?}", e),
|
Err(e) => warn!("Failed to send boot report: {:?}", e),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// Create a report with the A key pressed. (no shift modifier)
|
defmt::unimplemented!("Only supports boot mode keyboards!");
|
||||||
let report = KeyboardReport {
|
// // Create a report with the A key pressed. (no shift modifier)
|
||||||
keycodes: [4, 0, 0, 0, 0, 0],
|
// let report = KeyboardReport {
|
||||||
leds: 0,
|
// keycodes: [4, 0, 0, 0, 0, 0],
|
||||||
modifier: 0,
|
// leds: 0,
|
||||||
reserved: 0,
|
// modifier: 0,
|
||||||
};
|
// reserved: 0,
|
||||||
// Send the report.
|
// };
|
||||||
match writer.write_serialize(&report).await {
|
// // Send the report.
|
||||||
Ok(()) => {}
|
// match writer.write_serialize(&report).await {
|
||||||
Err(e) => warn!("Failed to send report: {:?}", e),
|
// Ok(()) => {}
|
||||||
};
|
// Err(e) => warn!("Failed to send report: {:?}", e),
|
||||||
}
|
// };
|
||||||
}
|
|
||||||
KeyboardEvent {
|
|
||||||
key: 'a',
|
|
||||||
action: KeyboardAction::Depress,
|
|
||||||
} => {
|
|
||||||
if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8
|
|
||||||
{
|
|
||||||
match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
|
|
||||||
Ok(()) => {}
|
|
||||||
Err(e) => warn!("Failed to send boot report: {:?}", e),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
let report = KeyboardReport {
|
|
||||||
keycodes: [0, 0, 0, 0, 0, 0],
|
|
||||||
leds: 0,
|
|
||||||
modifier: 0,
|
|
||||||
reserved: 0,
|
|
||||||
};
|
|
||||||
match writer.write_serialize(&report).await {
|
|
||||||
Ok(()) => {}
|
|
||||||
Err(e) => warn!("Failed to send report: {:?}", e),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
defmt::panic!("Unexpected event!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user