rktk_drivers_common/mouse/paw3395/
mod.rs1#![allow(dead_code)]
4
5pub mod config;
6mod error;
7mod power_up;
8mod registers;
9
10use embassy_time::Timer;
11use embedded_hal::spi::Operation;
12use embedded_hal_async::spi::SpiDevice;
13use error::Paw3395Error;
14use registers as reg;
15use rktk::drivers::interface::mouse::MouseDriver;
16
17mod timing {
18 pub const NCS_SCLK: u32 = 120;
19 pub const SCLK_NCS_READ: u32 = 120;
20 pub const SCLK_NCS_WRITE: u32 = 1000;
21 pub const SRAD: u32 = 2 * 1000;
22 pub const SWW_R: u32 = 5 * 1000;
23 pub const SRW_R: u32 = 2 * 1000;
24 pub const BEXIT: u32 = 500;
25}
26
27#[derive(Default, Debug)]
28pub struct BurstData {
29 pub op_mode: u8,
30 pub lift_stat: bool,
31 pub mot: bool,
32 pub observation: u8,
33 pub dx: i16,
34 pub dy: i16,
35 pub surface_quality: u8,
36 pub raw_data_sum: u8,
37 pub max_raw_data: u8,
38 pub min_raw_data: u8,
39 pub shutter: u16,
40}
41
42pub struct Paw3395<S: SpiDevice> {
43 spi: S,
44 config: config::Config,
45}
46
47impl<S: SpiDevice> Paw3395<S> {
48 pub fn new(spi: S, config: config::Config) -> Self {
49 Self { spi, config }
50 }
51}
52
53impl<S: SpiDevice> MouseDriver for Paw3395<S> {
54 type Error = Paw3395Error<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().await.map(|data| (data.dx as i8, data.dy as i8))
62 }
63
64 async fn set_cpi(&mut self, cpi: u16) -> Result<(), Self::Error> {
65 self.set_cpi(cpi).await?;
66 Ok(())
67 }
68
69 async fn get_cpi(&mut self) -> Result<u16, Self::Error> {
70 Err(Paw3395Error::NotSupported)
71 }
72}
73
74impl<S: SpiDevice> Paw3395<S> {
75 async fn write(&mut self, address: u8, data: u8) -> Result<(), Paw3395Error<S::Error>> {
76 self.spi
77 .transaction(&mut [
78 Operation::DelayNs(timing::NCS_SCLK),
79 Operation::Write(&[address | 0x80, data]),
80 Operation::DelayNs(timing::SCLK_NCS_WRITE),
81 ])
82 .await
83 .map_err(Paw3395Error::Spi)?;
84
85 Timer::after_nanos((timing::SWW_R - timing::SCLK_NCS_WRITE) as u64).await;
86
87 Ok(())
88 }
89
90 async fn read(&mut self, address: u8) -> Result<u8, Paw3395Error<S::Error>> {
91 let mut buf = [0x00];
92 self.spi
93 .transaction(&mut [
94 Operation::DelayNs(timing::NCS_SCLK),
95 Operation::Write(&[address & 0x7f]),
97 Operation::DelayNs(timing::SRAD),
98 Operation::Read(&mut buf),
99 Operation::DelayNs(timing::SCLK_NCS_READ),
100 ])
101 .await
102 .map_err(Paw3395Error::Spi)?;
103
104 Timer::after_nanos((timing::SRW_R - timing::SCLK_NCS_WRITE) as u64).await;
106
107 Ok(buf[0])
108 }
109
110 pub async fn burst_read(&mut self) -> Result<BurstData, Paw3395Error<S::Error>> {
111 let mut buf = [0u8; 12];
112 self.spi
113 .transaction(&mut [
114 Operation::DelayNs(timing::NCS_SCLK),
115 Operation::Write(&[reg::MOTION_BURST]),
116 Operation::DelayNs(timing::SRAD),
117 Operation::Read(&mut buf),
118 ])
119 .await
120 .map_err(Paw3395Error::Spi)?;
121
122 Timer::after_nanos(timing::BEXIT as u64).await;
123
124 let data = BurstData {
126 op_mode: buf[0] & 0b11,
127 lift_stat: (buf[0] >> 3) & 1 == 1,
128 mot: (buf[0] >> 7) & 1 == 1,
129 observation: buf[1],
130 dx: ((buf[3] as i16) << 8) | (buf[2] as i16),
131 dy: ((buf[5] as i16) << 8) | (buf[4] as i16),
132 surface_quality: buf[6],
133 raw_data_sum: buf[7],
134 max_raw_data: buf[8],
135 min_raw_data: buf[9],
136 shutter: ((buf[11] as u16) << 8) | (buf[10] as u16),
137 };
138
139 Ok(data)
140 }
141
142 pub async fn set_cpi(&mut self, cpi: u16) -> Result<(), Paw3395Error<S::Error>> {
143 let resolution = (cpi / 50) - 1;
144 let resolution_low = resolution as u8;
145 let resolution_high = (resolution >> 8) as u8;
146
147 self.write(reg::RESOLUTION_X_LOW, resolution_low).await?;
148 self.write(reg::RESOLUTION_X_HIGH, resolution_high).await?;
149 self.write(reg::RESOLUTION_Y_LOW, resolution_low).await?;
150 self.write(reg::RESOLUTION_Y_HIGH, resolution_high).await?;
151 self.write(reg::SET_RESOLUTION, 0x01).await?;
152
153 Ok(())
154 }
155
156 pub async fn get_cpi(&mut self) -> Result<u16, S::Error> {
157 let resolution_x_low = self.read(reg::RESOLUTION_X_LOW).await.unwrap_or_default();
158 let resolution_x_high = self.read(reg::RESOLUTION_X_HIGH).await.unwrap_or_default();
159 let resolution_x = ((resolution_x_high as u16) << 8) | resolution_x_low as u16;
160 Ok((resolution_x + 1) * 50)
161 }
162
163 pub async fn check_signature(&mut self) -> Result<bool, Paw3395Error<S::Error>> {
164 let pid = self.read(reg::PRODUCT_ID).await.unwrap_or(0);
165 let ipid = self.read(reg::INV_PRODUCT_ID).await.unwrap_or(0);
166
167 Ok(pid == 0x51 && ipid == 0xAE)
168 }
169
170 async fn shutdown(&mut self) -> Result<(), Paw3395Error<S::Error>> {
171 self.write(reg::SHUTDOWN, 0xB6).await?;
172 Timer::after_millis(5).await;
173 Ok(())
174 }
175
176 async fn power_up(&mut self) -> Result<(), Paw3395Error<S::Error>> {
177 Timer::after_millis(50).await;
178
179 self.write(reg::POWER_UP_RESET, 0x5A).await?;
180 Timer::after_millis(5).await;
181
182 for (addr, data) in power_up::POWER_UP_SEQS_1.iter() {
183 self.write(*addr, *data).await?;
184 }
185
186 'outer: {
187 for _ in 0..60 {
188 Timer::after_millis(1).await;
189 if self.read(0x6C).await? == 0x80 {
190 break 'outer;
191 };
192 }
193
194 for (addr, data) in power_up::POWER_UP_SEQS_2.iter() {
195 self.write(*addr, *data).await?;
196 }
197 }
198
199 for (addr, data) in power_up::POWER_UP_SEQS_3.iter() {
200 self.write(*addr, *data).await?;
201 }
202
203 self.read(reg::MOTION).await?;
204 self.read(reg::DELTA_X_L).await?;
205 self.read(reg::DELTA_X_H).await?;
206 self.read(reg::DELTA_Y_L).await?;
207 self.read(reg::DELTA_Y_H).await?;
208
209 if !self.check_signature().await.unwrap_or(false) {
210 return Err(Paw3395Error::InvalidSignature);
211 }
212
213 Timer::after_micros(100).await;
214
215 for (addr, data) in self.config.mode.commands.iter() {
217 self.write(*addr, *data).await?;
218 }
219 if let Some(c) = self.config.mode._0x40 {
220 let mut _0x40 = self.read(0x40).await?;
221 _0x40 |= c;
222 self.write(0x40, _0x40).await?;
223 }
224
225 self.write(0x7F, 0x0C).await?;
227 let lift_config = self.read(0x4E).await?;
228 self.write(0x7F, 0x00).await?;
229 let lift_config = lift_config | self.config.lift_cutoff as u8;
230 self.write(0x7F, 0x0C).await?;
231 self.write(0x4E, lift_config).await?;
232 self.write(0x7F, 0x00).await?;
233
234 Ok(())
235 }
236}