# cirque-pinnacle
Rust crate for working with [Cirque Pinnacle Glidepoint](https://www.cirque.com/glidepoint-circle-trackpads) 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
```bash
cargo add cirque-pinnacle
```
## Usage
The only thing that the crate requires is an [SpiDevice](https://docs.rs/embedded-hal/1.0.0/embedded_hal/spi/trait.SpiDevice.html) instance. For example, here is how you can make one for [ESP32](https://en.wikipedia.org/wiki/ESP32) using [esp-hal](https://github.com/esp-rs/esp-hal):
```rust
#![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:
```rust
let mode = cirque_pinnacle::Absolute::default();
let mut pad = mode.init(spi_device).unwrap();
```
Get some information about the device:
```rust
println!("firmware ID: {}", pad.firmware_id().unwrap());
println!("firmware version: {}", pad.firmware_version().unwrap());
println!("product ID: {}", pad.product_id().unwrap());
```
Read touch coordinates:
```rust
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.