Implement twitching mouse

This commit is contained in:
hodasemi 2023-01-31 10:46:10 +01:00
parent 75f626ef02
commit e55af0616d
2 changed files with 91 additions and 28 deletions

View file

@ -10,4 +10,7 @@ cortex-m = "0.7.2"
cortex-m-rt = "0.7.2" cortex-m-rt = "0.7.2"
rp-pico = "0.6.0" rp-pico = "0.6.0"
panic-halt = "0.2.0" panic-halt = "0.2.0"
defmt = "0.3.0" defmt = "0.3.0"
usb-device = "0.2.9"
usbd-hid = "0.6.1"
critical-section = "1.1.1"

View file

@ -5,19 +5,35 @@
// be linked) // be linked)
use panic_halt as _; use panic_halt as _;
// Pull in any important traits use rp_pico as bsp;
use rp_pico::{
use bsp::{
entry, entry,
hal::{self, pac, prelude::*}, hal::{
self, pac,
pac::{interrupt, Interrupt},
prelude::*,
usb::UsbBus,
},
}; };
/// Entry point to our bare-metal application. use cortex_m::delay::Delay;
///
/// The `#[entry]` macro ensures the Cortex-M start-up code calls this function use usb_device::{class_prelude::*, prelude::*};
/// as soon as all global variables are initialised. use usbd_hid::{
/// descriptor::{MouseReport, SerializedDescriptor},
/// The function configures the RP2040 peripherals, then blinks the LED in an hid_class::HIDClass,
/// infinite loop. };
/// The USB Device Driver (shared with the interrupt).
static mut USB_DEVICE: Option<UsbDevice<UsbBus>> = None;
/// The USB Bus Driver (shared with the interrupt).
static mut USB_BUS: Option<UsbBusAllocator<UsbBus>> = None;
/// The USB Human Interface Device Driver (shared with the interrupt).
static mut USB_HID: Option<HIDClass<UsbBus>> = None;
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
// Grab our singleton objects // Grab our singleton objects
@ -42,26 +58,70 @@ fn main() -> ! {
.ok() .ok()
.unwrap(); .unwrap();
// The delay object lets us wait for specified amounts of time (in unsafe {
// milliseconds) USB_BUS = Some(UsbBusAllocator::new(UsbBus::new(
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); pac.USBCTRL_REGS,
pac.USBCTRL_DPRAM,
clocks.usb_clock,
true,
&mut pac.RESETS,
)))
};
// The single-cycle I/O block controls our GPIO pins unsafe {
let sio = hal::Sio::new(pac.SIO); USB_HID = Some(HIDClass::new(
USB_BUS.as_ref().unwrap(),
MouseReport::desc(),
60,
));
}
// Set the pins up according to their function on this particular board unsafe {
let pins = rp_pico::Pins::new( USB_DEVICE = Some(
pac.IO_BANK0, UsbDeviceBuilder::new(USB_BUS.as_ref().unwrap(), UsbVidPid(0x046d, 0x101b))
pac.PADS_BANK0, .manufacturer("Logitech")
sio.gpio_bank0, .product("Marathon Mouse/Performance Plus M705")
&mut pac.RESETS, .serial_number("B14D65DA")
); .build(),
);
}
// Set the LED to be an output unsafe {
let mut led_pin = pins.led.into_push_pull_output(); pac::NVIC::unmask(Interrupt::USBCTRL_IRQ);
}
// Blink the LED at 1 Hz let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
loop {}
loop {
mouse_move(&mut delay, 4);
mouse_move(&mut delay, -4);
}
} }
// End of file fn mouse_move(delay: &mut Delay, v: i8) {
delay.delay_ms(100);
let rep = MouseReport {
x: 0,
y: v,
buttons: 0,
wheel: 0,
pan: 0,
};
push_mouse_movement(rep).unwrap_or(0);
}
/// with interrupts disabled, to avoid a race hazard with the USB IRQ.
fn push_mouse_movement(report: MouseReport) -> Result<usize, usb_device::UsbError> {
critical_section::with(|_| unsafe { USB_HID.as_mut().map(|hid| hid.push_input(&report)) })
.unwrap()
}
#[allow(non_snake_case)]
#[interrupt]
unsafe fn USBCTRL_IRQ() {
// Handle USB request
let usb_dev = USB_DEVICE.as_mut().unwrap();
let usb_hid = USB_HID.as_mut().unwrap();
usb_dev.poll(&mut [usb_hid]);
}