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