Compare commits
12 Commits
nmello/bul
...
usb-keycod
| Author | SHA1 | Date | |
|---|---|---|---|
|
74e63c513f
|
|||
| 78c77a6b2d | |||
|
59a3ab1596
|
|||
| 06660ff07a | |||
|
4c14894758
|
|||
| 189a8c463f | |||
|
ea01fe2071
|
|||
| 2b99a56a4a | |||
|
681c93f558
|
|||
| 0dc8e721b2 | |||
|
e49e5b1311
|
|||
| f8ee319fbe |
152
.github/workflows/ci.yml
vendored
Normal file
152
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
# .github/workflows/ci.yml
|
||||||
|
|
||||||
|
name: Rust CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, master]
|
||||||
|
pull_request:
|
||||||
|
branches: [main, master]
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * 1' # Weekly Sunday midnight UTC
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_INCREMENTAL: 0
|
||||||
|
RUSTFLAGS: "-Dwarnings"
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
name: Check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1.17.0
|
||||||
|
with:
|
||||||
|
target: thumbv6m-none-eabi
|
||||||
|
|
||||||
|
- name: Cache dependencies
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: "."
|
||||||
|
|
||||||
|
- name: Run cargo check
|
||||||
|
run: cargo check
|
||||||
|
|
||||||
|
clippy:
|
||||||
|
name: Clippy
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1.17.0
|
||||||
|
with:
|
||||||
|
components: clippy
|
||||||
|
target: thumbv6m-none-eabi
|
||||||
|
|
||||||
|
- name: Cache dependencies
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: "."
|
||||||
|
|
||||||
|
- name: Run clippy
|
||||||
|
run: cargo clippy -- -D warnings
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
name: Format
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1.17.0
|
||||||
|
with:
|
||||||
|
components: rustfmt
|
||||||
|
target: thumbv6m-none-eabi
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
run: cargo fmt --all -- --check
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [check, clippy, fmt]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1.17.0
|
||||||
|
with:
|
||||||
|
target: thumbv6m-none-eabi
|
||||||
|
|
||||||
|
- name: Cache dependencies
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: "."
|
||||||
|
|
||||||
|
- name: Build debug
|
||||||
|
run: cargo build --verbose
|
||||||
|
|
||||||
|
- name: Build release
|
||||||
|
run: cargo build --release --verbose
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-artifacts
|
||||||
|
path: target/
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
docs:
|
||||||
|
name: Documentation
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1.17.0
|
||||||
|
with:
|
||||||
|
components: rust-docs
|
||||||
|
target: thumbv6m-none-eabi
|
||||||
|
|
||||||
|
- name: Build documentation
|
||||||
|
run: cargo doc --no-deps --document-private-items
|
||||||
|
|
||||||
|
- name: Upload documentation
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: documentation
|
||||||
|
path: target/thumbv6m-none-eabi/doc/
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
pages:
|
||||||
|
name: Deploy Docs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [docs]
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
permissions:
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Pages
|
||||||
|
uses: actions/configure-pages@v4
|
||||||
|
|
||||||
|
- name: Build documentation
|
||||||
|
run: cargo doc --no-deps
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-pages-artifact@v4
|
||||||
|
with:
|
||||||
|
path: target/doc/
|
||||||
|
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v4
|
||||||
148
src/keyboard.rs
148
src/keyboard.rs
@@ -1,17 +1,138 @@
|
|||||||
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;
|
||||||
use futures_util::stream::{FuturesUnordered, StreamExt};
|
use futures_util::stream::{FuturesUnordered, StreamExt};
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum UsbKeycodes {
|
||||||
|
A = 4,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
D,
|
||||||
|
E,
|
||||||
|
F,
|
||||||
|
G,
|
||||||
|
H,
|
||||||
|
I,
|
||||||
|
J,
|
||||||
|
K,
|
||||||
|
L,
|
||||||
|
M,
|
||||||
|
N,
|
||||||
|
O,
|
||||||
|
P,
|
||||||
|
Q,
|
||||||
|
R,
|
||||||
|
S,
|
||||||
|
T,
|
||||||
|
U,
|
||||||
|
V,
|
||||||
|
W,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Z,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Three,
|
||||||
|
Four,
|
||||||
|
Five,
|
||||||
|
Six,
|
||||||
|
Seven,
|
||||||
|
Eight,
|
||||||
|
Nine,
|
||||||
|
Zero,
|
||||||
|
Enter,
|
||||||
|
Escape,
|
||||||
|
BackSpace,
|
||||||
|
Tab,
|
||||||
|
Space,
|
||||||
|
Hyphen,
|
||||||
|
Equal,
|
||||||
|
SquareBracketLeft,
|
||||||
|
SquareBracketRight,
|
||||||
|
BackSlash,
|
||||||
|
|
||||||
|
Semicolon = 51,
|
||||||
|
SingleQuote,
|
||||||
|
Backtick,
|
||||||
|
Comma,
|
||||||
|
Period,
|
||||||
|
ForwardSlash,
|
||||||
|
CapsLock,
|
||||||
|
F1,
|
||||||
|
F2,
|
||||||
|
F3,
|
||||||
|
F4,
|
||||||
|
F5,
|
||||||
|
F6,
|
||||||
|
F7,
|
||||||
|
F8,
|
||||||
|
F9,
|
||||||
|
F10,
|
||||||
|
F11,
|
||||||
|
F12,
|
||||||
|
PrintScreen,
|
||||||
|
ScrollLock,
|
||||||
|
Pause,
|
||||||
|
Insert,
|
||||||
|
Home,
|
||||||
|
PageUp,
|
||||||
|
Delete,
|
||||||
|
End,
|
||||||
|
PageDown,
|
||||||
|
Right,
|
||||||
|
Left,
|
||||||
|
Down,
|
||||||
|
Up,
|
||||||
|
NumLock,
|
||||||
|
|
||||||
|
F13 = 104,
|
||||||
|
F14,
|
||||||
|
F15,
|
||||||
|
F16,
|
||||||
|
F17,
|
||||||
|
F18,
|
||||||
|
F19,
|
||||||
|
F20,
|
||||||
|
F21,
|
||||||
|
F22,
|
||||||
|
F23,
|
||||||
|
F24,
|
||||||
|
Execute,
|
||||||
|
Help,
|
||||||
|
Menu,
|
||||||
|
Select,
|
||||||
|
Again,
|
||||||
|
Undo,
|
||||||
|
Cut,
|
||||||
|
Copy,
|
||||||
|
Paste,
|
||||||
|
Find,
|
||||||
|
Mute,
|
||||||
|
VolumeUp,
|
||||||
|
VolumeDown,
|
||||||
|
|
||||||
|
ControlLeft = 224,
|
||||||
|
ShiftLeft,
|
||||||
|
AltLeft,
|
||||||
|
GUILeft,
|
||||||
|
ControlRight,
|
||||||
|
ShiftRight,
|
||||||
|
AltRight,
|
||||||
|
GUIRight,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Key<'a> {
|
pub struct Key<'a> {
|
||||||
button: Input<'a>,
|
button: Input<'a>,
|
||||||
value: char,
|
value: UsbKeycodes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Key<'_> {
|
impl Key<'_> {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub async fn set_value(mut self, value: char) {
|
pub async fn set_value(mut self, value: UsbKeycodes) {
|
||||||
self.value = value;
|
self.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,6 +142,7 @@ pub struct Keyboard<'d, const KEY_N: usize> {
|
|||||||
num_keys: usize,
|
num_keys: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, defmt::Format)]
|
||||||
pub enum KeyboardError {
|
pub enum KeyboardError {
|
||||||
MaxKeys,
|
MaxKeys,
|
||||||
}
|
}
|
||||||
@@ -33,7 +155,7 @@ impl<'d, const KEY_N: usize> Keyboard<'d, KEY_N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_key(&mut self, button: Input<'d>, value: char) -> Result<(), KeyboardError> {
|
pub fn add_key(&mut self, button: Input<'d>, value: UsbKeycodes) -> Result<(), KeyboardError> {
|
||||||
let key = self
|
let key = self
|
||||||
.keys
|
.keys
|
||||||
.get_mut(self.num_keys)
|
.get_mut(self.num_keys)
|
||||||
@@ -45,8 +167,10 @@ 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>(
|
||||||
where
|
mut self,
|
||||||
|
sender: Sender<'ch, M, Vec<UsbKeycodes>, N>,
|
||||||
|
) where
|
||||||
M: RawMutex,
|
M: RawMutex,
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
@@ -56,14 +180,14 @@ impl<'d, const KEY_N: usize> Keyboard<'d, KEY_N> {
|
|||||||
.collect::<FuturesUnordered<_>>()
|
.collect::<FuturesUnordered<_>>()
|
||||||
.next()
|
.next()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
let mut pressed: Vec<UsbKeycodes> = 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(),
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
sender.send(pressed).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
92
src/main.rs
92
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, UsbKeycodes};
|
||||||
|
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<UsbKeycodes>, 64> = Channel::new();
|
||||||
|
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
@@ -45,18 +47,86 @@ async fn main(_spawner: Spawner) {
|
|||||||
let driver = Driver::new(p.USB, Irqs);
|
let driver = Driver::new(p.USB, Irqs);
|
||||||
let mut usb_buf = usb::UsbKeyboardBuf::new();
|
let mut usb_buf = usb::UsbKeyboardBuf::new();
|
||||||
let usbkey = usb::UsbKeyboard::create_usb(&mut usb_buf, driver);
|
let usbkey = usb::UsbKeyboard::create_usb(&mut usb_buf, driver);
|
||||||
|
let mut keyboard = Keyboard::<10>::new();
|
||||||
|
|
||||||
// Set up the signal pin that will be used to trigger the keyboard.
|
let mut signal_pin = Input::new(p.PIN_15, Pull::None);
|
||||||
let mut signal_pin = Input::new(p.PIN_16, Pull::None);
|
|
||||||
|
|
||||||
// Enable the schmitt trigger to slightly debounce.
|
|
||||||
signal_pin.set_schmitt(true);
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::X) {
|
||||||
let mut keyboard = Keyboard::<1>::new();
|
|
||||||
match keyboard.add_key(signal_pin, 'a') {
|
|
||||||
Ok(()) => info!("Key 'a' registered"),
|
Ok(()) => info!("Key 'a' registered"),
|
||||||
Err(_) => {
|
Err(e) => {
|
||||||
defmt::panic!("Failed to register key!");
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_16, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::C) {
|
||||||
|
Ok(()) => info!("Key 's' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_17, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::X) {
|
||||||
|
Ok(()) => info!("Key 'x' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_18, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::D) {
|
||||||
|
Ok(()) => info!("Key 'd' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_19, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::C) {
|
||||||
|
Ok(()) => info!("Key 'c' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_20, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::ShiftLeft) {
|
||||||
|
Ok(()) => info!("Key 'w' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_14, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::Up) {
|
||||||
|
Ok(()) => info!("Key 'w' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_13, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::Down) {
|
||||||
|
Ok(()) => info!("Key 'w' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_12, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::Right) {
|
||||||
|
Ok(()) => info!("Key 'w' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut signal_pin = Input::new(p.PIN_11, Pull::None);
|
||||||
|
signal_pin.set_schmitt(true);
|
||||||
|
match keyboard.add_key(signal_pin, UsbKeycodes::Left) {
|
||||||
|
Ok(()) => info!("Key 'w' registered"),
|
||||||
|
Err(e) => {
|
||||||
|
defmt::panic!("Failed to register key! {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
103
src/usb.rs
103
src/usb.rs
@@ -1,8 +1,9 @@
|
|||||||
|
use crate::keyboard::UsbKeycodes;
|
||||||
|
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 +19,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::Low => KeyboardAction::Depress,
|
|
||||||
Level::High => 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 +108,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<UsbKeycodes>, N>)
|
||||||
where
|
where
|
||||||
M: RawMutex,
|
M: RawMutex,
|
||||||
{
|
{
|
||||||
@@ -148,58 +128,31 @@ 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,
|
boot_keys[idx] = key as u8;
|
||||||
} => {
|
}
|
||||||
if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8
|
|
||||||
{
|
if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
|
||||||
match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
|
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