aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2022-11-19 14:05:18 -0500
committerBrian Cully <bjc@kublai.com>2022-11-19 14:05:18 -0500
commitc0ec86f5ec4428543ae18af941c7e3ef6877a369 (patch)
tree0b7d979ede27fef53255c0a306a203c27290fc07 /src
parent20377d4522d513b66406d4ef8231a7cdbfedc157 (diff)
downloadluchie-c0ec86f5ec4428543ae18af941c7e3ef6877a369.tar.gz
luchie-c0ec86f5ec4428543ae18af941c7e3ef6877a369.zip
usb: add mousewheel hid implementation
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bin/luchie.rs74
-rw-r--r--src/cirque.rs10
2 files changed, 66 insertions, 18 deletions
diff --git a/src/bin/luchie.rs b/src/bin/luchie.rs
index 7dedc8d..7d25a00 100755
--- a/src/bin/luchie.rs
+++ b/src/bin/luchie.rs
@@ -3,6 +3,8 @@
//extern crate panic_semihosting;
+use core::cmp;
+
use luchie::{
cirque::Cirque,
log, logger, logln,
@@ -22,6 +24,10 @@ use stm32f1xx_hal::{
usb::{self, UsbBus},
};
use usb_device::prelude::*;
+use usbd_human_interface_device::{
+ prelude::*,
+ device::mouse::{WheelMouseInterface, WheelMouseReport},
+};
use usbd_serial::{SerialPort, USB_CLASS_CDC};
#[entry]
@@ -35,15 +41,11 @@ fn main() -> ! {
.cfgr
.use_hse(8.MHz())
.sysclk(72.MHz()) // TODO: gd32 can get up to 120MHz
- // .pclk1(24.MHz()) // TODO: causes issues with gd32 usb (dropped packets) and garbled usart1 output
+ .pclk1(24.MHz()) // TODO: causes issues with gd32 usb (dropped packets) and garbled usart1 output
.freeze(&mut flash.acr);
assert!(clocks.usbclk_valid());
- let mut gpiob = dp.GPIOB.split();
- let mut led = gpiob.pb2.into_push_pull_output(&mut gpiob.crl);
- led.set_low();
-
let mut afio = dp.AFIO.constrain();
let mut gpioa = dp.GPIOA.split();
@@ -117,6 +119,11 @@ fn main() -> ! {
let mut serial = SerialPort::new(&usb_bus);
+ let mut mouse_report = WheelMouseReport::default();
+ let mut mouse = UsbHidClassBuilder::new()
+ .add_interface(WheelMouseInterface::default_config())
+ .build(&usb_bus);
+
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0xdead, 0xbeef))
.manufacturer("Fake company")
.product("Serial port")
@@ -124,17 +131,23 @@ fn main() -> ! {
.device_class(USB_CLASS_CDC)
.build();
+ while usb_dev.state() != UsbDeviceState::Configured {
+ usb_dev.poll(&mut [&mut serial, &mut mouse]);
+ }
+
+ logln!("💡 init led");
+ let mut gpiob = dp.GPIOB.split();
+ let mut led = gpiob.pb2.into_push_pull_output(&mut gpiob.crl);
+ led.set_low();
+
logln!("🎉 luchie started!");
+
+ let mut is_pressed = false;
+ let mut last_x = 0u16;
+ let mut last_y = 0u16;
loop {
// logln!(".");
- if let Ok(mut td) = cirque.poll(&mut spi) {
- td.scale_to(1920, 1080);
- logln!("td: {:?}", td);
- }
-
- if !usb_dev.poll(&mut [&mut serial]) {
- continue;
- }
+ usb_dev.poll(&mut [&mut serial, &mut mouse]);
let mut buf = [0u8; 64];
@@ -162,6 +175,41 @@ fn main() -> ! {
}
_ => {}
}
+
+ if let Ok(td) = cirque.poll(&mut spi) {
+ logln!("td: {:?}", td);
+ if td.is_pressed {
+ if is_pressed {
+ /*
+ * The trackpad's actual valid return values are
+ * only about 2^11, so overflow isn't possible
+ * when converting to signed 16 bit integers.
+ */
+ let s_x: i16 = td.x as i16 - last_x as i16;
+ let s_y: i16 = td.y as i16 - last_y as i16;
+
+ // Clamp to i8 range.
+ let raw_x = cmp::max(i8::MIN as i16, cmp::min(i8::MAX as i16, s_x));
+ let raw_y = cmp::max(i8::MIN as i16, cmp::min(i8::MAX as i16, s_y));
+ mouse_report.x = raw_x as i8;
+ mouse_report.y = raw_y as i8;
+ }
+ is_pressed = true;
+ last_x = td.x;
+ last_y = td.y;
+ } else {
+ mouse_report.x = 0;
+ mouse_report.y = 0;
+ is_pressed = false;
+ }
+ match mouse.interface().write_report(&mouse_report) {
+ Err(UsbHidError::WouldBlock) => {},
+ Err(e) => {
+ panic!("couldn't write mouse report: {:?}", e)
+ },
+ _ => {},
+ }
+ }
}
}
diff --git a/src/cirque.rs b/src/cirque.rs
index 23df15b..0f40c51 100644
--- a/src/cirque.rs
+++ b/src/cirque.rs
@@ -98,11 +98,11 @@ where
#[allow(unused)]
#[derive(Debug)]
pub struct TouchData {
- x: u16,
- y: u16,
- z: u8,
- buttons: u8,
- is_pressed: bool,
+ pub x: u16,
+ pub y: u16,
+ pub z: u8,
+ pub buttons: u8,
+ pub is_pressed: bool,
}
impl TouchData {