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()
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(Paw3395Error::NotSupported)
73 }
74}
75
76impl<S: SpiDevice> Paw3395<S> {
77 async fn write(&mut self, address: u8, data: u8) -> Result<(), Paw3395Error<S::Error>> {
78 self.spi
79 .transaction(&mut [
80 Operation::DelayNs(timing::NCS_SCLK),
81 Operation::Write(&[address | 0x80, data]),
82 Operation::DelayNs(timing::SCLK_NCS_WRITE),
83 ])
84 .await
85 .map_err(Paw3395Error::Spi)?;
86
87 Timer::after_nanos((timing::SWW_R - timing::SCLK_NCS_WRITE) as u64).await;
88
89 Ok(())
90 }
91
92 async fn read(&mut self, address: u8) -> Result<u8, Paw3395Error<S::Error>> {
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(timing::SRAD),
100 Operation::Read(&mut buf),
101 Operation::DelayNs(timing::SCLK_NCS_READ),
102 ])
103 .await
104 .map_err(Paw3395Error::Spi)?;
105
106 Timer::after_nanos((timing::SRW_R - timing::SCLK_NCS_WRITE) as u64).await;
108
109 Ok(buf[0])
110 }
111
112 pub async fn burst_read(&mut self) -> Result<BurstData, Paw3395Error<S::Error>> {
113 let mut buf = [0u8; 12];
114 self.spi
115 .transaction(&mut [
116 Operation::DelayNs(timing::NCS_SCLK),
117 Operation::Write(&[reg::MOTION_BURST]),
118 Operation::DelayNs(timing::SRAD),
119 Operation::Read(&mut buf),
120 ])
121 .await
122 .map_err(Paw3395Error::Spi)?;
123
124 Timer::after_nanos(timing::BEXIT as u64).await;
125
126 let data = BurstData {
128 op_mode: buf[0] & 0b11,
129 lift_stat: (buf[0] >> 3) & 1 == 1,
130 mot: (buf[0] >> 7) & 1 == 1,
131 observation: buf[1],
132 dx: ((buf[3] as i16) << 8) | (buf[2] as i16),
133 dy: ((buf[5] as i16) << 8) | (buf[4] as i16),
134 surface_quality: buf[6],
135 raw_data_sum: buf[7],
136 max_raw_data: buf[8],
137 min_raw_data: buf[9],
138 shutter: ((buf[11] as u16) << 8) | (buf[10] as u16),
139 };
140
141 Ok(data)
142 }
143
144 pub async fn set_cpi(&mut self, cpi: u16) -> Result<(), Paw3395Error<S::Error>> {
145 let resolution = (cpi / 50) - 1;
146 let resolution_low = resolution as u8;
147 let resolution_high = (resolution >> 8) as u8;
148
149 self.write(reg::RESOLUTION_X_LOW, resolution_low).await?;
150 self.write(reg::RESOLUTION_X_HIGH, resolution_high).await?;
151 self.write(reg::RESOLUTION_Y_LOW, resolution_low).await?;
152 self.write(reg::RESOLUTION_Y_HIGH, resolution_high).await?;
153 self.write(reg::SET_RESOLUTION, 0x01).await?;
154
155 Ok(())
156 }
157
158 pub async fn get_cpi(&mut self) -> Result<u16, S::Error> {
159 let resolution_x_low = self.read(reg::RESOLUTION_X_LOW).await.unwrap_or_default();
160 let resolution_x_high = self.read(reg::RESOLUTION_X_HIGH).await.unwrap_or_default();
161 let resolution_x = ((resolution_x_high as u16) << 8) | resolution_x_low as u16;
162 Ok((resolution_x + 1) * 50)
163 }
164
165 pub async fn check_signature(&mut self) -> Result<bool, Paw3395Error<S::Error>> {
166 let pid = self.read(reg::PRODUCT_ID).await.unwrap_or(0);
167 let ipid = self.read(reg::INV_PRODUCT_ID).await.unwrap_or(0);
168
169 Ok(pid == 0x51 && ipid == 0xAE)
170 }
171
172 async fn shutdown(&mut self) -> Result<(), Paw3395Error<S::Error>> {
173 self.write(reg::SHUTDOWN, 0xB6).await?;
174 Timer::after_millis(5).await;
175 Ok(())
176 }
177
178 async fn power_up(&mut self) -> Result<(), Paw3395Error<S::Error>> {
179 Timer::after_micros(50).await;
180
181 self.write(reg::POWER_UP_RESET, 0x5A).await?;
182 Timer::after_millis(5).await;
183
184 for (addr, data) in power_up::POWER_UP_SEQS_1.iter() {
185 self.write(*addr, *data).await?;
186 }
187
188 'outer: {
189 for _ in 0..60 {
190 Timer::after_millis(1).await;
191 if self.read(0x6C).await? == 0x80 {
192 break 'outer;
193 };
194 }
195
196 for (addr, data) in power_up::POWER_UP_SEQS_2.iter() {
197 self.write(*addr, *data).await?;
198 }
199 }
200
201 for (addr, data) in power_up::POWER_UP_SEQS_3.iter() {
202 self.write(*addr, *data).await?;
203 }
204
205 self.read(reg::MOTION).await?;
206 self.read(reg::DELTA_X_L).await?;
207 self.read(reg::DELTA_X_H).await?;
208 self.read(reg::DELTA_Y_L).await?;
209 self.read(reg::DELTA_Y_H).await?;
210
211 if !self.check_signature().await.unwrap_or(false) {
212 return Err(Paw3395Error::InvalidSignature);
213 }
214
215 Timer::after_micros(100).await;
216
217 for (addr, data) in self.config.mode.commands.iter() {
219 self.write(*addr, *data).await?;
220 }
221 if let Some(c) = self.config.mode._0x40 {
222 let mut _0x40 = self.read(0x40).await?;
223 _0x40 |= c;
224 self.write(0x40, _0x40).await?;
225 }
226
227 self.write(0x7F, 0x0C).await?;
229 let lift_config = self.read(0x4E).await?;
230 self.write(0x7F, 0x00).await?;
231 let lift_config = lift_config | self.config.lift_cutoff as u8;
232 self.write(0x7F, 0x0C).await?;
233 self.write(0x4E, lift_config).await?;
234 self.write(0x7F, 0x00).await?;
235
236 Ok(())
237 }
238}