#![no_std] #![no_main] // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use panic_halt as _; use rp_pico as bsp; use bsp::{ entry, hal::{ self, pac, pac::{interrupt, Interrupt}, prelude::*, usb::UsbBus, }, XOSC_CRYSTAL_FREQ, }; use cortex_m::delay::Delay; 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; #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks let clocks = hal::clocks::init_clocks_and_plls( XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); unsafe { USB_BUS = Some(UsbBusAllocator::new(UsbBus::new( pac.USBCTRL_REGS, pac.USBCTRL_DPRAM, clocks.usb_clock, true, &mut pac.RESETS, ))) }; unsafe { USB_HID = Some(HIDClass::new( USB_BUS.as_ref().unwrap(), MouseReport::desc(), 10, )); } 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") .build(), ); } unsafe { pac::NVIC::unmask(Interrupt::USBCTRL_IRQ); } let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); const PIXEL: i8 = 2; const WAIT_TIME: u32 = 10000; loop { mouse_move(&mut delay, WAIT_TIME, PIXEL); mouse_move(&mut delay, 50, -PIXEL); } } fn mouse_move(delay: &mut Delay, wait_time: u32, v: i8) { 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]); }