use rp_pico as bsp; use bsp::{ hal::{ clocks::ClocksManager, pac, pac::{interrupt, Interrupt}, usb::UsbBus, Clock, }, pac::{RESETS, USBCTRL_DPRAM, USBCTRL_REGS}, }; use cortex_m::{delay::Delay, Peripherals as CortexPeripherals}; use usb_device::{class_prelude::*, prelude::*}; use usbd_hid::{ descriptor::{MouseReport, SerializedDescriptor}, hid_class::HIDClass, }; /// The USB Device Driver (shared with the interrupt). static mut USB_DEVICE: Option> = None; /// The USB Bus Driver (shared with the interrupt). static mut USB_BUS: Option> = None; /// The USB Human Interface Device Driver (shared with the interrupt). static mut USB_HID: Option> = None; pub struct MouseHID { delay: Delay, } impl MouseHID { const PIXEL: i8 = 2; const WAIT_TIME: u32 = 10000; pub fn new( usbctrl_reg: USBCTRL_REGS, usbctrl_dpram: USBCTRL_DPRAM, resets: &mut RESETS, core: CortexPeripherals, clocks: ClocksManager, ) -> Self { unsafe { USB_BUS = Some(UsbBusAllocator::new(UsbBus::new( usbctrl_reg, usbctrl_dpram, clocks.usb_clock, true, resets, ))) }; unsafe { USB_HID = Some(HIDClass::new( USB_BUS.as_ref().unwrap(), MouseReport::desc(), 60, )); } unsafe { USB_DEVICE = Some( UsbDeviceBuilder::new(USB_BUS.as_ref().unwrap(), UsbVidPid(0x046d, 0x101b)) .manufacturer("Logitech") .product("Marathon Mouse/Performance Plus M705") .serial_number("B14D65DA") .device_class(0) .build(), ); } unsafe { pac::NVIC::unmask(Interrupt::USBCTRL_IRQ); } let delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); Self { delay } } pub fn run(&mut self) { self.mouse_move(Self::WAIT_TIME, Self::PIXEL); self.mouse_move(50, -Self::PIXEL); } fn mouse_move(&mut self, wait_time: u32, v: i8) { self.delay.delay_ms(wait_time); 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 { 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]); }