use crate::*;
use embedded_hal::spi::SpiDevice;
#[expect(clippy::struct_excessive_bools)]
pub struct Relative {
pub x: bool,
pub y: bool,
pub filter: bool,
pub swap_x_y: bool,
pub glide_extend: bool,
pub scroll: bool,
pub secondary_tap: bool,
pub taps: bool,
pub intellimouse: bool,
}
impl Default for Relative {
fn default() -> Self {
Self {
x: true,
y: true,
filter: true,
swap_x_y: false,
glide_extend: false,
scroll: false,
secondary_tap: false,
taps: true,
intellimouse: false,
}
}
}
impl Relative {
pub fn init<S: SpiDevice<u8>>(&self, spi: S) -> Result<Touchpad<S, Self>, S::Error> {
let config1 =
1 | u8::from(!self.y) << 4 | u8::from(!self.x) << 3 | u8::from(!self.filter) << 2;
let config2 = u8::from(self.swap_x_y) << 7
| u8::from(!self.glide_extend) << 4
| u8::from(!self.scroll) << 3
| u8::from(!self.secondary_tap) << 2
| u8::from(!self.taps) << 1
| u8::from(self.intellimouse);
init(spi, config1, config2)
}
}
#[expect(clippy::struct_excessive_bools)]
pub struct Absolute {
pub x: bool,
pub y: bool,
pub filter: bool,
invert_x: bool,
invert_y: bool,
}
impl Default for Absolute {
fn default() -> Self {
Self {
x: true,
y: true,
filter: true,
invert_x: false,
invert_y: false,
}
}
}
impl Absolute {
pub fn init<S: SpiDevice<u8>>(&self, spi: S) -> Result<Touchpad<S, Self>, S::Error> {
let config1 = 1
| u8::from(self.invert_y) << 7
| u8::from(self.invert_x) << 6
| u8::from(!self.y) << 4
| u8::from(!self.x) << 3
| u8::from(!self.filter) << 2
| 1 << 1;
let config2 = 0b11111; init(spi, config1, config2)
}
}
pub trait Mode {}
impl Mode for Relative {}
impl Mode for Absolute {}
fn init<M, S>(spi: S, config1: u8, config2: u8) -> Result<Touchpad<S, M>, S::Error>
where
S: SpiDevice<u8>,
M: Mode,
{
let mut pinnacle = Touchpad::new(spi);
pinnacle.clear_flags()?;
pinnacle.set_power_mode(PowerMode::Active)?;
pinnacle.write(FEED_CONFIG2_ADDR, config2)?;
pinnacle.write(FEED_CONFIG1_ADDR, config1)?;
Ok(pinnacle)
}
#[derive(Copy, Clone, Debug)]
pub struct AbsoluteData {
pub x: u16,
pub y: u16,
pub z: u8,
pub button_flags: u8,
}
impl AbsoluteData {
pub const X_MIN: u16 = 0;
pub const Y_MIN: u16 = 0;
pub const X_MAX: u16 = 2047;
pub const Y_MAX: u16 = 1535;
#[must_use]
pub const fn touched(&self) -> bool {
self.z != 0
}
#[must_use]
pub fn x_f32(&self) -> f32 {
f32::from(self.x * 2) / f32::from(Self::X_MAX) - 1.0
}
#[must_use]
pub fn y_f32(&self) -> f32 {
f32::from(self.y * 2) / f32::from(Self::Y_MAX) - 1.0
}
}
#[derive(Copy, Clone, Debug)]
pub struct RelativeData {
pub x: i16,
pub y: i16,
pub wheel: i8,
pub buttons: Buttons,
}
#[derive(Copy, Clone, Debug)]
pub struct Buttons {
pub primary: bool,
pub secondary: bool,
pub auxiliary: bool,
}