Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use core::convert::Infallible;
use embedded_hal::{
blocking::{delay::DelayMs, i2c::WriteRead},
digital::v2::OutputPin,
};
use rp2040_hal::Timer;
use rtt_target::rprintln;
const ADDRESS: u8 = 0x3B;
pub enum Registers {
Motion = 0x02,
DeltaX = 0x03,
DeltaY = 0x04,
}
pub struct Touchpad<I: WriteRead, R: OutputPin, S: OutputPin> {
i2c: I,
reset: R,
shutdown: S,
}
impl<I: WriteRead, R: OutputPin<Error = Infallible>, S: OutputPin<Error = Infallible>>
Touchpad<I, R, S>
{
// TODO can take a reference to a timer
pub fn new(i2c: I, mut reset: R, mut shutdown: S, mut timer: Timer) -> Self {
shutdown.set_low().unwrap();
reset.set_low().unwrap();
timer.delay_ms(100);
reset.set_high().unwrap();
Self {
i2c,
reset,
shutdown,
}
}
pub fn get_delta_motion(&mut self) -> Result<(i8, i8), I::Error> {
let mut x = [0];
self.i2c
.write_read(ADDRESS, &[Registers::DeltaX as u8], &mut x)?;
let x = x[0];
let mut y = [0];
self.i2c
.write_read(ADDRESS, &[Registers::DeltaY as u8], &mut y)?;
let y = y[0];
let x = if x < 128 {
x.try_into().unwrap()
} else {
i8::try_from(i16::from(x) - 256).unwrap()
};
let y = if y < 128 {
y.try_into().unwrap()
} else {
i8::try_from(i16::from(y) - 256).unwrap()
};
Ok((x, y))
}
}