ProjektMaus/src/main.rs

147 lines
3.6 KiB
Rust
Raw Normal View History

2023-03-19 15:19:56 +00:00
#![no_std]
#![no_main]
2023-03-20 20:50:34 +00:00
mod mouse_sensor;
2023-03-19 15:19:56 +00:00
// 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,
};
2023-03-20 20:50:34 +00:00
use crate::mouse_sensor::MouseSensor;
2023-03-19 15:19:56 +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;
#[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();
2023-03-20 20:50:34 +00:00
// The single-cycle I/O block controls our GPIO pins
let sio = hal::Sio::new(pac.SIO);
// Set the pins up according to their function on this particular board
let pins = rp_pico::Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
let mouse_sensor = MouseSensor::new(pins, &mut pac.RESETS, pac.SPI0, &clocks);
2023-03-19 15:19:56 +00:00
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(),
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 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<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]);
}