use crate::{serial::Serial, MouseInfoSender}; use rp_pico as bsp; use bsp::{ hal::{ clocks::ClocksManager, pac, pac::{interrupt, Interrupt}, usb::UsbBus, }, pac::{RESETS, USBCTRL_DPRAM, USBCTRL_REGS}, }; use usb_device::{class_prelude::*, prelude::*}; use usbd_hid::descriptor::MouseReport; static mut USB_BUS: Option> = None; static mut USB_SERIAL: Option = None; static mut USB_DEVICE: Option> = None; pub struct CustomHID<'a> { out_ep: EndpointOut<'a, UsbBus>, in_ep: EndpointIn<'a, UsbBus>, } impl<'a> CustomHID<'a> { pub fn new( usbctrl_reg: USBCTRL_REGS, usbctrl_dpram: USBCTRL_DPRAM, resets: &mut RESETS, clocks: ClocksManager, poll_ms: u8, ) -> Self { // Set up the USB driver unsafe { USB_BUS = Some(UsbBusAllocator::new(UsbBus::new( usbctrl_reg, usbctrl_dpram, clocks.usb_clock, true, resets, ))) }; unsafe { USB_SERIAL = Some(Serial::new(USB_BUS.as_ref().unwrap())); } unsafe { USB_DEVICE = Some( UsbDeviceBuilder::new(USB_BUS.as_ref().unwrap(), UsbVidPid(0x16c0, 0x27dd)) .manufacturer("Fake company") .product("Serial port") .serial_number("TEST") .device_class(2) // from: https://www.usb.org/defined-class-codes .build(), ); } let (in_ep, out_ep) = unsafe { pac::NVIC::unmask(Interrupt::USBCTRL_IRQ); ( USB_BUS.as_ref().unwrap().interrupt(64, poll_ms), USB_BUS.as_ref().unwrap().interrupt(64, poll_ms), ) }; Self { in_ep, out_ep } } } impl<'a> MouseInfoSender for CustomHID<'a> { fn send(&mut self, x: i8, y: i8, buttons: u8, wheel: i8, pan: i8) { push_mouse_movement(MouseReport { x, y, buttons, wheel, pan, }) } } /// with interrupts disabled, to avoid a race hazard with the USB IRQ. fn push_mouse_movement(report: MouseReport) { critical_section::with(|_| unsafe { let serial = USB_SERIAL.as_mut().unwrap(); serial.send_text("x"); serial.send_number(report.x, 10); serial.send_text("y"); serial.send_number(report.y, 10); }); } #[allow(non_snake_case)] #[interrupt] unsafe fn USBCTRL_IRQ() { // Handle USB request let usb_dev = USB_DEVICE.as_mut().unwrap(); let usb_hid = USB_SERIAL.as_mut().unwrap(); usb_dev.poll(&mut [usb_hid]); }