Skip to content

Rust crate for working with Cirque Pinnacle Glidepoint touchpads on embedded systems

License

Notifications You must be signed in to change notification settings

orsinium-labs/cirque-pinnacle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cirque-pinnacle

Rust crate for working with Cirque Pinnacle Glidepoint touchpads on embedded systems.

Features:

  • no_std
  • no allocation
  • supports all modern Cirque touchpads
  • both absolute and relative mode
  • can configure and force calibration
  • supports almost all features, including many that are not documented
  • safe to use API

Installation

cargo add cirque-pinnacle

Usage

The only thing that the crate requires is an SpiDevice instance. For example, here is how you can make one for ESP32 using esp-hal:

#![no_std]
#![no_main]
use embedded_hal_bus::spi::ExclusiveDevice;
use esp_backtrace as _;
use esp_hal::delay::Delay;
use esp_hal::prelude::*;
use esp_hal::spi::SpiMode;
use esp_hal::{
    gpio::{Level, Output},
    spi::master::Spi,
};
use esp_println::println;

#[entry]
fn main() -> ! {
    let mut config = esp_hal::Config::default();
    config.cpu_clock = CpuClock::max();
    let peripherals = esp_hal::init(config);
    let delay = Delay::new();
    let sclk = peripherals.GPIO1;
    let miso = peripherals.GPIO2;
    let mosi = peripherals.GPIO15;
    let cs = peripherals.GPIO7;

    let cs = Output::new(cs, Level::High);
    let spi = Spi::new_with_config(
        peripherals.SPI3,
        esp_hal::spi::master::Config {
            frequency: 400u32.kHz(),
            mode: SpiMode::Mode1,
            ..esp_hal::spi::master::Config::default()
        },
    )
    .with_sck(sclk)
    .with_mosi(mosi)
    .with_miso(miso);
    let spi_device = ExclusiveDevice::new(spi, cs, delay).unwrap();
    todo!();
}

You can then configure and initialize the touchpad:

let mode = cirque_pinnacle::Absolute::default();
let mut pad = mode.init(spi_device).unwrap();

Get some information about the device:

println!("firmware ID: {}", pad.firmware_id().unwrap());
println!("firmware version: {}", pad.firmware_version().unwrap());
println!("product ID: {}", pad.product_id().unwrap());

Read touch coordinates:

loop {
    let pos = pad.read_absolute().unwrap();
    if pos.touched() {
        println!("x={} y={} z={}", pos.x, pos.y, pos.z);
    }
}

Each time you read coordinates, the DR pin of the touchpad gets deasserted. It will be asserted again when new data is available. So, in a real application, you can use the DR pin for interrupts to not miss any touchpad events.