1
2 /*
3 * Copyright (c) 2017, STMicroelectronics - All Rights Reserved
4 *
5 * This file is part of VL53L1 Core and is dual licensed,
6 * either 'STMicroelectronics
7 * Proprietary license'
8 * or 'BSD 3-clause "New" or "Revised" License' , at your option.
9 *
10 ********************************************************************************
11 *
12 * 'STMicroelectronics Proprietary license'
13 *
14 ********************************************************************************
15 *
16 * License terms: STMicroelectronics Proprietary in accordance with licensing
17 * terms at www.st.com/sla0081
18 *
19 * STMicroelectronics confidential
20 * Reproduction and Communication of this document is strictly prohibited unless
21 * specifically authorized in writing by STMicroelectronics.
22 *
23 *
24 ********************************************************************************
25 *
26 * Alternatively, VL53L1 Core may be distributed under the terms of
27 * 'BSD 3-clause "New" or "Revised" License', in which case the following
28 * provisions apply instead of the ones mentioned above :
29 *
30 ********************************************************************************
31 *
32 * License terms: BSD 3-clause "New" or "Revised" License.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions are met:
36 *
37 * 1. Redistributions of source code must retain the above copyright notice, this
38 * list of conditions and the following disclaimer.
39 *
40 * 2. Redistributions in binary form must reproduce the above copyright notice,
41 * this list of conditions and the following disclaimer in the documentation
42 * and/or other materials provided with the distribution.
43 *
44 * 3. Neither the name of the copyright holder nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
54 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
55 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
56 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
57 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 *
59 *
60 ********************************************************************************
61 *
62 */
63 #include "vl53l1_api.h"
64 #include "vl53l1_api_strings.h"
65 #include "vl53l1_register_settings.h"
66 #include "vl53l1_register_funcs.h"
67 #include "vl53l1_core.h"
68 #include "vl53l1_api_calibration.h"
69 #include "vl53l1_wait.h"
70 #include "vl53l1_preset_setup.h"
71 #include "vl53l1_api_debug.h"
72 #include "vl53l1_api_core.h"
73
74 /* Check for minimum user zone requested by Xtalk calibration */
75 /* no need for VL53L1_MAX_USER_ZONES check, set 5 to pass the test */
76 #define ZONE_CHECK 5
77
78 #if ZONE_CHECK < 5
79 #error Must define at least 5 zones in MAX_USER_ZONES constant
80 #endif
81
82
83 #ifdef VL53L1_NOCALIB
84 #define OFFSET_CALIB_EMPTY
85 #endif
86
87 #ifndef VL53L1_NOCALIB
88 #define OFFSET_CALIB
89 #endif
90
91 #define LOG_FUNCTION_START(fmt, ...) \
92 _LOG_FUNCTION_START(VL53L1_TRACE_MODULE_API, fmt, ##__VA_ARGS__)
93 #define LOG_FUNCTION_END(status, ...) \
94 _LOG_FUNCTION_END(VL53L1_TRACE_MODULE_API, status, ##__VA_ARGS__)
95 #define LOG_FUNCTION_END_FMT(status, fmt, ...) \
96 _LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_API, status, \
97 fmt, ##__VA_ARGS__)
98
99 #ifdef VL53L1_LOG_ENABLE
100 #define trace_print(level, ...) trace_print_module_function(\
101 VL53L1_TRACE_MODULE_API, level, VL53L1_TRACE_FUNCTION_NONE, \
102 ##__VA_ARGS__)
103 #endif
104
105 #ifndef MIN
106 #define MIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
107 #endif
108 #ifndef MAX
109 #define MAX(v1, v2) ((v1) < (v2) ? (v2) : (v1))
110 #endif
111
112 #define DMAX_REFLECTANCE_IDX 2
113 /* Use Dmax index 2 because it's the 50% reflectance case by default */
114
115 /* Following LOWPOWER_AUTO figures have been measured observing vcsel
116 * emissions on an actual device
117 */
118 #define LOWPOWER_AUTO_VHV_LOOP_DURATION_US 245
119 #define LOWPOWER_AUTO_OVERHEAD_BEFORE_A_RANGING 1448
120 #define LOWPOWER_AUTO_OVERHEAD_BETWEEN_A_B_RANGING 2100
121
122 #define FDA_MAX_TIMING_BUDGET_US 550000
123 /* Maximum timing budget allowed codex #456189*/
124
125
126 /* local static utilities functions */
127
128 /* Bare Driver Tuning parameter table indexed with VL53L1_Tuning_t */
129 static int32_t BDTable[VL53L1_TUNING_MAX_TUNABLE_KEY] = {
130 TUNING_VERSION,
131 TUNING_PROXY_MIN,
132 TUNING_SINGLE_TARGET_XTALK_TARGET_DISTANCE_MM,
133 TUNING_SINGLE_TARGET_XTALK_SAMPLE_NUMBER,
134 TUNING_MIN_AMBIENT_DMAX_VALID,
135 TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER,
136 TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM,
137 TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT
138 };
139
140
141 #define VL53L1_NVM_POWER_UP_DELAY_US 50
142 #define VL53L1_NVM_READ_TRIGGER_DELAY_US 5
143
VL53L1_nvm_enable(VL53L1_DEV Dev,uint16_t nvm_ctrl_pulse_width,int32_t nvm_power_up_delay_us)144 static VL53L1_Error VL53L1_nvm_enable(
145 VL53L1_DEV Dev,
146 uint16_t nvm_ctrl_pulse_width,
147 int32_t nvm_power_up_delay_us)
148 {
149 /*
150 * Sequence below enables NVM for reading
151 *
152 * - Enable power force
153 * - Disable firmware
154 * - Power up NVM
155 * - Wait for 50us while the NVM powers up
156 * - Configure for reading and set the pulse width (16-bit)
157 */
158
159 VL53L1_Error status = VL53L1_ERROR_NONE;
160
161 LOG_FUNCTION_START("");
162
163
164 /* Disable Firmware */
165
166 if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/
167 status = VL53L1_disable_firmware(Dev);
168
169
170 /* Enable Power Force */
171
172 if (status == VL53L1_ERROR_NONE)
173 status = VL53L1_enable_powerforce(Dev);
174
175 /* Wait the required time for the regulators, bandgap,
176 * oscillator to wake up and settle
177 */
178
179 if (status == VL53L1_ERROR_NONE)
180 status = VL53L1_WaitUs(
181 Dev,
182 VL53L1_ENABLE_POWERFORCE_SETTLING_TIME_US);
183
184 /* Power up NVM */
185
186 if (status == VL53L1_ERROR_NONE)
187 status = VL53L1_WrByte(
188 Dev,
189 VL53L1_RANGING_CORE__NVM_CTRL__PDN,
190 0x01);
191
192 /* Enable NVM Clock */
193
194 if (status == VL53L1_ERROR_NONE)
195 status = VL53L1_WrByte(
196 Dev,
197 VL53L1_RANGING_CORE__CLK_CTRL1,
198 0x05);
199
200 /* Wait the required time for NVM to power up*/
201
202 if (status == VL53L1_ERROR_NONE)
203 status = VL53L1_WaitUs(
204 Dev,
205 nvm_power_up_delay_us);
206
207 /* Select read mode and set control pulse width */
208
209 if (status == VL53L1_ERROR_NONE)
210 status = VL53L1_WrByte(
211 Dev,
212 VL53L1_RANGING_CORE__NVM_CTRL__MODE,
213 0x01);
214
215 if (status == VL53L1_ERROR_NONE)
216 status = VL53L1_WrWord(
217 Dev,
218 VL53L1_RANGING_CORE__NVM_CTRL__PULSE_WIDTH_MSB,
219 nvm_ctrl_pulse_width);
220
221 LOG_FUNCTION_END(status);
222
223 return status;
224
225 }
226
227
VL53L1_nvm_read(VL53L1_DEV Dev,uint8_t start_address,uint8_t count,uint8_t * pdata)228 static VL53L1_Error VL53L1_nvm_read(
229 VL53L1_DEV Dev,
230 uint8_t start_address,
231 uint8_t count,
232 uint8_t *pdata)
233 {
234 /*
235 * Sequence per 32-bit NVM read access:
236 *
237 * - Set up the 5-bit (0-127) NVM Address
238 * - Trigger the read of the NVM data by toggling NVM_CTRL__READN
239 * - Read the NVM data - 4 bytes wide read/write interface
240 * - Increment data byte pointer by 4 ready for the next loop
241 */
242
243 VL53L1_Error status = VL53L1_ERROR_NONE;
244 uint8_t nvm_addr = 0;
245
246 LOG_FUNCTION_START("");
247
248 for (nvm_addr = start_address; nvm_addr < (start_address+count) ; nvm_addr++) {
249
250 /* Step 1 : set address */
251
252 if (status == VL53L1_ERROR_NONE)
253 status = VL53L1_WrByte(
254 Dev,
255 VL53L1_RANGING_CORE__NVM_CTRL__ADDR,
256 nvm_addr);
257
258 /* Step 2 : trigger reading of data */
259
260 if (status == VL53L1_ERROR_NONE)
261 status = VL53L1_WrByte(
262 Dev,
263 VL53L1_RANGING_CORE__NVM_CTRL__READN,
264 0x00);
265
266 /* Step 3 : wait the required time */
267
268 if (status == VL53L1_ERROR_NONE)
269 status = VL53L1_WaitUs(
270 Dev,
271 VL53L1_NVM_READ_TRIGGER_DELAY_US);
272
273 if (status == VL53L1_ERROR_NONE)
274 status = VL53L1_WrByte(
275 Dev,
276 VL53L1_RANGING_CORE__NVM_CTRL__READN,
277 0x01);
278
279 /* Step 3 : read 4-byte wide data register */
280 if (status == VL53L1_ERROR_NONE)
281 status = VL53L1_ReadMulti(
282 Dev,
283 VL53L1_RANGING_CORE__NVM_CTRL__DATAOUT_MMM,
284 pdata,
285 4);
286
287 /* Step 4 : increment byte buffer pointer */
288
289 pdata = pdata + 4;
290
291
292 }
293
294 LOG_FUNCTION_END(status);
295
296 return status;
297 }
298
VL53L1_nvm_disable(VL53L1_DEV Dev)299 static VL53L1_Error VL53L1_nvm_disable(
300 VL53L1_DEV Dev)
301 {
302 /*
303 * Power down NVM (OTP) to extend lifetime
304 */
305
306 VL53L1_Error status = VL53L1_ERROR_NONE;
307
308 LOG_FUNCTION_START("");
309
310 if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/
311 status = VL53L1_WrByte(
312 Dev,
313 VL53L1_RANGING_CORE__NVM_CTRL__READN,
314 0x01);
315
316 /* Power down NVM */
317
318 if (status == VL53L1_ERROR_NONE)
319 status = VL53L1_WrByte(
320 Dev,
321 VL53L1_RANGING_CORE__NVM_CTRL__PDN,
322 0x00);
323
324 /* Keep power force enabled */
325
326 if (status == VL53L1_ERROR_NONE)
327 status = VL53L1_disable_powerforce(Dev);
328
329 /* (Re)Enable Firmware */
330
331 if (status == VL53L1_ERROR_NONE)
332 status = VL53L1_enable_firmware(Dev);
333
334 LOG_FUNCTION_END(status);
335
336 return status;
337
338 }
339
VL53L1_read_nvm_raw_data(VL53L1_DEV Dev,uint8_t start_address,uint8_t count,uint8_t * pnvm_raw_data)340 static VL53L1_Error VL53L1_read_nvm_raw_data(
341 VL53L1_DEV Dev,
342 uint8_t start_address,
343 uint8_t count,
344 uint8_t *pnvm_raw_data)
345 {
346
347 /*
348 * Reads ALL 512 bytes of NVM data
349 */
350
351 VL53L1_Error status = VL53L1_ERROR_NONE;
352
353 LOG_FUNCTION_START("");
354
355 /*
356 * Enable NVM and set control pulse width
357 */
358
359 if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/
360 status = VL53L1_nvm_enable(
361 Dev,
362 0x0004,
363 VL53L1_NVM_POWER_UP_DELAY_US);
364
365 /*
366 * Read the raw NVM data
367 * - currently all of 128 * 4 bytes = 512 bytes are read
368 */
369
370 if (status == VL53L1_ERROR_NONE)
371 status = VL53L1_nvm_read(
372 Dev,
373 start_address,
374 count,
375 pnvm_raw_data);
376
377 /*
378 * Disable NVM
379 */
380
381 if (status == VL53L1_ERROR_NONE)
382 status = VL53L1_nvm_disable(Dev);
383
384 LOG_FUNCTION_END(status);
385
386 return status;
387
388 }
389
SingleTargetXTalkCalibration(VL53L1_DEV Dev)390 static VL53L1_Error SingleTargetXTalkCalibration(VL53L1_DEV Dev)
391 {
392 VL53L1_Error Status = VL53L1_ERROR_NONE;
393
394 uint32_t sum_ranging = 0;
395 uint32_t sum_spads = 0;
396 FixPoint1616_t sum_signalRate = 0;
397 FixPoint1616_t total_count = 0;
398 uint8_t xtalk_meas = 0;
399 uint8_t xtalk_measmax =
400 BDTable[VL53L1_TUNING_SINGLE_TARGET_XTALK_SAMPLE_NUMBER];
401 VL53L1_RangingMeasurementData_t RMData;
402 FixPoint1616_t xTalkStoredMeanSignalRate;
403 FixPoint1616_t xTalkStoredMeanRange;
404 FixPoint1616_t xTalkStoredMeanRtnSpads;
405 uint32_t xTalkStoredMeanRtnSpadsAsInt;
406 uint32_t xTalkCalDistanceAsInt;
407 FixPoint1616_t XTalkCompensationRateMegaCps;
408 uint32_t signalXTalkTotalPerSpad;
409 VL53L1_PresetModes PresetMode;
410 VL53L1_CalibrationData_t CalibrationData;
411 VL53L1_CustomerNvmManaged_t *pC;
412
413
414 LOG_FUNCTION_START("");
415
416 /* check if the following are selected
417 * VL53L1_PRESETMODE_AUTONOMOUS,
418 * VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS
419 * VL53L1_PRESETMODE_LITE_RANGING
420 */
421 PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
422
423 if ((PresetMode != VL53L1_PRESETMODE_AUTONOMOUS) &&
424 (PresetMode != VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS) &&
425 (PresetMode != VL53L1_PRESETMODE_LITE_RANGING)) {
426 Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
427 goto ENDFUNC;
428 }
429
430 /* disable crosstalk calibration */
431 Status = VL53L1_disable_xtalk_compensation(Dev);
432 CHECK_ERROR_GO_ENDFUNC;
433
434 Status = VL53L1_StartMeasurement(Dev);
435 CHECK_ERROR_GO_ENDFUNC;
436
437 sum_ranging = 0;
438 sum_spads = 0;
439 sum_signalRate = 0;
440 total_count = 0;
441 for (xtalk_meas = 0; xtalk_meas < xtalk_measmax; xtalk_meas++) {
442 VL53L1_WaitMeasurementDataReady(Dev);
443 VL53L1_GetRangingMeasurementData(Dev, &RMData);
444 VL53L1_ClearInterruptAndStartMeasurement(Dev);
445 if (RMData.RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID) {
446 sum_ranging += RMData.RangeMilliMeter;
447 sum_signalRate += RMData.SignalRateRtnMegaCps;
448 sum_spads += RMData.EffectiveSpadRtnCount / 256;
449 total_count++;
450 }
451 }
452 Status = VL53L1_StopMeasurement(Dev);
453
454 if (total_count > 0) {
455 /* FixPoint1616_t / uint16_t = FixPoint1616_t */
456 xTalkStoredMeanSignalRate = sum_signalRate / total_count;
457 xTalkStoredMeanRange = (FixPoint1616_t)(sum_ranging << 16);
458 xTalkStoredMeanRange /= total_count;
459 xTalkStoredMeanRtnSpads = (FixPoint1616_t)(sum_spads << 16);
460 xTalkStoredMeanRtnSpads /= total_count;
461
462 /* Round Mean Spads to Whole Number.
463 * Typically the calculated mean SPAD count is a whole number
464 * or very close to a whole
465 * number, therefore any truncation will not result in a
466 * significant loss in accuracy.
467 * Also, for a grey target at a typical distance of around
468 * 400mm, around 220 SPADs will
469 * be enabled, therefore, any truncation will result in a loss
470 * of accuracy of less than
471 * 0.5%.
472 */
473 xTalkStoredMeanRtnSpadsAsInt = (xTalkStoredMeanRtnSpads +
474 0x8000) >> 16;
475
476 /* Round Cal Distance to Whole Number.
477 * Note that the cal distance is in mm, therefore no resolution
478 * is lost.
479 */
480 xTalkCalDistanceAsInt = ((uint32_t)BDTable[
481 VL53L1_TUNING_SINGLE_TARGET_XTALK_TARGET_DISTANCE_MM]);
482 if (xTalkStoredMeanRtnSpadsAsInt == 0 ||
483 xTalkCalDistanceAsInt == 0 ||
484 xTalkStoredMeanRange >= (xTalkCalDistanceAsInt << 16)) {
485 XTalkCompensationRateMegaCps = 0;
486 } else {
487 /* Apply division by mean spad count early in the
488 * calculation to keep the numbers small.
489 * This ensures we can maintain a 32bit calculation.
490 * Fixed1616 / int := Fixed1616
491 */
492 signalXTalkTotalPerSpad = (xTalkStoredMeanSignalRate) /
493 xTalkStoredMeanRtnSpadsAsInt;
494
495 /* Complete the calculation for total Signal XTalk per
496 * SPAD
497 * Fixed1616 * (Fixed1616 - Fixed1616/int) :=
498 * (2^16 * Fixed1616)
499 */
500 signalXTalkTotalPerSpad *= (((uint32_t)1 << 16) -
501 (xTalkStoredMeanRange / xTalkCalDistanceAsInt));
502
503 /* Round from 2^16 * Fixed1616, to Fixed1616. */
504 XTalkCompensationRateMegaCps = (signalXTalkTotalPerSpad
505 + 0x8000) >> 16;
506 }
507
508
509 Status = VL53L1_GetCalibrationData(Dev, &CalibrationData);
510 CHECK_ERROR_GO_ENDFUNC;
511
512 pC = &CalibrationData.customer;
513
514 pC->algo__crosstalk_compensation_plane_offset_kcps =
515 (uint32_t)(1000 * ((XTalkCompensationRateMegaCps +
516 ((uint32_t)1<<6)) >> (16-9)));
517
518 Status = VL53L1_SetCalibrationData(Dev, &CalibrationData);
519 CHECK_ERROR_GO_ENDFUNC;
520
521 Status = VL53L1_enable_xtalk_compensation(Dev);
522
523 } else
524 /* return error because no valid data found */
525 Status = VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL;
526
527 ENDFUNC:
528 LOG_FUNCTION_END(Status);
529 return Status;
530
531 }
532
533 /* Check Rectangle in user's coordinate system:
534 * 15 TL(x,y) o-----*
535 * ^ | |
536 * | *-----o BR(x,y)
537 * 0------------------------- >15
538 * check Rectangle definition conforms to the (0,15,15) coordinate system
539 * with a minimum of 4x4 size
540 */
CheckValidRectRoi(VL53L1_UserRoi_t ROI)541 static VL53L1_Error CheckValidRectRoi(VL53L1_UserRoi_t ROI)
542 {
543 VL53L1_Error Status = VL53L1_ERROR_NONE;
544
545 LOG_FUNCTION_START("");
546
547 /* Negative check are not necessary because value is unsigned */
548 if ((ROI.TopLeftX > 15) || (ROI.TopLeftY > 15) ||
549 (ROI.BotRightX > 15) || (ROI.BotRightY > 15))
550 Status = VL53L1_ERROR_INVALID_PARAMS;
551
552 if ((ROI.TopLeftX > ROI.BotRightX) || (ROI.TopLeftY < ROI.BotRightY))
553 Status = VL53L1_ERROR_INVALID_PARAMS;
554
555 LOG_FUNCTION_END(Status);
556 return Status;
557 }
558
ConvertModeToLLD(VL53L1_Error * pStatus,VL53L1_ThresholdMode CrossMode)559 static VL53L1_GPIO_Interrupt_Mode ConvertModeToLLD(VL53L1_Error *pStatus,
560 VL53L1_ThresholdMode CrossMode)
561 {
562 VL53L1_GPIO_Interrupt_Mode Mode;
563
564 switch (CrossMode) {
565 case VL53L1_THRESHOLD_CROSSED_LOW:
566 Mode = VL53L1_GPIOINTMODE_LEVEL_LOW;
567 break;
568 case VL53L1_THRESHOLD_CROSSED_HIGH:
569 Mode = VL53L1_GPIOINTMODE_LEVEL_HIGH;
570 break;
571 case VL53L1_THRESHOLD_OUT_OF_WINDOW:
572 Mode = VL53L1_GPIOINTMODE_OUT_OF_WINDOW;
573 break;
574 case VL53L1_THRESHOLD_IN_WINDOW:
575 Mode = VL53L1_GPIOINTMODE_IN_WINDOW;
576 break;
577 default:
578 /* define Mode to avoid warning but actual value doesn't mind */
579 Mode = VL53L1_GPIOINTMODE_LEVEL_HIGH;
580 *pStatus = VL53L1_ERROR_INVALID_PARAMS;
581 }
582 return Mode;
583 }
584
ConvertModeFromLLD(VL53L1_Error * pStatus,VL53L1_GPIO_Interrupt_Mode CrossMode)585 static VL53L1_ThresholdMode ConvertModeFromLLD(VL53L1_Error *pStatus,
586 VL53L1_GPIO_Interrupt_Mode CrossMode)
587 {
588 VL53L1_ThresholdMode Mode;
589
590 switch (CrossMode) {
591 case VL53L1_GPIOINTMODE_LEVEL_LOW:
592 Mode = VL53L1_THRESHOLD_CROSSED_LOW;
593 break;
594 case VL53L1_GPIOINTMODE_LEVEL_HIGH:
595 Mode = VL53L1_THRESHOLD_CROSSED_HIGH;
596 break;
597 case VL53L1_GPIOINTMODE_OUT_OF_WINDOW:
598 Mode = VL53L1_THRESHOLD_OUT_OF_WINDOW;
599 break;
600 case VL53L1_GPIOINTMODE_IN_WINDOW:
601 Mode = VL53L1_THRESHOLD_IN_WINDOW;
602 break;
603 default:
604 /* define Mode to avoid warning but actual value doesn't mind */
605 Mode = VL53L1_THRESHOLD_CROSSED_HIGH;
606 *pStatus = VL53L1_ERROR_UNDEFINED;
607 }
608 return Mode;
609 }
610
611 /* Group PAL General Functions */
612
VL53L1_GetVersion(VL53L1_Version_t * pVersion)613 VL53L1_Error VL53L1_GetVersion(VL53L1_Version_t *pVersion)
614 {
615 VL53L1_Error Status = VL53L1_ERROR_NONE;
616
617 LOG_FUNCTION_START("");
618
619 pVersion->major = VL53L1_IMPLEMENTATION_VER_MAJOR;
620 pVersion->minor = VL53L1_IMPLEMENTATION_VER_MINOR;
621 pVersion->build = VL53L1_IMPLEMENTATION_VER_SUB;
622
623 pVersion->revision = VL53L1_IMPLEMENTATION_VER_REVISION;
624
625 LOG_FUNCTION_END(Status);
626 return Status;
627 }
628
VL53L1_GetProductRevision(VL53L1_DEV Dev,uint8_t * pProductRevisionMajor,uint8_t * pProductRevisionMinor)629 VL53L1_Error VL53L1_GetProductRevision(VL53L1_DEV Dev,
630 uint8_t *pProductRevisionMajor, uint8_t *pProductRevisionMinor)
631 {
632 VL53L1_Error Status = VL53L1_ERROR_NONE;
633 uint8_t revision_id;
634 VL53L1_LLDriverData_t *pLLData;
635
636 LOG_FUNCTION_START("");
637
638 pLLData = VL53L1DevStructGetLLDriverHandle(Dev);
639 revision_id = pLLData->nvm_copy_data.identification__revision_id;
640 *pProductRevisionMajor = 1;
641 *pProductRevisionMinor = (revision_id & 0xF0) >> 4;
642
643 LOG_FUNCTION_END(Status);
644 return Status;
645
646 }
647
VL53L1_GetDeviceInfo(VL53L1_DEV Dev,VL53L1_DeviceInfo_t * pVL53L1_DeviceInfo)648 VL53L1_Error VL53L1_GetDeviceInfo(VL53L1_DEV Dev,
649 VL53L1_DeviceInfo_t *pVL53L1_DeviceInfo)
650 {
651 VL53L1_Error Status = VL53L1_ERROR_NONE;
652 uint8_t revision_id;
653 VL53L1_LLDriverData_t *pLLData;
654
655 LOG_FUNCTION_START("");
656
657 pLLData = VL53L1DevStructGetLLDriverHandle(Dev);
658
659 strncpy(pVL53L1_DeviceInfo->ProductId, "",
660 VL53L1_DEVINFO_STRLEN-1);
661 pVL53L1_DeviceInfo->ProductType =
662 pLLData->nvm_copy_data.identification__module_type;
663
664 revision_id = pLLData->nvm_copy_data.identification__revision_id;
665 pVL53L1_DeviceInfo->ProductRevisionMajor = 1;
666 pVL53L1_DeviceInfo->ProductRevisionMinor = (revision_id & 0xF0) >> 4;
667
668 #ifndef VL53L1_USE_EMPTY_STRING
669 if (pVL53L1_DeviceInfo->ProductRevisionMinor == 0)
670 strncpy(pVL53L1_DeviceInfo->Name,
671 VL53L1_STRING_DEVICE_INFO_NAME0,
672 VL53L1_DEVINFO_STRLEN-1);
673 else
674 strncpy(pVL53L1_DeviceInfo->Name,
675 VL53L1_STRING_DEVICE_INFO_NAME1,
676 VL53L1_DEVINFO_STRLEN-1);
677 strncpy(pVL53L1_DeviceInfo->Type,
678 VL53L1_STRING_DEVICE_INFO_TYPE,
679 VL53L1_DEVINFO_STRLEN-1);
680 #else
681 pVL53L1_DeviceInfo->Name[0] = 0;
682 pVL53L1_DeviceInfo->Type[0] = 0;
683 #endif
684
685 LOG_FUNCTION_END(Status);
686 return Status;
687 }
688
689
VL53L1_GetRangeStatusString(uint8_t RangeStatus,char * pRangeStatusString)690 VL53L1_Error VL53L1_GetRangeStatusString(uint8_t RangeStatus,
691 char *pRangeStatusString)
692 {
693 VL53L1_Error Status = VL53L1_ERROR_NONE;
694
695 LOG_FUNCTION_START("");
696
697 Status = VL53L1_get_range_status_string(RangeStatus,
698 pRangeStatusString);
699
700 LOG_FUNCTION_END(Status);
701 return Status;
702 }
703
VL53L1_GetPalErrorString(VL53L1_Error PalErrorCode,char * pPalErrorString)704 VL53L1_Error VL53L1_GetPalErrorString(VL53L1_Error PalErrorCode,
705 char *pPalErrorString)
706 {
707 VL53L1_Error Status = VL53L1_ERROR_NONE;
708
709 LOG_FUNCTION_START("");
710
711 Status = VL53L1_get_pal_error_string(PalErrorCode, pPalErrorString);
712
713 LOG_FUNCTION_END(Status);
714 return Status;
715 }
716
VL53L1_GetPalStateString(VL53L1_State PalStateCode,char * pPalStateString)717 VL53L1_Error VL53L1_GetPalStateString(VL53L1_State PalStateCode,
718 char *pPalStateString)
719 {
720 VL53L1_Error Status = VL53L1_ERROR_NONE;
721
722 LOG_FUNCTION_START("");
723
724 Status = VL53L1_get_pal_state_string(PalStateCode, pPalStateString);
725
726 LOG_FUNCTION_END(Status);
727 return Status;
728 }
729
VL53L1_GetPalState(VL53L1_DEV Dev,VL53L1_State * pPalState)730 VL53L1_Error VL53L1_GetPalState(VL53L1_DEV Dev, VL53L1_State *pPalState)
731 {
732 VL53L1_Error Status = VL53L1_ERROR_NONE;
733
734 LOG_FUNCTION_START("");
735
736 *pPalState = VL53L1DevDataGet(Dev, PalState);
737
738 LOG_FUNCTION_END(Status);
739 return Status;
740 }
741
742 /* End Group PAL General Functions */
743
744 /* Group PAL Init Functions */
VL53L1_SetDeviceAddress(VL53L1_DEV Dev,uint8_t DeviceAddress)745 VL53L1_Error VL53L1_SetDeviceAddress(VL53L1_DEV Dev, uint8_t DeviceAddress)
746 {
747 VL53L1_Error Status = VL53L1_ERROR_NONE;
748
749 LOG_FUNCTION_START("");
750
751 Status = VL53L1_WrByte(Dev, VL53L1_I2C_SLAVE__DEVICE_ADDRESS,
752 DeviceAddress / 2);
753
754 LOG_FUNCTION_END(Status);
755 return Status;
756 }
757
VL53L1_DataInit(VL53L1_DEV Dev)758 VL53L1_Error VL53L1_DataInit(VL53L1_DEV Dev)
759 {
760 VL53L1_Error Status = VL53L1_ERROR_NONE;
761 uint8_t i;
762
763 LOG_FUNCTION_START("");
764
765 /* 2V8 power mode selection codex 447463 */
766 #ifdef USE_I2C_2V8
767 Status = VL53L1_RdByte(Dev, VL53L1_PAD_I2C_HV__EXTSUP_CONFIG, &i);
768 if (Status == VL53L1_ERROR_NONE) {
769 i = (i & 0xfe) | 0x01;
770 Status = VL53L1_WrByte(Dev, VL53L1_PAD_I2C_HV__EXTSUP_CONFIG,
771 i);
772 }
773 #endif
774
775 if (Status == VL53L1_ERROR_NONE)
776 Status = VL53L1_data_init(Dev, 1);
777
778 if (Status == VL53L1_ERROR_NONE) {
779 VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_WAIT_STATICINIT);
780 VL53L1DevDataSet(Dev, CurrentParameters.PresetMode,
781 VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS);
782 }
783
784 /* Enable all check */
785 for (i = 0; i < VL53L1_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
786 if (Status == VL53L1_ERROR_NONE)
787 Status |= VL53L1_SetLimitCheckEnable(Dev, i, 1);
788 else
789 break;
790
791 }
792
793 /* Limit default values */
794 if (Status == VL53L1_ERROR_NONE) {
795 Status = VL53L1_SetLimitCheckValue(Dev,
796 VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
797 (FixPoint1616_t)(18 * 65536));
798 }
799 if (Status == VL53L1_ERROR_NONE) {
800 Status = VL53L1_SetLimitCheckValue(Dev,
801 VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
802 (FixPoint1616_t)(25 * 65536 / 100));
803 /* 0.25 * 65536 */
804 }
805
806 LOG_FUNCTION_END(Status);
807 return Status;
808 }
809
810
VL53L1_StaticInit(VL53L1_DEV Dev)811 VL53L1_Error VL53L1_StaticInit(VL53L1_DEV Dev)
812 {
813 VL53L1_Error Status = VL53L1_ERROR_NONE;
814 uint8_t measurement_mode;
815
816 LOG_FUNCTION_START("");
817
818 VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_IDLE);
819
820 measurement_mode = VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
821 VL53L1DevDataSet(Dev, LLData.measurement_mode, measurement_mode);
822
823 VL53L1DevDataSet(Dev, CurrentParameters.NewDistanceMode,
824 VL53L1_DISTANCEMODE_LONG);
825
826 VL53L1DevDataSet(Dev, CurrentParameters.InternalDistanceMode,
827 VL53L1_DISTANCEMODE_LONG);
828
829 VL53L1DevDataSet(Dev, CurrentParameters.DistanceMode,
830 VL53L1_DISTANCEMODE_LONG);
831
832 /* ticket 472728 fix */
833 Status = VL53L1_SetPresetMode(Dev,
834 VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS);
835 /* end of ticket 472728 fix */
836 LOG_FUNCTION_END(Status);
837 return Status;
838 }
839
VL53L1_WaitDeviceBooted(VL53L1_DEV Dev)840 VL53L1_Error VL53L1_WaitDeviceBooted(VL53L1_DEV Dev)
841 {
842 VL53L1_Error Status = VL53L1_ERROR_NONE;
843
844 LOG_FUNCTION_START("");
845
846 Status = VL53L1_poll_for_boot_completion(Dev,
847 VL53L1_BOOT_COMPLETION_POLLING_TIMEOUT_MS);
848
849 LOG_FUNCTION_END(Status);
850 return Status;
851 }
852
853 /* End Group PAL Init Functions */
854
855 /* Group PAL Parameters Functions */
ComputeDevicePresetMode(VL53L1_PresetModes PresetMode,VL53L1_DistanceModes DistanceMode,VL53L1_DevicePresetModes * pDevicePresetMode)856 static VL53L1_Error ComputeDevicePresetMode(
857 VL53L1_PresetModes PresetMode,
858 VL53L1_DistanceModes DistanceMode,
859 VL53L1_DevicePresetModes *pDevicePresetMode)
860 {
861 VL53L1_Error Status = VL53L1_ERROR_NONE;
862
863 uint8_t DistIdx;
864 VL53L1_DevicePresetModes LightModes[3] = {
865 VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_SHORT_RANGE,
866 VL53L1_DEVICEPRESETMODE_STANDARD_RANGING,
867 VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_LONG_RANGE};
868
869
870 VL53L1_DevicePresetModes TimedModes[3] = {
871 VL53L1_DEVICEPRESETMODE_TIMED_RANGING_SHORT_RANGE,
872 VL53L1_DEVICEPRESETMODE_TIMED_RANGING,
873 VL53L1_DEVICEPRESETMODE_TIMED_RANGING_LONG_RANGE};
874
875 VL53L1_DevicePresetModes LowPowerTimedModes[3] = {
876 VL53L1_DEVICEPRESETMODE_LOWPOWERAUTO_SHORT_RANGE,
877 VL53L1_DEVICEPRESETMODE_LOWPOWERAUTO_MEDIUM_RANGE,
878 VL53L1_DEVICEPRESETMODE_LOWPOWERAUTO_LONG_RANGE};
879
880 *pDevicePresetMode = VL53L1_DEVICEPRESETMODE_STANDARD_RANGING;
881
882 switch (DistanceMode) {
883 case VL53L1_DISTANCEMODE_SHORT:
884 DistIdx = 0;
885 break;
886 case VL53L1_DISTANCEMODE_MEDIUM:
887 DistIdx = 1;
888 break;
889 default:
890 DistIdx = 2;
891 }
892
893 switch (PresetMode) {
894 case VL53L1_PRESETMODE_LITE_RANGING:
895 *pDevicePresetMode = LightModes[DistIdx];
896 break;
897
898
899 case VL53L1_PRESETMODE_AUTONOMOUS:
900 *pDevicePresetMode = TimedModes[DistIdx];
901 break;
902
903 case VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS:
904 *pDevicePresetMode = LowPowerTimedModes[DistIdx];
905 break;
906
907 default:
908 /* Unsupported mode */
909 Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
910 }
911
912 return Status;
913 }
914
SetPresetMode(VL53L1_DEV Dev,VL53L1_PresetModes PresetMode,VL53L1_DistanceModes DistanceMode,uint32_t inter_measurement_period_ms)915 static VL53L1_Error SetPresetMode(VL53L1_DEV Dev,
916 VL53L1_PresetModes PresetMode,
917 VL53L1_DistanceModes DistanceMode,
918 uint32_t inter_measurement_period_ms)
919 {
920 VL53L1_Error Status = VL53L1_ERROR_NONE;
921 VL53L1_DevicePresetModes device_preset_mode;
922 uint8_t measurement_mode;
923 uint16_t dss_config__target_total_rate_mcps;
924 uint32_t phasecal_config_timeout_us;
925 uint32_t mm_config_timeout_us;
926 uint32_t lld_range_config_timeout_us;
927
928 LOG_FUNCTION_START("%d", (int)PresetMode);
929
930 if ((PresetMode == VL53L1_PRESETMODE_AUTONOMOUS) ||
931 (PresetMode == VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS))
932 measurement_mode = VL53L1_DEVICEMEASUREMENTMODE_TIMED;
933 else
934 measurement_mode = VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
935
936
937 Status = ComputeDevicePresetMode(PresetMode, DistanceMode,
938 &device_preset_mode);
939
940 if (Status == VL53L1_ERROR_NONE)
941 Status = VL53L1_get_preset_mode_timing_cfg(Dev,
942 device_preset_mode,
943 &dss_config__target_total_rate_mcps,
944 &phasecal_config_timeout_us,
945 &mm_config_timeout_us,
946 &lld_range_config_timeout_us);
947
948 if (Status == VL53L1_ERROR_NONE)
949 Status = VL53L1_set_preset_mode(
950 Dev,
951 device_preset_mode,
952 dss_config__target_total_rate_mcps,
953 phasecal_config_timeout_us,
954 mm_config_timeout_us,
955 lld_range_config_timeout_us,
956 inter_measurement_period_ms);
957
958 if (Status == VL53L1_ERROR_NONE)
959 VL53L1DevDataSet(Dev, LLData.measurement_mode, measurement_mode);
960
961 if (Status == VL53L1_ERROR_NONE)
962 VL53L1DevDataSet(Dev, CurrentParameters.PresetMode, PresetMode);
963
964 LOG_FUNCTION_END(Status);
965 return Status;
966 }
967
VL53L1_SetPresetMode(VL53L1_DEV Dev,VL53L1_PresetModes PresetMode)968 VL53L1_Error VL53L1_SetPresetMode(VL53L1_DEV Dev, VL53L1_PresetModes PresetMode)
969 {
970 VL53L1_Error Status = VL53L1_ERROR_NONE;
971 VL53L1_DistanceModes DistanceMode = VL53L1_DISTANCEMODE_LONG;
972
973 LOG_FUNCTION_START("%d", (int)PresetMode);
974
975 Status = SetPresetMode(Dev,
976 PresetMode,
977 DistanceMode,
978 1000);
979
980 if (Status == VL53L1_ERROR_NONE) {
981 VL53L1DevDataSet(Dev, CurrentParameters.InternalDistanceMode,
982 DistanceMode);
983
984 VL53L1DevDataSet(Dev, CurrentParameters.NewDistanceMode,
985 DistanceMode);
986
987 if ((PresetMode == VL53L1_PRESETMODE_LITE_RANGING) ||
988 (PresetMode == VL53L1_PRESETMODE_AUTONOMOUS) ||
989 (PresetMode == VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS))
990 Status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(
991 Dev, 41000);
992 else
993 /* Set default timing budget to 30Hz (33.33 ms)*/
994 Status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(
995 Dev, 33333);
996 }
997
998 if (Status == VL53L1_ERROR_NONE) {
999 /* Set default intermeasurement period to 1000 ms */
1000 Status = VL53L1_SetInterMeasurementPeriodMilliSeconds(Dev,
1001 1000);
1002 }
1003
1004 LOG_FUNCTION_END(Status);
1005 return Status;
1006 }
1007
1008
VL53L1_GetPresetMode(VL53L1_DEV Dev,VL53L1_PresetModes * pPresetMode)1009 VL53L1_Error VL53L1_GetPresetMode(VL53L1_DEV Dev,
1010 VL53L1_PresetModes *pPresetMode)
1011 {
1012 VL53L1_Error Status = VL53L1_ERROR_NONE;
1013
1014 LOG_FUNCTION_START("");
1015
1016 *pPresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
1017
1018 LOG_FUNCTION_END(Status);
1019 return Status;
1020 }
1021
VL53L1_SetDistanceMode(VL53L1_DEV Dev,VL53L1_DistanceModes DistanceMode)1022 VL53L1_Error VL53L1_SetDistanceMode(VL53L1_DEV Dev,
1023 VL53L1_DistanceModes DistanceMode)
1024 {
1025 VL53L1_Error Status = VL53L1_ERROR_NONE;
1026 VL53L1_PresetModes PresetMode;
1027 VL53L1_DistanceModes InternalDistanceMode;
1028 uint32_t inter_measurement_period_ms;
1029 uint32_t TimingBudget;
1030 uint32_t MmTimeoutUs;
1031 uint32_t PhaseCalTimeoutUs;
1032 VL53L1_user_zone_t user_zone;
1033
1034 LOG_FUNCTION_START("%d", (int)DistanceMode);
1035
1036 PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
1037
1038 /* when the distance mode is valid:
1039 * Manual Mode: all modes
1040 * AUTO AUTO_LITE : LITE_RANGING, RANGING
1041 */
1042
1043 if ((DistanceMode != VL53L1_DISTANCEMODE_SHORT) &&
1044 (DistanceMode != VL53L1_DISTANCEMODE_MEDIUM) &&
1045 (DistanceMode != VL53L1_DISTANCEMODE_LONG))
1046 return VL53L1_ERROR_INVALID_PARAMS;
1047
1048 /* The internal distance mode is limited to Short, Medium or
1049 * long only
1050 */
1051 if (Status == VL53L1_ERROR_NONE) {
1052 if ((DistanceMode == VL53L1_DISTANCEMODE_SHORT) ||
1053 (DistanceMode == VL53L1_DISTANCEMODE_MEDIUM))
1054 InternalDistanceMode = DistanceMode;
1055 else /* (DistanceMode == VL53L1_DISTANCEMODE_LONG) */
1056 InternalDistanceMode = VL53L1_DISTANCEMODE_LONG;
1057 }
1058
1059 if (Status == VL53L1_ERROR_NONE)
1060 Status = VL53L1_get_user_zone(Dev, &user_zone);
1061
1062 inter_measurement_period_ms = VL53L1DevDataGet(Dev,
1063 LLData.inter_measurement_period_ms);
1064
1065 if (Status == VL53L1_ERROR_NONE)
1066 Status = VL53L1_get_timeouts_us(Dev, &PhaseCalTimeoutUs,
1067 &MmTimeoutUs, &TimingBudget);
1068
1069 if (Status == VL53L1_ERROR_NONE)
1070 Status = SetPresetMode(Dev,
1071 PresetMode,
1072 InternalDistanceMode,
1073 inter_measurement_period_ms);
1074
1075 if (Status == VL53L1_ERROR_NONE) {
1076 VL53L1DevDataSet(Dev, CurrentParameters.InternalDistanceMode,
1077 InternalDistanceMode);
1078 VL53L1DevDataSet(Dev, CurrentParameters.NewDistanceMode,
1079 InternalDistanceMode);
1080 VL53L1DevDataSet(Dev, CurrentParameters.DistanceMode,
1081 DistanceMode);
1082 }
1083
1084 if (Status == VL53L1_ERROR_NONE) {
1085 Status = VL53L1_set_timeouts_us(Dev, PhaseCalTimeoutUs,
1086 MmTimeoutUs, TimingBudget);
1087
1088 if (Status == VL53L1_ERROR_NONE)
1089 VL53L1DevDataSet(Dev, LLData.range_config_timeout_us,
1090 TimingBudget);
1091 }
1092
1093 if (Status == VL53L1_ERROR_NONE)
1094 Status = VL53L1_set_user_zone(Dev, &user_zone);
1095
1096 LOG_FUNCTION_END(Status);
1097 return Status;
1098 }
1099
VL53L1_GetDistanceMode(VL53L1_DEV Dev,VL53L1_DistanceModes * pDistanceMode)1100 VL53L1_Error VL53L1_GetDistanceMode(VL53L1_DEV Dev,
1101 VL53L1_DistanceModes *pDistanceMode)
1102 {
1103 VL53L1_Error Status = VL53L1_ERROR_NONE;
1104
1105 LOG_FUNCTION_START("");
1106
1107 *pDistanceMode = VL53L1DevDataGet(Dev, CurrentParameters.DistanceMode);
1108
1109 LOG_FUNCTION_END(Status);
1110 return Status;
1111 }
1112
1113
1114
1115
VL53L1_SetMeasurementTimingBudgetMicroSeconds(VL53L1_DEV Dev,uint32_t MeasurementTimingBudgetMicroSeconds)1116 VL53L1_Error VL53L1_SetMeasurementTimingBudgetMicroSeconds(VL53L1_DEV Dev,
1117 uint32_t MeasurementTimingBudgetMicroSeconds)
1118 {
1119 VL53L1_Error Status = VL53L1_ERROR_NONE;
1120 uint8_t Mm1Enabled;
1121 uint8_t Mm2Enabled;
1122 uint32_t TimingGuard;
1123 uint32_t divisor;
1124 uint32_t TimingBudget;
1125 uint32_t MmTimeoutUs;
1126 VL53L1_PresetModes PresetMode;
1127 uint32_t PhaseCalTimeoutUs;
1128 uint32_t vhv;
1129 int32_t vhv_loops;
1130 uint32_t FDAMaxTimingBudgetUs = FDA_MAX_TIMING_BUDGET_US;
1131
1132 LOG_FUNCTION_START("");
1133
1134 /* Timing budget is limited to 10 seconds */
1135 if (MeasurementTimingBudgetMicroSeconds > 10000000)
1136 Status = VL53L1_ERROR_INVALID_PARAMS;
1137
1138 if (Status == VL53L1_ERROR_NONE) {
1139 Status = VL53L1_GetSequenceStepEnable(Dev,
1140 VL53L1_SEQUENCESTEP_MM1, &Mm1Enabled);
1141 }
1142
1143 if (Status == VL53L1_ERROR_NONE) {
1144 Status = VL53L1_GetSequenceStepEnable(Dev,
1145 VL53L1_SEQUENCESTEP_MM2, &Mm2Enabled);
1146 }
1147
1148 if (Status == VL53L1_ERROR_NONE)
1149 Status = VL53L1_get_timeouts_us(Dev,
1150 &PhaseCalTimeoutUs,
1151 &MmTimeoutUs,
1152 &TimingBudget);
1153
1154 if (Status == VL53L1_ERROR_NONE) {
1155 PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
1156
1157 TimingGuard = 0;
1158 divisor = 1;
1159 switch (PresetMode) {
1160 case VL53L1_PRESETMODE_LITE_RANGING:
1161 if ((Mm1Enabled == 1) || (Mm2Enabled == 1))
1162 TimingGuard = 5000;
1163 else
1164 TimingGuard = 1000;
1165 break;
1166
1167 case VL53L1_PRESETMODE_AUTONOMOUS:
1168 FDAMaxTimingBudgetUs *= 2;
1169 if ((Mm1Enabled == 1) || (Mm2Enabled == 1))
1170 TimingGuard = 26600;
1171 else
1172 TimingGuard = 21600;
1173 divisor = 2;
1174 break;
1175
1176 case VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS:
1177 FDAMaxTimingBudgetUs *= 2;
1178 vhv = LOWPOWER_AUTO_VHV_LOOP_DURATION_US;
1179 VL53L1_get_tuning_parm(Dev,
1180 VL53L1_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND,
1181 &vhv_loops);
1182 if (vhv_loops > 0) {
1183 vhv += vhv_loops *
1184 LOWPOWER_AUTO_VHV_LOOP_DURATION_US;
1185 }
1186 TimingGuard = LOWPOWER_AUTO_OVERHEAD_BEFORE_A_RANGING +
1187 LOWPOWER_AUTO_OVERHEAD_BETWEEN_A_B_RANGING +
1188 vhv;
1189 divisor = 2;
1190 break;
1191
1192 default:
1193 /* Unsupported mode */
1194 Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
1195 }
1196
1197 if (MeasurementTimingBudgetMicroSeconds <= TimingGuard)
1198 Status = VL53L1_ERROR_INVALID_PARAMS;
1199 else {
1200 TimingBudget = (MeasurementTimingBudgetMicroSeconds
1201 - TimingGuard);
1202 }
1203
1204 if (Status == VL53L1_ERROR_NONE) {
1205 if (TimingBudget > FDAMaxTimingBudgetUs)
1206 Status = VL53L1_ERROR_INVALID_PARAMS;
1207 else {
1208 TimingBudget /= divisor;
1209 Status = VL53L1_set_timeouts_us(
1210 Dev,
1211 PhaseCalTimeoutUs,
1212 MmTimeoutUs,
1213 TimingBudget);
1214 }
1215
1216 if (Status == VL53L1_ERROR_NONE)
1217 VL53L1DevDataSet(Dev,
1218 LLData.range_config_timeout_us,
1219 TimingBudget);
1220 }
1221 }
1222 if (Status == VL53L1_ERROR_NONE) {
1223 VL53L1DevDataSet(Dev,
1224 CurrentParameters.MeasurementTimingBudgetMicroSeconds,
1225 MeasurementTimingBudgetMicroSeconds);
1226 }
1227
1228 LOG_FUNCTION_END(Status);
1229 return Status;
1230 }
1231
1232
VL53L1_GetMeasurementTimingBudgetMicroSeconds(VL53L1_DEV Dev,uint32_t * pMeasurementTimingBudgetMicroSeconds)1233 VL53L1_Error VL53L1_GetMeasurementTimingBudgetMicroSeconds(VL53L1_DEV Dev,
1234 uint32_t *pMeasurementTimingBudgetMicroSeconds)
1235 {
1236 VL53L1_Error Status = VL53L1_ERROR_NONE;
1237 uint8_t Mm1Enabled = 0;
1238 uint8_t Mm2Enabled = 0;
1239 uint32_t MmTimeoutUs = 0;
1240 uint32_t RangeTimeoutUs = 0;
1241 uint32_t MeasTimingBdg = 0;
1242 uint32_t PhaseCalTimeoutUs = 0;
1243 VL53L1_PresetModes PresetMode;
1244 uint32_t TimingGuard;
1245 uint32_t vhv;
1246 int32_t vhv_loops;
1247
1248 LOG_FUNCTION_START("");
1249
1250 *pMeasurementTimingBudgetMicroSeconds = 0;
1251
1252 if (Status == VL53L1_ERROR_NONE)
1253 Status = VL53L1_GetSequenceStepEnable(Dev,
1254 VL53L1_SEQUENCESTEP_MM1, &Mm1Enabled);
1255
1256 if (Status == VL53L1_ERROR_NONE)
1257 Status = VL53L1_GetSequenceStepEnable(Dev,
1258 VL53L1_SEQUENCESTEP_MM2, &Mm2Enabled);
1259
1260 if (Status == VL53L1_ERROR_NONE)
1261 Status = VL53L1_get_timeouts_us(Dev,
1262 &PhaseCalTimeoutUs,
1263 &MmTimeoutUs,
1264 &RangeTimeoutUs);
1265
1266 if (Status == VL53L1_ERROR_NONE) {
1267 PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
1268
1269 switch (PresetMode) {
1270 case VL53L1_PRESETMODE_LITE_RANGING:
1271 if ((Mm1Enabled == 1) || (Mm2Enabled == 1))
1272 MeasTimingBdg = RangeTimeoutUs + 5000;
1273 else
1274 MeasTimingBdg = RangeTimeoutUs + 1000;
1275
1276 break;
1277
1278 case VL53L1_PRESETMODE_AUTONOMOUS:
1279 if ((Mm1Enabled == 1) || (Mm2Enabled == 1))
1280 MeasTimingBdg = 2 * RangeTimeoutUs + 26600;
1281 else
1282 MeasTimingBdg = 2 * RangeTimeoutUs + 21600;
1283
1284 break;
1285
1286 case VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS:
1287 vhv = LOWPOWER_AUTO_VHV_LOOP_DURATION_US;
1288 VL53L1_get_tuning_parm(Dev,
1289 VL53L1_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND,
1290 &vhv_loops);
1291 if (vhv_loops > 0) {
1292 vhv += vhv_loops *
1293 LOWPOWER_AUTO_VHV_LOOP_DURATION_US;
1294 }
1295 TimingGuard = LOWPOWER_AUTO_OVERHEAD_BEFORE_A_RANGING +
1296 LOWPOWER_AUTO_OVERHEAD_BETWEEN_A_B_RANGING +
1297 vhv;
1298 MeasTimingBdg = 2 * RangeTimeoutUs + TimingGuard;
1299 break;
1300
1301 default:
1302 /* Unsupported mode */
1303 Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
1304 }
1305 }
1306 if (Status == VL53L1_ERROR_NONE)
1307 *pMeasurementTimingBudgetMicroSeconds = MeasTimingBdg;
1308
1309 LOG_FUNCTION_END(Status);
1310 return Status;
1311 }
1312
1313
1314
VL53L1_SetInterMeasurementPeriodMilliSeconds(VL53L1_DEV Dev,uint32_t InterMeasurementPeriodMilliSeconds)1315 VL53L1_Error VL53L1_SetInterMeasurementPeriodMilliSeconds(VL53L1_DEV Dev,
1316 uint32_t InterMeasurementPeriodMilliSeconds)
1317 {
1318 VL53L1_Error Status = VL53L1_ERROR_NONE;
1319 uint32_t adjustedIMP;
1320
1321 LOG_FUNCTION_START("");
1322
1323 /* Fix for Ticket 468205 actual measurement period shorter than set */
1324 adjustedIMP = InterMeasurementPeriodMilliSeconds;
1325 adjustedIMP += (adjustedIMP * 64) / 1000;
1326 /* End of fix for Ticket 468205 */
1327 Status = VL53L1_set_inter_measurement_period_ms(Dev,
1328 adjustedIMP);
1329
1330 LOG_FUNCTION_END(Status);
1331 return Status;
1332 }
1333
VL53L1_GetInterMeasurementPeriodMilliSeconds(VL53L1_DEV Dev,uint32_t * pInterMeasurementPeriodMilliSeconds)1334 VL53L1_Error VL53L1_GetInterMeasurementPeriodMilliSeconds(VL53L1_DEV Dev,
1335 uint32_t *pInterMeasurementPeriodMilliSeconds)
1336 {
1337 VL53L1_Error Status = VL53L1_ERROR_NONE;
1338 uint32_t adjustedIMP;
1339
1340 LOG_FUNCTION_START("");
1341
1342 Status = VL53L1_get_inter_measurement_period_ms(Dev, &adjustedIMP);
1343 /* Fix for Ticket 468205 actual measurement period shorter than set */
1344 adjustedIMP -= (adjustedIMP * 64) / 1000;
1345 *pInterMeasurementPeriodMilliSeconds = adjustedIMP;
1346 /* End of fix for Ticket 468205 */
1347
1348 LOG_FUNCTION_END(Status);
1349 return Status;
1350 }
1351
1352
1353 /* End Group PAL Parameters Functions */
1354
1355
1356 /* Group Limit check Functions */
1357
VL53L1_GetNumberOfLimitCheck(uint16_t * pNumberOfLimitCheck)1358 VL53L1_Error VL53L1_GetNumberOfLimitCheck(uint16_t *pNumberOfLimitCheck)
1359 {
1360 VL53L1_Error Status = VL53L1_ERROR_NONE;
1361
1362 LOG_FUNCTION_START("");
1363
1364 *pNumberOfLimitCheck = VL53L1_CHECKENABLE_NUMBER_OF_CHECKS;
1365
1366 LOG_FUNCTION_END(Status);
1367 return Status;
1368 }
1369
VL53L1_GetLimitCheckInfo(uint16_t LimitCheckId,char * pLimitCheckString)1370 VL53L1_Error VL53L1_GetLimitCheckInfo(uint16_t LimitCheckId,
1371 char *pLimitCheckString)
1372 {
1373 VL53L1_Error Status = VL53L1_ERROR_NONE;
1374
1375 LOG_FUNCTION_START("");
1376
1377 Status = VL53L1_get_limit_check_info(LimitCheckId,
1378 pLimitCheckString);
1379
1380 LOG_FUNCTION_END(Status);
1381 return Status;
1382 }
1383
VL53L1_GetLimitCheckStatus(VL53L1_DEV Dev,uint16_t LimitCheckId,uint8_t * pLimitCheckStatus)1384 VL53L1_Error VL53L1_GetLimitCheckStatus(VL53L1_DEV Dev, uint16_t LimitCheckId,
1385 uint8_t *pLimitCheckStatus)
1386 {
1387 VL53L1_Error Status = VL53L1_ERROR_NONE;
1388 uint8_t Temp8;
1389
1390 LOG_FUNCTION_START("");
1391
1392 if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
1393 Status = VL53L1_ERROR_INVALID_PARAMS;
1394 } else {
1395 VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
1396 LimitCheckId, Temp8);
1397 *pLimitCheckStatus = Temp8;
1398 }
1399
1400 LOG_FUNCTION_END(Status);
1401 return Status;
1402 }
1403
SetLimitValue(VL53L1_DEV Dev,uint16_t LimitCheckId,FixPoint1616_t value)1404 static VL53L1_Error SetLimitValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
1405 FixPoint1616_t value)
1406 {
1407 VL53L1_Error Status = VL53L1_ERROR_NONE;
1408 uint16_t tmpuint16; /* temporary variable */
1409
1410 LOG_FUNCTION_START("");
1411
1412 switch (LimitCheckId) {
1413 case VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE:
1414 tmpuint16 = VL53L1_FIXPOINT1616TOFIXPOINT142(value);
1415 VL53L1_set_lite_sigma_threshold(Dev, tmpuint16);
1416 break;
1417 case VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
1418 tmpuint16 = VL53L1_FIXPOINT1616TOFIXPOINT97(value);
1419 VL53L1_set_lite_min_count_rate(Dev, tmpuint16);
1420 break;
1421 default:
1422 Status = VL53L1_ERROR_INVALID_PARAMS;
1423 }
1424
1425 LOG_FUNCTION_END(Status);
1426 return Status;
1427 }
1428
1429
VL53L1_SetLimitCheckEnable(VL53L1_DEV Dev,uint16_t LimitCheckId,uint8_t LimitCheckEnable)1430 VL53L1_Error VL53L1_SetLimitCheckEnable(VL53L1_DEV Dev, uint16_t LimitCheckId,
1431 uint8_t LimitCheckEnable)
1432 {
1433 VL53L1_Error Status = VL53L1_ERROR_NONE;
1434 FixPoint1616_t TempFix1616 = 0;
1435
1436 LOG_FUNCTION_START("");
1437
1438
1439 if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
1440 Status = VL53L1_ERROR_INVALID_PARAMS;
1441 } else {
1442 /* TempFix1616 contains either 0 or the limit value */
1443 if (LimitCheckEnable == 0)
1444 TempFix1616 = 0;
1445 else
1446 VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1447 LimitCheckId, TempFix1616);
1448
1449 Status = SetLimitValue(Dev, LimitCheckId, TempFix1616);
1450 }
1451
1452 if (Status == VL53L1_ERROR_NONE)
1453 VL53L1_SETARRAYPARAMETERFIELD(Dev,
1454 LimitChecksEnable,
1455 LimitCheckId,
1456 ((LimitCheckEnable == 0) ? 0 : 1));
1457
1458
1459
1460 LOG_FUNCTION_END(Status);
1461 return Status;
1462 }
1463
VL53L1_GetLimitCheckEnable(VL53L1_DEV Dev,uint16_t LimitCheckId,uint8_t * pLimitCheckEnable)1464 VL53L1_Error VL53L1_GetLimitCheckEnable(VL53L1_DEV Dev, uint16_t LimitCheckId,
1465 uint8_t *pLimitCheckEnable)
1466 {
1467 VL53L1_Error Status = VL53L1_ERROR_NONE;
1468 uint8_t Temp8;
1469
1470 LOG_FUNCTION_START("");
1471
1472 if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
1473 Status = VL53L1_ERROR_INVALID_PARAMS;
1474 *pLimitCheckEnable = 0;
1475 } else {
1476 VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
1477 LimitCheckId, Temp8);
1478 *pLimitCheckEnable = Temp8;
1479 }
1480
1481
1482 LOG_FUNCTION_END(Status);
1483 return Status;
1484 }
1485
VL53L1_SetLimitCheckValue(VL53L1_DEV Dev,uint16_t LimitCheckId,FixPoint1616_t LimitCheckValue)1486 VL53L1_Error VL53L1_SetLimitCheckValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
1487 FixPoint1616_t LimitCheckValue)
1488 {
1489 VL53L1_Error Status = VL53L1_ERROR_NONE;
1490 uint8_t LimitChecksEnable;
1491
1492 LOG_FUNCTION_START("");
1493
1494 if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
1495 Status = VL53L1_ERROR_INVALID_PARAMS;
1496 } else {
1497
1498 VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
1499 LimitCheckId,
1500 LimitChecksEnable);
1501
1502 if (LimitChecksEnable == 0) {
1503 /* disabled write only internal value */
1504 VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1505 LimitCheckId, LimitCheckValue);
1506 } else {
1507
1508 Status = SetLimitValue(Dev, LimitCheckId,
1509 LimitCheckValue);
1510
1511 if (Status == VL53L1_ERROR_NONE) {
1512 VL53L1_SETARRAYPARAMETERFIELD(Dev,
1513 LimitChecksValue,
1514 LimitCheckId, LimitCheckValue);
1515 }
1516 }
1517 }
1518
1519 LOG_FUNCTION_END(Status);
1520 return Status;
1521 }
1522
VL53L1_GetLimitCheckValue(VL53L1_DEV Dev,uint16_t LimitCheckId,FixPoint1616_t * pLimitCheckValue)1523 VL53L1_Error VL53L1_GetLimitCheckValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
1524 FixPoint1616_t *pLimitCheckValue)
1525 {
1526 VL53L1_Error Status = VL53L1_ERROR_NONE;
1527 uint16_t MinCountRate;
1528 FixPoint1616_t TempFix1616;
1529 uint16_t SigmaThresh;
1530
1531 LOG_FUNCTION_START("");
1532
1533 switch (LimitCheckId) {
1534 case VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE:
1535 Status = VL53L1_get_lite_sigma_threshold(Dev, &SigmaThresh);
1536 TempFix1616 = VL53L1_FIXPOINT142TOFIXPOINT1616(SigmaThresh);
1537 break;
1538 case VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
1539 Status = VL53L1_get_lite_min_count_rate(Dev, &MinCountRate);
1540 TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(MinCountRate);
1541 break;
1542 default:
1543 Status = VL53L1_ERROR_INVALID_PARAMS;
1544 }
1545
1546 if (Status == VL53L1_ERROR_NONE) {
1547
1548 if (TempFix1616 == 0) {
1549 /* disabled: return value from memory */
1550 VL53L1_GETARRAYPARAMETERFIELD(Dev,
1551 LimitChecksValue, LimitCheckId,
1552 TempFix1616);
1553 *pLimitCheckValue = TempFix1616;
1554 VL53L1_SETARRAYPARAMETERFIELD(Dev,
1555 LimitChecksEnable, LimitCheckId, 0);
1556 } else {
1557 *pLimitCheckValue = TempFix1616;
1558 VL53L1_SETARRAYPARAMETERFIELD(Dev,
1559 LimitChecksValue, LimitCheckId,
1560 TempFix1616);
1561 VL53L1_SETARRAYPARAMETERFIELD(Dev,
1562 LimitChecksEnable, LimitCheckId, 1);
1563 }
1564 }
1565 LOG_FUNCTION_END(Status);
1566 return Status;
1567
1568 }
1569
VL53L1_GetLimitCheckCurrent(VL53L1_DEV Dev,uint16_t LimitCheckId,FixPoint1616_t * pLimitCheckCurrent)1570 VL53L1_Error VL53L1_GetLimitCheckCurrent(VL53L1_DEV Dev, uint16_t LimitCheckId,
1571 FixPoint1616_t *pLimitCheckCurrent)
1572 {
1573 VL53L1_Error Status = VL53L1_ERROR_NONE;
1574 FixPoint1616_t TempFix1616 = 0;
1575
1576 LOG_FUNCTION_START("");
1577
1578 if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
1579 Status = VL53L1_ERROR_INVALID_PARAMS;
1580 } else {
1581 VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksCurrent,
1582 LimitCheckId, TempFix1616);
1583 *pLimitCheckCurrent = TempFix1616;
1584 }
1585
1586 LOG_FUNCTION_END(Status);
1587 return Status;
1588
1589 }
1590
1591 /* End Group Limit check Functions */
1592
1593
1594
1595 /* Group ROI Functions */
1596
VL53L1_SetUserROI(VL53L1_DEV Dev,VL53L1_UserRoi_t * pRoi)1597 VL53L1_Error VL53L1_SetUserROI(VL53L1_DEV Dev,
1598 VL53L1_UserRoi_t *pRoi)
1599 {
1600 VL53L1_Error Status = VL53L1_ERROR_NONE;
1601 VL53L1_user_zone_t user_zone;
1602
1603 Status = CheckValidRectRoi(*pRoi);
1604 if (Status != VL53L1_ERROR_NONE)
1605 return VL53L1_ERROR_INVALID_PARAMS;
1606
1607 user_zone.x_centre = (pRoi->BotRightX + pRoi->TopLeftX + 1) / 2;
1608 user_zone.y_centre = (pRoi->TopLeftY + pRoi->BotRightY + 1) / 2;
1609 user_zone.width = (pRoi->BotRightX - pRoi->TopLeftX);
1610 user_zone.height = (pRoi->TopLeftY - pRoi->BotRightY);
1611 if ((user_zone.width < 3) || (user_zone.height < 3))
1612 Status = VL53L1_ERROR_INVALID_PARAMS;
1613 else
1614 Status = VL53L1_set_user_zone(Dev, &user_zone);
1615
1616 LOG_FUNCTION_END(Status);
1617 return Status;
1618 }
1619
VL53L1_GetUserROI(VL53L1_DEV Dev,VL53L1_UserRoi_t * pRoi)1620 VL53L1_Error VL53L1_GetUserROI(VL53L1_DEV Dev,
1621 VL53L1_UserRoi_t *pRoi)
1622 {
1623 VL53L1_Error Status = VL53L1_ERROR_NONE;
1624 VL53L1_user_zone_t user_zone;
1625
1626 Status = VL53L1_get_user_zone(Dev, &user_zone);
1627
1628 pRoi->TopLeftX = (2 * user_zone.x_centre - user_zone.width) >> 1;
1629 pRoi->TopLeftY = (2 * user_zone.y_centre + user_zone.height) >> 1;
1630 pRoi->BotRightX = (2 * user_zone.x_centre + user_zone.width) >> 1;
1631 pRoi->BotRightY = (2 * user_zone.y_centre - user_zone.height) >> 1;
1632
1633 LOG_FUNCTION_END(Status);
1634 return Status;
1635 }
1636
1637
1638
1639 /* End Group ROI Functions */
1640
1641
1642 /* Group Sequence Step Functions */
1643
VL53L1_GetNumberOfSequenceSteps(VL53L1_DEV Dev,uint8_t * pNumberOfSequenceSteps)1644 VL53L1_Error VL53L1_GetNumberOfSequenceSteps(VL53L1_DEV Dev,
1645 uint8_t *pNumberOfSequenceSteps)
1646 {
1647 VL53L1_Error Status = VL53L1_ERROR_NONE;
1648
1649 SUPPRESS_UNUSED_WARNING(Dev);
1650
1651 LOG_FUNCTION_START("");
1652
1653 *pNumberOfSequenceSteps = VL53L1_SEQUENCESTEP_NUMBER_OF_ITEMS;
1654
1655 LOG_FUNCTION_END(Status);
1656 return Status;
1657 }
1658
VL53L1_GetSequenceStepsInfo(VL53L1_SequenceStepId SequenceStepId,char * pSequenceStepsString)1659 VL53L1_Error VL53L1_GetSequenceStepsInfo(VL53L1_SequenceStepId SequenceStepId,
1660 char *pSequenceStepsString)
1661 {
1662 VL53L1_Error Status = VL53L1_ERROR_NONE;
1663
1664 LOG_FUNCTION_START("");
1665
1666 Status = VL53L1_get_sequence_steps_info(
1667 SequenceStepId,
1668 pSequenceStepsString);
1669
1670 LOG_FUNCTION_END(Status);
1671
1672 return Status;
1673 }
1674
VL53L1_SetSequenceStepEnable(VL53L1_DEV Dev,VL53L1_SequenceStepId SequenceStepId,uint8_t SequenceStepEnabled)1675 VL53L1_Error VL53L1_SetSequenceStepEnable(VL53L1_DEV Dev,
1676 VL53L1_SequenceStepId SequenceStepId, uint8_t SequenceStepEnabled)
1677 {
1678 VL53L1_Error Status = VL53L1_ERROR_NONE;
1679 uint32_t MeasurementTimingBudgetMicroSeconds;
1680
1681 LOG_FUNCTION_START("");
1682
1683 /* the VL53L1_SequenceStepId correspond to the LLD
1684 * VL53L1_DeviceSequenceConfig
1685 */
1686
1687 Status = VL53L1_set_sequence_config_bit(Dev,
1688 (VL53L1_DeviceSequenceConfig)SequenceStepId,
1689 SequenceStepEnabled);
1690
1691 /* Apply New Setting */
1692 if (Status == VL53L1_ERROR_NONE) {
1693
1694 /* Recalculate timing budget */
1695 MeasurementTimingBudgetMicroSeconds = VL53L1DevDataGet(Dev,
1696 CurrentParameters.MeasurementTimingBudgetMicroSeconds);
1697
1698 VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev,
1699 MeasurementTimingBudgetMicroSeconds);
1700 }
1701
1702 LOG_FUNCTION_END(Status);
1703
1704 return Status;
1705 }
1706
1707
VL53L1_GetSequenceStepEnable(VL53L1_DEV Dev,VL53L1_SequenceStepId SequenceStepId,uint8_t * pSequenceStepEnabled)1708 VL53L1_Error VL53L1_GetSequenceStepEnable(VL53L1_DEV Dev,
1709 VL53L1_SequenceStepId SequenceStepId, uint8_t *pSequenceStepEnabled)
1710 {
1711 VL53L1_Error Status = VL53L1_ERROR_NONE;
1712
1713 LOG_FUNCTION_START("");
1714
1715 Status = VL53L1_get_sequence_config_bit(Dev,
1716 (VL53L1_DeviceSequenceConfig)SequenceStepId,
1717 pSequenceStepEnabled);
1718
1719 LOG_FUNCTION_END(Status);
1720 return Status;
1721 }
1722
1723
1724 /* End Group Sequence Step Functions Functions */
1725
1726
1727
1728 /* Group PAL Measurement Functions */
1729
1730
1731
VL53L1_StartMeasurement(VL53L1_DEV Dev)1732 VL53L1_Error VL53L1_StartMeasurement(VL53L1_DEV Dev)
1733 {
1734 #define TIMED_MODE_TIMING_GUARD_MILLISECONDS 4
1735 VL53L1_Error Status = VL53L1_ERROR_NONE;
1736 uint8_t DeviceMeasurementMode;
1737 VL53L1_State CurrPalState;
1738 VL53L1_Error lStatus;
1739 uint32_t MTBus, IMPms;
1740
1741 LOG_FUNCTION_START("");
1742
1743 CurrPalState = VL53L1DevDataGet(Dev, PalState);
1744 switch (CurrPalState) {
1745 case VL53L1_STATE_IDLE:
1746 Status = VL53L1_ERROR_NONE;
1747 break;
1748 case VL53L1_STATE_POWERDOWN:
1749 case VL53L1_STATE_WAIT_STATICINIT:
1750 case VL53L1_STATE_STANDBY:
1751 case VL53L1_STATE_RUNNING:
1752 case VL53L1_STATE_RESET:
1753 case VL53L1_STATE_UNKNOWN:
1754 case VL53L1_STATE_ERROR:
1755 Status = VL53L1_ERROR_INVALID_COMMAND;
1756 break;
1757 default:
1758 Status = VL53L1_ERROR_UNDEFINED;
1759 }
1760
1761 DeviceMeasurementMode = VL53L1DevDataGet(Dev, LLData.measurement_mode);
1762
1763 /* Check timing configuration between timing budget and
1764 * inter measurement period */
1765 if ((Status == VL53L1_ERROR_NONE) &&
1766 (DeviceMeasurementMode == VL53L1_DEVICEMEASUREMENTMODE_TIMED)) {
1767 lStatus = VL53L1_GetMeasurementTimingBudgetMicroSeconds(Dev,
1768 &MTBus);
1769 /* convert timing budget in ms */
1770 MTBus /= 1000;
1771 lStatus = VL53L1_GetInterMeasurementPeriodMilliSeconds(Dev,
1772 &IMPms);
1773 /* trick to get rid of compiler "set but not used" warning */
1774 SUPPRESS_UNUSED_WARNING(lStatus);
1775 if (IMPms < MTBus + TIMED_MODE_TIMING_GUARD_MILLISECONDS)
1776 Status = VL53L1_ERROR_INVALID_PARAMS;
1777 }
1778
1779 if (Status == VL53L1_ERROR_NONE)
1780 Status = VL53L1_init_and_start_range(
1781 Dev,
1782 DeviceMeasurementMode,
1783 VL53L1_DEVICECONFIGLEVEL_FULL);
1784
1785 /* Set PAL State to Running */
1786 if (Status == VL53L1_ERROR_NONE)
1787 VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_RUNNING);
1788
1789
1790 LOG_FUNCTION_END(Status);
1791 return Status;
1792 }
1793
VL53L1_StopMeasurement(VL53L1_DEV Dev)1794 VL53L1_Error VL53L1_StopMeasurement(VL53L1_DEV Dev)
1795 {
1796 VL53L1_Error Status = VL53L1_ERROR_NONE;
1797
1798 LOG_FUNCTION_START("");
1799
1800 Status = VL53L1_stop_range(Dev);
1801
1802 /* Set PAL State to Idle */
1803 if (Status == VL53L1_ERROR_NONE)
1804 VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_IDLE);
1805
1806 LOG_FUNCTION_END(Status);
1807 return Status;
1808 }
1809
ChangePresetMode(VL53L1_DEV Dev)1810 static VL53L1_Error ChangePresetMode(VL53L1_DEV Dev)
1811 {
1812 VL53L1_Error Status = VL53L1_ERROR_NONE;
1813 VL53L1_PresetModes PresetMode;
1814 VL53L1_DistanceModes NewDistanceMode;
1815 VL53L1_user_zone_t user_zone;
1816 uint32_t TimingBudget;
1817 uint32_t MmTimeoutUs;
1818 uint32_t PhaseCalTimeoutUs;
1819 uint8_t DeviceMeasurementMode;
1820 uint32_t inter_measurement_period_ms;
1821
1822 LOG_FUNCTION_START("");
1823
1824 Status = VL53L1_get_user_zone(Dev, &user_zone);
1825 /* Initialize variables fix ticket EwokP #475395 */
1826 PresetMode = VL53L1DevDataGet(Dev,
1827 CurrentParameters.PresetMode);
1828 NewDistanceMode = VL53L1DevDataGet(Dev,
1829 CurrentParameters.NewDistanceMode);
1830 /* End of Initialize variables fix ticket EwokP #475395 */
1831 if (Status == VL53L1_ERROR_NONE)
1832 Status = VL53L1_get_timeouts_us(Dev, &PhaseCalTimeoutUs,
1833 &MmTimeoutUs, &TimingBudget);
1834
1835 if (Status == VL53L1_ERROR_NONE)
1836 Status = VL53L1_stop_range(Dev);
1837
1838 if (Status == VL53L1_ERROR_NONE)
1839 Status = VL53L1_WaitUs(Dev, 500);
1840
1841 if (Status == VL53L1_ERROR_NONE) {
1842 inter_measurement_period_ms = VL53L1DevDataGet(Dev,
1843 LLData.inter_measurement_period_ms);
1844
1845 Status = SetPresetMode(Dev,
1846 PresetMode,
1847 NewDistanceMode,
1848 inter_measurement_period_ms);
1849 }
1850
1851 if (Status == VL53L1_ERROR_NONE) {
1852 Status = VL53L1_set_timeouts_us(Dev, PhaseCalTimeoutUs,
1853 MmTimeoutUs, TimingBudget);
1854
1855 if (Status == VL53L1_ERROR_NONE)
1856 VL53L1DevDataSet(Dev, LLData.range_config_timeout_us,
1857 TimingBudget);
1858 }
1859
1860 if (Status == VL53L1_ERROR_NONE)
1861 Status = VL53L1_set_user_zone(Dev, &user_zone);
1862
1863 if (Status == VL53L1_ERROR_NONE) {
1864 DeviceMeasurementMode = VL53L1DevDataGet(Dev,
1865 LLData.measurement_mode);
1866
1867 Status = VL53L1_init_and_start_range(
1868 Dev,
1869 DeviceMeasurementMode,
1870 VL53L1_DEVICECONFIGLEVEL_FULL);
1871 }
1872
1873 if (Status == VL53L1_ERROR_NONE)
1874 VL53L1DevDataSet(Dev,
1875 CurrentParameters.InternalDistanceMode,
1876 NewDistanceMode);
1877
1878 LOG_FUNCTION_END(Status);
1879 return Status;
1880 }
1881
1882
VL53L1_ClearInterruptAndStartMeasurement(VL53L1_DEV Dev)1883 VL53L1_Error VL53L1_ClearInterruptAndStartMeasurement(VL53L1_DEV Dev)
1884 {
1885 VL53L1_Error Status = VL53L1_ERROR_NONE;
1886 uint8_t DeviceMeasurementMode;
1887 VL53L1_DistanceModes InternalDistanceMode;
1888 VL53L1_DistanceModes NewDistanceMode;
1889
1890 LOG_FUNCTION_START("");
1891
1892 DeviceMeasurementMode = VL53L1DevDataGet(Dev, LLData.measurement_mode);
1893 InternalDistanceMode = VL53L1DevDataGet(Dev,
1894 CurrentParameters.InternalDistanceMode);
1895 NewDistanceMode = VL53L1DevDataGet(Dev,
1896 CurrentParameters.NewDistanceMode);
1897
1898 if (NewDistanceMode != InternalDistanceMode)
1899 Status = ChangePresetMode(Dev);
1900 else
1901 Status = VL53L1_clear_interrupt_and_enable_next_range(
1902 Dev,
1903 DeviceMeasurementMode);
1904
1905 LOG_FUNCTION_END(Status);
1906 return Status;
1907 }
1908
1909
VL53L1_GetMeasurementDataReady(VL53L1_DEV Dev,uint8_t * pMeasurementDataReady)1910 VL53L1_Error VL53L1_GetMeasurementDataReady(VL53L1_DEV Dev,
1911 uint8_t *pMeasurementDataReady)
1912 {
1913 VL53L1_Error Status = VL53L1_ERROR_NONE;
1914
1915 LOG_FUNCTION_START("");
1916
1917 Status = VL53L1_is_new_data_ready(Dev, pMeasurementDataReady);
1918
1919 LOG_FUNCTION_END(Status);
1920 return Status;
1921 }
1922
VL53L1_WaitMeasurementDataReady(VL53L1_DEV Dev)1923 VL53L1_Error VL53L1_WaitMeasurementDataReady(VL53L1_DEV Dev)
1924 {
1925 VL53L1_Error Status = VL53L1_ERROR_NONE;
1926
1927 LOG_FUNCTION_START("");
1928
1929 /* Note that the timeout is given by:
1930 * VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS defined in def.h
1931 */
1932
1933 Status = VL53L1_poll_for_range_completion(Dev,
1934 VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
1935
1936 LOG_FUNCTION_END(Status);
1937 return Status;
1938 }
1939
1940
1941
ComputeRQL(uint8_t active_results,uint8_t FilteredRangeStatus,VL53L1_range_data_t * presults_data)1942 static uint8_t ComputeRQL(uint8_t active_results,
1943 uint8_t FilteredRangeStatus,
1944 VL53L1_range_data_t *presults_data)
1945 {
1946 int16_t SRL = 300;
1947 uint16_t SRAS = 30;
1948 FixPoint1616_t RAS;
1949 FixPoint1616_t SRQL;
1950 FixPoint1616_t GI = 7713587; /* 117.7 * 65536 */
1951 FixPoint1616_t GGm = 3198157; /* 48.8 * 65536 */
1952 FixPoint1616_t LRAP = 6554; /* 0.1 * 65536 */
1953 FixPoint1616_t partial;
1954 uint8_t finalvalue;
1955 uint8_t returnvalue;
1956
1957 if (active_results == 0)
1958 returnvalue = 0;
1959 else if (FilteredRangeStatus == VL53L1_DEVICEERROR_PHASECONSISTENCY)
1960 returnvalue = 50;
1961 else {
1962 if (presults_data->median_range_mm < SRL)
1963 RAS = SRAS * 65536;
1964 else
1965 RAS = LRAP * presults_data->median_range_mm;
1966
1967 /* Fix1616 + (fix1616 * uint16_t / fix1616) * 65536 = fix1616 */
1968 if (RAS != 0) {
1969 partial = (GGm * presults_data->sigma_mm);
1970 partial = partial + (RAS >> 1);
1971 partial = partial / RAS;
1972 partial = partial * 65536;
1973 if (partial <= GI)
1974 SRQL = GI - partial;
1975 else
1976 SRQL = 50 * 65536;
1977 } else
1978 SRQL = 100 * 65536;
1979
1980 finalvalue = (uint8_t)(SRQL >> 16);
1981 returnvalue = MAX(50, MIN(100, finalvalue));
1982 }
1983
1984 return returnvalue;
1985 }
1986
1987
ConvertStatusLite(uint8_t FilteredRangeStatus)1988 static uint8_t ConvertStatusLite(uint8_t FilteredRangeStatus)
1989 {
1990 uint8_t RangeStatus;
1991
1992 switch (FilteredRangeStatus) {
1993 case VL53L1_DEVICEERROR_GPHSTREAMCOUNT0READY:
1994 RangeStatus = VL53L1_RANGESTATUS_SYNCRONISATION_INT;
1995 break;
1996 case VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK:
1997 RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL;
1998 break;
1999 case VL53L1_DEVICEERROR_RANGEPHASECHECK:
2000 RangeStatus = VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL;
2001 break;
2002 case VL53L1_DEVICEERROR_MSRCNOTARGET:
2003 RangeStatus = VL53L1_RANGESTATUS_SIGNAL_FAIL;
2004 break;
2005 case VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK:
2006 RangeStatus = VL53L1_RANGESTATUS_SIGMA_FAIL;
2007 break;
2008 case VL53L1_DEVICEERROR_PHASECONSISTENCY:
2009 RangeStatus = VL53L1_RANGESTATUS_WRAP_TARGET_FAIL;
2010 break;
2011 case VL53L1_DEVICEERROR_RANGEIGNORETHRESHOLD:
2012 RangeStatus = VL53L1_RANGESTATUS_XTALK_SIGNAL_FAIL;
2013 break;
2014 case VL53L1_DEVICEERROR_MINCLIP:
2015 RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_MIN_RANGE_CLIPPED;
2016 break;
2017 case VL53L1_DEVICEERROR_RANGECOMPLETE:
2018 RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID;
2019 break;
2020 default:
2021 RangeStatus = VL53L1_RANGESTATUS_NONE;
2022 }
2023
2024 return RangeStatus;
2025 }
2026
2027
2028
SetSimpleData(VL53L1_DEV Dev,uint8_t active_results,uint8_t device_status,VL53L1_range_data_t * presults_data,VL53L1_RangingMeasurementData_t * pRangeData)2029 static VL53L1_Error SetSimpleData(VL53L1_DEV Dev,
2030 uint8_t active_results, uint8_t device_status,
2031 VL53L1_range_data_t *presults_data,
2032 VL53L1_RangingMeasurementData_t *pRangeData)
2033 {
2034 VL53L1_Error Status = VL53L1_ERROR_NONE;
2035 uint8_t FilteredRangeStatus;
2036 uint8_t SigmaLimitflag;
2037 uint8_t SignalLimitflag;
2038 uint8_t Temp8Enable;
2039 uint8_t Temp8;
2040 FixPoint1616_t AmbientRate;
2041 FixPoint1616_t SignalRate;
2042 FixPoint1616_t TempFix1616;
2043 FixPoint1616_t LimitCheckValue;
2044 int16_t Range;
2045
2046 pRangeData->TimeStamp = presults_data->time_stamp;
2047
2048 FilteredRangeStatus = presults_data->range_status & 0x1F;
2049
2050 pRangeData->RangeQualityLevel = ComputeRQL(active_results,
2051 FilteredRangeStatus,
2052 presults_data);
2053
2054 SignalRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
2055 presults_data->peak_signal_count_rate_mcps);
2056 pRangeData->SignalRateRtnMegaCps
2057 = SignalRate;
2058
2059 AmbientRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
2060 presults_data->ambient_count_rate_mcps);
2061 pRangeData->AmbientRateRtnMegaCps = AmbientRate;
2062
2063 pRangeData->EffectiveSpadRtnCount =
2064 presults_data->actual_effective_spads;
2065
2066 TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
2067 presults_data->sigma_mm);
2068
2069 pRangeData->SigmaMilliMeter = TempFix1616;
2070
2071 pRangeData->RangeMilliMeter = presults_data->median_range_mm;
2072
2073 pRangeData->RangeFractionalPart = 0;
2074
2075 /* Treat device error status first */
2076 switch (device_status) {
2077 case VL53L1_DEVICEERROR_MULTCLIPFAIL:
2078 case VL53L1_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
2079 case VL53L1_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
2080 case VL53L1_DEVICEERROR_NOVHVVALUEFOUND:
2081 pRangeData->RangeStatus = VL53L1_RANGESTATUS_HARDWARE_FAIL;
2082 break;
2083 case VL53L1_DEVICEERROR_USERROICLIP:
2084 pRangeData->RangeStatus = VL53L1_RANGESTATUS_MIN_RANGE_FAIL;
2085 break;
2086 default:
2087 pRangeData->RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID;
2088 }
2089
2090 /* Now deal with range status according to the ranging preset */
2091 if (pRangeData->RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID) {
2092 pRangeData->RangeStatus =
2093 ConvertStatusLite(FilteredRangeStatus);
2094 }
2095
2096 /* Update current Limit Check */
2097 TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
2098 presults_data->sigma_mm);
2099 VL53L1_SETARRAYPARAMETERFIELD(Dev,
2100 LimitChecksCurrent, VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
2101 TempFix1616);
2102
2103 TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
2104 presults_data->peak_signal_count_rate_mcps);
2105 VL53L1_SETARRAYPARAMETERFIELD(Dev,
2106 LimitChecksCurrent, VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
2107 TempFix1616);
2108
2109 /* Update Limit Check Status */
2110 /* Sigma */
2111 VL53L1_GetLimitCheckValue(Dev,
2112 VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
2113 &LimitCheckValue);
2114
2115 SigmaLimitflag = (FilteredRangeStatus ==
2116 VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK)
2117 ? 1 : 0;
2118
2119 VL53L1_GetLimitCheckEnable(Dev,
2120 VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
2121 &Temp8Enable);
2122
2123 Temp8 = ((Temp8Enable == 1) && (SigmaLimitflag == 1)) ? 1 : 0;
2124 VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
2125 VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE, Temp8);
2126
2127 /* Signal Rate */
2128 VL53L1_GetLimitCheckValue(Dev,
2129 VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
2130 &LimitCheckValue);
2131
2132 SignalLimitflag = (FilteredRangeStatus ==
2133 VL53L1_DEVICEERROR_MSRCNOTARGET)
2134 ? 1 : 0;
2135
2136 VL53L1_GetLimitCheckEnable(Dev,
2137 VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
2138 &Temp8Enable);
2139
2140 Temp8 = ((Temp8Enable == 1) && (SignalLimitflag == 1)) ? 1 : 0;
2141 VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
2142 VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, Temp8);
2143
2144 Range = pRangeData->RangeMilliMeter;
2145 if ((pRangeData->RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID) &&
2146 (Range < 0)) {
2147 if (Range < BDTable[VL53L1_TUNING_PROXY_MIN])
2148 pRangeData->RangeStatus =
2149 VL53L1_RANGESTATUS_RANGE_INVALID;
2150 else
2151 pRangeData->RangeMilliMeter = 0;
2152 }
2153
2154 return Status;
2155 }
2156
2157
2158
VL53L1_GetRangingMeasurementData(VL53L1_DEV Dev,VL53L1_RangingMeasurementData_t * pRangingMeasurementData)2159 VL53L1_Error VL53L1_GetRangingMeasurementData(VL53L1_DEV Dev,
2160 VL53L1_RangingMeasurementData_t *pRangingMeasurementData)
2161 {
2162 VL53L1_Error Status = VL53L1_ERROR_NONE;
2163 VL53L1_range_results_t results;
2164 VL53L1_range_results_t *presults = &results;
2165 VL53L1_range_data_t *presults_data;
2166
2167 LOG_FUNCTION_START("");
2168
2169
2170 /* Clear Ranging Data */
2171 memset(pRangingMeasurementData, 0xFF,
2172 sizeof(VL53L1_RangingMeasurementData_t));
2173
2174 /* Get Ranging Data */
2175 Status = VL53L1_get_device_results(
2176 Dev,
2177 VL53L1_DEVICERESULTSLEVEL_FULL,
2178 presults);
2179
2180 if (Status == VL53L1_ERROR_NONE) {
2181 pRangingMeasurementData->StreamCount = presults->stream_count;
2182
2183 /* in case of lite ranging or autonomous the following function
2184 * returns index = 0
2185 */
2186 presults_data = &(presults->data[0]);
2187 Status = SetSimpleData(Dev, 1,
2188 presults->device_status,
2189 presults_data,
2190 pRangingMeasurementData);
2191 }
2192
2193 LOG_FUNCTION_END(Status);
2194 return Status;
2195 }
2196
2197
2198
2199
2200
2201 /* End Group PAL Measurement Functions */
2202
2203
2204 /* Group Calibration functions */
VL53L1_SetTuningParameter(VL53L1_DEV Dev,uint16_t TuningParameterId,int32_t TuningParameterValue)2205 VL53L1_Error VL53L1_SetTuningParameter(VL53L1_DEV Dev,
2206 uint16_t TuningParameterId, int32_t TuningParameterValue)
2207 {
2208 VL53L1_Error Status = VL53L1_ERROR_NONE;
2209
2210 LOG_FUNCTION_START("");
2211 if (TuningParameterId >= 32768)
2212 Status = VL53L1_set_tuning_parm(Dev,
2213 TuningParameterId,
2214 TuningParameterValue);
2215 else {
2216 if (TuningParameterId < VL53L1_TUNING_MAX_TUNABLE_KEY)
2217 BDTable[TuningParameterId] = TuningParameterValue;
2218 else
2219 Status = VL53L1_ERROR_INVALID_PARAMS;
2220 }
2221
2222 LOG_FUNCTION_END(Status);
2223 return Status;
2224 }
2225
VL53L1_GetTuningParameter(VL53L1_DEV Dev,uint16_t TuningParameterId,int32_t * pTuningParameterValue)2226 VL53L1_Error VL53L1_GetTuningParameter(VL53L1_DEV Dev,
2227 uint16_t TuningParameterId, int32_t *pTuningParameterValue)
2228 {
2229 VL53L1_Error Status = VL53L1_ERROR_NONE;
2230
2231 LOG_FUNCTION_START("");
2232
2233 if (TuningParameterId >= 32768)
2234 Status = VL53L1_get_tuning_parm(Dev,
2235 TuningParameterId,
2236 pTuningParameterValue);
2237 else {
2238 if (TuningParameterId < VL53L1_TUNING_MAX_TUNABLE_KEY)
2239 *pTuningParameterValue = BDTable[TuningParameterId];
2240 else
2241 Status = VL53L1_ERROR_INVALID_PARAMS;
2242 }
2243
2244 LOG_FUNCTION_END(Status);
2245 return Status;
2246 }
2247
2248
VL53L1_PerformRefSpadManagement(VL53L1_DEV Dev)2249 VL53L1_Error VL53L1_PerformRefSpadManagement(VL53L1_DEV Dev)
2250 {
2251 #ifdef VL53L1_NOCALIB
2252 VL53L1_Error Status = VL53L1_ERROR_NOT_SUPPORTED;
2253
2254 SUPPRESS_UNUSED_WARNING(Dev);
2255
2256 LOG_FUNCTION_START("");
2257 #else
2258 VL53L1_Error Status = VL53L1_ERROR_NONE;
2259 VL53L1_Error RawStatus;
2260 uint8_t dcrbuffer[24];
2261 uint8_t *comms_buffer;
2262 uint8_t numloc[2] = {5,3};
2263 VL53L1_LLDriverData_t *pdev;
2264 VL53L1_customer_nvm_managed_t *pc;
2265 VL53L1_PresetModes PresetMode;
2266
2267 LOG_FUNCTION_START("");
2268
2269 pdev = VL53L1DevStructGetLLDriverHandle(Dev);
2270 pc = &pdev->customer;
2271
2272 if (Status == VL53L1_ERROR_NONE)
2273 {
2274 PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
2275 Status = VL53L1_run_ref_spad_char(Dev, &RawStatus);
2276 /* We discovered RefSpad mngt badly breaks some preset mode
2277 * The WA is to apply again the current one
2278 */
2279 if (Status == VL53L1_ERROR_NONE)
2280 Status = VL53L1_SetPresetMode(Dev, PresetMode);
2281 }
2282
2283 if (Status == VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH) {
2284 /* Fix ticket #466282 RefSpad management error/warning -29
2285 * force usage of location 3 and 5 refspads in registers
2286 */
2287 Status = VL53L1_read_nvm_raw_data(Dev,
2288 (uint8_t)(0xA0 >> 2),
2289 (uint8_t)(24 >> 2),
2290 dcrbuffer);
2291
2292 if (Status == VL53L1_ERROR_NONE)
2293 Status = VL53L1_WriteMulti( Dev,
2294 VL53L1_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS,
2295 numloc, 2);
2296
2297 if (Status == VL53L1_ERROR_NONE) {
2298 pc->ref_spad_man__num_requested_ref_spads = numloc[0];
2299 pc->ref_spad_man__ref_location = numloc[1];
2300 }
2301
2302 if (Status == VL53L1_ERROR_NONE)
2303 comms_buffer = &dcrbuffer[16];
2304
2305 /*
2306 * update & copy reference SPAD enables to customer nvm managed
2307 */
2308
2309 if (Status == VL53L1_ERROR_NONE)
2310 Status = VL53L1_WriteMulti(Dev,
2311 VL53L1_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
2312 comms_buffer, 6);
2313
2314 if (Status == VL53L1_ERROR_NONE) {
2315 pc->global_config__spad_enables_ref_0 = comms_buffer[0];
2316 pc->global_config__spad_enables_ref_1 = comms_buffer[1];
2317 pc->global_config__spad_enables_ref_2 = comms_buffer[2];
2318 pc->global_config__spad_enables_ref_3 = comms_buffer[3];
2319 pc->global_config__spad_enables_ref_4 = comms_buffer[4];
2320 pc->global_config__spad_enables_ref_5 = comms_buffer[5];
2321 }
2322 /* End of fix ticket #466282 */
2323 }
2324
2325 #endif
2326
2327 LOG_FUNCTION_END(Status);
2328 return Status;
2329 }
2330
2331
VL53L1_SetXTalkCompensationEnable(VL53L1_DEV Dev,uint8_t XTalkCompensationEnable)2332 VL53L1_Error VL53L1_SetXTalkCompensationEnable(VL53L1_DEV Dev,
2333 uint8_t XTalkCompensationEnable)
2334 {
2335 VL53L1_Error Status = VL53L1_ERROR_NONE;
2336
2337 LOG_FUNCTION_START("");
2338
2339 if (XTalkCompensationEnable == 0)
2340 Status = VL53L1_disable_xtalk_compensation(Dev);
2341 else
2342 Status = VL53L1_enable_xtalk_compensation(Dev);
2343
2344 LOG_FUNCTION_END(Status);
2345 return Status;
2346 }
2347
2348
VL53L1_GetXTalkCompensationEnable(VL53L1_DEV Dev,uint8_t * pXTalkCompensationEnable)2349 VL53L1_Error VL53L1_GetXTalkCompensationEnable(VL53L1_DEV Dev,
2350 uint8_t *pXTalkCompensationEnable)
2351 {
2352 VL53L1_Error Status = VL53L1_ERROR_NONE;
2353
2354 LOG_FUNCTION_START("");
2355
2356 VL53L1_get_xtalk_compensation_enable(
2357 Dev,
2358 pXTalkCompensationEnable);
2359
2360 LOG_FUNCTION_END(Status);
2361 return Status;
2362 }
2363
VL53L1_PerformSingleTargetXTalkCalibration(VL53L1_DEV Dev,int32_t CalDistanceMilliMeter)2364 VL53L1_Error VL53L1_PerformSingleTargetXTalkCalibration(VL53L1_DEV Dev,
2365 int32_t CalDistanceMilliMeter)
2366 {
2367 VL53L1_Error Status = VL53L1_ERROR_NONE;
2368
2369 LOG_FUNCTION_START("");
2370
2371 if (CalDistanceMilliMeter > 0) {
2372 BDTable[VL53L1_TUNING_SINGLE_TARGET_XTALK_TARGET_DISTANCE_MM] =
2373 CalDistanceMilliMeter;
2374 Status = SingleTargetXTalkCalibration(Dev);
2375 } else
2376 Status = VL53L1_ERROR_INVALID_PARAMS;
2377
2378 LOG_FUNCTION_END(Status);
2379 return Status;
2380 }
2381
2382
VL53L1_SetOffsetCalibrationMode(VL53L1_DEV Dev,VL53L1_OffsetCalibrationModes OffsetCalibrationMode)2383 VL53L1_Error VL53L1_SetOffsetCalibrationMode(VL53L1_DEV Dev,
2384 VL53L1_OffsetCalibrationModes OffsetCalibrationMode)
2385 {
2386 VL53L1_Error Status = VL53L1_ERROR_NONE;
2387 VL53L1_OffsetCalibrationMode offset_cal_mode;
2388
2389 LOG_FUNCTION_START("");
2390
2391 if (OffsetCalibrationMode == VL53L1_OFFSETCALIBRATIONMODE_STANDARD) {
2392 offset_cal_mode = VL53L1_DEVICEPRESETMODE_STANDARD_RANGING;
2393 } else if (OffsetCalibrationMode ==
2394 VL53L1_OFFSETCALIBRATIONMODE_PRERANGE_ONLY) {
2395 offset_cal_mode =
2396 VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY;
2397 } else {
2398 Status = VL53L1_ERROR_INVALID_PARAMS;
2399 }
2400
2401 if (Status == VL53L1_ERROR_NONE)
2402 Status = VL53L1_set_offset_calibration_mode(Dev,
2403 offset_cal_mode);
2404
2405 LOG_FUNCTION_END(Status);
2406 return Status;
2407 }
2408
2409
2410 #ifdef OFFSET_CALIB
VL53L1_PerformOffsetCalibration(VL53L1_DEV Dev,int32_t CalDistanceMilliMeter)2411 VL53L1_Error VL53L1_PerformOffsetCalibration(VL53L1_DEV Dev,
2412 int32_t CalDistanceMilliMeter)
2413 {
2414 VL53L1_Error Status = VL53L1_ERROR_NONE;
2415 VL53L1_Error UnfilteredStatus;
2416 VL53L1_OffsetCalibrationMode offset_cal_mode;
2417
2418 LOG_FUNCTION_START("");
2419
2420 if (Status == VL53L1_ERROR_NONE)
2421 Status = VL53L1_get_offset_calibration_mode(Dev,
2422 &offset_cal_mode);
2423
2424 if (Status != VL53L1_ERROR_NONE) {
2425 LOG_FUNCTION_END(Status);
2426 return Status;
2427 }
2428
2429 if ((offset_cal_mode ==
2430 VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD) ||
2431 (offset_cal_mode ==
2432 VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY
2433 )) {
2434 if (Status == VL53L1_ERROR_NONE)
2435 Status = VL53L1_run_offset_calibration(
2436 Dev,
2437 (int16_t)CalDistanceMilliMeter,
2438 &UnfilteredStatus);
2439 } else {
2440 Status = VL53L1_ERROR_INVALID_PARAMS;
2441 }
2442 LOG_FUNCTION_END(Status);
2443 return Status;
2444 }
2445 #endif
2446 #ifdef OFFSET_CALIB_EMPTY
VL53L1_PerformOffsetCalibration(VL53L1_DEV Dev,int32_t CalDistanceMilliMeter)2447 VL53L1_Error VL53L1_PerformOffsetCalibration(VL53L1_DEV Dev,
2448 int32_t CalDistanceMilliMeter)
2449 {
2450 VL53L1_Error Status = VL53L1_ERROR_NOT_SUPPORTED;
2451 SUPPRESS_UNUSED_WARNING(Dev);
2452 SUPPRESS_UNUSED_WARNING(CalDistanceMilliMeter);
2453 return Status;
2454 }
2455 #endif
2456
VL53L1_PerformOffsetSimpleCalibration(VL53L1_DEV Dev,int32_t CalDistanceMilliMeter)2457 VL53L1_Error VL53L1_PerformOffsetSimpleCalibration(VL53L1_DEV Dev,
2458 int32_t CalDistanceMilliMeter)
2459 {
2460 VL53L1_Error Status = VL53L1_ERROR_NONE;
2461 int32_t sum_ranging;
2462 uint8_t offset_meas;
2463 int16_t Max, UnderMax, OverMax, Repeat;
2464 int32_t total_count, inloopcount;
2465 int32_t IncRounding;
2466 int16_t meanDistance_mm;
2467 int16_t offset;
2468 VL53L1_RangingMeasurementData_t RangingMeasurementData;
2469 VL53L1_LLDriverData_t *pdev;
2470 uint8_t goodmeas;
2471
2472 LOG_FUNCTION_START("");
2473
2474 pdev = VL53L1DevStructGetLLDriverHandle(Dev);
2475 /* Disable any offsets */
2476 pdev->customer.algo__part_to_part_range_offset_mm = 0;
2477 pdev->customer.mm_config__inner_offset_mm = 0;
2478 pdev->customer.mm_config__outer_offset_mm = 0;
2479
2480 Repeat=BDTable[VL53L1_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
2481 Max=BDTable[VL53L1_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
2482 UnderMax = 1 + (Max / 2);
2483 OverMax = Max + (Max / 2);
2484 sum_ranging = 0;
2485 total_count = 0;
2486
2487 while ((Repeat > 0) && (Status == VL53L1_ERROR_NONE)) {
2488 Status = VL53L1_StartMeasurement(Dev);
2489 /* Very first ranging completion interrupt must be ignored */
2490 if (Status == VL53L1_ERROR_NONE)
2491 Status = VL53L1_WaitMeasurementDataReady(Dev);
2492 if (Status == VL53L1_ERROR_NONE)
2493 Status = VL53L1_GetRangingMeasurementData(Dev,
2494 &RangingMeasurementData);
2495 if (Status == VL53L1_ERROR_NONE)
2496 Status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
2497 /* offset calibration main loop */
2498 inloopcount = 0;
2499 offset_meas = 0;
2500 while ((Status == VL53L1_ERROR_NONE) && (inloopcount < Max) &&
2501 (offset_meas < OverMax)) {
2502 Status = VL53L1_WaitMeasurementDataReady(Dev);
2503 if (Status == VL53L1_ERROR_NONE)
2504 Status = VL53L1_GetRangingMeasurementData(Dev,
2505 &RangingMeasurementData);
2506 goodmeas = (RangingMeasurementData.RangeStatus ==
2507 VL53L1_RANGESTATUS_RANGE_VALID);
2508 if ((Status == VL53L1_ERROR_NONE) && goodmeas) {
2509 sum_ranging = sum_ranging +
2510 RangingMeasurementData.RangeMilliMeter;
2511 inloopcount++;
2512 }
2513 if (Status == VL53L1_ERROR_NONE) {
2514 Status = VL53L1_ClearInterruptAndStartMeasurement(
2515 Dev);
2516 }
2517 offset_meas++;
2518 }
2519 total_count += inloopcount;
2520
2521 /* no enough valid values found */
2522 if (inloopcount < UnderMax) {
2523 Status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
2524 }
2525
2526 VL53L1_StopMeasurement(Dev);
2527
2528 Repeat--;
2529
2530 }
2531 /* check overflow (unlikely if target is near to the device) */
2532 if ((sum_ranging < 0) ||
2533 (sum_ranging > ((int32_t) total_count * 0xffff))) {
2534 Status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
2535 }
2536
2537 if ((Status == VL53L1_ERROR_NONE) && (total_count > 0)) {
2538 IncRounding = total_count / 2;
2539 meanDistance_mm = (int16_t)((sum_ranging + IncRounding)
2540 / total_count);
2541 offset = (int16_t)CalDistanceMilliMeter - meanDistance_mm;
2542 pdev->customer.algo__part_to_part_range_offset_mm = 0;
2543 pdev->customer.mm_config__inner_offset_mm = offset;
2544 pdev->customer.mm_config__outer_offset_mm = offset;
2545
2546 Status = VL53L1_set_customer_nvm_managed(Dev,
2547 &(pdev->customer));
2548 }
2549
2550 LOG_FUNCTION_END(Status);
2551 return Status;
2552 }
2553
VL53L1_SetCalibrationData(VL53L1_DEV Dev,VL53L1_CalibrationData_t * pCalibrationData)2554 VL53L1_Error VL53L1_SetCalibrationData(VL53L1_DEV Dev,
2555 VL53L1_CalibrationData_t *pCalibrationData)
2556 {
2557 VL53L1_Error Status = VL53L1_ERROR_NONE;
2558 VL53L1_CustomerNvmManaged_t *pC;
2559 VL53L1_calibration_data_t cal_data;
2560 uint32_t x;
2561
2562 LOG_FUNCTION_START("");
2563
2564 cal_data.struct_version = pCalibrationData->struct_version -
2565 VL53L1_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
2566
2567
2568
2569 /* memcpy(DEST, SRC, N) */
2570 memcpy(
2571 &(cal_data.add_off_cal_data),
2572 &(pCalibrationData->add_off_cal_data),
2573 sizeof(VL53L1_additional_offset_cal_data_t));
2574
2575 /* memcpy (DEST, SRC, N) */
2576 memcpy(
2577 &(cal_data.optical_centre),
2578 &(pCalibrationData->optical_centre),
2579 sizeof(VL53L1_optical_centre_t));
2580
2581 /* memcpy (DEST, SRC, N) */
2582 memcpy(
2583 &(cal_data.gain_cal),
2584 &(pCalibrationData->gain_cal),
2585 sizeof(VL53L1_gain_calibration_data_t));
2586
2587 /* memcpy (DEST, SRC, N) */
2588 memcpy(
2589 &(cal_data.cal_peak_rate_map),
2590 &(pCalibrationData->cal_peak_rate_map),
2591 sizeof(VL53L1_cal_peak_rate_map_t));
2592
2593 pC = &pCalibrationData->customer;
2594 x = pC->algo__crosstalk_compensation_plane_offset_kcps;
2595 cal_data.customer.algo__crosstalk_compensation_plane_offset_kcps =
2596 (uint16_t)(x&0x0000FFFF);
2597
2598 cal_data.customer.global_config__spad_enables_ref_0 =
2599 pC->global_config__spad_enables_ref_0;
2600 cal_data.customer.global_config__spad_enables_ref_1 =
2601 pC->global_config__spad_enables_ref_1;
2602 cal_data.customer.global_config__spad_enables_ref_2 =
2603 pC->global_config__spad_enables_ref_2;
2604 cal_data.customer.global_config__spad_enables_ref_3 =
2605 pC->global_config__spad_enables_ref_3;
2606 cal_data.customer.global_config__spad_enables_ref_4 =
2607 pC->global_config__spad_enables_ref_4;
2608 cal_data.customer.global_config__spad_enables_ref_5 =
2609 pC->global_config__spad_enables_ref_5;
2610 cal_data.customer.global_config__ref_en_start_select =
2611 pC->global_config__ref_en_start_select;
2612 cal_data.customer.ref_spad_man__num_requested_ref_spads =
2613 pC->ref_spad_man__num_requested_ref_spads;
2614 cal_data.customer.ref_spad_man__ref_location =
2615 pC->ref_spad_man__ref_location;
2616 cal_data.customer.algo__crosstalk_compensation_x_plane_gradient_kcps =
2617 pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
2618 cal_data.customer.algo__crosstalk_compensation_y_plane_gradient_kcps =
2619 pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
2620 cal_data.customer.ref_spad_char__total_rate_target_mcps =
2621 pC->ref_spad_char__total_rate_target_mcps;
2622 cal_data.customer.algo__part_to_part_range_offset_mm =
2623 pC->algo__part_to_part_range_offset_mm;
2624 cal_data.customer.mm_config__inner_offset_mm =
2625 pC->mm_config__inner_offset_mm;
2626 cal_data.customer.mm_config__outer_offset_mm =
2627 pC->mm_config__outer_offset_mm;
2628
2629 Status = VL53L1_set_part_to_part_data(Dev, &cal_data);
2630 LOG_FUNCTION_END(Status);
2631 return Status;
2632
2633 }
2634
VL53L1_GetCalibrationData(VL53L1_DEV Dev,VL53L1_CalibrationData_t * pCalibrationData)2635 VL53L1_Error VL53L1_GetCalibrationData(VL53L1_DEV Dev,
2636 VL53L1_CalibrationData_t *pCalibrationData)
2637 {
2638 VL53L1_Error Status = VL53L1_ERROR_NONE;
2639 VL53L1_calibration_data_t cal_data;
2640 VL53L1_CustomerNvmManaged_t *pC;
2641 VL53L1_customer_nvm_managed_t *pC2;
2642
2643 LOG_FUNCTION_START("");
2644
2645 /* struct_version is filled inside get part to part function */
2646 Status = VL53L1_get_part_to_part_data(Dev, &cal_data);
2647
2648 pCalibrationData->struct_version = cal_data.struct_version +
2649 VL53L1_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
2650
2651
2652 /* memcpy(DEST, SRC, N) */
2653 memcpy(
2654 &(pCalibrationData->add_off_cal_data),
2655 &(cal_data.add_off_cal_data),
2656 sizeof(VL53L1_additional_offset_cal_data_t));
2657
2658 /* memcpy (DEST, SRC, N) */
2659 memcpy(
2660 &(pCalibrationData->optical_centre),
2661 &(cal_data.optical_centre),
2662 sizeof(VL53L1_optical_centre_t));
2663
2664 /* memcpy (DEST, SRC, N) */
2665 memcpy(
2666 &(pCalibrationData->gain_cal),
2667 &(cal_data.gain_cal),
2668 sizeof(VL53L1_gain_calibration_data_t));
2669
2670 /* memcpy (DEST, SRC, N) */
2671 memcpy(
2672 &(pCalibrationData->cal_peak_rate_map),
2673 &(cal_data.cal_peak_rate_map),
2674 sizeof(VL53L1_cal_peak_rate_map_t));
2675
2676
2677 pC = &pCalibrationData->customer;
2678 pC2 = &cal_data.customer;
2679 pC->global_config__spad_enables_ref_0 =
2680 pC2->global_config__spad_enables_ref_0;
2681 pC->global_config__spad_enables_ref_1 =
2682 pC2->global_config__spad_enables_ref_1;
2683 pC->global_config__spad_enables_ref_2 =
2684 pC2->global_config__spad_enables_ref_2;
2685 pC->global_config__spad_enables_ref_3 =
2686 pC2->global_config__spad_enables_ref_3;
2687 pC->global_config__spad_enables_ref_4 =
2688 pC2->global_config__spad_enables_ref_4;
2689 pC->global_config__spad_enables_ref_5 =
2690 pC2->global_config__spad_enables_ref_5;
2691 pC->global_config__ref_en_start_select =
2692 pC2->global_config__ref_en_start_select;
2693 pC->ref_spad_man__num_requested_ref_spads =
2694 pC2->ref_spad_man__num_requested_ref_spads;
2695 pC->ref_spad_man__ref_location =
2696 pC2->ref_spad_man__ref_location;
2697 pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
2698 pC2->algo__crosstalk_compensation_x_plane_gradient_kcps;
2699 pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
2700 pC2->algo__crosstalk_compensation_y_plane_gradient_kcps;
2701 pC->ref_spad_char__total_rate_target_mcps =
2702 pC2->ref_spad_char__total_rate_target_mcps;
2703 pC->algo__part_to_part_range_offset_mm =
2704 pC2->algo__part_to_part_range_offset_mm;
2705 pC->mm_config__inner_offset_mm =
2706 pC2->mm_config__inner_offset_mm;
2707 pC->mm_config__outer_offset_mm =
2708 pC2->mm_config__outer_offset_mm;
2709
2710 pC->algo__crosstalk_compensation_plane_offset_kcps =
2711 (uint32_t)(
2712 pC2->algo__crosstalk_compensation_plane_offset_kcps);
2713 LOG_FUNCTION_END(Status);
2714 return Status;
2715 }
2716
2717
2718
VL53L1_GetOpticalCenter(VL53L1_DEV Dev,FixPoint1616_t * pOpticalCenterX,FixPoint1616_t * pOpticalCenterY)2719 VL53L1_Error VL53L1_GetOpticalCenter(VL53L1_DEV Dev,
2720 FixPoint1616_t *pOpticalCenterX,
2721 FixPoint1616_t *pOpticalCenterY)
2722 {
2723 VL53L1_Error Status = VL53L1_ERROR_NONE;
2724 VL53L1_calibration_data_t CalibrationData;
2725
2726 LOG_FUNCTION_START("");
2727
2728 *pOpticalCenterX = 0;
2729 *pOpticalCenterY = 0;
2730 Status = VL53L1_get_part_to_part_data(Dev, &CalibrationData);
2731 if (Status == VL53L1_ERROR_NONE) {
2732 *pOpticalCenterX = VL53L1_FIXPOINT44TOFIXPOINT1616(
2733 CalibrationData.optical_centre.x_centre);
2734 *pOpticalCenterY = VL53L1_FIXPOINT44TOFIXPOINT1616(
2735 CalibrationData.optical_centre.y_centre);
2736 }
2737
2738 LOG_FUNCTION_END(Status);
2739 return Status;
2740 }
2741
2742 /* END Group Calibration functions */
2743
2744
2745 /* Group PAL detection triggered events Functions */
2746
VL53L1_SetThresholdConfig(VL53L1_DEV Dev,VL53L1_DetectionConfig_t * pConfig)2747 VL53L1_Error VL53L1_SetThresholdConfig(VL53L1_DEV Dev,
2748 VL53L1_DetectionConfig_t *pConfig)
2749 {
2750 #define BADTHRESBOUNDS(T) \
2751 (((T.CrossMode == VL53L1_THRESHOLD_OUT_OF_WINDOW) || \
2752 (T.CrossMode == VL53L1_THRESHOLD_IN_WINDOW)) && (T.Low > T.High))
2753
2754 VL53L1_Error Status = VL53L1_ERROR_NONE;
2755 VL53L1_GPIO_interrupt_config_t Cfg;
2756 uint16_t g;
2757 FixPoint1616_t gain, high1616, low1616;
2758 VL53L1_LLDriverData_t *pdev;
2759
2760 LOG_FUNCTION_START("");
2761
2762 pdev = VL53L1DevStructGetLLDriverHandle(Dev);
2763
2764 Status = VL53L1_get_GPIO_interrupt_config(Dev, &Cfg);
2765 if (Status == VL53L1_ERROR_NONE) {
2766 if (pConfig->DetectionMode == VL53L1_DETECTION_NORMAL_RUN) {
2767 Cfg.intr_new_measure_ready = 1;
2768 Status = VL53L1_set_GPIO_interrupt_config_struct(Dev,
2769 Cfg);
2770 } else {
2771 if (BADTHRESBOUNDS(pConfig->Distance))
2772 Status = VL53L1_ERROR_INVALID_PARAMS;
2773 if ((Status == VL53L1_ERROR_NONE) &&
2774 (BADTHRESBOUNDS(pConfig->Rate)))
2775 Status = VL53L1_ERROR_INVALID_PARAMS;
2776 if (Status == VL53L1_ERROR_NONE) {
2777 Cfg.intr_new_measure_ready = 0;
2778 Cfg.intr_no_target = pConfig->IntrNoTarget;
2779 /* fix ticket 466238
2780 * Apply invert distance gain to thresholds */
2781 g = pdev->gain_cal.standard_ranging_gain_factor;
2782 /* gain is ufix 5.11, convert to 16.16 */
2783 gain = (FixPoint1616_t) ((uint32_t)g << 5);
2784 high1616 = (FixPoint1616_t) ((uint32_t)
2785 pConfig->Distance.High << 16);
2786 low1616 = (FixPoint1616_t) ((uint32_t)
2787 pConfig->Distance.Low << 16);
2788 /* +32768 to round the results*/
2789 high1616 = (high1616 + 32768) / gain;
2790 low1616 = (low1616 + 32768) / gain;
2791 Cfg.threshold_distance_high = (uint16_t)
2792 (high1616 & 0xFFFF);
2793 Cfg.threshold_distance_low = (uint16_t)
2794 (low1616 & 0xFFFF);
2795 /* end fix ticket 466238 */
2796 Cfg.threshold_rate_high =
2797 VL53L1_FIXPOINT1616TOFIXPOINT97(
2798 pConfig->Rate.High);
2799 Cfg.threshold_rate_low =
2800 VL53L1_FIXPOINT1616TOFIXPOINT97(
2801 pConfig->Rate.Low);
2802
2803 Cfg.intr_mode_distance = ConvertModeToLLD(
2804 &Status,
2805 pConfig->Distance.CrossMode);
2806 if (Status == VL53L1_ERROR_NONE)
2807 Cfg.intr_mode_rate = ConvertModeToLLD(
2808 &Status,
2809 pConfig->Rate.CrossMode);
2810 }
2811
2812 /* Refine thresholds combination now */
2813 if (Status == VL53L1_ERROR_NONE) {
2814 Cfg.intr_combined_mode = 1;
2815 switch (pConfig->DetectionMode) {
2816 case VL53L1_DETECTION_DISTANCE_ONLY:
2817 Cfg.threshold_rate_high = 0;
2818 Cfg.threshold_rate_low = 0;
2819 break;
2820 case VL53L1_DETECTION_RATE_ONLY:
2821 Cfg.threshold_distance_high = 0;
2822 Cfg.threshold_distance_low = 0;
2823 break;
2824 case VL53L1_DETECTION_DISTANCE_OR_RATE:
2825 /* Nothing to do all is already
2826 * in place
2827 */
2828 break;
2829 case VL53L1_DETECTION_DISTANCE_AND_RATE:
2830 Cfg.intr_combined_mode = 0;
2831 break;
2832 default:
2833 Status = VL53L1_ERROR_INVALID_PARAMS;
2834 }
2835 }
2836
2837 if (Status == VL53L1_ERROR_NONE)
2838 Status =
2839 VL53L1_set_GPIO_interrupt_config_struct(Dev,
2840 Cfg);
2841
2842 }
2843 }
2844
2845 LOG_FUNCTION_END(Status);
2846 return Status;
2847 }
2848
2849
VL53L1_GetThresholdConfig(VL53L1_DEV Dev,VL53L1_DetectionConfig_t * pConfig)2850 VL53L1_Error VL53L1_GetThresholdConfig(VL53L1_DEV Dev,
2851 VL53L1_DetectionConfig_t *pConfig)
2852 {
2853 VL53L1_Error Status = VL53L1_ERROR_NONE;
2854 VL53L1_GPIO_interrupt_config_t Cfg;
2855
2856 LOG_FUNCTION_START("");
2857
2858 Status = VL53L1_get_GPIO_interrupt_config(Dev, &Cfg);
2859
2860 if (Status != VL53L1_ERROR_NONE) {
2861 LOG_FUNCTION_END(Status);
2862 return Status;
2863 }
2864
2865 pConfig->IntrNoTarget = Cfg.intr_no_target;
2866 pConfig->Distance.High = Cfg.threshold_distance_high;
2867 pConfig->Distance.Low = Cfg.threshold_distance_low;
2868 pConfig->Rate.High =
2869 VL53L1_FIXPOINT97TOFIXPOINT1616(
2870 Cfg.threshold_rate_high);
2871 pConfig->Rate.Low =
2872 VL53L1_FIXPOINT97TOFIXPOINT1616(Cfg.threshold_rate_low);
2873 pConfig->Distance.CrossMode =
2874 ConvertModeFromLLD(&Status, Cfg.intr_mode_distance);
2875 if (Status == VL53L1_ERROR_NONE)
2876 pConfig->Rate.CrossMode =
2877 ConvertModeFromLLD(&Status, Cfg.intr_mode_rate);
2878
2879 if (Cfg.intr_new_measure_ready == 1) {
2880 pConfig->DetectionMode = VL53L1_DETECTION_NORMAL_RUN;
2881 } else {
2882 /* Refine thresholds combination now */
2883 if (Status == VL53L1_ERROR_NONE) {
2884 if (Cfg.intr_combined_mode == 0)
2885 pConfig->DetectionMode =
2886 VL53L1_DETECTION_DISTANCE_AND_RATE;
2887 else {
2888 if ((Cfg.threshold_distance_high == 0) &&
2889 (Cfg.threshold_distance_low == 0))
2890 pConfig->DetectionMode =
2891 VL53L1_DETECTION_RATE_ONLY;
2892 else if ((Cfg.threshold_rate_high == 0) &&
2893 (Cfg.threshold_rate_low == 0))
2894 pConfig->DetectionMode =
2895 VL53L1_DETECTION_DISTANCE_ONLY;
2896 else
2897 pConfig->DetectionMode =
2898 VL53L1_DETECTION_DISTANCE_OR_RATE;
2899 }
2900 }
2901 }
2902
2903 LOG_FUNCTION_END(Status);
2904 return Status;
2905 }
2906
2907
2908 /* End Group PAL IRQ Triggered events Functions */
2909
2910