amiro-lld / include / VL53L0X / v1 / Api_vl53l0x / core / src / vl53l0x_api_core.c @ 6ebebd4d
History | View | Annotate | Download (73.5 KB)
1 | 6ebebd4d | Andre Raming | /*******************************************************************************
|
---|---|---|---|
2 | Copyright � 2016, STMicroelectronics International N.V.
|
||
3 | All rights reserved.
|
||
4 | |||
5 | Redistribution and use in source and binary forms, with or without
|
||
6 | modification, are permitted provided that the following conditions are met:
|
||
7 | * Redistributions of source code must retain the above copyright
|
||
8 | notice, this list of conditions and the following disclaimer.
|
||
9 | * Redistributions in binary form must reproduce the above copyright
|
||
10 | notice, this list of conditions and the following disclaimer in the
|
||
11 | documentation and/or other materials provided with the distribution.
|
||
12 | * Neither the name of STMicroelectronics nor the
|
||
13 | names of its contributors may be used to endorse or promote products
|
||
14 | derived from this software without specific prior written permission.
|
||
15 | |||
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
18 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
||
19 | NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
|
||
20 | IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
|
||
21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||
24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
27 | ******************************************************************************/
|
||
28 | |||
29 | #include "vl53l0x_api.h" |
||
30 | #include "vl53l0x_api_core.h" |
||
31 | #include "vl53l0x_api_calibration.h" |
||
32 | //#include "periphAL.h"
|
||
33 | |||
34 | |||
35 | #ifndef __KERNEL__
|
||
36 | #include <stdlib.h> |
||
37 | #endif
|
||
38 | #define LOG_FUNCTION_START(fmt, ...) \
|
||
39 | _LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__) |
||
40 | #define LOG_FUNCTION_END(status, ...) \
|
||
41 | _LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__) |
||
42 | #define LOG_FUNCTION_END_FMT(status, fmt, ...) \
|
||
43 | _LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__) |
||
44 | |||
45 | VL53L0X_Error VL53L0X_reverse_bytes(uint8_t *data, uint32_t size) |
||
46 | { |
||
47 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
48 | uint8_t tempData; |
||
49 | uint32_t mirrorIndex; |
||
50 | uint32_t middle = size/2;
|
||
51 | uint32_t index; |
||
52 | |||
53 | for (index = 0; index < middle; index++) { |
||
54 | mirrorIndex = size - index - 1;
|
||
55 | tempData = data[index]; |
||
56 | data[index] = data[mirrorIndex]; |
||
57 | data[mirrorIndex] = tempData; |
||
58 | } |
||
59 | return Status;
|
||
60 | } |
||
61 | |||
62 | VL53L0X_Error VL53L0X_measurement_poll_for_completion(VL53L0X_DEV Dev) |
||
63 | { |
||
64 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
65 | uint8_t NewDataReady = 0;
|
||
66 | uint32_t LoopNb; |
||
67 | |||
68 | LOG_FUNCTION_START("");
|
||
69 | |||
70 | LoopNb = 0;
|
||
71 | |||
72 | do {
|
||
73 | Status = VL53L0X_GetMeasurementDataReady(Dev, &NewDataReady); |
||
74 | if (Status != 0) |
||
75 | break; /* the error is set */ |
||
76 | |||
77 | if (NewDataReady == 1) |
||
78 | break; /* done note that status == 0 */ |
||
79 | |||
80 | LoopNb++; |
||
81 | if (LoopNb >= VL53L0X_DEFAULT_MAX_LOOP) {
|
||
82 | Status = VL53L0X_ERROR_TIME_OUT; |
||
83 | break;
|
||
84 | } |
||
85 | |||
86 | // sleep for 1 millisec
|
||
87 | usleep(1000);
|
||
88 | |||
89 | } while (1); |
||
90 | |||
91 | LOG_FUNCTION_END(Status); |
||
92 | |||
93 | return Status;
|
||
94 | } |
||
95 | |||
96 | |||
97 | uint8_t VL53L0X_decode_vcsel_period(uint8_t vcsel_period_reg) |
||
98 | { |
||
99 | /*!
|
||
100 | * Converts the encoded VCSEL period register value into the real
|
||
101 | * period in PLL clocks
|
||
102 | */
|
||
103 | |||
104 | uint8_t vcsel_period_pclks = 0;
|
||
105 | |||
106 | vcsel_period_pclks = (vcsel_period_reg + 1) << 1; |
||
107 | |||
108 | return vcsel_period_pclks;
|
||
109 | } |
||
110 | |||
111 | uint8_t VL53L0X_encode_vcsel_period(uint8_t vcsel_period_pclks) |
||
112 | { |
||
113 | /*!
|
||
114 | * Converts the encoded VCSEL period register value into the real period
|
||
115 | * in PLL clocks
|
||
116 | */
|
||
117 | |||
118 | uint8_t vcsel_period_reg = 0;
|
||
119 | |||
120 | vcsel_period_reg = (vcsel_period_pclks >> 1) - 1; |
||
121 | |||
122 | return vcsel_period_reg;
|
||
123 | } |
||
124 | |||
125 | |||
126 | uint32_t VL53L0X_isqrt(uint32_t num) |
||
127 | { |
||
128 | /*
|
||
129 | * Implements an integer square root
|
||
130 | *
|
||
131 | * From: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
|
||
132 | */
|
||
133 | |||
134 | uint32_t res = 0;
|
||
135 | uint32_t bit = 1 << 30; |
||
136 | /* The second-to-top bit is set:
|
||
137 | * 1 << 14 for 16-bits, 1 << 30 for 32 bits */
|
||
138 | |||
139 | /* "bit" starts at the highest power of four <= the argument. */
|
||
140 | while (bit > num)
|
||
141 | bit >>= 2;
|
||
142 | |||
143 | |||
144 | while (bit != 0) { |
||
145 | if (num >= res + bit) {
|
||
146 | num -= res + bit; |
||
147 | res = (res >> 1) + bit;
|
||
148 | } else
|
||
149 | res >>= 1;
|
||
150 | |||
151 | bit >>= 2;
|
||
152 | } |
||
153 | |||
154 | return res;
|
||
155 | } |
||
156 | |||
157 | |||
158 | uint32_t VL53L0X_quadrature_sum(uint32_t a, uint32_t b) |
||
159 | { |
||
160 | /*
|
||
161 | * Implements a quadrature sum
|
||
162 | *
|
||
163 | * rea = sqrt(a^2 + b^2)
|
||
164 | *
|
||
165 | * Trap overflow case max input value is 65535 (16-bit value)
|
||
166 | * as internal calc are 32-bit wide
|
||
167 | *
|
||
168 | * If overflow then seta output to maximum
|
||
169 | */
|
||
170 | uint32_t res = 0;
|
||
171 | |||
172 | if (a > 65535 || b > 65535) |
||
173 | res = 65535;
|
||
174 | else
|
||
175 | res = VL53L0X_isqrt(a * a + b * b); |
||
176 | |||
177 | return res;
|
||
178 | } |
||
179 | |||
180 | |||
181 | VL53L0X_Error VL53L0X_device_read_strobe(VL53L0X_DEV Dev) |
||
182 | { |
||
183 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
184 | uint8_t strobe; |
||
185 | uint32_t LoopNb; |
||
186 | LOG_FUNCTION_START("");
|
||
187 | |||
188 | Status |= VL53L0X_WrByte(Dev, 0x83, 0x00); |
||
189 | |||
190 | /* polling
|
||
191 | * use timeout to avoid deadlock*/
|
||
192 | if (Status == VL53L0X_ERROR_NONE) {
|
||
193 | LoopNb = 0;
|
||
194 | do {
|
||
195 | Status = VL53L0X_RdByte(Dev, 0x83, &strobe);
|
||
196 | if ((strobe != 0x00) || Status != VL53L0X_ERROR_NONE) |
||
197 | break;
|
||
198 | |||
199 | LoopNb = LoopNb + 1;
|
||
200 | } while (LoopNb < VL53L0X_DEFAULT_MAX_LOOP);
|
||
201 | |||
202 | if (LoopNb >= VL53L0X_DEFAULT_MAX_LOOP)
|
||
203 | Status = VL53L0X_ERROR_TIME_OUT; |
||
204 | |||
205 | } |
||
206 | |||
207 | Status |= VL53L0X_WrByte(Dev, 0x83, 0x01); |
||
208 | |||
209 | LOG_FUNCTION_END(Status); |
||
210 | return Status;
|
||
211 | |||
212 | } |
||
213 | |||
214 | VL53L0X_Error VL53L0X_get_info_from_device(VL53L0X_DEV Dev, uint8_t option) |
||
215 | { |
||
216 | |||
217 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
218 | uint8_t byte; |
||
219 | uint32_t TmpDWord; |
||
220 | uint8_t ModuleId; |
||
221 | uint8_t Revision; |
||
222 | uint8_t ReferenceSpadCount = 0;
|
||
223 | uint8_t ReferenceSpadType = 0;
|
||
224 | uint32_t PartUIDUpper = 0;
|
||
225 | uint32_t PartUIDLower = 0;
|
||
226 | uint32_t OffsetFixed1104_mm = 0;
|
||
227 | int16_t OffsetMicroMeters = 0;
|
||
228 | uint32_t DistMeasTgtFixed1104_mm = 400 << 4; |
||
229 | uint32_t DistMeasFixed1104_400_mm = 0;
|
||
230 | uint32_t SignalRateMeasFixed1104_400_mm = 0;
|
||
231 | char ProductId[19]; |
||
232 | char *ProductId_tmp;
|
||
233 | uint8_t ReadDataFromDeviceDone; |
||
234 | FixPoint1616_t SignalRateMeasFixed400mmFix = 0;
|
||
235 | uint8_t NvmRefGoodSpadMap[VL53L0X_REF_SPAD_BUFFER_SIZE]; |
||
236 | int i;
|
||
237 | |||
238 | |||
239 | LOG_FUNCTION_START("");
|
||
240 | |||
241 | ReadDataFromDeviceDone = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, |
||
242 | ReadDataFromDeviceDone); |
||
243 | |||
244 | /* This access is done only once after that a GetDeviceInfo or
|
||
245 | * datainit is done*/
|
||
246 | if (ReadDataFromDeviceDone != 7) { |
||
247 | |||
248 | Status |= VL53L0X_WrByte(Dev, 0x80, 0x01); |
||
249 | Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01); |
||
250 | Status |= VL53L0X_WrByte(Dev, 0x00, 0x00); |
||
251 | |||
252 | Status |= VL53L0X_WrByte(Dev, 0xFF, 0x06); |
||
253 | Status |= VL53L0X_RdByte(Dev, 0x83, &byte);
|
||
254 | Status |= VL53L0X_WrByte(Dev, 0x83, byte|4); |
||
255 | Status |= VL53L0X_WrByte(Dev, 0xFF, 0x07); |
||
256 | Status |= VL53L0X_WrByte(Dev, 0x81, 0x01); |
||
257 | |||
258 | //Status |= VL53L0X_PollingDelay(Dev); TODO NEED THIS ??
|
||
259 | |||
260 | Status |= VL53L0X_WrByte(Dev, 0x80, 0x01); |
||
261 | |||
262 | if (((option & 1) == 1) && |
||
263 | ((ReadDataFromDeviceDone & 1) == 0)) { |
||
264 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x6b); |
||
265 | Status |= VL53L0X_device_read_strobe(Dev); |
||
266 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
267 | |||
268 | ReferenceSpadCount = (uint8_t)((TmpDWord >> 8) & 0x07f); |
||
269 | ReferenceSpadType = (uint8_t)((TmpDWord >> 15) & 0x01); |
||
270 | |||
271 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x24); |
||
272 | Status |= VL53L0X_device_read_strobe(Dev); |
||
273 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
274 | |||
275 | |||
276 | NvmRefGoodSpadMap[0] = (uint8_t)((TmpDWord >> 24) |
||
277 | & 0xff);
|
||
278 | NvmRefGoodSpadMap[1] = (uint8_t)((TmpDWord >> 16) |
||
279 | & 0xff);
|
||
280 | NvmRefGoodSpadMap[2] = (uint8_t)((TmpDWord >> 8) |
||
281 | & 0xff);
|
||
282 | NvmRefGoodSpadMap[3] = (uint8_t)(TmpDWord & 0xff); |
||
283 | |||
284 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x25); |
||
285 | Status |= VL53L0X_device_read_strobe(Dev); |
||
286 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
287 | |||
288 | NvmRefGoodSpadMap[4] = (uint8_t)((TmpDWord >> 24) |
||
289 | & 0xff);
|
||
290 | NvmRefGoodSpadMap[5] = (uint8_t)((TmpDWord >> 16) |
||
291 | & 0xff);
|
||
292 | } |
||
293 | |||
294 | if (((option & 2) == 2) && |
||
295 | ((ReadDataFromDeviceDone & 2) == 0)) { |
||
296 | |||
297 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x02); |
||
298 | Status |= VL53L0X_device_read_strobe(Dev); |
||
299 | Status |= VL53L0X_RdByte(Dev, 0x90, &ModuleId);
|
||
300 | |||
301 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x7B); |
||
302 | Status |= VL53L0X_device_read_strobe(Dev); |
||
303 | Status |= VL53L0X_RdByte(Dev, 0x90, &Revision);
|
||
304 | |||
305 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x77); |
||
306 | Status |= VL53L0X_device_read_strobe(Dev); |
||
307 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
308 | |||
309 | ProductId[0] = (char)((TmpDWord >> 25) & 0x07f); |
||
310 | ProductId[1] = (char)((TmpDWord >> 18) & 0x07f); |
||
311 | ProductId[2] = (char)((TmpDWord >> 11) & 0x07f); |
||
312 | ProductId[3] = (char)((TmpDWord >> 4) & 0x07f); |
||
313 | |||
314 | byte = (uint8_t)((TmpDWord & 0x00f) << 3); |
||
315 | |||
316 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x78); |
||
317 | Status |= VL53L0X_device_read_strobe(Dev); |
||
318 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
319 | |||
320 | ProductId[4] = (char)(byte + |
||
321 | ((TmpDWord >> 29) & 0x07f)); |
||
322 | ProductId[5] = (char)((TmpDWord >> 22) & 0x07f); |
||
323 | ProductId[6] = (char)((TmpDWord >> 15) & 0x07f); |
||
324 | ProductId[7] = (char)((TmpDWord >> 8) & 0x07f); |
||
325 | ProductId[8] = (char)((TmpDWord >> 1) & 0x07f); |
||
326 | |||
327 | byte = (uint8_t)((TmpDWord & 0x001) << 6); |
||
328 | |||
329 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x79); |
||
330 | |||
331 | Status |= VL53L0X_device_read_strobe(Dev); |
||
332 | |||
333 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
334 | |||
335 | ProductId[9] = (char)(byte + |
||
336 | ((TmpDWord >> 26) & 0x07f)); |
||
337 | ProductId[10] = (char)((TmpDWord >> 19) & 0x07f); |
||
338 | ProductId[11] = (char)((TmpDWord >> 12) & 0x07f); |
||
339 | ProductId[12] = (char)((TmpDWord >> 5) & 0x07f); |
||
340 | |||
341 | byte = (uint8_t)((TmpDWord & 0x01f) << 2); |
||
342 | |||
343 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x7A); |
||
344 | |||
345 | Status |= VL53L0X_device_read_strobe(Dev); |
||
346 | |||
347 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
348 | |||
349 | ProductId[13] = (char)(byte + |
||
350 | ((TmpDWord >> 30) & 0x07f)); |
||
351 | ProductId[14] = (char)((TmpDWord >> 23) & 0x07f); |
||
352 | ProductId[15] = (char)((TmpDWord >> 16) & 0x07f); |
||
353 | ProductId[16] = (char)((TmpDWord >> 9) & 0x07f); |
||
354 | ProductId[17] = (char)((TmpDWord >> 2) & 0x07f); |
||
355 | ProductId[18] = '\0'; |
||
356 | |||
357 | } |
||
358 | |||
359 | if (((option & 4) == 4) && |
||
360 | ((ReadDataFromDeviceDone & 4) == 0)) { |
||
361 | |||
362 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x7B); |
||
363 | Status |= VL53L0X_device_read_strobe(Dev); |
||
364 | Status |= VL53L0X_RdDWord(Dev, 0x90, &PartUIDUpper);
|
||
365 | |||
366 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x7C); |
||
367 | Status |= VL53L0X_device_read_strobe(Dev); |
||
368 | Status |= VL53L0X_RdDWord(Dev, 0x90, &PartUIDLower);
|
||
369 | |||
370 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x73); |
||
371 | Status |= VL53L0X_device_read_strobe(Dev); |
||
372 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
373 | |||
374 | SignalRateMeasFixed1104_400_mm = (TmpDWord & |
||
375 | 0x0000000ff) << 8; |
||
376 | |||
377 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x74); |
||
378 | Status |= VL53L0X_device_read_strobe(Dev); |
||
379 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
380 | |||
381 | SignalRateMeasFixed1104_400_mm |= ((TmpDWord & |
||
382 | 0xff000000) >> 24); |
||
383 | |||
384 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x75); |
||
385 | Status |= VL53L0X_device_read_strobe(Dev); |
||
386 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
387 | |||
388 | DistMeasFixed1104_400_mm = (TmpDWord & 0x0000000ff)
|
||
389 | << 8;
|
||
390 | |||
391 | Status |= VL53L0X_WrByte(Dev, 0x94, 0x76); |
||
392 | Status |= VL53L0X_device_read_strobe(Dev); |
||
393 | Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord);
|
||
394 | |||
395 | DistMeasFixed1104_400_mm |= ((TmpDWord & 0xff000000)
|
||
396 | >> 24);
|
||
397 | } |
||
398 | |||
399 | Status |= VL53L0X_WrByte(Dev, 0x81, 0x00); |
||
400 | Status |= VL53L0X_WrByte(Dev, 0xFF, 0x06); |
||
401 | Status |= VL53L0X_RdByte(Dev, 0x83, &byte);
|
||
402 | Status |= VL53L0X_WrByte(Dev, 0x83, byte&0xfb); |
||
403 | Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01); |
||
404 | Status |= VL53L0X_WrByte(Dev, 0x00, 0x01); |
||
405 | |||
406 | Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); |
||
407 | Status |= VL53L0X_WrByte(Dev, 0x80, 0x00); |
||
408 | } |
||
409 | |||
410 | if ((Status == VL53L0X_ERROR_NONE) &&
|
||
411 | (ReadDataFromDeviceDone != 7)) {
|
||
412 | /* Assign to variable if status is ok */
|
||
413 | if (((option & 1) == 1) && |
||
414 | ((ReadDataFromDeviceDone & 1) == 0)) { |
||
415 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
416 | ReferenceSpadCount, ReferenceSpadCount); |
||
417 | |||
418 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
419 | ReferenceSpadType, ReferenceSpadType); |
||
420 | |||
421 | for (i = 0; i < VL53L0X_REF_SPAD_BUFFER_SIZE; i++) { |
||
422 | Dev->Data.SpadData.RefGoodSpadMap[i] = |
||
423 | NvmRefGoodSpadMap[i]; |
||
424 | } |
||
425 | } |
||
426 | |||
427 | if (((option & 2) == 2) && |
||
428 | ((ReadDataFromDeviceDone & 2) == 0)) { |
||
429 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
430 | ModuleId, ModuleId); |
||
431 | |||
432 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
433 | Revision, Revision); |
||
434 | |||
435 | ProductId_tmp = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, |
||
436 | ProductId); |
||
437 | VL53L0X_COPYSTRING(ProductId_tmp, ProductId); |
||
438 | |||
439 | } |
||
440 | |||
441 | if (((option & 4) == 4) && |
||
442 | ((ReadDataFromDeviceDone & 4) == 0)) { |
||
443 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
444 | PartUIDUpper, PartUIDUpper); |
||
445 | |||
446 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
447 | PartUIDLower, PartUIDLower); |
||
448 | |||
449 | SignalRateMeasFixed400mmFix = |
||
450 | VL53L0X_FIXPOINT97TOFIXPOINT1616( |
||
451 | SignalRateMeasFixed1104_400_mm); |
||
452 | |||
453 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
454 | SignalRateMeasFixed400mm, |
||
455 | SignalRateMeasFixed400mmFix); |
||
456 | |||
457 | OffsetMicroMeters = 0;
|
||
458 | if (DistMeasFixed1104_400_mm != 0) { |
||
459 | OffsetFixed1104_mm = |
||
460 | DistMeasFixed1104_400_mm - |
||
461 | DistMeasTgtFixed1104_mm; |
||
462 | OffsetMicroMeters = (OffsetFixed1104_mm |
||
463 | * 1000) >> 4; |
||
464 | OffsetMicroMeters *= -1;
|
||
465 | } |
||
466 | |||
467 | PALDevDataSet(Dev, |
||
468 | Part2PartOffsetAdjustmentNVMMicroMeter, |
||
469 | OffsetMicroMeters); |
||
470 | } |
||
471 | byte = (uint8_t)(ReadDataFromDeviceDone|option); |
||
472 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, ReadDataFromDeviceDone, |
||
473 | byte); |
||
474 | } |
||
475 | |||
476 | LOG_FUNCTION_END(Status); |
||
477 | return Status;
|
||
478 | } |
||
479 | |||
480 | |||
481 | uint32_t VL53L0X_calc_macro_period_ps(VL53L0X_DEV Dev, uint8_t vcsel_period_pclks) |
||
482 | { |
||
483 | uint64_t PLL_period_ps; |
||
484 | uint32_t macro_period_vclks; |
||
485 | uint32_t macro_period_ps; |
||
486 | |||
487 | LOG_FUNCTION_START("");
|
||
488 | |||
489 | /* The above calculation will produce rounding errors,
|
||
490 | therefore set fixed value
|
||
491 | */
|
||
492 | PLL_period_ps = 1655;
|
||
493 | |||
494 | macro_period_vclks = 2304;
|
||
495 | macro_period_ps = (uint32_t)(macro_period_vclks |
||
496 | * vcsel_period_pclks * PLL_period_ps); |
||
497 | |||
498 | LOG_FUNCTION_END("");
|
||
499 | return macro_period_ps;
|
||
500 | } |
||
501 | |||
502 | uint16_t VL53L0X_encode_timeout(uint32_t timeout_macro_clks) |
||
503 | { |
||
504 | /*!
|
||
505 | * Encode timeout in macro periods in (LSByte * 2^MSByte) + 1 format
|
||
506 | */
|
||
507 | |||
508 | uint16_t encoded_timeout = 0;
|
||
509 | uint32_t ls_byte = 0;
|
||
510 | uint16_t ms_byte = 0;
|
||
511 | |||
512 | if (timeout_macro_clks > 0) { |
||
513 | ls_byte = timeout_macro_clks - 1;
|
||
514 | |||
515 | while ((ls_byte & 0xFFFFFF00) > 0) { |
||
516 | ls_byte = ls_byte >> 1;
|
||
517 | ms_byte++; |
||
518 | } |
||
519 | |||
520 | encoded_timeout = (ms_byte << 8)
|
||
521 | + (uint16_t) (ls_byte & 0x000000FF);
|
||
522 | } |
||
523 | |||
524 | return encoded_timeout;
|
||
525 | |||
526 | } |
||
527 | |||
528 | uint32_t VL53L0X_decode_timeout(uint16_t encoded_timeout) |
||
529 | { |
||
530 | /*!
|
||
531 | * Decode 16-bit timeout register value - format (LSByte * 2^MSByte) + 1
|
||
532 | */
|
||
533 | |||
534 | uint32_t timeout_macro_clks = 0;
|
||
535 | |||
536 | timeout_macro_clks = ((uint32_t) (encoded_timeout & 0x00FF)
|
||
537 | << (uint32_t) ((encoded_timeout & 0xFF00) >> 8)) + 1; |
||
538 | |||
539 | return timeout_macro_clks;
|
||
540 | } |
||
541 | |||
542 | |||
543 | /* To convert ms into register value */
|
||
544 | uint32_t VL53L0X_calc_timeout_mclks(VL53L0X_DEV Dev, |
||
545 | uint32_t timeout_period_us, |
||
546 | uint8_t vcsel_period_pclks) |
||
547 | { |
||
548 | uint32_t macro_period_ps; |
||
549 | uint32_t macro_period_ns; |
||
550 | uint32_t timeout_period_mclks = 0;
|
||
551 | |||
552 | macro_period_ps = VL53L0X_calc_macro_period_ps(Dev, vcsel_period_pclks); |
||
553 | macro_period_ns = (macro_period_ps + 500) / 1000; |
||
554 | |||
555 | timeout_period_mclks = |
||
556 | (uint32_t) (((timeout_period_us * 1000)
|
||
557 | + (macro_period_ns / 2)) / macro_period_ns);
|
||
558 | |||
559 | return timeout_period_mclks;
|
||
560 | } |
||
561 | |||
562 | /* To convert register value into us */
|
||
563 | uint32_t VL53L0X_calc_timeout_us(VL53L0X_DEV Dev, |
||
564 | uint16_t timeout_period_mclks, |
||
565 | uint8_t vcsel_period_pclks) |
||
566 | { |
||
567 | uint32_t macro_period_ps; |
||
568 | uint32_t macro_period_ns; |
||
569 | uint32_t actual_timeout_period_us = 0;
|
||
570 | |||
571 | macro_period_ps = VL53L0X_calc_macro_period_ps(Dev, vcsel_period_pclks); |
||
572 | macro_period_ns = (macro_period_ps + 500) / 1000; |
||
573 | |||
574 | actual_timeout_period_us = |
||
575 | ((timeout_period_mclks * macro_period_ns) + 500) / 1000; |
||
576 | |||
577 | return actual_timeout_period_us;
|
||
578 | } |
||
579 | |||
580 | |||
581 | VL53L0X_Error get_sequence_step_timeout(VL53L0X_DEV Dev, |
||
582 | VL53L0X_SequenceStepId SequenceStepId, |
||
583 | uint32_t *pTimeOutMicroSecs) |
||
584 | { |
||
585 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
586 | uint8_t CurrentVCSELPulsePeriodPClk; |
||
587 | uint8_t EncodedTimeOutByte = 0;
|
||
588 | uint32_t TimeoutMicroSeconds = 0;
|
||
589 | uint16_t PreRangeEncodedTimeOut = 0;
|
||
590 | uint16_t MsrcTimeOutMClks; |
||
591 | uint16_t PreRangeTimeOutMClks; |
||
592 | uint16_t FinalRangeTimeOutMClks = 0;
|
||
593 | uint16_t FinalRangeEncodedTimeOut; |
||
594 | VL53L0X_SchedulerSequenceSteps_t SchedulerSequenceSteps; |
||
595 | |||
596 | if ((SequenceStepId == VL53L0X_SEQUENCESTEP_TCC) ||
|
||
597 | (SequenceStepId == VL53L0X_SEQUENCESTEP_DSS) || |
||
598 | (SequenceStepId == VL53L0X_SEQUENCESTEP_MSRC)) { |
||
599 | |||
600 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
601 | VL53L0X_VCSEL_PERIOD_PRE_RANGE, |
||
602 | &CurrentVCSELPulsePeriodPClk); |
||
603 | if (Status == VL53L0X_ERROR_NONE) {
|
||
604 | Status = VL53L0X_RdByte(Dev, |
||
605 | VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP, |
||
606 | &EncodedTimeOutByte); |
||
607 | } |
||
608 | MsrcTimeOutMClks = VL53L0X_decode_timeout(EncodedTimeOutByte); |
||
609 | |||
610 | TimeoutMicroSeconds = VL53L0X_calc_timeout_us(Dev, |
||
611 | MsrcTimeOutMClks, |
||
612 | CurrentVCSELPulsePeriodPClk); |
||
613 | } else if (SequenceStepId == VL53L0X_SEQUENCESTEP_PRE_RANGE) { |
||
614 | /* Retrieve PRE-RANGE VCSEL Period */
|
||
615 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
616 | VL53L0X_VCSEL_PERIOD_PRE_RANGE, |
||
617 | &CurrentVCSELPulsePeriodPClk); |
||
618 | |||
619 | /* Retrieve PRE-RANGE Timeout in Macro periods (MCLKS) */
|
||
620 | if (Status == VL53L0X_ERROR_NONE) {
|
||
621 | |||
622 | /* Retrieve PRE-RANGE VCSEL Period */
|
||
623 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
624 | VL53L0X_VCSEL_PERIOD_PRE_RANGE, |
||
625 | &CurrentVCSELPulsePeriodPClk); |
||
626 | |||
627 | if (Status == VL53L0X_ERROR_NONE) {
|
||
628 | Status = VL53L0X_RdWord(Dev, |
||
629 | VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, |
||
630 | &PreRangeEncodedTimeOut); |
||
631 | } |
||
632 | |||
633 | PreRangeTimeOutMClks = VL53L0X_decode_timeout( |
||
634 | PreRangeEncodedTimeOut); |
||
635 | |||
636 | TimeoutMicroSeconds = VL53L0X_calc_timeout_us(Dev, |
||
637 | PreRangeTimeOutMClks, |
||
638 | CurrentVCSELPulsePeriodPClk); |
||
639 | } |
||
640 | } else if (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE) { |
||
641 | |||
642 | VL53L0X_GetSequenceStepEnables(Dev, &SchedulerSequenceSteps); |
||
643 | PreRangeTimeOutMClks = 0;
|
||
644 | |||
645 | if (SchedulerSequenceSteps.PreRangeOn) {
|
||
646 | /* Retrieve PRE-RANGE VCSEL Period */
|
||
647 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
648 | VL53L0X_VCSEL_PERIOD_PRE_RANGE, |
||
649 | &CurrentVCSELPulsePeriodPClk); |
||
650 | |||
651 | /* Retrieve PRE-RANGE Timeout in Macro periods
|
||
652 | * (MCLKS) */
|
||
653 | if (Status == VL53L0X_ERROR_NONE) {
|
||
654 | Status = VL53L0X_RdWord(Dev, |
||
655 | VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, |
||
656 | &PreRangeEncodedTimeOut); |
||
657 | PreRangeTimeOutMClks = VL53L0X_decode_timeout( |
||
658 | PreRangeEncodedTimeOut); |
||
659 | } |
||
660 | } |
||
661 | |||
662 | if (Status == VL53L0X_ERROR_NONE) {
|
||
663 | /* Retrieve FINAL-RANGE VCSEL Period */
|
||
664 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
665 | VL53L0X_VCSEL_PERIOD_FINAL_RANGE, |
||
666 | &CurrentVCSELPulsePeriodPClk); |
||
667 | } |
||
668 | |||
669 | /* Retrieve FINAL-RANGE Timeout in Macro periods (MCLKS) */
|
||
670 | if (Status == VL53L0X_ERROR_NONE) {
|
||
671 | Status = VL53L0X_RdWord(Dev, |
||
672 | VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, |
||
673 | &FinalRangeEncodedTimeOut); |
||
674 | FinalRangeTimeOutMClks = VL53L0X_decode_timeout( |
||
675 | FinalRangeEncodedTimeOut); |
||
676 | } |
||
677 | |||
678 | FinalRangeTimeOutMClks -= PreRangeTimeOutMClks; |
||
679 | TimeoutMicroSeconds = VL53L0X_calc_timeout_us(Dev, |
||
680 | FinalRangeTimeOutMClks, |
||
681 | CurrentVCSELPulsePeriodPClk); |
||
682 | } |
||
683 | |||
684 | *pTimeOutMicroSecs = TimeoutMicroSeconds; |
||
685 | |||
686 | return Status;
|
||
687 | } |
||
688 | |||
689 | |||
690 | VL53L0X_Error set_sequence_step_timeout(VL53L0X_DEV Dev, |
||
691 | VL53L0X_SequenceStepId SequenceStepId, |
||
692 | uint32_t TimeOutMicroSecs) |
||
693 | { |
||
694 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
695 | uint8_t CurrentVCSELPulsePeriodPClk; |
||
696 | uint8_t MsrcEncodedTimeOut; |
||
697 | uint16_t PreRangeEncodedTimeOut; |
||
698 | uint16_t PreRangeTimeOutMClks; |
||
699 | uint16_t MsrcRangeTimeOutMClks; |
||
700 | uint32_t FinalRangeTimeOutMClks; |
||
701 | uint16_t FinalRangeEncodedTimeOut; |
||
702 | VL53L0X_SchedulerSequenceSteps_t SchedulerSequenceSteps; |
||
703 | |||
704 | if ((SequenceStepId == VL53L0X_SEQUENCESTEP_TCC) ||
|
||
705 | (SequenceStepId == VL53L0X_SEQUENCESTEP_DSS) || |
||
706 | (SequenceStepId == VL53L0X_SEQUENCESTEP_MSRC)) { |
||
707 | |||
708 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
709 | VL53L0X_VCSEL_PERIOD_PRE_RANGE, |
||
710 | &CurrentVCSELPulsePeriodPClk); |
||
711 | |||
712 | if (Status == VL53L0X_ERROR_NONE) {
|
||
713 | MsrcRangeTimeOutMClks = VL53L0X_calc_timeout_mclks(Dev, |
||
714 | TimeOutMicroSecs, |
||
715 | (uint8_t)CurrentVCSELPulsePeriodPClk); |
||
716 | |||
717 | if (MsrcRangeTimeOutMClks > 256) |
||
718 | MsrcEncodedTimeOut = 255;
|
||
719 | else
|
||
720 | MsrcEncodedTimeOut = |
||
721 | (uint8_t)MsrcRangeTimeOutMClks - 1;
|
||
722 | |||
723 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
724 | LastEncodedTimeout, |
||
725 | MsrcEncodedTimeOut); |
||
726 | } |
||
727 | |||
728 | if (Status == VL53L0X_ERROR_NONE) {
|
||
729 | Status = VL53L0X_WrByte(Dev, |
||
730 | VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP, |
||
731 | MsrcEncodedTimeOut); |
||
732 | } |
||
733 | } else {
|
||
734 | |||
735 | if (SequenceStepId == VL53L0X_SEQUENCESTEP_PRE_RANGE) {
|
||
736 | |||
737 | if (Status == VL53L0X_ERROR_NONE) {
|
||
738 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
739 | VL53L0X_VCSEL_PERIOD_PRE_RANGE, |
||
740 | &CurrentVCSELPulsePeriodPClk); |
||
741 | PreRangeTimeOutMClks = |
||
742 | VL53L0X_calc_timeout_mclks(Dev, |
||
743 | TimeOutMicroSecs, |
||
744 | (uint8_t)CurrentVCSELPulsePeriodPClk); |
||
745 | PreRangeEncodedTimeOut = VL53L0X_encode_timeout( |
||
746 | PreRangeTimeOutMClks); |
||
747 | |||
748 | VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, |
||
749 | LastEncodedTimeout, |
||
750 | PreRangeEncodedTimeOut); |
||
751 | } |
||
752 | |||
753 | if (Status == VL53L0X_ERROR_NONE) {
|
||
754 | Status = VL53L0X_WrWord(Dev, |
||
755 | VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, |
||
756 | PreRangeEncodedTimeOut); |
||
757 | } |
||
758 | |||
759 | if (Status == VL53L0X_ERROR_NONE) {
|
||
760 | VL53L0X_SETDEVICESPECIFICPARAMETER( |
||
761 | Dev, |
||
762 | PreRangeTimeoutMicroSecs, |
||
763 | TimeOutMicroSecs); |
||
764 | } |
||
765 | } else if (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE) { |
||
766 | |||
767 | /* For the final range timeout, the pre-range timeout
|
||
768 | * must be added. To do this both final and pre-range
|
||
769 | * timeouts must be expressed in macro periods MClks
|
||
770 | * because they have different vcsel periods.
|
||
771 | */
|
||
772 | |||
773 | VL53L0X_GetSequenceStepEnables(Dev, |
||
774 | &SchedulerSequenceSteps); |
||
775 | PreRangeTimeOutMClks = 0;
|
||
776 | if (SchedulerSequenceSteps.PreRangeOn) {
|
||
777 | |||
778 | /* Retrieve PRE-RANGE VCSEL Period */
|
||
779 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
780 | VL53L0X_VCSEL_PERIOD_PRE_RANGE, |
||
781 | &CurrentVCSELPulsePeriodPClk); |
||
782 | |||
783 | /* Retrieve PRE-RANGE Timeout in Macro periods
|
||
784 | * (MCLKS) */
|
||
785 | if (Status == VL53L0X_ERROR_NONE) {
|
||
786 | Status = VL53L0X_RdWord(Dev, 0x51,
|
||
787 | &PreRangeEncodedTimeOut); |
||
788 | PreRangeTimeOutMClks = |
||
789 | VL53L0X_decode_timeout( |
||
790 | PreRangeEncodedTimeOut); |
||
791 | } |
||
792 | } |
||
793 | |||
794 | /* Calculate FINAL RANGE Timeout in Macro Periods
|
||
795 | * (MCLKS) and add PRE-RANGE value
|
||
796 | */
|
||
797 | if (Status == VL53L0X_ERROR_NONE) {
|
||
798 | |||
799 | Status = VL53L0X_GetVcselPulsePeriod(Dev, |
||
800 | VL53L0X_VCSEL_PERIOD_FINAL_RANGE, |
||
801 | &CurrentVCSELPulsePeriodPClk); |
||
802 | } |
||
803 | if (Status == VL53L0X_ERROR_NONE) {
|
||
804 | |||
805 | FinalRangeTimeOutMClks = |
||
806 | VL53L0X_calc_timeout_mclks(Dev, |
||
807 | TimeOutMicroSecs, |
||
808 | (uint8_t) CurrentVCSELPulsePeriodPClk); |
||
809 | |||
810 | FinalRangeTimeOutMClks += PreRangeTimeOutMClks; |
||
811 | |||
812 | FinalRangeEncodedTimeOut = |
||
813 | VL53L0X_encode_timeout(FinalRangeTimeOutMClks); |
||
814 | |||
815 | if (Status == VL53L0X_ERROR_NONE) {
|
||
816 | Status = VL53L0X_WrWord(Dev, 0x71,
|
||
817 | FinalRangeEncodedTimeOut); |
||
818 | } |
||
819 | |||
820 | if (Status == VL53L0X_ERROR_NONE) {
|
||
821 | VL53L0X_SETDEVICESPECIFICPARAMETER( |
||
822 | Dev, |
||
823 | FinalRangeTimeoutMicroSecs, |
||
824 | TimeOutMicroSecs); |
||
825 | } |
||
826 | } |
||
827 | } else
|
||
828 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
829 | |||
830 | } |
||
831 | return Status;
|
||
832 | } |
||
833 | |||
834 | VL53L0X_Error VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV Dev, |
||
835 | VL53L0X_VcselPeriod VcselPeriodType, uint8_t VCSELPulsePeriodPCLK) |
||
836 | { |
||
837 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
838 | uint8_t vcsel_period_reg; |
||
839 | uint8_t MinPreVcselPeriodPCLK = 12;
|
||
840 | uint8_t MaxPreVcselPeriodPCLK = 18;
|
||
841 | uint8_t MinFinalVcselPeriodPCLK = 8;
|
||
842 | uint8_t MaxFinalVcselPeriodPCLK = 14;
|
||
843 | uint32_t MeasurementTimingBudgetMicroSeconds; |
||
844 | uint32_t FinalRangeTimeoutMicroSeconds; |
||
845 | uint32_t PreRangeTimeoutMicroSeconds; |
||
846 | uint32_t MsrcTimeoutMicroSeconds; |
||
847 | uint8_t PhaseCalInt = 0;
|
||
848 | |||
849 | /* Check if valid clock period requested */
|
||
850 | |||
851 | if ((VCSELPulsePeriodPCLK % 2) != 0) { |
||
852 | /* Value must be an even number */
|
||
853 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
854 | } else if (VcselPeriodType == VL53L0X_VCSEL_PERIOD_PRE_RANGE && |
||
855 | (VCSELPulsePeriodPCLK < MinPreVcselPeriodPCLK || |
||
856 | VCSELPulsePeriodPCLK > MaxPreVcselPeriodPCLK)) { |
||
857 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
858 | } else if (VcselPeriodType == VL53L0X_VCSEL_PERIOD_FINAL_RANGE && |
||
859 | (VCSELPulsePeriodPCLK < MinFinalVcselPeriodPCLK || |
||
860 | VCSELPulsePeriodPCLK > MaxFinalVcselPeriodPCLK)) { |
||
861 | |||
862 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
863 | } |
||
864 | |||
865 | /* Apply specific settings for the requested clock period */
|
||
866 | |||
867 | if (Status != VL53L0X_ERROR_NONE)
|
||
868 | return Status;
|
||
869 | |||
870 | |||
871 | if (VcselPeriodType == VL53L0X_VCSEL_PERIOD_PRE_RANGE) {
|
||
872 | |||
873 | /* Set phase check limits */
|
||
874 | if (VCSELPulsePeriodPCLK == 12) { |
||
875 | |||
876 | Status = VL53L0X_WrByte(Dev, |
||
877 | VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, |
||
878 | 0x18);
|
||
879 | Status = VL53L0X_WrByte(Dev, |
||
880 | VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, |
||
881 | 0x08);
|
||
882 | } else if (VCSELPulsePeriodPCLK == 14) { |
||
883 | |||
884 | Status = VL53L0X_WrByte(Dev, |
||
885 | VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, |
||
886 | 0x30);
|
||
887 | Status = VL53L0X_WrByte(Dev, |
||
888 | VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, |
||
889 | 0x08);
|
||
890 | } else if (VCSELPulsePeriodPCLK == 16) { |
||
891 | |||
892 | Status = VL53L0X_WrByte(Dev, |
||
893 | VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, |
||
894 | 0x40);
|
||
895 | Status = VL53L0X_WrByte(Dev, |
||
896 | VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, |
||
897 | 0x08);
|
||
898 | } else if (VCSELPulsePeriodPCLK == 18) { |
||
899 | |||
900 | Status = VL53L0X_WrByte(Dev, |
||
901 | VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, |
||
902 | 0x50);
|
||
903 | Status = VL53L0X_WrByte(Dev, |
||
904 | VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, |
||
905 | 0x08);
|
||
906 | } |
||
907 | } else if (VcselPeriodType == VL53L0X_VCSEL_PERIOD_FINAL_RANGE) { |
||
908 | |||
909 | if (VCSELPulsePeriodPCLK == 8) { |
||
910 | |||
911 | Status = VL53L0X_WrByte(Dev, |
||
912 | VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, |
||
913 | 0x10);
|
||
914 | Status = VL53L0X_WrByte(Dev, |
||
915 | VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, |
||
916 | 0x08);
|
||
917 | |||
918 | Status |= VL53L0X_WrByte(Dev, |
||
919 | VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x02);
|
||
920 | Status |= VL53L0X_WrByte(Dev, |
||
921 | VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x0C);
|
||
922 | |||
923 | Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); |
||
924 | Status |= VL53L0X_WrByte(Dev, |
||
925 | VL53L0X_REG_ALGO_PHASECAL_LIM, |
||
926 | 0x30);
|
||
927 | Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); |
||
928 | } else if (VCSELPulsePeriodPCLK == 10) { |
||
929 | |||
930 | Status = VL53L0X_WrByte(Dev, |
||
931 | VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, |
||
932 | 0x28);
|
||
933 | Status = VL53L0X_WrByte(Dev, |
||
934 | VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, |
||
935 | 0x08);
|
||
936 | |||
937 | Status |= VL53L0X_WrByte(Dev, |
||
938 | VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
|
||
939 | Status |= VL53L0X_WrByte(Dev, |
||
940 | VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x09);
|
||
941 | |||
942 | Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); |
||
943 | Status |= VL53L0X_WrByte(Dev, |
||
944 | VL53L0X_REG_ALGO_PHASECAL_LIM, |
||
945 | 0x20);
|
||
946 | Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); |
||
947 | } else if (VCSELPulsePeriodPCLK == 12) { |
||
948 | |||
949 | Status = VL53L0X_WrByte(Dev, |
||
950 | VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, |
||
951 | 0x38);
|
||
952 | Status = VL53L0X_WrByte(Dev, |
||
953 | VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, |
||
954 | 0x08);
|
||
955 | |||
956 | Status |= VL53L0X_WrByte(Dev, |
||
957 | VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
|
||
958 | Status |= VL53L0X_WrByte(Dev, |
||
959 | VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x08);
|
||
960 | |||
961 | Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); |
||
962 | Status |= VL53L0X_WrByte(Dev, |
||
963 | VL53L0X_REG_ALGO_PHASECAL_LIM, |
||
964 | 0x20);
|
||
965 | Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); |
||
966 | } else if (VCSELPulsePeriodPCLK == 14) { |
||
967 | |||
968 | Status = VL53L0X_WrByte(Dev, |
||
969 | VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, |
||
970 | 0x048);
|
||
971 | Status = VL53L0X_WrByte(Dev, |
||
972 | VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, |
||
973 | 0x08);
|
||
974 | |||
975 | Status |= VL53L0X_WrByte(Dev, |
||
976 | VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
|
||
977 | Status |= VL53L0X_WrByte(Dev, |
||
978 | VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x07);
|
||
979 | |||
980 | Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); |
||
981 | Status |= VL53L0X_WrByte(Dev, |
||
982 | VL53L0X_REG_ALGO_PHASECAL_LIM, |
||
983 | 0x20);
|
||
984 | Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); |
||
985 | } |
||
986 | } |
||
987 | |||
988 | |||
989 | /* Re-calculate and apply timeouts, in macro periods */
|
||
990 | |||
991 | if (Status == VL53L0X_ERROR_NONE) {
|
||
992 | vcsel_period_reg = VL53L0X_encode_vcsel_period((uint8_t) |
||
993 | VCSELPulsePeriodPCLK); |
||
994 | |||
995 | /* When the VCSEL period for the pre or final range is changed,
|
||
996 | * the corresponding timeout must be read from the device using
|
||
997 | * the current VCSEL period, then the new VCSEL period can be
|
||
998 | * applied. The timeout then must be written back to the device
|
||
999 | * using the new VCSEL period.
|
||
1000 | *
|
||
1001 | * For the MSRC timeout, the same applies - this timeout being
|
||
1002 | * dependant on the pre-range vcsel period.
|
||
1003 | */
|
||
1004 | switch (VcselPeriodType) {
|
||
1005 | case VL53L0X_VCSEL_PERIOD_PRE_RANGE:
|
||
1006 | Status = get_sequence_step_timeout(Dev, |
||
1007 | VL53L0X_SEQUENCESTEP_PRE_RANGE, |
||
1008 | &PreRangeTimeoutMicroSeconds); |
||
1009 | |||
1010 | if (Status == VL53L0X_ERROR_NONE)
|
||
1011 | Status = get_sequence_step_timeout(Dev, |
||
1012 | VL53L0X_SEQUENCESTEP_MSRC, |
||
1013 | &MsrcTimeoutMicroSeconds); |
||
1014 | |||
1015 | if (Status == VL53L0X_ERROR_NONE)
|
||
1016 | Status = VL53L0X_WrByte(Dev, |
||
1017 | VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD, |
||
1018 | vcsel_period_reg); |
||
1019 | |||
1020 | |||
1021 | if (Status == VL53L0X_ERROR_NONE)
|
||
1022 | Status = set_sequence_step_timeout(Dev, |
||
1023 | VL53L0X_SEQUENCESTEP_PRE_RANGE, |
||
1024 | PreRangeTimeoutMicroSeconds); |
||
1025 | |||
1026 | |||
1027 | if (Status == VL53L0X_ERROR_NONE)
|
||
1028 | Status = set_sequence_step_timeout(Dev, |
||
1029 | VL53L0X_SEQUENCESTEP_MSRC, |
||
1030 | MsrcTimeoutMicroSeconds); |
||
1031 | |||
1032 | VL53L0X_SETDEVICESPECIFICPARAMETER( |
||
1033 | Dev, |
||
1034 | PreRangeVcselPulsePeriod, |
||
1035 | VCSELPulsePeriodPCLK); |
||
1036 | break;
|
||
1037 | case VL53L0X_VCSEL_PERIOD_FINAL_RANGE:
|
||
1038 | Status = get_sequence_step_timeout(Dev, |
||
1039 | VL53L0X_SEQUENCESTEP_FINAL_RANGE, |
||
1040 | &FinalRangeTimeoutMicroSeconds); |
||
1041 | |||
1042 | if (Status == VL53L0X_ERROR_NONE)
|
||
1043 | Status = VL53L0X_WrByte(Dev, |
||
1044 | VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD, |
||
1045 | vcsel_period_reg); |
||
1046 | |||
1047 | |||
1048 | if (Status == VL53L0X_ERROR_NONE)
|
||
1049 | Status = set_sequence_step_timeout(Dev, |
||
1050 | VL53L0X_SEQUENCESTEP_FINAL_RANGE, |
||
1051 | FinalRangeTimeoutMicroSeconds); |
||
1052 | |||
1053 | VL53L0X_SETDEVICESPECIFICPARAMETER( |
||
1054 | Dev, |
||
1055 | FinalRangeVcselPulsePeriod, |
||
1056 | VCSELPulsePeriodPCLK); |
||
1057 | break;
|
||
1058 | default:
|
||
1059 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1060 | } |
||
1061 | } |
||
1062 | |||
1063 | /* Finally, the timing budget must be re-applied */
|
||
1064 | if (Status == VL53L0X_ERROR_NONE) {
|
||
1065 | VL53L0X_GETPARAMETERFIELD(Dev, |
||
1066 | MeasurementTimingBudgetMicroSeconds, |
||
1067 | MeasurementTimingBudgetMicroSeconds); |
||
1068 | |||
1069 | Status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev, |
||
1070 | MeasurementTimingBudgetMicroSeconds); |
||
1071 | } |
||
1072 | |||
1073 | /* Perform the phase calibration. This is needed after changing on
|
||
1074 | * vcsel period.
|
||
1075 | * get_data_enable = 0, restore_config = 1 */
|
||
1076 | if (Status == VL53L0X_ERROR_NONE)
|
||
1077 | Status = VL53L0X_perform_phase_calibration( |
||
1078 | Dev, &PhaseCalInt, 0, 1); |
||
1079 | |||
1080 | return Status;
|
||
1081 | } |
||
1082 | |||
1083 | VL53L0X_Error VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV Dev, |
||
1084 | VL53L0X_VcselPeriod VcselPeriodType, uint8_t *pVCSELPulsePeriodPCLK) |
||
1085 | { |
||
1086 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
1087 | uint8_t vcsel_period_reg; |
||
1088 | |||
1089 | switch (VcselPeriodType) {
|
||
1090 | case VL53L0X_VCSEL_PERIOD_PRE_RANGE:
|
||
1091 | Status = VL53L0X_RdByte(Dev, |
||
1092 | VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD, |
||
1093 | &vcsel_period_reg); |
||
1094 | break;
|
||
1095 | case VL53L0X_VCSEL_PERIOD_FINAL_RANGE:
|
||
1096 | Status = VL53L0X_RdByte(Dev, |
||
1097 | VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD, |
||
1098 | &vcsel_period_reg); |
||
1099 | break;
|
||
1100 | default:
|
||
1101 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1102 | } |
||
1103 | |||
1104 | if (Status == VL53L0X_ERROR_NONE)
|
||
1105 | *pVCSELPulsePeriodPCLK = |
||
1106 | VL53L0X_decode_vcsel_period(vcsel_period_reg); |
||
1107 | |||
1108 | return Status;
|
||
1109 | } |
||
1110 | |||
1111 | |||
1112 | |||
1113 | VL53L0X_Error VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV Dev, |
||
1114 | uint32_t MeasurementTimingBudgetMicroSeconds) |
||
1115 | { |
||
1116 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
1117 | uint32_t FinalRangeTimingBudgetMicroSeconds; |
||
1118 | VL53L0X_SchedulerSequenceSteps_t SchedulerSequenceSteps; |
||
1119 | uint32_t MsrcDccTccTimeoutMicroSeconds = 2000;
|
||
1120 | uint32_t StartOverheadMicroSeconds = 1910;
|
||
1121 | uint32_t EndOverheadMicroSeconds = 960;
|
||
1122 | uint32_t MsrcOverheadMicroSeconds = 660;
|
||
1123 | uint32_t TccOverheadMicroSeconds = 590;
|
||
1124 | uint32_t DssOverheadMicroSeconds = 690;
|
||
1125 | uint32_t PreRangeOverheadMicroSeconds = 660;
|
||
1126 | uint32_t FinalRangeOverheadMicroSeconds = 550;
|
||
1127 | uint32_t PreRangeTimeoutMicroSeconds = 0;
|
||
1128 | uint32_t cMinTimingBudgetMicroSeconds = 20000;
|
||
1129 | uint32_t SubTimeout = 0;
|
||
1130 | |||
1131 | LOG_FUNCTION_START("");
|
||
1132 | |||
1133 | if (MeasurementTimingBudgetMicroSeconds
|
||
1134 | < cMinTimingBudgetMicroSeconds) { |
||
1135 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1136 | return Status;
|
||
1137 | } |
||
1138 | |||
1139 | FinalRangeTimingBudgetMicroSeconds = |
||
1140 | MeasurementTimingBudgetMicroSeconds - |
||
1141 | (StartOverheadMicroSeconds + EndOverheadMicroSeconds); |
||
1142 | |||
1143 | Status = VL53L0X_GetSequenceStepEnables(Dev, &SchedulerSequenceSteps); |
||
1144 | |||
1145 | if (Status == VL53L0X_ERROR_NONE &&
|
||
1146 | (SchedulerSequenceSteps.TccOn || |
||
1147 | SchedulerSequenceSteps.MsrcOn || |
||
1148 | SchedulerSequenceSteps.DssOn)) { |
||
1149 | |||
1150 | /* TCC, MSRC and DSS all share the same timeout */
|
||
1151 | Status = get_sequence_step_timeout(Dev, |
||
1152 | VL53L0X_SEQUENCESTEP_MSRC, |
||
1153 | &MsrcDccTccTimeoutMicroSeconds); |
||
1154 | |||
1155 | /* Subtract the TCC, MSRC and DSS timeouts if they are
|
||
1156 | * enabled. */
|
||
1157 | |||
1158 | if (Status != VL53L0X_ERROR_NONE)
|
||
1159 | return Status;
|
||
1160 | |||
1161 | /* TCC */
|
||
1162 | if (SchedulerSequenceSteps.TccOn) {
|
||
1163 | |||
1164 | SubTimeout = MsrcDccTccTimeoutMicroSeconds |
||
1165 | + TccOverheadMicroSeconds; |
||
1166 | |||
1167 | if (SubTimeout <
|
||
1168 | FinalRangeTimingBudgetMicroSeconds) { |
||
1169 | FinalRangeTimingBudgetMicroSeconds -= |
||
1170 | SubTimeout; |
||
1171 | } else {
|
||
1172 | /* Requested timeout too big. */
|
||
1173 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1174 | } |
||
1175 | } |
||
1176 | |||
1177 | if (Status != VL53L0X_ERROR_NONE) {
|
||
1178 | LOG_FUNCTION_END(Status); |
||
1179 | return Status;
|
||
1180 | } |
||
1181 | |||
1182 | /* DSS */
|
||
1183 | if (SchedulerSequenceSteps.DssOn) {
|
||
1184 | |||
1185 | SubTimeout = 2 * (MsrcDccTccTimeoutMicroSeconds +
|
||
1186 | DssOverheadMicroSeconds); |
||
1187 | |||
1188 | if (SubTimeout < FinalRangeTimingBudgetMicroSeconds) {
|
||
1189 | FinalRangeTimingBudgetMicroSeconds |
||
1190 | -= SubTimeout; |
||
1191 | } else {
|
||
1192 | /* Requested timeout too big. */
|
||
1193 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1194 | } |
||
1195 | } else if (SchedulerSequenceSteps.MsrcOn) { |
||
1196 | /* MSRC */
|
||
1197 | SubTimeout = MsrcDccTccTimeoutMicroSeconds + |
||
1198 | MsrcOverheadMicroSeconds; |
||
1199 | |||
1200 | if (SubTimeout < FinalRangeTimingBudgetMicroSeconds) {
|
||
1201 | FinalRangeTimingBudgetMicroSeconds |
||
1202 | -= SubTimeout; |
||
1203 | } else {
|
||
1204 | /* Requested timeout too big. */
|
||
1205 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1206 | } |
||
1207 | } |
||
1208 | |||
1209 | } |
||
1210 | |||
1211 | if (Status != VL53L0X_ERROR_NONE) {
|
||
1212 | LOG_FUNCTION_END(Status); |
||
1213 | return Status;
|
||
1214 | } |
||
1215 | |||
1216 | if (SchedulerSequenceSteps.PreRangeOn) {
|
||
1217 | |||
1218 | /* Subtract the Pre-range timeout if enabled. */
|
||
1219 | |||
1220 | Status = get_sequence_step_timeout(Dev, |
||
1221 | VL53L0X_SEQUENCESTEP_PRE_RANGE, |
||
1222 | &PreRangeTimeoutMicroSeconds); |
||
1223 | |||
1224 | SubTimeout = PreRangeTimeoutMicroSeconds + |
||
1225 | PreRangeOverheadMicroSeconds; |
||
1226 | |||
1227 | if (SubTimeout < FinalRangeTimingBudgetMicroSeconds) {
|
||
1228 | FinalRangeTimingBudgetMicroSeconds -= SubTimeout; |
||
1229 | } else {
|
||
1230 | /* Requested timeout too big. */
|
||
1231 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1232 | } |
||
1233 | } |
||
1234 | |||
1235 | |||
1236 | if (Status == VL53L0X_ERROR_NONE &&
|
||
1237 | SchedulerSequenceSteps.FinalRangeOn) { |
||
1238 | |||
1239 | FinalRangeTimingBudgetMicroSeconds -= |
||
1240 | FinalRangeOverheadMicroSeconds; |
||
1241 | |||
1242 | /* Final Range Timeout
|
||
1243 | * Note that the final range timeout is determined by the timing
|
||
1244 | * budget and the sum of all other timeouts within the sequence.
|
||
1245 | * If there is no room for the final range timeout, then an error
|
||
1246 | * will be set. Otherwise the remaining time will be applied to
|
||
1247 | * the final range.
|
||
1248 | */
|
||
1249 | Status = set_sequence_step_timeout(Dev, |
||
1250 | VL53L0X_SEQUENCESTEP_FINAL_RANGE, |
||
1251 | FinalRangeTimingBudgetMicroSeconds); |
||
1252 | |||
1253 | VL53L0X_SETPARAMETERFIELD(Dev, |
||
1254 | MeasurementTimingBudgetMicroSeconds, |
||
1255 | MeasurementTimingBudgetMicroSeconds); |
||
1256 | } |
||
1257 | |||
1258 | LOG_FUNCTION_END(Status); |
||
1259 | |||
1260 | return Status;
|
||
1261 | } |
||
1262 | |||
1263 | VL53L0X_Error VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV Dev, |
||
1264 | uint32_t *pMeasurementTimingBudgetMicroSeconds) |
||
1265 | { |
||
1266 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
1267 | VL53L0X_SchedulerSequenceSteps_t SchedulerSequenceSteps; |
||
1268 | uint32_t FinalRangeTimeoutMicroSeconds; |
||
1269 | uint32_t MsrcDccTccTimeoutMicroSeconds = 2000;
|
||
1270 | uint32_t StartOverheadMicroSeconds = 1910;
|
||
1271 | uint32_t EndOverheadMicroSeconds = 960;
|
||
1272 | uint32_t MsrcOverheadMicroSeconds = 660;
|
||
1273 | uint32_t TccOverheadMicroSeconds = 590;
|
||
1274 | uint32_t DssOverheadMicroSeconds = 690;
|
||
1275 | uint32_t PreRangeOverheadMicroSeconds = 660;
|
||
1276 | uint32_t FinalRangeOverheadMicroSeconds = 550;
|
||
1277 | uint32_t PreRangeTimeoutMicroSeconds = 0;
|
||
1278 | |||
1279 | LOG_FUNCTION_START("");
|
||
1280 | |||
1281 | /* Start and end overhead times always present */
|
||
1282 | *pMeasurementTimingBudgetMicroSeconds |
||
1283 | = StartOverheadMicroSeconds + EndOverheadMicroSeconds; |
||
1284 | |||
1285 | Status = VL53L0X_GetSequenceStepEnables(Dev, &SchedulerSequenceSteps); |
||
1286 | |||
1287 | if (Status != VL53L0X_ERROR_NONE) {
|
||
1288 | LOG_FUNCTION_END(Status); |
||
1289 | return Status;
|
||
1290 | } |
||
1291 | |||
1292 | |||
1293 | if (SchedulerSequenceSteps.TccOn ||
|
||
1294 | SchedulerSequenceSteps.MsrcOn || |
||
1295 | SchedulerSequenceSteps.DssOn) { |
||
1296 | |||
1297 | Status = get_sequence_step_timeout(Dev, |
||
1298 | VL53L0X_SEQUENCESTEP_MSRC, |
||
1299 | &MsrcDccTccTimeoutMicroSeconds); |
||
1300 | |||
1301 | if (Status == VL53L0X_ERROR_NONE) {
|
||
1302 | if (SchedulerSequenceSteps.TccOn) {
|
||
1303 | *pMeasurementTimingBudgetMicroSeconds += |
||
1304 | MsrcDccTccTimeoutMicroSeconds + |
||
1305 | TccOverheadMicroSeconds; |
||
1306 | } |
||
1307 | |||
1308 | if (SchedulerSequenceSteps.DssOn) {
|
||
1309 | *pMeasurementTimingBudgetMicroSeconds += |
||
1310 | 2 * (MsrcDccTccTimeoutMicroSeconds +
|
||
1311 | DssOverheadMicroSeconds); |
||
1312 | } else if (SchedulerSequenceSteps.MsrcOn) { |
||
1313 | *pMeasurementTimingBudgetMicroSeconds += |
||
1314 | MsrcDccTccTimeoutMicroSeconds + |
||
1315 | MsrcOverheadMicroSeconds; |
||
1316 | } |
||
1317 | } |
||
1318 | } |
||
1319 | |||
1320 | if (Status == VL53L0X_ERROR_NONE) {
|
||
1321 | if (SchedulerSequenceSteps.PreRangeOn) {
|
||
1322 | Status = get_sequence_step_timeout(Dev, |
||
1323 | VL53L0X_SEQUENCESTEP_PRE_RANGE, |
||
1324 | &PreRangeTimeoutMicroSeconds); |
||
1325 | *pMeasurementTimingBudgetMicroSeconds += |
||
1326 | PreRangeTimeoutMicroSeconds + |
||
1327 | PreRangeOverheadMicroSeconds; |
||
1328 | } |
||
1329 | } |
||
1330 | |||
1331 | if (Status == VL53L0X_ERROR_NONE) {
|
||
1332 | if (SchedulerSequenceSteps.FinalRangeOn) {
|
||
1333 | Status = get_sequence_step_timeout(Dev, |
||
1334 | VL53L0X_SEQUENCESTEP_FINAL_RANGE, |
||
1335 | &FinalRangeTimeoutMicroSeconds); |
||
1336 | *pMeasurementTimingBudgetMicroSeconds += |
||
1337 | (FinalRangeTimeoutMicroSeconds + |
||
1338 | FinalRangeOverheadMicroSeconds); |
||
1339 | } |
||
1340 | } |
||
1341 | |||
1342 | if (Status == VL53L0X_ERROR_NONE) {
|
||
1343 | VL53L0X_SETPARAMETERFIELD(Dev, |
||
1344 | MeasurementTimingBudgetMicroSeconds, |
||
1345 | *pMeasurementTimingBudgetMicroSeconds); |
||
1346 | } |
||
1347 | |||
1348 | LOG_FUNCTION_END(Status); |
||
1349 | return Status;
|
||
1350 | } |
||
1351 | |||
1352 | |||
1353 | |||
1354 | VL53L0X_Error VL53L0X_load_tuning_settings(VL53L0X_DEV Dev, |
||
1355 | uint8_t *pTuningSettingBuffer) |
||
1356 | { |
||
1357 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
1358 | int i;
|
||
1359 | int Index;
|
||
1360 | uint8_t msb; |
||
1361 | uint8_t lsb; |
||
1362 | uint8_t SelectParam; |
||
1363 | uint8_t NumberOfWrites; |
||
1364 | uint8_t Address; |
||
1365 | uint8_t localBuffer[4]; /* max */ |
||
1366 | uint16_t Temp16; |
||
1367 | |||
1368 | LOG_FUNCTION_START("");
|
||
1369 | |||
1370 | Index = 0;
|
||
1371 | |||
1372 | while ((*(pTuningSettingBuffer + Index) != 0) && |
||
1373 | (Status == VL53L0X_ERROR_NONE)) { |
||
1374 | NumberOfWrites = *(pTuningSettingBuffer + Index); |
||
1375 | Index++; |
||
1376 | if (NumberOfWrites == 0xFF) { |
||
1377 | /* internal parameters */
|
||
1378 | SelectParam = *(pTuningSettingBuffer + Index); |
||
1379 | Index++; |
||
1380 | switch (SelectParam) {
|
||
1381 | case 0: /* uint16_t SigmaEstRefArray -> 2 bytes */ |
||
1382 | msb = *(pTuningSettingBuffer + Index); |
||
1383 | Index++; |
||
1384 | lsb = *(pTuningSettingBuffer + Index); |
||
1385 | Index++; |
||
1386 | Temp16 = VL53L0X_MAKEUINT16(lsb, msb); |
||
1387 | PALDevDataSet(Dev, SigmaEstRefArray, Temp16); |
||
1388 | break;
|
||
1389 | case 1: /* uint16_t SigmaEstEffPulseWidth -> 2 bytes */ |
||
1390 | msb = *(pTuningSettingBuffer + Index); |
||
1391 | Index++; |
||
1392 | lsb = *(pTuningSettingBuffer + Index); |
||
1393 | Index++; |
||
1394 | Temp16 = VL53L0X_MAKEUINT16(lsb, msb); |
||
1395 | PALDevDataSet(Dev, SigmaEstEffPulseWidth, |
||
1396 | Temp16); |
||
1397 | break;
|
||
1398 | case 2: /* uint16_t SigmaEstEffAmbWidth -> 2 bytes */ |
||
1399 | msb = *(pTuningSettingBuffer + Index); |
||
1400 | Index++; |
||
1401 | lsb = *(pTuningSettingBuffer + Index); |
||
1402 | Index++; |
||
1403 | Temp16 = VL53L0X_MAKEUINT16(lsb, msb); |
||
1404 | PALDevDataSet(Dev, SigmaEstEffAmbWidth, Temp16); |
||
1405 | break;
|
||
1406 | case 3: /* uint16_t targetRefRate -> 2 bytes */ |
||
1407 | msb = *(pTuningSettingBuffer + Index); |
||
1408 | Index++; |
||
1409 | lsb = *(pTuningSettingBuffer + Index); |
||
1410 | Index++; |
||
1411 | Temp16 = VL53L0X_MAKEUINT16(lsb, msb); |
||
1412 | PALDevDataSet(Dev, targetRefRate, Temp16); |
||
1413 | break;
|
||
1414 | default: /* invalid parameter */ |
||
1415 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1416 | } |
||
1417 | |||
1418 | } else if (NumberOfWrites <= 4) { |
||
1419 | Address = *(pTuningSettingBuffer + Index); |
||
1420 | Index++; |
||
1421 | |||
1422 | for (i = 0; i < NumberOfWrites; i++) { |
||
1423 | localBuffer[i] = *(pTuningSettingBuffer + |
||
1424 | Index); |
||
1425 | Index++; |
||
1426 | } |
||
1427 | |||
1428 | Status = VL53L0X_WriteMulti(Dev, Address, localBuffer, |
||
1429 | NumberOfWrites); |
||
1430 | |||
1431 | } else {
|
||
1432 | Status = VL53L0X_ERROR_INVALID_PARAMS; |
||
1433 | } |
||
1434 | } |
||
1435 | |||
1436 | LOG_FUNCTION_END(Status); |
||
1437 | return Status;
|
||
1438 | } |
||
1439 | |||
1440 | VL53L0X_Error VL53L0X_get_total_xtalk_rate(VL53L0X_DEV Dev, |
||
1441 | VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, |
||
1442 | FixPoint1616_t *ptotal_xtalk_rate_mcps) |
||
1443 | { |
||
1444 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
1445 | |||
1446 | uint8_t xtalkCompEnable; |
||
1447 | FixPoint1616_t totalXtalkMegaCps; |
||
1448 | FixPoint1616_t xtalkPerSpadMegaCps; |
||
1449 | |||
1450 | *ptotal_xtalk_rate_mcps = 0;
|
||
1451 | |||
1452 | Status = VL53L0X_GetXTalkCompensationEnable(Dev, &xtalkCompEnable); |
||
1453 | if (Status == VL53L0X_ERROR_NONE) {
|
||
1454 | |||
1455 | if (xtalkCompEnable) {
|
||
1456 | |||
1457 | VL53L0X_GETPARAMETERFIELD( |
||
1458 | Dev, |
||
1459 | XTalkCompensationRateMegaCps, |
||
1460 | xtalkPerSpadMegaCps); |
||
1461 | |||
1462 | /* FixPoint1616 * FixPoint 8:8 = FixPoint0824 */
|
||
1463 | totalXtalkMegaCps = |
||
1464 | pRangingMeasurementData->EffectiveSpadRtnCount * |
||
1465 | xtalkPerSpadMegaCps; |
||
1466 | |||
1467 | /* FixPoint0824 >> 8 = FixPoint1616 */
|
||
1468 | *ptotal_xtalk_rate_mcps = |
||
1469 | (totalXtalkMegaCps + 0x80) >> 8; |
||
1470 | } |
||
1471 | } |
||
1472 | |||
1473 | return Status;
|
||
1474 | } |
||
1475 | |||
1476 | VL53L0X_Error VL53L0X_get_total_signal_rate(VL53L0X_DEV Dev, |
||
1477 | VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, |
||
1478 | FixPoint1616_t *ptotal_signal_rate_mcps) |
||
1479 | { |
||
1480 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
1481 | FixPoint1616_t totalXtalkMegaCps; |
||
1482 | |||
1483 | LOG_FUNCTION_START("");
|
||
1484 | |||
1485 | *ptotal_signal_rate_mcps = |
||
1486 | pRangingMeasurementData->SignalRateRtnMegaCps; |
||
1487 | |||
1488 | Status = VL53L0X_get_total_xtalk_rate( |
||
1489 | Dev, pRangingMeasurementData, &totalXtalkMegaCps); |
||
1490 | |||
1491 | if (Status == VL53L0X_ERROR_NONE)
|
||
1492 | *ptotal_signal_rate_mcps += totalXtalkMegaCps; |
||
1493 | |||
1494 | return Status;
|
||
1495 | } |
||
1496 | |||
1497 | VL53L0X_Error VL53L0X_calc_dmax( |
||
1498 | VL53L0X_DEV Dev, |
||
1499 | FixPoint1616_t totalSignalRate_mcps, |
||
1500 | FixPoint1616_t totalCorrSignalRate_mcps, |
||
1501 | FixPoint1616_t pwMult, |
||
1502 | uint32_t sigmaEstimateP1, |
||
1503 | FixPoint1616_t sigmaEstimateP2, |
||
1504 | uint32_t peakVcselDuration_us, |
||
1505 | uint32_t *pdmax_mm) |
||
1506 | { |
||
1507 | const uint32_t cSigmaLimit = 18; |
||
1508 | const FixPoint1616_t cSignalLimit = 0x4000; /* 0.25 */ |
||
1509 | const FixPoint1616_t cSigmaEstRef = 0x00000042; /* 0.001 */ |
||
1510 | const uint32_t cAmbEffWidthSigmaEst_ns = 6; |
||
1511 | const uint32_t cAmbEffWidthDMax_ns = 7; |
||
1512 | uint32_t dmaxCalRange_mm; |
||
1513 | FixPoint1616_t dmaxCalSignalRateRtn_mcps; |
||
1514 | FixPoint1616_t minSignalNeeded; |
||
1515 | FixPoint1616_t minSignalNeeded_p1; |
||
1516 | FixPoint1616_t minSignalNeeded_p2; |
||
1517 | FixPoint1616_t minSignalNeeded_p3; |
||
1518 | FixPoint1616_t minSignalNeeded_p4; |
||
1519 | FixPoint1616_t sigmaLimitTmp; |
||
1520 | FixPoint1616_t sigmaEstSqTmp; |
||
1521 | FixPoint1616_t signalLimitTmp; |
||
1522 | FixPoint1616_t SignalAt0mm; |
||
1523 | FixPoint1616_t dmaxDark; |
||
1524 | FixPoint1616_t dmaxAmbient; |
||
1525 | FixPoint1616_t dmaxDarkTmp; |
||
1526 | FixPoint1616_t sigmaEstP2Tmp; |
||
1527 | uint32_t signalRateTemp_mcps; |
||
1528 | |||
1529 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
1530 | |||
1531 | LOG_FUNCTION_START("");
|
||
1532 | |||
1533 | dmaxCalRange_mm = |
||
1534 | PALDevDataGet(Dev, DmaxCalRangeMilliMeter); |
||
1535 | |||
1536 | dmaxCalSignalRateRtn_mcps = |
||
1537 | PALDevDataGet(Dev, DmaxCalSignalRateRtnMegaCps); |
||
1538 | |||
1539 | /* uint32 * FixPoint1616 = FixPoint1616 */
|
||
1540 | SignalAt0mm = dmaxCalRange_mm * dmaxCalSignalRateRtn_mcps; |
||
1541 | |||
1542 | /* FixPoint1616 >> 8 = FixPoint2408 */
|
||
1543 | SignalAt0mm = (SignalAt0mm + 0x80) >> 8; |
||
1544 | SignalAt0mm *= dmaxCalRange_mm; |
||
1545 | |||
1546 | minSignalNeeded_p1 = 0;
|
||
1547 | if (totalCorrSignalRate_mcps > 0) { |
||
1548 | |||
1549 | /* Shift by 10 bits to increase resolution prior to the
|
||
1550 | * division */
|
||
1551 | signalRateTemp_mcps = totalSignalRate_mcps << 10;
|
||
1552 | |||
1553 | /* Add rounding value prior to division */
|
||
1554 | minSignalNeeded_p1 = signalRateTemp_mcps + |
||
1555 | (totalCorrSignalRate_mcps/2);
|
||
1556 | |||
1557 | /* FixPoint0626/FixPoint1616 = FixPoint2210 */
|
||
1558 | minSignalNeeded_p1 /= totalCorrSignalRate_mcps; |
||
1559 | |||
1560 | /* Apply a factored version of the speed of light.
|
||
1561 | Correction to be applied at the end */
|
||
1562 | minSignalNeeded_p1 *= 3;
|
||
1563 | |||
1564 | /* FixPoint2210 * FixPoint2210 = FixPoint1220 */
|
||
1565 | minSignalNeeded_p1 *= minSignalNeeded_p1; |
||
1566 | |||
1567 | /* FixPoint1220 >> 16 = FixPoint2804 */
|
||
1568 | minSignalNeeded_p1 = (minSignalNeeded_p1 + 0x8000) >> 16; |
||
1569 | } |
||
1570 | |||
1571 | minSignalNeeded_p2 = pwMult * sigmaEstimateP1; |
||
1572 | |||
1573 | /* FixPoint1616 >> 16 = uint32 */
|
||
1574 | minSignalNeeded_p2 = (minSignalNeeded_p2 + 0x8000) >> 16; |
||
1575 | |||
1576 | /* uint32 * uint32 = uint32 */
|
||
1577 | minSignalNeeded_p2 *= minSignalNeeded_p2; |
||
1578 | |||
1579 | /* Check sigmaEstimateP2
|
||
1580 | * If this value is too high there is not enough signal rate
|
||
1581 | * to calculate dmax value so set a suitable value to ensure
|
||
1582 | * a very small dmax.
|
||
1583 | */
|
||
1584 | sigmaEstP2Tmp = (sigmaEstimateP2 + 0x8000) >> 16; |
||
1585 | sigmaEstP2Tmp = (sigmaEstP2Tmp + cAmbEffWidthSigmaEst_ns/2)/
|
||
1586 | cAmbEffWidthSigmaEst_ns; |
||
1587 | sigmaEstP2Tmp *= cAmbEffWidthDMax_ns; |
||
1588 | |||
1589 | if (sigmaEstP2Tmp > 0xffff) { |
||
1590 | minSignalNeeded_p3 = 0xfff00000;
|
||
1591 | } else {
|
||
1592 | |||
1593 | /* DMAX uses a different ambient width from sigma, so apply
|
||
1594 | * correction.
|
||
1595 | * Perform division before multiplication to prevent overflow.
|
||
1596 | */
|
||
1597 | sigmaEstimateP2 = (sigmaEstimateP2 + cAmbEffWidthSigmaEst_ns/2)/
|
||
1598 | cAmbEffWidthSigmaEst_ns; |
||
1599 | sigmaEstimateP2 *= cAmbEffWidthDMax_ns; |
||
1600 | |||
1601 | /* FixPoint1616 >> 16 = uint32 */
|
||
1602 | minSignalNeeded_p3 = (sigmaEstimateP2 + 0x8000) >> 16; |
||
1603 | |||
1604 | minSignalNeeded_p3 *= minSignalNeeded_p3; |
||
1605 | |||
1606 | } |
||
1607 | |||
1608 | /* FixPoint1814 / uint32 = FixPoint1814 */
|
||
1609 | sigmaLimitTmp = ((cSigmaLimit << 14) + 500) / 1000; |
||
1610 | |||
1611 | /* FixPoint1814 * FixPoint1814 = FixPoint3628 := FixPoint0428 */
|
||
1612 | sigmaLimitTmp *= sigmaLimitTmp; |
||
1613 | |||
1614 | /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
|
||
1615 | sigmaEstSqTmp = cSigmaEstRef * cSigmaEstRef; |
||
1616 | |||
1617 | /* FixPoint3232 >> 4 = FixPoint0428 */
|
||
1618 | sigmaEstSqTmp = (sigmaEstSqTmp + 0x08) >> 4; |
||
1619 | |||
1620 | /* FixPoint0428 - FixPoint0428 = FixPoint0428 */
|
||
1621 | sigmaLimitTmp -= sigmaEstSqTmp; |
||
1622 | |||
1623 | /* uint32_t * FixPoint0428 = FixPoint0428 */
|
||
1624 | minSignalNeeded_p4 = 4 * 12 * sigmaLimitTmp; |
||
1625 | |||
1626 | /* FixPoint0428 >> 14 = FixPoint1814 */
|
||
1627 | minSignalNeeded_p4 = (minSignalNeeded_p4 + 0x2000) >> 14; |
||
1628 | |||
1629 | /* uint32 + uint32 = uint32 */
|
||
1630 | minSignalNeeded = (minSignalNeeded_p2 + minSignalNeeded_p3); |
||
1631 | |||
1632 | /* uint32 / uint32 = uint32 */
|
||
1633 | minSignalNeeded += (peakVcselDuration_us/2);
|
||
1634 | minSignalNeeded /= peakVcselDuration_us; |
||
1635 | |||
1636 | /* uint32 << 14 = FixPoint1814 */
|
||
1637 | minSignalNeeded <<= 14;
|
||
1638 | |||
1639 | /* FixPoint1814 / FixPoint1814 = uint32 */
|
||
1640 | minSignalNeeded += (minSignalNeeded_p4/2);
|
||
1641 | minSignalNeeded /= minSignalNeeded_p4; |
||
1642 | |||
1643 | /* FixPoint3200 * FixPoint2804 := FixPoint2804*/
|
||
1644 | minSignalNeeded *= minSignalNeeded_p1; |
||
1645 | |||
1646 | /* Apply correction by dividing by 1000000.
|
||
1647 | * This assumes 10E16 on the numerator of the equation
|
||
1648 | * and 10E-22 on the denominator.
|
||
1649 | * We do this because 32bit fix point calculation can't
|
||
1650 | * handle the larger and smaller elements of this equation,
|
||
1651 | * i.e. speed of light and pulse widths.
|
||
1652 | */
|
||
1653 | minSignalNeeded = (minSignalNeeded + 500) / 1000; |
||
1654 | minSignalNeeded <<= 4;
|
||
1655 | |||
1656 | minSignalNeeded = (minSignalNeeded + 500) / 1000; |
||
1657 | |||
1658 | /* FixPoint1616 >> 8 = FixPoint2408 */
|
||
1659 | signalLimitTmp = (cSignalLimit + 0x80) >> 8; |
||
1660 | |||
1661 | /* FixPoint2408/FixPoint2408 = uint32 */
|
||
1662 | if (signalLimitTmp != 0) |
||
1663 | dmaxDarkTmp = (SignalAt0mm + (signalLimitTmp / 2))
|
||
1664 | / signalLimitTmp; |
||
1665 | else
|
||
1666 | dmaxDarkTmp = 0;
|
||
1667 | |||
1668 | dmaxDark = VL53L0X_isqrt(dmaxDarkTmp); |
||
1669 | |||
1670 | /* FixPoint2408/FixPoint2408 = uint32 */
|
||
1671 | if (minSignalNeeded != 0) |
||
1672 | dmaxAmbient = (SignalAt0mm + minSignalNeeded/2)
|
||
1673 | / minSignalNeeded; |
||
1674 | else
|
||
1675 | dmaxAmbient = 0;
|
||
1676 | |||
1677 | dmaxAmbient = VL53L0X_isqrt(dmaxAmbient); |
||
1678 | |||
1679 | *pdmax_mm = dmaxDark; |
||
1680 | if (dmaxDark > dmaxAmbient)
|
||
1681 | *pdmax_mm = dmaxAmbient; |
||
1682 | |||
1683 | LOG_FUNCTION_END(Status); |
||
1684 | |||
1685 | return Status;
|
||
1686 | } |
||
1687 | |||
1688 | |||
1689 | VL53L0X_Error VL53L0X_calc_sigma_estimate(VL53L0X_DEV Dev, |
||
1690 | VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, |
||
1691 | FixPoint1616_t *pSigmaEstimate, |
||
1692 | uint32_t *pDmax_mm) |
||
1693 | { |
||
1694 | /* Expressed in 100ths of a ns, i.e. centi-ns */
|
||
1695 | const uint32_t cPulseEffectiveWidth_centi_ns = 800; |
||
1696 | /* Expressed in 100ths of a ns, i.e. centi-ns */
|
||
1697 | const uint32_t cAmbientEffectiveWidth_centi_ns = 600; |
||
1698 | const FixPoint1616_t cDfltFinalRangeIntegrationTimeMilliSecs = 0x00190000; /* 25ms */ |
||
1699 | const uint32_t cVcselPulseWidth_ps = 4700; /* pico secs */ |
||
1700 | const FixPoint1616_t cSigmaEstMax = 0x028F87AE; |
||
1701 | const FixPoint1616_t cSigmaEstRtnMax = 0xF000; |
||
1702 | const FixPoint1616_t cAmbToSignalRatioMax = 0xF0000000/ |
||
1703 | cAmbientEffectiveWidth_centi_ns; |
||
1704 | /* Time Of Flight per mm (6.6 pico secs) */
|
||
1705 | const FixPoint1616_t cTOF_per_mm_ps = 0x0006999A; |
||
1706 | const uint32_t c16BitRoundingParam = 0x00008000; |
||
1707 | const FixPoint1616_t cMaxXTalk_kcps = 0x00320000; |
||
1708 | const uint32_t cPllPeriod_ps = 1655; |
||
1709 | |||
1710 | uint32_t vcselTotalEventsRtn; |
||
1711 | uint32_t finalRangeTimeoutMicroSecs; |
||
1712 | uint32_t preRangeTimeoutMicroSecs; |
||
1713 | uint32_t finalRangeIntegrationTimeMilliSecs; |
||
1714 | FixPoint1616_t sigmaEstimateP1; |
||
1715 | FixPoint1616_t sigmaEstimateP2; |
||
1716 | FixPoint1616_t sigmaEstimateP3; |
||
1717 | FixPoint1616_t deltaT_ps; |
||
1718 | FixPoint1616_t pwMult; |
||
1719 | FixPoint1616_t sigmaEstRtn; |
||
1720 | FixPoint1616_t sigmaEstimate; |
||
1721 | FixPoint1616_t xTalkCorrection; |
||
1722 | FixPoint1616_t ambientRate_kcps; |
||
1723 | FixPoint1616_t peakSignalRate_kcps; |
||
1724 | FixPoint1616_t xTalkCompRate_mcps; |
||
1725 | uint32_t xTalkCompRate_kcps; |
||
1726 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
1727 | FixPoint1616_t diff1_mcps; |
||
1728 | FixPoint1616_t diff2_mcps; |
||
1729 | FixPoint1616_t sqr1; |
||
1730 | FixPoint1616_t sqr2; |
||
1731 | FixPoint1616_t sqrSum; |
||
1732 | FixPoint1616_t sqrtResult_centi_ns; |
||
1733 | FixPoint1616_t sqrtResult; |
||
1734 | FixPoint1616_t totalSignalRate_mcps; |
||
1735 | FixPoint1616_t correctedSignalRate_mcps; |
||
1736 | FixPoint1616_t sigmaEstRef; |
||
1737 | uint32_t vcselWidth; |
||
1738 | uint32_t finalRangeMacroPCLKS; |
||
1739 | uint32_t preRangeMacroPCLKS; |
||
1740 | uint32_t peakVcselDuration_us; |
||
1741 | uint8_t finalRangeVcselPCLKS; |
||
1742 | uint8_t preRangeVcselPCLKS; |
||
1743 | /*! \addtogroup calc_sigma_estimate
|
||
1744 | * @{
|
||
1745 | *
|
||
1746 | * Estimates the range sigma
|
||
1747 | */
|
||
1748 | |||
1749 | LOG_FUNCTION_START("");
|
||
1750 | |||
1751 | VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps, |
||
1752 | xTalkCompRate_mcps); |
||
1753 | |||
1754 | /*
|
||
1755 | * We work in kcps rather than mcps as this helps keep within the
|
||
1756 | * confines of the 32 Fix1616 type.
|
||
1757 | */
|
||
1758 | |||
1759 | ambientRate_kcps = |
||
1760 | (pRangingMeasurementData->AmbientRateRtnMegaCps * 1000) >> 16; |
||
1761 | |||
1762 | correctedSignalRate_mcps = |
||
1763 | pRangingMeasurementData->SignalRateRtnMegaCps; |
||
1764 | |||
1765 | |||
1766 | Status = VL53L0X_get_total_signal_rate( |
||
1767 | Dev, pRangingMeasurementData, &totalSignalRate_mcps); |
||
1768 | Status = VL53L0X_get_total_xtalk_rate( |
||
1769 | Dev, pRangingMeasurementData, &xTalkCompRate_mcps); |
||
1770 | |||
1771 | |||
1772 | /* Signal rate measurement provided by device is the
|
||
1773 | * peak signal rate, not average.
|
||
1774 | */
|
||
1775 | peakSignalRate_kcps = (totalSignalRate_mcps * 1000);
|
||
1776 | peakSignalRate_kcps = (peakSignalRate_kcps + 0x8000) >> 16; |
||
1777 | |||
1778 | xTalkCompRate_kcps = xTalkCompRate_mcps * 1000;
|
||
1779 | |||
1780 | if (xTalkCompRate_kcps > cMaxXTalk_kcps)
|
||
1781 | xTalkCompRate_kcps = cMaxXTalk_kcps; |
||
1782 | |||
1783 | if (Status == VL53L0X_ERROR_NONE) {
|
||
1784 | |||
1785 | /* Calculate final range macro periods */
|
||
1786 | finalRangeTimeoutMicroSecs = VL53L0X_GETDEVICESPECIFICPARAMETER( |
||
1787 | Dev, FinalRangeTimeoutMicroSecs); |
||
1788 | |||
1789 | finalRangeVcselPCLKS = VL53L0X_GETDEVICESPECIFICPARAMETER( |
||
1790 | Dev, FinalRangeVcselPulsePeriod); |
||
1791 | |||
1792 | finalRangeMacroPCLKS = VL53L0X_calc_timeout_mclks( |
||
1793 | Dev, finalRangeTimeoutMicroSecs, finalRangeVcselPCLKS); |
||
1794 | |||
1795 | /* Calculate pre-range macro periods */
|
||
1796 | preRangeTimeoutMicroSecs = VL53L0X_GETDEVICESPECIFICPARAMETER( |
||
1797 | Dev, PreRangeTimeoutMicroSecs); |
||
1798 | |||
1799 | preRangeVcselPCLKS = VL53L0X_GETDEVICESPECIFICPARAMETER( |
||
1800 | Dev, PreRangeVcselPulsePeriod); |
||
1801 | |||
1802 | preRangeMacroPCLKS = VL53L0X_calc_timeout_mclks( |
||
1803 | Dev, preRangeTimeoutMicroSecs, preRangeVcselPCLKS); |
||
1804 | |||
1805 | vcselWidth = 3;
|
||
1806 | if (finalRangeVcselPCLKS == 8) |
||
1807 | vcselWidth = 2;
|
||
1808 | |||
1809 | |||
1810 | peakVcselDuration_us = vcselWidth * 2048 *
|
||
1811 | (preRangeMacroPCLKS + finalRangeMacroPCLKS); |
||
1812 | peakVcselDuration_us = (peakVcselDuration_us + 500)/1000; |
||
1813 | peakVcselDuration_us *= cPllPeriod_ps; |
||
1814 | peakVcselDuration_us = (peakVcselDuration_us + 500)/1000; |
||
1815 | |||
1816 | /* Fix1616 >> 8 = Fix2408 */
|
||
1817 | totalSignalRate_mcps = (totalSignalRate_mcps + 0x80) >> 8; |
||
1818 | |||
1819 | /* Fix2408 * uint32 = Fix2408 */
|
||
1820 | vcselTotalEventsRtn = totalSignalRate_mcps * |
||
1821 | peakVcselDuration_us; |
||
1822 | |||
1823 | /* Fix2408 >> 8 = uint32 */
|
||
1824 | vcselTotalEventsRtn = (vcselTotalEventsRtn + 0x80) >> 8; |
||
1825 | |||
1826 | /* Fix2408 << 8 = Fix1616 = */
|
||
1827 | totalSignalRate_mcps <<= 8;
|
||
1828 | } |
||
1829 | |||
1830 | if (Status != VL53L0X_ERROR_NONE) {
|
||
1831 | LOG_FUNCTION_END(Status); |
||
1832 | return Status;
|
||
1833 | } |
||
1834 | |||
1835 | if (peakSignalRate_kcps == 0) { |
||
1836 | *pSigmaEstimate = cSigmaEstMax; |
||
1837 | PALDevDataSet(Dev, SigmaEstimate, cSigmaEstMax); |
||
1838 | *pDmax_mm = 0;
|
||
1839 | } else {
|
||
1840 | if (vcselTotalEventsRtn < 1) |
||
1841 | vcselTotalEventsRtn = 1;
|
||
1842 | |||
1843 | sigmaEstimateP1 = cPulseEffectiveWidth_centi_ns; |
||
1844 | |||
1845 | /* ((FixPoint1616 << 16)* uint32)/uint32 = FixPoint1616 */
|
||
1846 | sigmaEstimateP2 = (ambientRate_kcps << 16)/peakSignalRate_kcps;
|
||
1847 | if (sigmaEstimateP2 > cAmbToSignalRatioMax) {
|
||
1848 | /* Clip to prevent overflow. Will ensure safe
|
||
1849 | * max result. */
|
||
1850 | sigmaEstimateP2 = cAmbToSignalRatioMax; |
||
1851 | } |
||
1852 | sigmaEstimateP2 *= cAmbientEffectiveWidth_centi_ns; |
||
1853 | |||
1854 | sigmaEstimateP3 = 2 * VL53L0X_isqrt(vcselTotalEventsRtn * 12); |
||
1855 | |||
1856 | /* uint32 * FixPoint1616 = FixPoint1616 */
|
||
1857 | deltaT_ps = pRangingMeasurementData->RangeMilliMeter * |
||
1858 | cTOF_per_mm_ps; |
||
1859 | |||
1860 | /*
|
||
1861 | * vcselRate - xtalkCompRate
|
||
1862 | * (uint32 << 16) - FixPoint1616 = FixPoint1616.
|
||
1863 | * Divide result by 1000 to convert to mcps.
|
||
1864 | * 500 is added to ensure rounding when integer division
|
||
1865 | * truncates.
|
||
1866 | */
|
||
1867 | diff1_mcps = (((peakSignalRate_kcps << 16) -
|
||
1868 | 2 * xTalkCompRate_kcps) + 500)/1000; |
||
1869 | |||
1870 | /* vcselRate + xtalkCompRate */
|
||
1871 | diff2_mcps = ((peakSignalRate_kcps << 16) + 500)/1000; |
||
1872 | |||
1873 | /* Shift by 8 bits to increase resolution prior to the
|
||
1874 | * division */
|
||
1875 | diff1_mcps <<= 8;
|
||
1876 | |||
1877 | /* FixPoint0824/FixPoint1616 = FixPoint2408 */
|
||
1878 | xTalkCorrection = abs(diff1_mcps/diff2_mcps); |
||
1879 | |||
1880 | /* FixPoint2408 << 8 = FixPoint1616 */
|
||
1881 | xTalkCorrection <<= 8;
|
||
1882 | |||
1883 | if(pRangingMeasurementData->RangeStatus != 0){ |
||
1884 | pwMult = 1 << 16; |
||
1885 | } else {
|
||
1886 | /* FixPoint1616/uint32 = FixPoint1616 */
|
||
1887 | pwMult = deltaT_ps/cVcselPulseWidth_ps; /* smaller than 1.0f */
|
||
1888 | |||
1889 | /*
|
||
1890 | * FixPoint1616 * FixPoint1616 = FixPoint3232, however both
|
||
1891 | * values are small enough such that32 bits will not be
|
||
1892 | * exceeded.
|
||
1893 | */
|
||
1894 | pwMult *= ((1 << 16) - xTalkCorrection); |
||
1895 | |||
1896 | /* (FixPoint3232 >> 16) = FixPoint1616 */
|
||
1897 | pwMult = (pwMult + c16BitRoundingParam) >> 16;
|
||
1898 | |||
1899 | /* FixPoint1616 + FixPoint1616 = FixPoint1616 */
|
||
1900 | pwMult += (1 << 16); |
||
1901 | |||
1902 | /*
|
||
1903 | * At this point the value will be 1.xx, therefore if we square
|
||
1904 | * the value this will exceed 32 bits. To address this perform
|
||
1905 | * a single shift to the right before the multiplication.
|
||
1906 | */
|
||
1907 | pwMult >>= 1;
|
||
1908 | /* FixPoint1715 * FixPoint1715 = FixPoint3430 */
|
||
1909 | pwMult = pwMult * pwMult; |
||
1910 | |||
1911 | /* (FixPoint3430 >> 14) = Fix1616 */
|
||
1912 | pwMult >>= 14;
|
||
1913 | } |
||
1914 | |||
1915 | /* FixPoint1616 * uint32 = FixPoint1616 */
|
||
1916 | sqr1 = pwMult * sigmaEstimateP1; |
||
1917 | |||
1918 | /* (FixPoint1616 >> 16) = FixPoint3200 */
|
||
1919 | sqr1 = (sqr1 + 0x8000) >> 16; |
||
1920 | |||
1921 | /* FixPoint3200 * FixPoint3200 = FixPoint6400 */
|
||
1922 | sqr1 *= sqr1; |
||
1923 | |||
1924 | sqr2 = sigmaEstimateP2; |
||
1925 | |||
1926 | /* (FixPoint1616 >> 16) = FixPoint3200 */
|
||
1927 | sqr2 = (sqr2 + 0x8000) >> 16; |
||
1928 | |||
1929 | /* FixPoint3200 * FixPoint3200 = FixPoint6400 */
|
||
1930 | sqr2 *= sqr2; |
||
1931 | |||
1932 | /* FixPoint64000 + FixPoint6400 = FixPoint6400 */
|
||
1933 | sqrSum = sqr1 + sqr2; |
||
1934 | |||
1935 | /* SQRT(FixPoin6400) = FixPoint3200 */
|
||
1936 | sqrtResult_centi_ns = VL53L0X_isqrt(sqrSum); |
||
1937 | |||
1938 | /* (FixPoint3200 << 16) = FixPoint1616 */
|
||
1939 | sqrtResult_centi_ns <<= 16;
|
||
1940 | |||
1941 | /*
|
||
1942 | * Note that the Speed Of Light is expressed in um per 1E-10
|
||
1943 | * seconds (2997) Therefore to get mm/ns we have to divide by
|
||
1944 | * 10000
|
||
1945 | */
|
||
1946 | sigmaEstRtn = (((sqrtResult_centi_ns+50)/100) / |
||
1947 | sigmaEstimateP3); |
||
1948 | sigmaEstRtn *= VL53L0X_SPEED_OF_LIGHT_IN_AIR; |
||
1949 | |||
1950 | /* Add 5000 before dividing by 10000 to ensure rounding. */
|
||
1951 | sigmaEstRtn += 5000;
|
||
1952 | sigmaEstRtn /= 10000;
|
||
1953 | |||
1954 | if (sigmaEstRtn > cSigmaEstRtnMax) {
|
||
1955 | /* Clip to prevent overflow. Will ensure safe
|
||
1956 | * max result. */
|
||
1957 | sigmaEstRtn = cSigmaEstRtnMax; |
||
1958 | } |
||
1959 | finalRangeIntegrationTimeMilliSecs = |
||
1960 | (finalRangeTimeoutMicroSecs + preRangeTimeoutMicroSecs + 500)/1000; |
||
1961 | |||
1962 | /* sigmaEstRef = 1mm * 25ms/final range integration time (inc pre-range)
|
||
1963 | * sqrt(FixPoint1616/int) = FixPoint2408)
|
||
1964 | */
|
||
1965 | sigmaEstRef = |
||
1966 | VL53L0X_isqrt((cDfltFinalRangeIntegrationTimeMilliSecs + |
||
1967 | finalRangeIntegrationTimeMilliSecs/2)/
|
||
1968 | finalRangeIntegrationTimeMilliSecs); |
||
1969 | |||
1970 | /* FixPoint2408 << 8 = FixPoint1616 */
|
||
1971 | sigmaEstRef <<= 8;
|
||
1972 | sigmaEstRef = (sigmaEstRef + 500)/1000; |
||
1973 | |||
1974 | /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
|
||
1975 | sqr1 = sigmaEstRtn * sigmaEstRtn; |
||
1976 | /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
|
||
1977 | sqr2 = sigmaEstRef * sigmaEstRef; |
||
1978 | |||
1979 | /* sqrt(FixPoint3232) = FixPoint1616 */
|
||
1980 | sqrtResult = VL53L0X_isqrt((sqr1 + sqr2)); |
||
1981 | /*
|
||
1982 | * Note that the Shift by 4 bits increases resolution prior to
|
||
1983 | * the sqrt, therefore the result must be shifted by 2 bits to
|
||
1984 | * the right to revert back to the FixPoint1616 format.
|
||
1985 | */
|
||
1986 | |||
1987 | sigmaEstimate = 1000 * sqrtResult;
|
||
1988 | |||
1989 | if ((peakSignalRate_kcps < 1) || (vcselTotalEventsRtn < 1) || |
||
1990 | (sigmaEstimate > cSigmaEstMax)) { |
||
1991 | sigmaEstimate = cSigmaEstMax; |
||
1992 | } |
||
1993 | |||
1994 | *pSigmaEstimate = (uint32_t)(sigmaEstimate); |
||
1995 | PALDevDataSet(Dev, SigmaEstimate, *pSigmaEstimate); |
||
1996 | Status = VL53L0X_calc_dmax( |
||
1997 | Dev, |
||
1998 | totalSignalRate_mcps, |
||
1999 | correctedSignalRate_mcps, |
||
2000 | pwMult, |
||
2001 | sigmaEstimateP1, |
||
2002 | sigmaEstimateP2, |
||
2003 | peakVcselDuration_us, |
||
2004 | pDmax_mm); |
||
2005 | } |
||
2006 | |||
2007 | LOG_FUNCTION_END(Status); |
||
2008 | return Status;
|
||
2009 | } |
||
2010 | |||
2011 | VL53L0X_Error VL53L0X_get_pal_range_status(VL53L0X_DEV Dev, |
||
2012 | uint8_t DeviceRangeStatus, |
||
2013 | FixPoint1616_t SignalRate, |
||
2014 | uint16_t EffectiveSpadRtnCount, |
||
2015 | VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, |
||
2016 | uint8_t *pPalRangeStatus) |
||
2017 | { |
||
2018 | VL53L0X_Error Status = VL53L0X_ERROR_NONE; |
||
2019 | uint8_t NoneFlag; |
||
2020 | uint8_t SigmaLimitflag = 0;
|
||
2021 | uint8_t SignalRefClipflag = 0;
|
||
2022 | uint8_t RangeIgnoreThresholdflag = 0;
|
||
2023 | uint8_t SigmaLimitCheckEnable = 0;
|
||
2024 | uint8_t SignalRateFinalRangeLimitCheckEnable = 0;
|
||
2025 | uint8_t SignalRefClipLimitCheckEnable = 0;
|
||
2026 | uint8_t RangeIgnoreThresholdLimitCheckEnable = 0;
|
||
2027 | FixPoint1616_t SigmaEstimate; |
||
2028 | FixPoint1616_t SigmaLimitValue; |
||
2029 | FixPoint1616_t SignalRefClipValue; |
||
2030 | FixPoint1616_t RangeIgnoreThresholdValue; |
||
2031 | FixPoint1616_t SignalRatePerSpad; |
||
2032 | uint8_t DeviceRangeStatusInternal = 0;
|
||
2033 | uint16_t tmpWord = 0;
|
||
2034 | uint8_t Temp8; |
||
2035 | uint32_t Dmax_mm = 0;
|
||
2036 | FixPoint1616_t LastSignalRefMcps; |
||
2037 | |||
2038 | LOG_FUNCTION_START("");
|
||
2039 | |||
2040 | |||
2041 | /*
|
||
2042 | * VL53L0X has a good ranging when the value of the
|
||
2043 | * DeviceRangeStatus = 11. This function will replace the value 0 with
|
||
2044 | * the value 11 in the DeviceRangeStatus.
|
||
2045 | * In addition, the SigmaEstimator is not included in the VL53L0X
|
||
2046 | * DeviceRangeStatus, this will be added in the PalRangeStatus.
|
||
2047 | */
|
||
2048 | |||
2049 | DeviceRangeStatusInternal = ((DeviceRangeStatus & 0x78) >> 3); |
||
2050 | |||
2051 | if (DeviceRangeStatusInternal == 0 || |
||
2052 | DeviceRangeStatusInternal == 5 ||
|
||
2053 | DeviceRangeStatusInternal == 7 ||
|
||
2054 | DeviceRangeStatusInternal == 12 ||
|
||
2055 | DeviceRangeStatusInternal == 13 ||
|
||
2056 | DeviceRangeStatusInternal == 14 ||
|
||
2057 | DeviceRangeStatusInternal == 15
|
||
2058 | ) { |
||
2059 | NoneFlag = 1;
|
||
2060 | } else {
|
||
2061 | NoneFlag = 0;
|
||
2062 | } |
||
2063 | |||
2064 | /*
|
||
2065 | * Check if Sigma limit is enabled, if yes then do comparison with limit
|
||
2066 | * value and put the result back into pPalRangeStatus.
|
||
2067 | */
|
||
2068 | if (Status == VL53L0X_ERROR_NONE)
|
||
2069 | Status = VL53L0X_GetLimitCheckEnable(Dev, |
||
2070 | VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, |
||
2071 | &SigmaLimitCheckEnable); |
||
2072 | |||
2073 | if ((SigmaLimitCheckEnable != 0) && (Status == VL53L0X_ERROR_NONE)) { |
||
2074 | /*
|
||
2075 | * compute the Sigma and check with limit
|
||
2076 | */
|
||
2077 | Status = VL53L0X_calc_sigma_estimate( |
||
2078 | Dev, |
||
2079 | pRangingMeasurementData, |
||
2080 | &SigmaEstimate, |
||
2081 | &Dmax_mm); |
||
2082 | if (Status == VL53L0X_ERROR_NONE)
|
||
2083 | pRangingMeasurementData->RangeDMaxMilliMeter = Dmax_mm; |
||
2084 | |||
2085 | if (Status == VL53L0X_ERROR_NONE) {
|
||
2086 | Status = VL53L0X_GetLimitCheckValue(Dev, |
||
2087 | VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, |
||
2088 | &SigmaLimitValue); |
||
2089 | |||
2090 | if ((SigmaLimitValue > 0) && |
||
2091 | (SigmaEstimate > SigmaLimitValue)) |
||
2092 | /* Limit Fail */
|
||
2093 | SigmaLimitflag = 1;
|
||
2094 | } |
||
2095 | } |
||
2096 | |||
2097 | /*
|
||
2098 | * Check if Signal ref clip limit is enabled, if yes then do comparison
|
||
2099 | * with limit value and put the result back into pPalRangeStatus.
|
||
2100 | */
|
||
2101 | if (Status == VL53L0X_ERROR_NONE)
|
||
2102 | Status = VL53L0X_GetLimitCheckEnable(Dev, |
||
2103 | VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, |
||
2104 | &SignalRefClipLimitCheckEnable); |
||
2105 | |||
2106 | if ((SignalRefClipLimitCheckEnable != 0) && |
||
2107 | (Status == VL53L0X_ERROR_NONE)) { |
||
2108 | |||
2109 | Status = VL53L0X_GetLimitCheckValue(Dev, |
||
2110 | VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, |
||
2111 | &SignalRefClipValue); |
||
2112 | |||
2113 | /* Read LastSignalRefMcps from device */
|
||
2114 | if (Status == VL53L0X_ERROR_NONE)
|
||
2115 | Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); |
||
2116 | |||
2117 | if (Status == VL53L0X_ERROR_NONE)
|
||
2118 | Status = VL53L0X_RdWord(Dev, |
||
2119 | VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF, |
||
2120 | &tmpWord); |
||
2121 | |||
2122 | if (Status == VL53L0X_ERROR_NONE)
|
||
2123 | Status = VL53L0X_WrByte(Dev, 0xFF, 0x00); |
||
2124 | |||
2125 | LastSignalRefMcps = VL53L0X_FIXPOINT97TOFIXPOINT1616(tmpWord); |
||
2126 | PALDevDataSet(Dev, LastSignalRefMcps, LastSignalRefMcps); |
||
2127 | |||
2128 | if ((SignalRefClipValue > 0) && |
||
2129 | (LastSignalRefMcps > SignalRefClipValue)) { |
||
2130 | /* Limit Fail */
|
||
2131 | SignalRefClipflag = 1;
|
||
2132 | } |
||
2133 | } |
||
2134 | |||
2135 | /*
|
||
2136 | * Check if Signal ref clip limit is enabled, if yes then do comparison
|
||
2137 | * with limit value and put the result back into pPalRangeStatus.
|
||
2138 | * EffectiveSpadRtnCount has a format 8.8
|
||
2139 | * If (Return signal rate < (1.5 x Xtalk x number of Spads)) : FAIL
|
||
2140 | */
|
||
2141 | if (Status == VL53L0X_ERROR_NONE)
|
||
2142 | Status = VL53L0X_GetLimitCheckEnable(Dev, |
||
2143 | VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, |
||
2144 | &RangeIgnoreThresholdLimitCheckEnable); |
||
2145 | |||
2146 | if ((RangeIgnoreThresholdLimitCheckEnable != 0) && |
||
2147 | (Status == VL53L0X_ERROR_NONE)) { |
||
2148 | |||
2149 | /* Compute the signal rate per spad */
|
||
2150 | if (EffectiveSpadRtnCount == 0) { |
||
2151 | SignalRatePerSpad = 0;
|
||
2152 | } else {
|
||
2153 | SignalRatePerSpad = (FixPoint1616_t)((256 * SignalRate)
|
||
2154 | / EffectiveSpadRtnCount); |
||
2155 | } |
||
2156 | |||
2157 | Status = VL53L0X_GetLimitCheckValue(Dev, |
||
2158 | VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, |
||
2159 | &RangeIgnoreThresholdValue); |
||
2160 | |||
2161 | if ((RangeIgnoreThresholdValue > 0) && |
||
2162 | (SignalRatePerSpad < RangeIgnoreThresholdValue)) { |
||
2163 | /* Limit Fail add 2^6 to range status */
|
||
2164 | RangeIgnoreThresholdflag = 1;
|
||
2165 | } |
||
2166 | } |
||
2167 | |||
2168 | if (Status == VL53L0X_ERROR_NONE) {
|
||
2169 | if (NoneFlag == 1) { |
||
2170 | *pPalRangeStatus = 255; /* NONE */ |
||
2171 | } else if (DeviceRangeStatusInternal == 1 || |
||
2172 | DeviceRangeStatusInternal == 2 ||
|
||
2173 | DeviceRangeStatusInternal == 3) {
|
||
2174 | *pPalRangeStatus = 5; /* HW fail */ |
||
2175 | } else if (DeviceRangeStatusInternal == 6 || |
||
2176 | DeviceRangeStatusInternal == 9) {
|
||
2177 | *pPalRangeStatus = 4; /* Phase fail */ |
||
2178 | } else if (DeviceRangeStatusInternal == 8 || |
||
2179 | DeviceRangeStatusInternal == 10 ||
|
||
2180 | SignalRefClipflag == 1) {
|
||
2181 | *pPalRangeStatus = 3; /* Min range */ |
||
2182 | } else if (DeviceRangeStatusInternal == 4 || |
||
2183 | RangeIgnoreThresholdflag == 1) {
|
||
2184 | *pPalRangeStatus = 2; /* Signal Fail */ |
||
2185 | } else if (SigmaLimitflag == 1) { |
||
2186 | *pPalRangeStatus = 1; /* Sigma Fail */ |
||
2187 | } else {
|
||
2188 | *pPalRangeStatus = 0; /* Range Valid */ |
||
2189 | } |
||
2190 | } |
||
2191 | |||
2192 | /* DMAX only relevant during range error */
|
||
2193 | if (*pPalRangeStatus == 0) |
||
2194 | pRangingMeasurementData->RangeDMaxMilliMeter = 0;
|
||
2195 | |||
2196 | /* fill the Limit Check Status */
|
||
2197 | |||
2198 | Status = VL53L0X_GetLimitCheckEnable(Dev, |
||
2199 | VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, |
||
2200 | &SignalRateFinalRangeLimitCheckEnable); |
||
2201 | |||
2202 | if (Status == VL53L0X_ERROR_NONE) {
|
||
2203 | if ((SigmaLimitCheckEnable == 0) || (SigmaLimitflag == 1)) |
||
2204 | Temp8 = 1;
|
||
2205 | else
|
||
2206 | Temp8 = 0;
|
||
2207 | VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, |
||
2208 | VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, Temp8); |
||
2209 | |||
2210 | if ((DeviceRangeStatusInternal == 4) || |
||
2211 | (SignalRateFinalRangeLimitCheckEnable == 0))
|
||
2212 | Temp8 = 1;
|
||
2213 | else
|
||
2214 | Temp8 = 0;
|
||
2215 | VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, |
||
2216 | VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, |
||
2217 | Temp8); |
||
2218 | |||
2219 | if ((SignalRefClipLimitCheckEnable == 0) || |
||
2220 | (SignalRefClipflag == 1))
|
||
2221 | Temp8 = 1;
|
||
2222 | else
|
||
2223 | Temp8 = 0;
|
||
2224 | |||
2225 | VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, |
||
2226 | VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, Temp8); |
||
2227 | |||
2228 | if ((RangeIgnoreThresholdLimitCheckEnable == 0) || |
||
2229 | (RangeIgnoreThresholdflag == 1))
|
||
2230 | Temp8 = 1;
|
||
2231 | else
|
||
2232 | Temp8 = 0;
|
||
2233 | |||
2234 | VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, |
||
2235 | VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, |
||
2236 | Temp8); |
||
2237 | } |
||
2238 | |||
2239 | LOG_FUNCTION_END(Status); |
||
2240 | return Status;
|
||
2241 | |||
2242 | } |