rktk_drivers_common/mouse/pmw3360/
mod.rs1#![allow(dead_code)]
4
5mod error;
6mod registers;
7mod srom_liftoff;
8mod srom_tracking;
9
10use embassy_time::Timer;
11use embedded_hal_async::spi::{Operation, SpiDevice};
12use error::Pmw3360Error;
13use registers as reg;
14use rktk::drivers::interface::mouse::MouseDriver;
15
16mod timing {
17 pub const NCS_SCLK: u32 = 120;
19}
20
21#[derive(Default)]
22pub struct BurstData {
23 pub motion: bool,
24 pub on_surface: bool,
25 pub dx: i16,
26 pub dy: i16,
27 pub surface_quality: u8,
28 pub raw_data_sum: u8,
29 pub max_raw_data: u8,
30 pub min_raw_data: u8,
31 pub shutter: u16,
32}
33
34pub struct Pmw3360<S: SpiDevice> {
35 spi: S,
36 in_burst_mode: bool,
37}
38
39impl<S: SpiDevice> Pmw3360<S> {
40 pub fn new(spi: S) -> Self {
41 Self {
42 spi,
43 in_burst_mode: false,
44 }
45 }
46}
47
48impl<S: SpiDevice> MouseDriver for Pmw3360<S> {
49 type Error = Pmw3360Error<S::Error>;
50
51 async fn init(&mut self) -> Result<(), Self::Error> {
52 self.power_up().await
53 }
54
55 async fn read(&mut self) -> Result<(i8, i8), Self::Error> {
56 self.burst_read()
57 .await
58 .map(|data| (data.dx as i8, data.dy as i8))
59 }
60
61 async fn set_cpi(&mut self, cpi: u16) -> Result<(), Self::Error> {
62 self.set_cpi(cpi).await?;
63 Ok(())
64 }
65
66 async fn get_cpi(&mut self) -> Result<u16, Self::Error> {
67 Err(Self::Error::NotSupported)
68 }
69}
70
71impl<S: SpiDevice> Pmw3360<S> {
72 async fn write(&mut self, address: u8, data: u8) -> Result<(), Pmw3360Error<S::Error>> {
73 self.in_burst_mode = false;
74 self.spi
75 .transaction(&mut [
76 Operation::DelayNs(timing::NCS_SCLK),
77 Operation::TransferInPlace(&mut [address | 0x80, data]),
79 Operation::DelayNs(35 * 1000),
81 ])
82 .await
83 .map_err(Pmw3360Error::Spi)?;
84
85 Timer::after_micros(145).await;
87
88 Ok(())
89 }
90
91 async fn read(&mut self, address: u8) -> Result<u8, Pmw3360Error<S::Error>> {
92 self.in_burst_mode = false;
93 let mut buf = [0x00];
94 self.spi
95 .transaction(&mut [
96 Operation::DelayNs(timing::NCS_SCLK),
97 Operation::Write(&[address & 0x7f]),
99 Operation::DelayNs(160 * 1000),
101 Operation::Read(&mut buf),
103 Operation::DelayNs(120),
105 ])
106 .await
107 .map_err(Pmw3360Error::Spi)?;
108
109 Timer::after_micros(20).await;
111
112 Ok(buf[0])
113 }
114
115 pub async fn burst_read(&mut self) -> Result<BurstData, Pmw3360Error<S::Error>> {
116 if !self.in_burst_mode {
117 self.write(reg::MOTION_BURST, 0x00).await?;
118 self.in_burst_mode = true;
119 }
120
121 let mut data = [0u8; 12];
122
123 self.spi
124 .transaction(&mut [
125 Operation::DelayNs(timing::NCS_SCLK),
126 Operation::Write(&[reg::MOTION_BURST]),
127 Operation::DelayNs(35 * 1000),
129 Operation::Read(&mut data),
130 ])
131 .await
132 .map_err(Pmw3360Error::Spi)?;
133
134 Timer::after_micros(1).await;
136
137 let data = BurstData {
139 motion: (data[0] & 0x80) != 0,
140 on_surface: (data[0] & 0x08) == 0,
141 dx: ((data[3] as i16) << 8) | (data[2] as i16),
142 dy: ((data[5] as i16) << 8) | (data[4] as i16),
143 surface_quality: data[6],
144 raw_data_sum: data[7],
145 max_raw_data: data[8],
146 min_raw_data: data[9],
147 shutter: ((data[11] as u16) << 8) | (data[10] as u16),
148 };
149
150 Ok(data)
151 }
152
153 pub async fn set_cpi(&mut self, cpi: u16) -> Result<(), Pmw3360Error<S::Error>> {
154 let val: u16;
155 if cpi < 100 {
156 val = 0
157 } else if cpi > 12000 {
158 val = 0x77
159 } else {
160 val = (cpi - 100) / 100;
161 }
162 self.write(reg::CONFIG_1, val as u8).await?;
163 Ok(())
164 }
165
166 pub async fn get_cpi(&mut self) -> Result<u16, S::Error> {
167 let val = self.read(reg::CONFIG_1).await.unwrap_or_default() as u16;
168 Ok((val + 1) * 100)
169 }
170
171 pub async fn check_signature(&mut self) -> Result<bool, Pmw3360Error<S::Error>> {
172 let srom = self.read(reg::SROM_ID).await.unwrap_or(0);
173 let pid = self.read(reg::PRODUCT_ID).await.unwrap_or(0);
174 let ipid = self.read(reg::INVERSE_PRODUCT_ID).await.unwrap_or(0);
175
176 Ok(srom == 0x00 && pid == 0x42 && ipid == 0xBD)
178 }
179
180 #[allow(dead_code)]
181 pub async fn self_test(&mut self) -> Result<bool, Pmw3360Error<S::Error>> {
182 self.write(reg::SROM_ENABLE, 0x15).await?;
183 Timer::after_micros(10000).await;
184
185 let u = self.read(reg::DATA_OUT_UPPER).await.unwrap_or(0); let l = self.read(reg::DATA_OUT_LOWER).await.unwrap_or(0); Ok(u == 0xBE && l == 0xEF)
189 }
190
191 async fn power_up(&mut self) -> Result<(), Pmw3360Error<S::Error>> {
192 let is_valid_signature = self.power_up_inner().await?;
193 if is_valid_signature {
194 Ok(())
195 } else {
196 Err(Pmw3360Error::InvalidSignature)
197 }
198 }
199
200 async fn power_up_inner(&mut self) -> Result<bool, Pmw3360Error<S::Error>> {
201 self.spi
203 .transaction(&mut [])
204 .await
205 .map_err(Pmw3360Error::Spi)?;
206
207 self.write(reg::POWER_UP_RESET, 0x5A).await?;
209
210 Timer::after_millis(100).await;
212
213 self.read(reg::MOTION).await?;
215 self.read(reg::DELTA_X_L).await?;
216 self.read(reg::DELTA_X_H).await?;
217 self.read(reg::DELTA_Y_L).await?;
218 self.read(reg::DELTA_Y_H).await?;
219
220 let is_valid_signature = self.check_signature().await.unwrap_or(false);
224
225 self.write(reg::CONFIG_2, 0x00).await?;
228
229 Timer::after_micros(100).await;
230
231 Ok(is_valid_signature)
232 }
233
234 }