Implement USB HID device

This commit is contained in:
Luca 2022-02-24 15:42:53 +01:00
parent 57b4c79d77
commit 7871f832ee
2 changed files with 104 additions and 21 deletions

View File

@ -10,4 +10,6 @@ cortex-m = "0.7.4"
cortex-m-rt = "0.7.1"
nb = "1"
panic-halt = "0.2.0"
stm32f0xx-hal = { version = "0.18.0", features = ["rt", "stm32f072"] }
stm32f0xx-hal = { version = "0.18.0", features = ["rt", "stm32f072", "stm32-usbd"] }
usb-device = "0.2.8"
usbd-hid = "0.5.2"

View File

@ -1,6 +1,6 @@
/*
* any key firmware
* Copyright (C) 2020 Luca Schmid
* Copyright (C) 2020-2022 Luca Schmid
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +26,33 @@ use stm32f0xx_hal::pac::Peripherals;
use stm32f0xx_hal::prelude::*;
use stm32f0xx_hal::pwm::tim3;
use stm32f0xx_hal::timers::Timer;
use stm32f0xx_hal::usb::{Peripheral, UsbBus};
use usb_device::prelude::*;
use usbd_hid::descriptor::KeyboardReport;
use usbd_hid::descriptor::generator_prelude::*;
use usbd_hid::hid_class::HIDClass;
enum Action {
Copy,
Paste,
}
impl Action {
fn as_report(&self) -> KeyboardReport {
KeyboardReport {
modifier: 1, // Left Ctrl
reserved: 0,
leds: 0,
keycodes: [
match *self {
Action::Copy => 0x6, // C
Action::Paste => 0x19, // V
},
0, 0, 0, 0, 0,
],
}
}
}
#[entry]
fn main() -> ! {
@ -36,10 +63,13 @@ fn main() -> ! {
let gpioa = p.GPIOA.split(&mut rcc);
let gpiob = p.GPIOB.split(&mut rcc);
let (mut led1_b, mut led1_g, mut led1_r) = cortex_m::interrupt::free(|cs| (
let (mut led1_b, mut led1_g, mut led1_r, btn1, usb_dm, usb_dp) = cortex_m::interrupt::free(|cs| (
gpioa.pa0.into_push_pull_output(cs),
gpioa.pa1.into_push_pull_output(cs),
gpioa.pa2.into_push_pull_output(cs),
gpioa.pa3,
gpioa.pa11,
gpioa.pa12,
));
led1_r.set_high().ok(); // 0
@ -62,16 +92,64 @@ fn main() -> ! {
led2_r.set_duty(led2_r_max); // 0
led2_g.set_duty(led2_g_max); // 0
led2_b.set_duty(led2_b_max); // 0
// ^ violet
led2_r.enable();
led2_g.enable();
led2_b.enable();
let mut timer = Timer::tim1(p.TIM1, 100.hz(), &mut rcc);
let usb = Peripheral {
usb: p.USB,
pin_dm: usb_dm,
pin_dp: usb_dp,
};
let usb_bus = UsbBus::new(usb);
let mut hid = HIDClass::new(&usb_bus, KeyboardReport::desc(), 127);
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x2342, 0x1337))
.manufacturer("f2o & luj0ga")
.product("anykey")
.serial_number("v1")
.device_class(3) // HID
.build();
let mut timer = Timer::tim1(p.TIM1, 1.khz(), &mut rcc);
let mut action = Action::Copy;
let mut counter = 0;
let mut hue = 0;
let mut prev = false;
loop {
usb_dev.poll(&mut [&mut hid]);
if counter == 0 {
if let Ok(btn1_pressed) = btn1.is_high() {
if btn1_pressed != prev {
prev = btn1_pressed;
let report = if btn1_pressed {
led1_g.set_low().ok();
action.as_report()
} else {
led1_g.set_high().ok();
KeyboardReport {
modifier: 0,
reserved: 0,
leds: 0,
keycodes: [0, 0, 0, 0, 0, 0],
}
};
cortex_m::interrupt::free(|_| hid.push_input(&report)).ok();
if btn1_pressed {
action = match action {
Action::Copy => Action::Paste,
Action::Paste => Action::Copy,
};
}
}
}
let h_i = hue / 60;
let f = hue as f32 / 60.0 - h_i as f32;
let q = 1.0 - f;
@ -90,6 +168,9 @@ fn main() -> ! {
led2_b.set_duty(led2_b_max - (led2_b_max as f32 * b) as u16);
hue = (hue + 1) % 360;
}
counter = (counter + 1) % 10;
block!(timer.wait()).ok();
}