1use crate::hw::I2cBus;
7use cortex_m::asm;
8use stm32f7xx_hal::i2c::{self, PinScl, PinSda};
9use stm32f7xx_hal::pac::I2C1;
10
11const DEFAULT_ADDR: u8 = 0x29;
12
13#[derive(Debug)]
14pub enum Error {
15 I2c(i2c::Error),
16 InvalidDevice,
17 Timeout,
18}
19
20impl From<i2c::Error> for Error {
21 fn from(e: i2c::Error) -> Self {
22 Error::I2c(e)
23 }
24}
25
26pub struct Vl53l0x<SCL, SDA> {
27 bus: I2cBus<SCL, SDA>,
28 addr: u8,
29 stop_variable: u8,
30}
31
32impl<SCL, SDA> Vl53l0x<SCL, SDA>
33where
34 SCL: PinScl<I2C1>,
35 SDA: PinSda<I2C1>,
36{
37 pub fn new(bus: I2cBus<SCL, SDA>) -> Result<Self, Error> {
39 let mut dev = Self {
40 bus,
41 addr: DEFAULT_ADDR,
42 stop_variable: 0,
43 };
44
45 let _ = dev.write_reg(0xFF, 0x00);
47 let _ = dev.write_reg(0x80, 0x00);
48 let _ = dev.write_reg(0xBF, 0x00);
49 asm::delay(1_000_000);
50 let _ = dev.write_reg(0xBF, 0x01);
51 asm::delay(1_000_000);
52
53 if dev.read_reg(0xC0)? != 0xEE {
54 return Err(Error::InvalidDevice);
55 }
56
57 let vhv = dev.read_reg(0x89)?;
59 dev.write_reg(0x89, vhv | 0x01)?;
60
61 dev.write_reg(0x88, 0x00)?;
63 dev.write_reg(0x80, 0x01)?;
64 dev.write_reg(0xFF, 0x01)?;
65 dev.write_reg(0x00, 0x00)?;
66 dev.stop_variable = dev.read_reg(0x91)?;
67 dev.write_reg(0x00, 0x01)?;
68 dev.write_reg(0xFF, 0x00)?;
69 dev.write_reg(0x80, 0x00)?;
70
71 let msrc = dev.read_reg(0x60)?;
73 dev.write_reg(0x60, msrc | 0x12)?;
74
75 dev.write_reg(0x44, 0x00)?;
77 dev.write_reg(0x45, 0x20)?;
78
79 dev.write_reg(0x01, 0xFF)?;
80
81 Ok(dev)
82 }
83
84 pub fn static_init(&mut self) -> Result<(), Error> {
86 self.write_reg(0x80, 0x01)?;
88 self.write_reg(0xFF, 0x01)?;
89 self.write_reg(0x00, 0x00)?;
90 self.write_reg(0xFF, 0x06)?;
91 let r83 = self.read_reg(0x83)?;
92 self.write_reg(0x83, r83 | 0x04)?;
93 self.write_reg(0xFF, 0x07)?;
94 self.write_reg(0x81, 0x01)?;
95 self.write_reg(0x80, 0x01)?;
96 self.write_reg(0x94, 0x6B)?;
97 self.write_reg(0x83, 0x00)?;
98
99 let mut ready = false;
101 for _ in 0..50_000u32 {
102 if self.read_reg(0x83)? != 0x00 {
103 ready = true;
104 break;
105 }
106 }
107 if !ready {
108 return Err(Error::Timeout);
109 }
110
111 self.write_reg(0x83, 0x01)?;
112 let tmp = self.read_reg(0x92)?;
113 let spad_count = tmp & 0x7F;
114 let spad_is_aperture = (tmp >> 7) & 0x01 != 0;
115
116 self.write_reg(0x81, 0x00)?;
118 self.write_reg(0xFF, 0x06)?;
119 let r83 = self.read_reg(0x83)?;
120 self.write_reg(0x83, r83 & !0x04)?;
121 self.write_reg(0xFF, 0x01)?;
122 self.write_reg(0x00, 0x01)?;
123 self.write_reg(0xFF, 0x00)?;
124 self.write_reg(0x80, 0x00)?;
125
126 self.write_reg(0xFF, 0x01)?;
127 self.write_reg(0x4F, 0x00)?;
128 self.write_reg(0x4E, 0x2C)?;
129 self.write_reg(0xFF, 0x00)?;
130 self.write_reg(0xB6, 0xB4)?;
131
132 let mut spad_map = [0u8; 6];
134 self.bus.write_read(self.addr, &[0xB0u8], &mut spad_map)?;
135
136 let first_spad_to_enable: u8 = if spad_is_aperture { 12 } else { 0 };
138 let mut spads_enabled: u8 = 0;
139
140 for i in 0u8..48 {
141 let byte = (i / 8) as usize;
142 let bit = i % 8;
143 if i < first_spad_to_enable || spads_enabled >= spad_count {
144 spad_map[byte] &= !(1 << bit);
145 } else if spad_map[byte] & (1 << bit) != 0 {
146 spads_enabled += 1;
147 }
148 }
149
150 let mut buf = [0u8; 7];
152 buf[0] = 0xB0;
153 buf[1..7].copy_from_slice(&spad_map);
154 self.bus.write(self.addr, &buf)?;
155
156 Ok(())
157 }
158
159 pub fn load_tuning(&mut self) -> Result<(), Error> {
161 let settings: &[(u8, u8)] = &[
162 (0xFF, 0x01),
163 (0x00, 0x00),
164 (0xFF, 0x00),
165 (0x09, 0x00),
166 (0x10, 0x00),
167 (0x11, 0x00),
168 (0x24, 0x01),
169 (0x25, 0xFF),
170 (0x75, 0x00),
171 (0xFF, 0x01),
172 (0x4E, 0x2C),
173 (0x48, 0x00),
174 (0x30, 0x20),
175 (0xFF, 0x00),
176 (0x30, 0x09),
177 (0x54, 0x00),
178 (0x31, 0x04),
179 (0x32, 0x03),
180 (0x40, 0x83),
181 (0x46, 0x25),
182 (0x60, 0x00),
183 (0x27, 0x00),
184 (0x50, 0x06),
185 (0x51, 0x00),
186 (0x52, 0x96),
187 (0x56, 0x08),
188 (0x57, 0x30),
189 (0x61, 0x00),
190 (0x62, 0x00),
191 (0x64, 0x00),
192 (0x65, 0x00),
193 (0x66, 0xA0),
194 (0xFF, 0x01),
195 (0x22, 0x32),
196 (0x47, 0x14),
197 (0x49, 0xFF),
198 (0x4A, 0x00),
199 (0xFF, 0x00),
200 (0x7A, 0x0A),
201 (0x7B, 0x00),
202 (0x78, 0x21),
203 (0xFF, 0x01),
204 (0x23, 0x34),
205 (0x42, 0x00),
206 (0x44, 0xFF),
207 (0x45, 0x26),
208 (0x46, 0x05),
209 (0x40, 0x40),
210 (0x0E, 0x06),
211 (0x20, 0x1A),
212 (0x43, 0x40),
213 (0xFF, 0x00),
214 (0x34, 0x03),
215 (0x35, 0x44),
216 (0xFF, 0x01),
217 (0x31, 0x04),
218 (0x4B, 0x09),
219 (0x4C, 0x05),
220 (0x4D, 0x04),
221 (0xFF, 0x00),
222 (0x44, 0x00),
223 (0x45, 0x20),
224 (0x47, 0x08),
225 (0x48, 0x28),
226 (0x67, 0x00),
227 (0x70, 0x04),
228 (0x71, 0x01),
229 (0x72, 0xFE),
230 (0x76, 0x00),
231 (0x77, 0x00),
232 (0xFF, 0x01),
233 (0x0D, 0x01),
234 (0xFF, 0x00),
235 (0x80, 0x01),
236 (0x01, 0xF8),
237 (0xFF, 0x01),
238 (0x8E, 0x01),
239 (0x00, 0x01),
240 (0xFF, 0x00),
241 (0x80, 0x00),
242 ];
243 for &(reg, val) in settings {
244 self.write_reg(reg, val)?;
245 }
246 Ok(())
247 }
248
249 pub fn calibrate(&mut self) -> Result<(), Error> {
251 self.write_reg(0x0A, 0x04)?;
252 let gpio_hv = self.read_reg(0x84)?;
253 self.write_reg(0x84, gpio_hv & !0x10)?;
254 self.write_reg(0x0B, 0x01)?;
255
256 self.write_reg(0x01, 0xFF)?;
257
258 self.write_reg(0x01, 0x01)?;
259 self.perform_single_ref_calibration(0x40)?;
260
261 self.write_reg(0x01, 0x02)?;
262 self.perform_single_ref_calibration(0x00)?;
263
264 self.write_reg(0x01, 0xFF)?;
265
266 Ok(())
267 }
268
269 pub fn read_range_mm(&mut self) -> Result<u16, Error> {
271 self.write_reg(0x80, 0x01)?;
273 self.write_reg(0xFF, 0x01)?;
274 self.write_reg(0x00, 0x00)?;
275 self.write_reg(0x91, self.stop_variable)?;
276 self.write_reg(0x00, 0x01)?;
277 self.write_reg(0xFF, 0x00)?;
278 self.write_reg(0x80, 0x00)?;
279
280 self.write_reg(0x00, 0x01)?;
281
282 for _ in 0..50_000u32 {
283 if self.read_reg(0x00)? & 0x01 == 0 {
284 break;
285 }
286 }
287
288 let mut done = false;
289 for _ in 0..50_000u32 {
290 if self.read_reg(0x13)? & 0x07 != 0 {
291 done = true;
292 break;
293 }
294 }
295 if !done {
296 return Err(Error::Timeout);
297 }
298
299 let mut buf = [0u8; 2];
300 self.bus.write_read(self.addr, &[0x1Eu8], &mut buf)?;
301 let mm = ((buf[0] as u16) << 8) | buf[1] as u16;
302
303 self.write_reg(0x0B, 0x01)?;
304
305 Ok(mm)
306 }
307
308 fn perform_single_ref_calibration(&mut self, vhv_init_byte: u8) -> Result<(), Error> {
309 self.write_reg(0x00, 0x01 | vhv_init_byte)?;
310
311 let mut done = false;
312 for _ in 0..50_000u32 {
313 if self.read_reg(0x13)? & 0x07 != 0 {
314 done = true;
315 break;
316 }
317 }
318 if !done {
319 return Err(Error::Timeout);
320 }
321
322 self.write_reg(0x0B, 0x01)?;
323 self.write_reg(0x00, 0x00)?;
324
325 Ok(())
326 }
327
328 fn write_reg(&mut self, reg: u8, val: u8) -> Result<(), Error> {
329 self.bus.write(self.addr, &[reg, val]).map_err(Error::I2c)
330 }
331
332 fn read_reg(&mut self, reg: u8) -> Result<u8, Error> {
333 let mut buf = [0u8; 1];
334 self.bus.write_read(self.addr, &[reg], &mut buf)?;
335 Ok(buf[0])
336 }
337}