PMW3610 Optical Mouse Sensor

PMW3610 is a low‑power optical mouse sensor.

NOTE
  • PMW3610 uses a single-wire (SDIO) half-duplex SPI.
  • motion pin is optional. If omitted, the sensor is polled.
  • Only Nrf and RP2040 are supported now.

toml configuration

WARNING

spi.mosi and spi.miso must be the same pin, or one of them empty.

[[input_device.pmw3610]]
name = "trackball0"

spi.instance = "bitbang0"
spi.sck = "P0_05"
spi.mosi = "P0_04"
spi.miso = "P0_04"
spi.cs = "P0_09"
# or spi = { instance = "bitbang0", sck = "P0_05", mosi = "P0_04", miso = "P0_04", cs = "P0_09" }

motion = "P0_02" # Optional. If omitted, the sensor is polled.

force_awake = false
smart_mode = true
cpi = 800
invert_x = true
# invert_y = true
# swap_xy = true

Rust configuration

Define Pmw3610Device and add it to run_devices! macro.

let pmw3610_config = Pmw3610Config {
    res_cpi: 800,
    // force_awake: true,
    smart_mode: true,
    swap_xy: true,
    // invert_x: true,
    // invert_y: true,
    ..Default::default()
};

let pmw3610_sck = Output::new(p.P0_05, Level::High, OutputDrive::Standard);
let pmw3610_sdio = Flex::new(p.P0_04);
let pmw3610_cs = Output::new(p.P0_09, Level::High, OutputDrive::Standard);
let pmw3610_motion = Some(Input::new(p.P0_02, Pull::Up));
// or if you want to omit the motion pin:
// let pmw3610_motion = Option::<Input<'static>>::None;

let pmw3610_spi = BitBangSpiBus::new(pmw3610_sck, pmw3610_sdio);

let mut pmw3610_device = Pmw3610Device::new(
    pmw3610_spi,
    pmw3610_cs,
    pmw3610_motion,
    pmw3610_config,
);

run_devices! (
    (matrix, pmw3610_device) => EVENT_CHANNEL,
),

And define a Pmw3610Processor and add it to run_processor_chain! macro to process the events.

WARNING

This should be added to the central if the sensor is on split peripheral.

use rmk::input_device::pmw3610::Pmw3610Processor;

let mut pmw3610_processor = Pmw3610Processor::new(&keymap);

run_processor_chain! {
    EVENT_CHANNEL => [pmw3610_processor],
},