Skip to content

Instantly share code, notes, and snippets.

@sli
Last active November 27, 2023 07:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sli/fef1fd3a9e7e1e44870671ec85fc023c to your computer and use it in GitHub Desktop.
Save sli/fef1fd3a9e7e1e44870671ec85fc023c to your computer and use it in GitHub Desktop.
Mouse jiggler for an rp2040
#![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