2023-01-31 08:59:52 +00:00
|
|
|
#![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 _;
|
|
|
|
|
2023-01-31 09:46:10 +00:00
|
|
|
use rp_pico as bsp;
|
|
|
|
|
|
|
|
use bsp::{
|
2023-01-31 08:59:52 +00:00
|
|
|
entry,
|
2023-01-31 09:46:10 +00:00
|
|
|
hal::{
|
|
|
|
self, pac,
|
|
|
|
pac::{interrupt, Interrupt},
|
|
|
|
prelude::*,
|
|
|
|
usb::UsbBus,
|
|
|
|
},
|
2023-02-01 05:10:38 +00:00
|
|
|
XOSC_CRYSTAL_FREQ,
|
2023-01-31 09:46:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
use cortex_m::delay::Delay;
|
|
|
|
|
|
|
|
use usb_device::{class_prelude::*, prelude::*};
|
|
|
|
use usbd_hid::{
|
|
|
|
descriptor::{MouseReport, SerializedDescriptor},
|
|
|
|
hid_class::HIDClass,
|
2023-01-31 08:59:52 +00:00
|
|
|
};
|
|
|
|
|
2023-01-31 09:46:10 +00:00
|
|
|
/// 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;
|
|
|
|
|
2023-01-31 08:59:52 +00:00
|
|
|
#[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(
|
2023-02-01 05:10:38 +00:00
|
|
|
XOSC_CRYSTAL_FREQ,
|
2023-01-31 08:59:52 +00:00
|
|
|
pac.XOSC,
|
|
|
|
pac.CLOCKS,
|
|
|
|
pac.PLL_SYS,
|
|
|
|
pac.PLL_USB,
|
|
|
|
&mut pac.RESETS,
|
|
|
|
&mut watchdog,
|
|
|
|
)
|
|
|
|
.ok()
|
|
|
|
.unwrap();
|
|
|
|
|
2023-01-31 09:46:10 +00:00
|
|
|
unsafe {
|
|
|
|
USB_BUS = Some(UsbBusAllocator::new(UsbBus::new(
|
|
|
|
pac.USBCTRL_REGS,
|
|
|
|
pac.USBCTRL_DPRAM,
|
|
|
|
clocks.usb_clock,
|
|
|
|
true,
|
|
|
|
&mut pac.RESETS,
|
|
|
|
)))
|
|
|
|
};
|
2023-01-31 08:59:52 +00:00
|
|
|
|
2023-01-31 09:46:10 +00:00
|
|
|
unsafe {
|
|
|
|
USB_HID = Some(HIDClass::new(
|
|
|
|
USB_BUS.as_ref().unwrap(),
|
|
|
|
MouseReport::desc(),
|
2023-02-02 07:24:59 +00:00
|
|
|
10,
|
2023-01-31 09:46:10 +00:00
|
|
|
));
|
|
|
|
}
|
2023-01-31 08:59:52 +00:00
|
|
|
|
2023-01-31 09:46:10 +00:00
|
|
|
unsafe {
|
|
|
|
USB_DEVICE = Some(
|
2023-02-02 16:01:04 +00:00
|
|
|
UsbDeviceBuilder::new(USB_BUS.as_ref().unwrap(), UsbVidPid(0x046d, 0x101b))
|
|
|
|
.manufacturer("Logitech")
|
|
|
|
.product("Marathon Mouse/Performance Plus M705")
|
|
|
|
.serial_number("B14D65DA")
|
2023-01-31 09:46:10 +00:00
|
|
|
.build(),
|
|
|
|
);
|
|
|
|
}
|
2023-01-31 08:59:52 +00:00
|
|
|
|
2023-01-31 09:46:10 +00:00
|
|
|
unsafe {
|
|
|
|
pac::NVIC::unmask(Interrupt::USBCTRL_IRQ);
|
|
|
|
}
|
2023-01-31 08:59:52 +00:00
|
|
|
|
2023-01-31 09:46:10 +00:00
|
|
|
let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
|
2023-02-01 05:10:38 +00:00
|
|
|
const PIXEL: i8 = 100;
|
|
|
|
const WAIT_TIME: u32 = 250;
|
2023-01-31 09:46:10 +00:00
|
|
|
|
|
|
|
loop {
|
2023-02-01 05:10:38 +00:00
|
|
|
mouse_move(&mut delay, WAIT_TIME, PIXEL);
|
|
|
|
mouse_move(&mut delay, WAIT_TIME, -PIXEL);
|
2023-01-31 09:46:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-02 07:24:59 +00:00
|
|
|
#[allow(unused)]
|
|
|
|
fn reworked_mouse_descriptor() -> &'static [u8] {
|
|
|
|
&[
|
|
|
|
5, 1, 9, 2, 161, 1, 9, 1, 161, 0, 5, 9, 25, 1, 41, 8, 21, 0, 37, 1, 117, 1, 149, 8,
|
|
|
|
// add usage vendor here manually
|
|
|
|
9, 2, // Input starts here
|
|
|
|
129, 2, 5, 1, 9, 48, 23, 129, 255, 255, 255, 37, 127, 117, 8, 149, 1, 129, 6, 9, 49, 129,
|
|
|
|
6, 9, 56, 129, 6, 5, 12, 10, 56, 2, 129, 6, 192, 192,
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2023-02-01 05:10:38 +00:00
|
|
|
fn mouse_move(delay: &mut Delay, wait_time: u32, v: i8) {
|
|
|
|
delay.delay_ms(wait_time);
|
2023-01-31 09:46:10 +00:00
|
|
|
|
|
|
|
let rep = MouseReport {
|
|
|
|
x: 0,
|
|
|
|
y: v,
|
|
|
|
buttons: 0,
|
|
|
|
wheel: 0,
|
|
|
|
pan: 0,
|
|
|
|
};
|
|
|
|
push_mouse_movement(rep).unwrap_or(0);
|
2023-01-31 08:59:52 +00:00
|
|
|
}
|
|
|
|
|
2023-01-31 09:46:10 +00:00
|
|
|
/// 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]);
|
|
|
|
}
|