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, Debug)]
22#[cfg_attr(feature = "defmt", derive(defmt::Format))]
23pub struct BurstData {
24 pub motion: bool,
25 pub on_surface: bool,
26 pub op_mode: u8,
27 pub frame_data_first: bool,
28 pub dx: i16,
29 pub dy: i16,
30 pub surface_quality: u8,
31 pub raw_data_sum: u8,
32 pub max_raw_data: u8,
33 pub min_raw_data: u8,
34 pub shutter: u16,
35}
36
37pub struct Pmw3360<S: SpiDevice> {
38 spi: S,
39 in_burst_mode: bool,
40 cpi: u16,
41}
42
43impl<S: SpiDevice> Pmw3360<S> {
44 pub fn new(spi: S) -> Self {
45 Self {
46 spi,
47 in_burst_mode: false,
48 cpi: 1000, }
50 }
51}
52
53impl<S: SpiDevice> MouseDriver for Pmw3360<S> {
54 type Error = Pmw3360Error<S::Error>;
55
56 async fn init(&mut self) -> Result<(), Self::Error> {
57 self.power_up().await
58 }
59
60 async fn read(&mut self) -> Result<(i8, i8), Self::Error> {
61 self.burst_read()
62 .await
63 .map(|data| (data.dx as i8, data.dy as i8))
64 }
65
66 async fn set_cpi(&mut self, cpi: u16) -> Result<(), Self::Error> {
67 self.set_cpi(cpi).await?;
68 Ok(())
69 }
70
71 async fn get_cpi(&mut self) -> Result<u16, Self::Error> {
72 Err(Self::Error::NotSupported)
73 }
74}
75
76impl<S: SpiDevice> Pmw3360<S> {
77 async fn write(&mut self, address: u8, data: u8) -> Result<(), Pmw3360Error<S::Error>> {
78 self.in_burst_mode = false;
79 self.spi
80 .transaction(&mut [
81 Operation::DelayNs(timing::NCS_SCLK),
82 Operation::TransferInPlace(&mut [address | 0x80, data]),
84 Operation::DelayNs(35 * 1000),
86 ])
87 .await
88 .map_err(Pmw3360Error::Spi)?;
89
90 Timer::after_micros(145).await;
92
93 Ok(())
94 }
95
96 async fn read(&mut self, address: u8) -> Result<u8, Pmw3360Error<S::Error>> {
97 self.in_burst_mode = false;
98 let mut buf = [0x00];
99 self.spi
100 .transaction(&mut [
101 Operation::DelayNs(timing::NCS_SCLK),
102 Operation::Write(&[address & 0x7f]),
104 Operation::DelayNs(160 * 1000),
106 Operation::Read(&mut buf),
108 Operation::DelayNs(120),
110 ])
111 .await
112 .map_err(Pmw3360Error::Spi)?;
113
114 Timer::after_micros(20).await;
116
117 Ok(buf[0])
118 }
119
120 pub async fn burst_read(&mut self) -> Result<BurstData, Pmw3360Error<S::Error>> {
121 if !self.in_burst_mode {
122 self.write(reg::MOTION_BURST, 0x00).await?;
123 self.in_burst_mode = true;
124 }
125
126 let mut data = [0u8; 12];
127
128 self.spi
129 .transaction(&mut [
130 Operation::DelayNs(timing::NCS_SCLK),
131 Operation::Write(&[reg::MOTION_BURST]),
132 Operation::DelayNs(35 * 1000),
134 Operation::Read(&mut data),
135 ])
136 .await
137 .map_err(Pmw3360Error::Spi)?;
138
139 Timer::after_micros(1).await;
141
142 let data = BurstData {
144 motion: (data[0] & 0x80) != 0,
145 on_surface: (data[0] & 0x08) == 0,
146 op_mode: (data[0] >> 1) & 0x03,
147 frame_data_first: data[0] & 0x01 != 0,
148 dx: ((data[3] as i16) << 8) | (data[2] as i16),
149 dy: ((data[5] as i16) << 8) | (data[4] as i16),
150 surface_quality: data[6],
151 raw_data_sum: data[7],
152 max_raw_data: data[8],
153 min_raw_data: data[9],
154 shutter: ((data[11] as u16) << 8) | (data[10] as u16),
155 };
156
157 if data.motion && data.op_mode == 0x01 && data.on_surface && data.dx == 0 && data.dy == 0 {
161 rktk_log::warn!("Invalid motion detected. Performing reset:\n{:?}", data);
162 self.power_up().await?;
163 }
164
165 Ok(data)
166 }
167
168 pub async fn set_cpi(&mut self, cpi: u16) -> Result<(), Pmw3360Error<S::Error>> {
169 self.cpi = cpi;
170 let val: u16;
171 if cpi < 100 {
172 val = 0
173 } else if cpi > 12000 {
174 val = 0x77
175 } else {
176 val = (cpi - 100) / 100;
177 }
178 self.write(reg::CONFIG_1, val as u8).await?;
179 Ok(())
180 }
181
182 pub async fn get_cpi(&mut self) -> Result<u16, S::Error> {
183 let val = self.read(reg::CONFIG_1).await.unwrap_or_default() as u16;
184 Ok((val + 1) * 100)
185 }
186
187 pub async fn check_signature(&mut self) -> Result<bool, Pmw3360Error<S::Error>> {
188 let srom = self.read(reg::SROM_ID).await.unwrap_or(0);
189 let pid = self.read(reg::PRODUCT_ID).await.unwrap_or(0);
190 let ipid = self.read(reg::INVERSE_PRODUCT_ID).await.unwrap_or(0);
191
192 Ok(srom == 0x00 && pid == 0x42 && ipid == 0xBD)
194 }
195
196 #[allow(dead_code)]
197 pub async fn self_test(&mut self) -> Result<bool, Pmw3360Error<S::Error>> {
198 self.write(reg::SROM_ENABLE, 0x15).await?;
199 Timer::after_micros(10000).await;
200
201 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)
205 }
206
207 async fn power_up(&mut self) -> Result<(), Pmw3360Error<S::Error>> {
208 let is_valid_signature = self.power_up_inner().await?;
209 if is_valid_signature {
210 self.set_cpi(self.cpi).await?;
211 Ok(())
212 } else {
213 Err(Pmw3360Error::InvalidSignature)
214 }
215 }
216
217 async fn power_up_inner(&mut self) -> Result<bool, Pmw3360Error<S::Error>> {
218 self.spi
220 .transaction(&mut [])
221 .await
222 .map_err(Pmw3360Error::Spi)?;
223
224 self.write(reg::POWER_UP_RESET, 0x5A).await?;
226
227 Timer::after_millis(100).await;
229
230 self.read(reg::MOTION).await?;
232 self.read(reg::DELTA_X_L).await?;
233 self.read(reg::DELTA_X_H).await?;
234 self.read(reg::DELTA_Y_L).await?;
235 self.read(reg::DELTA_Y_H).await?;
236
237 let is_valid_signature = self.check_signature().await.unwrap_or(false);
241
242 self.write(reg::CONFIG_2, 0x00).await?;
245
246 Timer::after_micros(100).await;
247
248 Ok(is_valid_signature)
249 }
250
251 }