Last active
November 27, 2023 07:39
-
-
Save sli/fef1fd3a9e7e1e44870671ec85fc023c to your computer and use it in GitHub Desktop.
Mouse jiggler for an rp2040
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![no_std] | |
#![no_main] | |
use adafruit_kb2040 as bsp; | |
use defmt_rtt as _; | |
use panic_halt as _; | |
use bsp::{ | |
entry, hal, | |
hal::{pac, pac::interrupt, pac::PIO0, prelude::*, timer::Timer}, | |
}; | |
use core::iter::once; | |
use cortex_m::delay::Delay; | |
use embedded_hal::{digital::v2::InputPin, timer::CountDown}; | |
use rp2040_hal::{ | |
gpio::{bank0::Gpio17, FunctionPio0, Pin, PullDown}, | |
pio::SM0, | |
}; | |
use smart_leds::{brightness, SmartLedsWrite}; | |
use usb_device::{class_prelude::*, prelude::*}; | |
use usbd_hid::{ | |
descriptor::{generator_prelude::*, MouseReport}, | |
hid_class::HIDClass, | |
}; | |
use ws2812_pio::Ws2812; | |
static PAUSE_DELAY: u32 = 200; | |
static MOVE_DISTANCE: i8 = 110; | |
static COLOR_RED: (u8, u8, u8) = (255, 0, 0); | |
static COLOR_GREEN: (u8, u8, u8) = (0, 255, 0); | |
static COLOR_BLUE: (u8, u8, u8) = (0, 0, 255); | |
static COLOR_YELLOW: (u8, u8, u8) = (255, 255, 0); | |
static COLOR_MAGENTA: (u8, u8, u8) = (255, 0, 255); | |
static COLOR_CYAN: (u8, u8, u8) = (0, 255, 255); | |
static mut USB_DEVICE: Option<UsbDevice<hal::usb::UsbBus>> = None; | |
static mut USB_BUS: Option<UsbBusAllocator<hal::usb::UsbBus>> = None; | |
static mut USB_HID_M: Option<HIDClass<hal::usb::UsbBus>> = None; | |
static REP_MOVE_UP: MouseReport = MouseReport { | |
x: 0, | |
y: -MOVE_DISTANCE, | |
buttons: 0, | |
wheel: 0, | |
pan: 0, | |
}; | |
static REP_MOVE_DOWN: MouseReport = MouseReport { | |
x: 0, | |
y: MOVE_DISTANCE, | |
buttons: 0, | |
wheel: 0, | |
pan: 0, | |
}; | |
#[entry] | |
fn main() -> ! { | |
let mut pac = pac::Peripherals::take().unwrap(); | |
let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); | |
let clocks = hal::clocks::init_clocks_and_plls( | |
bsp::XOSC_CRYSTAL_FREQ, | |
pac.XOSC, | |
pac.CLOCKS, | |
pac.PLL_SYS, | |
pac.PLL_USB, | |
&mut pac.RESETS, | |
&mut watchdog, | |
) | |
.ok() | |
.unwrap(); | |
let sio = hal::Sio::new(pac.SIO); | |
let pins = bsp::Pins::new( | |
pac.IO_BANK0, | |
pac.PADS_BANK0, | |
sio.gpio_bank0, | |
&mut pac.RESETS, | |
); | |
// Init timer. | |
let core = pac::CorePeripherals::take().unwrap(); | |
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); | |
let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); | |
// Init Neopixel | |
let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); | |
let mut ws = Ws2812::new( | |
pins.neopixel.into_function(), | |
&mut pio, | |
sm0, | |
clocks.peripheral_clock.freq(), | |
timer.count_down(), | |
); | |
// LED: Green | |
ws.write(brightness(once(COLOR_GREEN.into()), LED_BRIGHTNESS)) | |
.unwrap(); | |
// Create the USB environment. | |
let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( | |
pac.USBCTRL_REGS, | |
pac.USBCTRL_DPRAM, | |
clocks.usb_clock, | |
true, | |
&mut pac.RESETS, | |
)); | |
unsafe { | |
USB_BUS = Some(usb_bus); | |
} | |
let bus_ref = unsafe { USB_BUS.as_ref().unwrap() }; | |
let usb_hid_m = HIDClass::new(bus_ref, MouseReport::desc(), 60); | |
unsafe { | |
USB_HID_M = Some(usb_hid_m); | |
} | |
// LED: Magenta | |
ws.write(brightness(once(COLOR_MAGENTA.into()), LED_BRIGHTNESS)) | |
.unwrap(); | |
// Create the USB device. | |
let usb_dev = UsbDeviceBuilder::new(bus_ref, UsbVidPid(0x1337, 0x0001)) | |
.manufacturer("slippery") | |
.product("jiggler") | |
.serial_number("SN-D0002") | |
.device_class(0x03) | |
.build(); | |
unsafe { | |
USB_DEVICE = Some(usb_dev); | |
} | |
unsafe { | |
pac::NVIC::unmask(hal::pac::Interrupt::USBCTRL_IRQ); | |
}; | |
// LED: Yellow | |
ws.write(brightness(once(COLOR_YELLOW.into()), LED_BRIGHTNESS)) | |
.unwrap(); | |
loop { | |
application_jiggle(&mut delay); | |
} | |
} | |
fn application_jiggle(delay: &mut Delay) { | |
/* Move to order slot and click twice, LED: Cyan */ | |
{ | |
push_mouse_input(REP_MOVE_UP).ok().unwrap_or(0); | |
delay.delay_ms(PAUSE_DELAY); | |
} | |
/* Move back to pens, LED: Cyan until restart */ | |
{ | |
push_mouse_input(REP_MOVE_DOWN).ok().unwrap_or(0); | |
delay.delay_ms(PAUSE_DELAY); | |
} | |
} | |
fn push_mouse_input(report: MouseReport) -> Result<usize, usb_device::UsbError> { | |
critical_section::with(|_| unsafe { USB_HID_M.as_mut().map(|hid| hid.push_input(&report)) }) | |
.unwrap() | |
} | |
#[allow(non_snake_case)] | |
#[interrupt] | |
unsafe fn USBCTRL_IRQ() { | |
let usb_dev = USB_DEVICE.as_mut().unwrap(); | |
let usb_hid_m = USB_HID_M.as_mut().unwrap(); | |
usb_dev.poll(&mut [usb_hid_m]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment