1 /*******************************************************************************
2  Copyright � 2016, STMicroelectronics International N.V.
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of STMicroelectronics nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
19  NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
20  IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
21  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  ******************************************************************************/
28 
29 #include "vl53l0x_api.h"
30 #include "vl53l0x_tuning.h"
31 #include "vl53l0x_interrupt_threshold_settings.h"
32 #include "vl53l0x_api_core.h"
33 #include "vl53l0x_api_calibration.h"
34 #include "vl53l0x_api_strings.h"
35 
36 #ifndef __KERNEL__
37 #include <stdlib.h>
38 #endif
39 #define LOG_FUNCTION_START(fmt, ...) \
40 	_LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__)
41 #define LOG_FUNCTION_END(status, ...) \
42 	_LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__)
43 #define LOG_FUNCTION_END_FMT(status, fmt, ...) \
44 	_LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__)
45 
46 #ifdef VL53L0X_LOG_ENABLE
47 #define trace_print(level, ...) trace_print_module_function(TRACE_MODULE_API, \
48 	level, TRACE_FUNCTION_NONE, ##__VA_ARGS__)
49 #endif
50 
51 /* Group PAL General Functions */
52 
VL53L0X_GetVersion(VL53L0X_Version_t * pVersion)53 VL53L0X_Error VL53L0X_GetVersion(VL53L0X_Version_t *pVersion)
54 {
55 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
56 	LOG_FUNCTION_START("");
57 
58 	pVersion->major = VL53L0X_IMPLEMENTATION_VER_MAJOR;
59 	pVersion->minor = VL53L0X_IMPLEMENTATION_VER_MINOR;
60 	pVersion->build = VL53L0X_IMPLEMENTATION_VER_SUB;
61 
62 	pVersion->revision = VL53L0X_IMPLEMENTATION_VER_REVISION;
63 
64 	LOG_FUNCTION_END(Status);
65 	return Status;
66 }
67 
VL53L0X_GetPalSpecVersion(VL53L0X_Version_t * pPalSpecVersion)68 VL53L0X_Error VL53L0X_GetPalSpecVersion(VL53L0X_Version_t *pPalSpecVersion)
69 {
70 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
71 
72 	LOG_FUNCTION_START("");
73 
74 	pPalSpecVersion->major = VL53L0X_SPECIFICATION_VER_MAJOR;
75 	pPalSpecVersion->minor = VL53L0X_SPECIFICATION_VER_MINOR;
76 	pPalSpecVersion->build = VL53L0X_SPECIFICATION_VER_SUB;
77 
78 	pPalSpecVersion->revision = VL53L0X_SPECIFICATION_VER_REVISION;
79 
80 	LOG_FUNCTION_END(Status);
81 	return Status;
82 }
83 
VL53L0X_GetProductRevision(VL53L0X_DEV Dev,uint8_t * pProductRevisionMajor,uint8_t * pProductRevisionMinor)84 VL53L0X_Error VL53L0X_GetProductRevision(VL53L0X_DEV Dev,
85 	uint8_t *pProductRevisionMajor, uint8_t *pProductRevisionMinor)
86 {
87 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
88 	uint8_t revision_id;
89 
90 	LOG_FUNCTION_START("");
91 
92 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_IDENTIFICATION_REVISION_ID,
93 		&revision_id);
94 	*pProductRevisionMajor = 1;
95 	*pProductRevisionMinor = (revision_id & 0xF0) >> 4;
96 
97 	LOG_FUNCTION_END(Status);
98 	return Status;
99 
100 }
101 
VL53L0X_GetDeviceInfo(VL53L0X_DEV Dev,VL53L0X_DeviceInfo_t * pVL53L0X_DeviceInfo)102 VL53L0X_Error VL53L0X_GetDeviceInfo(VL53L0X_DEV Dev,
103 	VL53L0X_DeviceInfo_t *pVL53L0X_DeviceInfo)
104 {
105 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
106 	LOG_FUNCTION_START("");
107 
108 	Status = VL53L0X_get_device_info(Dev, pVL53L0X_DeviceInfo);
109 
110 	LOG_FUNCTION_END(Status);
111 	return Status;
112 }
113 
VL53L0X_GetDeviceErrorStatus(VL53L0X_DEV Dev,VL53L0X_DeviceError * pDeviceErrorStatus)114 VL53L0X_Error VL53L0X_GetDeviceErrorStatus(VL53L0X_DEV Dev,
115 	VL53L0X_DeviceError *pDeviceErrorStatus)
116 {
117 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
118 	uint8_t RangeStatus;
119 
120 	LOG_FUNCTION_START("");
121 
122 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_RESULT_RANGE_STATUS,
123 		&RangeStatus);
124 
125 	*pDeviceErrorStatus = (VL53L0X_DeviceError)((RangeStatus & 0x78) >> 3);
126 
127 	LOG_FUNCTION_END(Status);
128 	return Status;
129 }
130 
131 
VL53L0X_GetDeviceErrorString(VL53L0X_DeviceError ErrorCode,char * pDeviceErrorString)132 VL53L0X_Error VL53L0X_GetDeviceErrorString(VL53L0X_DeviceError ErrorCode,
133 	char *pDeviceErrorString)
134 {
135 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
136 
137 	LOG_FUNCTION_START("");
138 
139 	Status = VL53L0X_get_device_error_string(ErrorCode, pDeviceErrorString);
140 
141 	LOG_FUNCTION_END(Status);
142 	return Status;
143 }
144 
VL53L0X_GetRangeStatusString(uint8_t RangeStatus,char * pRangeStatusString)145 VL53L0X_Error VL53L0X_GetRangeStatusString(uint8_t RangeStatus,
146 	char *pRangeStatusString)
147 {
148 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
149 	LOG_FUNCTION_START("");
150 
151 	Status = VL53L0X_get_range_status_string(RangeStatus,
152 		pRangeStatusString);
153 
154 	LOG_FUNCTION_END(Status);
155 	return Status;
156 }
157 
VL53L0X_GetPalErrorString(VL53L0X_Error PalErrorCode,char * pPalErrorString)158 VL53L0X_Error VL53L0X_GetPalErrorString(VL53L0X_Error PalErrorCode,
159 	char *pPalErrorString)
160 {
161 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
162 	LOG_FUNCTION_START("");
163 
164 	Status = VL53L0X_get_pal_error_string(PalErrorCode, pPalErrorString);
165 
166 	LOG_FUNCTION_END(Status);
167 	return Status;
168 }
169 
VL53L0X_GetPalStateString(VL53L0X_State PalStateCode,char * pPalStateString)170 VL53L0X_Error VL53L0X_GetPalStateString(VL53L0X_State PalStateCode,
171 	char *pPalStateString)
172 {
173 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
174 	LOG_FUNCTION_START("");
175 
176 	Status = VL53L0X_get_pal_state_string(PalStateCode, pPalStateString);
177 
178 	LOG_FUNCTION_END(Status);
179 	return Status;
180 }
181 
VL53L0X_GetPalState(VL53L0X_DEV Dev,VL53L0X_State * pPalState)182 VL53L0X_Error VL53L0X_GetPalState(VL53L0X_DEV Dev, VL53L0X_State *pPalState)
183 {
184 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
185 	LOG_FUNCTION_START("");
186 
187 	*pPalState = PALDevDataGet(Dev, PalState);
188 
189 	LOG_FUNCTION_END(Status);
190 	return Status;
191 }
192 
VL53L0X_SetPowerMode(VL53L0X_DEV Dev,VL53L0X_PowerModes PowerMode)193 VL53L0X_Error VL53L0X_SetPowerMode(VL53L0X_DEV Dev, VL53L0X_PowerModes PowerMode)
194 {
195 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
196 	LOG_FUNCTION_START("");
197 
198 	/* Only level1 of Power mode exists */
199 	if ((PowerMode != VL53L0X_POWERMODE_STANDBY_LEVEL1)
200 		&& (PowerMode != VL53L0X_POWERMODE_IDLE_LEVEL1)) {
201 		Status = VL53L0X_ERROR_MODE_NOT_SUPPORTED;
202 	} else if (PowerMode == VL53L0X_POWERMODE_STANDBY_LEVEL1) {
203 		/* set the standby level1 of power mode */
204 		Status = VL53L0X_WrByte(Dev, 0x80, 0x00);
205 		if (Status == VL53L0X_ERROR_NONE) {
206 			/* Set PAL State to standby */
207 			PALDevDataSet(Dev, PalState, VL53L0X_STATE_STANDBY);
208 			PALDevDataSet(Dev, PowerMode,
209 				VL53L0X_POWERMODE_STANDBY_LEVEL1);
210 		}
211 
212 	} else {
213 		/* VL53L0X_POWERMODE_IDLE_LEVEL1 */
214 		Status = VL53L0X_WrByte(Dev, 0x80, 0x00);
215 		if (Status == VL53L0X_ERROR_NONE)
216 			Status = VL53L0X_StaticInit(Dev);
217 
218 		if (Status == VL53L0X_ERROR_NONE)
219 			PALDevDataSet(Dev, PowerMode,
220 				VL53L0X_POWERMODE_IDLE_LEVEL1);
221 
222 	}
223 
224 	LOG_FUNCTION_END(Status);
225 	return Status;
226 }
227 
VL53L0X_GetPowerMode(VL53L0X_DEV Dev,VL53L0X_PowerModes * pPowerMode)228 VL53L0X_Error VL53L0X_GetPowerMode(VL53L0X_DEV Dev, VL53L0X_PowerModes *pPowerMode)
229 {
230 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
231 	uint8_t Byte;
232 	LOG_FUNCTION_START("");
233 
234 	/* Only level1 of Power mode exists */
235 	Status = VL53L0X_RdByte(Dev, 0x80, &Byte);
236 
237 	if (Status == VL53L0X_ERROR_NONE) {
238 		if (Byte == 1) {
239 			PALDevDataSet(Dev, PowerMode,
240 				VL53L0X_POWERMODE_IDLE_LEVEL1);
241 		} else {
242 			PALDevDataSet(Dev, PowerMode,
243 				VL53L0X_POWERMODE_STANDBY_LEVEL1);
244 		}
245 	}
246 
247 	LOG_FUNCTION_END(Status);
248 	return Status;
249 }
250 
VL53L0X_SetOffsetCalibrationDataMicroMeter(VL53L0X_DEV Dev,int32_t OffsetCalibrationDataMicroMeter)251 VL53L0X_Error VL53L0X_SetOffsetCalibrationDataMicroMeter(VL53L0X_DEV Dev,
252 	int32_t OffsetCalibrationDataMicroMeter)
253 {
254 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
255 	LOG_FUNCTION_START("");
256 
257 	Status = VL53L0X_set_offset_calibration_data_micro_meter(Dev,
258 		OffsetCalibrationDataMicroMeter);
259 
260 	LOG_FUNCTION_END(Status);
261 	return Status;
262 }
263 
VL53L0X_GetOffsetCalibrationDataMicroMeter(VL53L0X_DEV Dev,int32_t * pOffsetCalibrationDataMicroMeter)264 VL53L0X_Error VL53L0X_GetOffsetCalibrationDataMicroMeter(VL53L0X_DEV Dev,
265 	int32_t *pOffsetCalibrationDataMicroMeter)
266 {
267 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
268 	LOG_FUNCTION_START("");
269 
270 	Status = VL53L0X_get_offset_calibration_data_micro_meter(Dev,
271 		pOffsetCalibrationDataMicroMeter);
272 
273 	LOG_FUNCTION_END(Status);
274 	return Status;
275 }
276 
VL53L0X_SetLinearityCorrectiveGain(VL53L0X_DEV Dev,int16_t LinearityCorrectiveGain)277 VL53L0X_Error VL53L0X_SetLinearityCorrectiveGain(VL53L0X_DEV Dev,
278 	int16_t LinearityCorrectiveGain)
279 {
280 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
281 	LOG_FUNCTION_START("");
282 
283 	if ((LinearityCorrectiveGain < 0) || (LinearityCorrectiveGain > 1000))
284 		Status = VL53L0X_ERROR_INVALID_PARAMS;
285 	else {
286 		PALDevDataSet(Dev, LinearityCorrectiveGain,
287 			LinearityCorrectiveGain);
288 
289 		if (LinearityCorrectiveGain != 1000) {
290 			/* Disable FW Xtalk */
291 			Status = VL53L0X_WrWord(Dev,
292 			VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, 0);
293 		}
294 	}
295 
296 	LOG_FUNCTION_END(Status);
297 	return Status;
298 }
299 
VL53L0X_GetLinearityCorrectiveGain(VL53L0X_DEV Dev,uint16_t * pLinearityCorrectiveGain)300 VL53L0X_Error VL53L0X_GetLinearityCorrectiveGain(VL53L0X_DEV Dev,
301 	uint16_t *pLinearityCorrectiveGain)
302 {
303 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
304 	LOG_FUNCTION_START("");
305 
306 	*pLinearityCorrectiveGain = PALDevDataGet(Dev, LinearityCorrectiveGain);
307 
308 	LOG_FUNCTION_END(Status);
309 	return Status;
310 }
311 
VL53L0X_SetGroupParamHold(VL53L0X_DEV Dev,uint8_t GroupParamHold)312 VL53L0X_Error VL53L0X_SetGroupParamHold(VL53L0X_DEV Dev, uint8_t GroupParamHold)
313 {
314 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
315 	LOG_FUNCTION_START("");
316 
317 	/* not implemented on VL53L0X */
318 
319 	LOG_FUNCTION_END(Status);
320 	return Status;
321 }
322 
VL53L0X_GetUpperLimitMilliMeter(VL53L0X_DEV Dev,uint16_t * pUpperLimitMilliMeter)323 VL53L0X_Error VL53L0X_GetUpperLimitMilliMeter(VL53L0X_DEV Dev,
324 	uint16_t *pUpperLimitMilliMeter)
325 {
326 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
327 	LOG_FUNCTION_START("");
328 
329 	/* not implemented on VL53L0X */
330 
331 	LOG_FUNCTION_END(Status);
332 	return Status;
333 }
334 
VL53L0X_GetTotalSignalRate(VL53L0X_DEV Dev,FixPoint1616_t * pTotalSignalRate)335 VL53L0X_Error VL53L0X_GetTotalSignalRate(VL53L0X_DEV Dev,
336 	FixPoint1616_t *pTotalSignalRate)
337 {
338 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
339 	VL53L0X_RangingMeasurementData_t LastRangeDataBuffer;
340 
341 	LOG_FUNCTION_START("");
342 
343 	LastRangeDataBuffer = PALDevDataGet(Dev, LastRangeMeasure);
344 
345 	Status = VL53L0X_get_total_signal_rate(
346 		Dev, &LastRangeDataBuffer, pTotalSignalRate);
347 
348 	LOG_FUNCTION_END(Status);
349 	return Status;
350 }
351 
352 /* End Group PAL General Functions */
353 
354 /* Group PAL Init Functions */
VL53L0X_SetDeviceAddress(VL53L0X_DEV Dev,uint8_t DeviceAddress)355 VL53L0X_Error VL53L0X_SetDeviceAddress(VL53L0X_DEV Dev, uint8_t DeviceAddress)
356 {
357 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
358 	LOG_FUNCTION_START("");
359 
360 	Status = VL53L0X_WrByte(Dev, VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS,
361 		DeviceAddress / 2);
362 
363 	LOG_FUNCTION_END(Status);
364 	return Status;
365 }
366 
VL53L0X_DataInit(VL53L0X_DEV Dev)367 VL53L0X_Error VL53L0X_DataInit(VL53L0X_DEV Dev)
368 {
369 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
370 	VL53L0X_DeviceParameters_t CurrentParameters;
371 	int i;
372 	uint8_t StopVariable;
373 
374 	LOG_FUNCTION_START("");
375 
376 	/* by default the I2C is running at 1V8 if you want to change it you
377 	 * need to include this define at compilation level. */
378 #ifdef USE_I2C_2V8
379 	Status = VL53L0X_UpdateByte(Dev,
380 		VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV,
381 		0xFE,
382 		0x01);
383 #endif
384 
385 	/* Set I2C standard mode */
386 	if (Status == VL53L0X_ERROR_NONE)
387 		Status = VL53L0X_WrByte(Dev, 0x88, 0x00);
388 
389 	VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, ReadDataFromDeviceDone, 0);
390 
391 #ifdef USE_IQC_STATION
392 	if (Status == VL53L0X_ERROR_NONE)
393 		Status = VL53L0X_apply_offset_adjustment(Dev);
394 #endif
395 
396 	/* Default value is 1000 for Linearity Corrective Gain */
397 	PALDevDataSet(Dev, LinearityCorrectiveGain, 1000);
398 
399 	/* Dmax default Parameter */
400 	PALDevDataSet(Dev, DmaxCalRangeMilliMeter, 400);
401 	PALDevDataSet(Dev, DmaxCalSignalRateRtnMegaCps,
402 		(FixPoint1616_t)((0x00016B85))); /* 1.42 No Cover Glass*/
403 
404 	/* Set Default static parameters
405 	 *set first temporary values 9.44MHz * 65536 = 618660 */
406 	VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, OscFrequencyMHz, 618660);
407 
408 	/* Set Default XTalkCompensationRateMegaCps to 0  */
409 	VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps, 0);
410 
411 	/* Get default parameters */
412 	Status = VL53L0X_GetDeviceParameters(Dev, &CurrentParameters);
413 	if (Status == VL53L0X_ERROR_NONE) {
414 		/* initialize PAL values */
415 		CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_SINGLE_RANGING;
416 		CurrentParameters.HistogramMode = VL53L0X_HISTOGRAMMODE_DISABLED;
417 		PALDevDataSet(Dev, CurrentParameters, CurrentParameters);
418 	}
419 
420 	/* Sigma estimator variable */
421 	PALDevDataSet(Dev, SigmaEstRefArray, 100);
422 	PALDevDataSet(Dev, SigmaEstEffPulseWidth, 900);
423 	PALDevDataSet(Dev, SigmaEstEffAmbWidth, 500);
424 	PALDevDataSet(Dev, targetRefRate, 0x0A00); /* 20 MCPS in 9:7 format */
425 
426 	/* Use internal default settings */
427 	PALDevDataSet(Dev, UseInternalTuningSettings, 1);
428 
429 	Status |= VL53L0X_WrByte(Dev, 0x80, 0x01);
430 	Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01);
431 	Status |= VL53L0X_WrByte(Dev, 0x00, 0x00);
432 	Status |= VL53L0X_RdByte(Dev, 0x91, &StopVariable);
433 	PALDevDataSet(Dev, StopVariable, StopVariable);
434 	Status |= VL53L0X_WrByte(Dev, 0x00, 0x01);
435 	Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00);
436 	Status |= VL53L0X_WrByte(Dev, 0x80, 0x00);
437 
438 	/* Enable all check */
439 	for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
440 		if (Status == VL53L0X_ERROR_NONE)
441 			Status |= VL53L0X_SetLimitCheckEnable(Dev, i, 1);
442 		else
443 			break;
444 
445 	}
446 
447 	/* Disable the following checks */
448 	if (Status == VL53L0X_ERROR_NONE)
449 		Status = VL53L0X_SetLimitCheckEnable(Dev,
450 			VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, 0);
451 
452 	if (Status == VL53L0X_ERROR_NONE)
453 		Status = VL53L0X_SetLimitCheckEnable(Dev,
454 			VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 0);
455 
456 	if (Status == VL53L0X_ERROR_NONE)
457 		Status = VL53L0X_SetLimitCheckEnable(Dev,
458 			VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC, 0);
459 
460 	if (Status == VL53L0X_ERROR_NONE)
461 		Status = VL53L0X_SetLimitCheckEnable(Dev,
462 			VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE, 0);
463 
464 	/* Limit default values */
465 	if (Status == VL53L0X_ERROR_NONE) {
466 		Status = VL53L0X_SetLimitCheckValue(Dev,
467 			VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
468 				(FixPoint1616_t)(18 * 65536));
469 	}
470 	if (Status == VL53L0X_ERROR_NONE) {
471 		Status = VL53L0X_SetLimitCheckValue(Dev,
472 			VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
473 				(FixPoint1616_t)(25 * 65536 / 100));
474 				/* 0.25 * 65536 */
475 	}
476 
477 	if (Status == VL53L0X_ERROR_NONE) {
478 		Status = VL53L0X_SetLimitCheckValue(Dev,
479 			VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
480 				(FixPoint1616_t)(35 * 65536));
481 	}
482 
483 	if (Status == VL53L0X_ERROR_NONE) {
484 		Status = VL53L0X_SetLimitCheckValue(Dev,
485 			VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
486 				(FixPoint1616_t)(0 * 65536));
487 	}
488 
489 	if (Status == VL53L0X_ERROR_NONE) {
490 
491 		PALDevDataSet(Dev, SequenceConfig, 0xFF);
492 		Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
493 			0xFF);
494 
495 		/* Set PAL state to tell that we are waiting for call to
496 		 * VL53L0X_StaticInit */
497 		PALDevDataSet(Dev, PalState, VL53L0X_STATE_WAIT_STATICINIT);
498 	}
499 
500 	if (Status == VL53L0X_ERROR_NONE)
501 		VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, RefSpadsInitialised, 0);
502 
503 
504 	LOG_FUNCTION_END(Status);
505 	return Status;
506 }
507 
VL53L0X_SetTuningSettingBuffer(VL53L0X_DEV Dev,uint8_t * pTuningSettingBuffer,uint8_t UseInternalTuningSettings)508 VL53L0X_Error VL53L0X_SetTuningSettingBuffer(VL53L0X_DEV Dev,
509 	uint8_t *pTuningSettingBuffer, uint8_t UseInternalTuningSettings)
510 {
511 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
512 
513 	LOG_FUNCTION_START("");
514 
515 	if (UseInternalTuningSettings == 1) {
516 		/* Force use internal settings */
517 		PALDevDataSet(Dev, UseInternalTuningSettings, 1);
518 	} else {
519 
520 		/* check that the first byte is not 0 */
521 		if (*pTuningSettingBuffer != 0) {
522 			PALDevDataSet(Dev, pTuningSettingsPointer,
523 				pTuningSettingBuffer);
524 			PALDevDataSet(Dev, UseInternalTuningSettings, 0);
525 
526 		} else {
527 			Status = VL53L0X_ERROR_INVALID_PARAMS;
528 		}
529 	}
530 
531 	LOG_FUNCTION_END(Status);
532 	return Status;
533 }
534 
VL53L0X_GetTuningSettingBuffer(VL53L0X_DEV Dev,uint8_t ** ppTuningSettingBuffer,uint8_t * pUseInternalTuningSettings)535 VL53L0X_Error VL53L0X_GetTuningSettingBuffer(VL53L0X_DEV Dev,
536 	uint8_t **ppTuningSettingBuffer, uint8_t *pUseInternalTuningSettings)
537 {
538 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
539 
540 	LOG_FUNCTION_START("");
541 
542 	*ppTuningSettingBuffer = PALDevDataGet(Dev, pTuningSettingsPointer);
543 	*pUseInternalTuningSettings = PALDevDataGet(Dev,
544 		UseInternalTuningSettings);
545 
546 	LOG_FUNCTION_END(Status);
547 	return Status;
548 }
549 
VL53L0X_StaticInit(VL53L0X_DEV Dev)550 VL53L0X_Error VL53L0X_StaticInit(VL53L0X_DEV Dev)
551 {
552 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
553 	VL53L0X_DeviceParameters_t CurrentParameters = {0};
554 	uint8_t *pTuningSettingBuffer;
555 	uint16_t tempword = 0;
556 	uint8_t tempbyte = 0;
557 	uint8_t UseInternalTuningSettings = 0;
558 	uint32_t count = 0;
559 	uint8_t isApertureSpads = 0;
560 	uint32_t refSpadCount = 0;
561 	uint8_t ApertureSpads = 0;
562 	uint8_t vcselPulsePeriodPCLK;
563 	uint32_t seqTimeoutMicroSecs;
564 
565 	LOG_FUNCTION_START("");
566 
567 	Status = VL53L0X_get_info_from_device(Dev, 1);
568 
569 	/* set the ref spad from NVM */
570 	count	= (uint32_t)VL53L0X_GETDEVICESPECIFICPARAMETER(Dev,
571 		ReferenceSpadCount);
572 	ApertureSpads = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev,
573 		ReferenceSpadType);
574 
575 	/* NVM value invalid */
576 	if ((ApertureSpads > 1) ||
577 		((ApertureSpads == 1) && (count > 32)) ||
578 		((ApertureSpads == 0) && (count > 12)))
579 		Status = VL53L0X_perform_ref_spad_management(Dev, &refSpadCount,
580 			&isApertureSpads);
581 	else
582 		Status = VL53L0X_set_reference_spads(Dev, count, ApertureSpads);
583 
584 
585 	/* Initialize tuning settings buffer to prevent compiler warning. */
586 	pTuningSettingBuffer = DefaultTuningSettings;
587 
588 	if (Status == VL53L0X_ERROR_NONE) {
589 		UseInternalTuningSettings = PALDevDataGet(Dev,
590 			UseInternalTuningSettings);
591 
592 		if (UseInternalTuningSettings == 0)
593 			pTuningSettingBuffer = PALDevDataGet(Dev,
594 				pTuningSettingsPointer);
595 		else
596 			pTuningSettingBuffer = DefaultTuningSettings;
597 
598 	}
599 
600 	if (Status == VL53L0X_ERROR_NONE)
601 		Status = VL53L0X_load_tuning_settings(Dev, pTuningSettingBuffer);
602 
603 
604 	/* Set interrupt config to new sample ready */
605 	if (Status == VL53L0X_ERROR_NONE) {
606 		Status = VL53L0X_SetGpioConfig(Dev, 0, 0,
607 		VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY,
608 		VL53L0X_INTERRUPTPOLARITY_LOW);
609 	}
610 
611 	if (Status == VL53L0X_ERROR_NONE) {
612 		Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
613 		Status |= VL53L0X_RdWord(Dev, 0x84, &tempword);
614 		Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00);
615 	}
616 
617 	if (Status == VL53L0X_ERROR_NONE) {
618 		VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, OscFrequencyMHz,
619 			VL53L0X_FIXPOINT412TOFIXPOINT1616(tempword));
620 	}
621 
622 	/* After static init, some device parameters may be changed,
623 	 * so update them */
624 	if (Status == VL53L0X_ERROR_NONE)
625 		Status = VL53L0X_GetDeviceParameters(Dev, &CurrentParameters);
626 
627 
628 	if (Status == VL53L0X_ERROR_NONE) {
629 		Status = VL53L0X_GetFractionEnable(Dev, &tempbyte);
630 		if (Status == VL53L0X_ERROR_NONE)
631 			PALDevDataSet(Dev, RangeFractionalEnable, tempbyte);
632 
633 	}
634 
635 	if (Status == VL53L0X_ERROR_NONE)
636 		PALDevDataSet(Dev, CurrentParameters, CurrentParameters);
637 
638 
639 	/* read the sequence config and save it */
640 	if (Status == VL53L0X_ERROR_NONE) {
641 		Status = VL53L0X_RdByte(Dev,
642 		VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &tempbyte);
643 		if (Status == VL53L0X_ERROR_NONE)
644 			PALDevDataSet(Dev, SequenceConfig, tempbyte);
645 
646 	}
647 
648 	/* Disable MSRC and TCC by default */
649 	if (Status == VL53L0X_ERROR_NONE)
650 		Status = VL53L0X_SetSequenceStepEnable(Dev,
651 					VL53L0X_SEQUENCESTEP_TCC, 0);
652 
653 
654 	if (Status == VL53L0X_ERROR_NONE)
655 		Status = VL53L0X_SetSequenceStepEnable(Dev,
656 		VL53L0X_SEQUENCESTEP_MSRC, 0);
657 
658 
659 	/* Set PAL State to standby */
660 	if (Status == VL53L0X_ERROR_NONE)
661 		PALDevDataSet(Dev, PalState, VL53L0X_STATE_IDLE);
662 
663 
664 
665 	/* Store pre-range vcsel period */
666 	if (Status == VL53L0X_ERROR_NONE) {
667 		Status = VL53L0X_GetVcselPulsePeriod(
668 			Dev,
669 			VL53L0X_VCSEL_PERIOD_PRE_RANGE,
670 			&vcselPulsePeriodPCLK);
671 	}
672 
673 	if (Status == VL53L0X_ERROR_NONE) {
674 			VL53L0X_SETDEVICESPECIFICPARAMETER(
675 				Dev,
676 				PreRangeVcselPulsePeriod,
677 				vcselPulsePeriodPCLK);
678 	}
679 
680 	/* Store final-range vcsel period */
681 	if (Status == VL53L0X_ERROR_NONE) {
682 		Status = VL53L0X_GetVcselPulsePeriod(
683 			Dev,
684 			VL53L0X_VCSEL_PERIOD_FINAL_RANGE,
685 			&vcselPulsePeriodPCLK);
686 	}
687 
688 	if (Status == VL53L0X_ERROR_NONE) {
689 			VL53L0X_SETDEVICESPECIFICPARAMETER(
690 				Dev,
691 				FinalRangeVcselPulsePeriod,
692 				vcselPulsePeriodPCLK);
693 	}
694 
695 	/* Store pre-range timeout */
696 	if (Status == VL53L0X_ERROR_NONE) {
697 		Status = get_sequence_step_timeout(
698 			Dev,
699 			VL53L0X_SEQUENCESTEP_PRE_RANGE,
700 			&seqTimeoutMicroSecs);
701 	}
702 
703 	if (Status == VL53L0X_ERROR_NONE) {
704 		VL53L0X_SETDEVICESPECIFICPARAMETER(
705 			Dev,
706 			PreRangeTimeoutMicroSecs,
707 			seqTimeoutMicroSecs);
708 	}
709 
710 	/* Store final-range timeout */
711 	if (Status == VL53L0X_ERROR_NONE) {
712 		Status = get_sequence_step_timeout(
713 			Dev,
714 			VL53L0X_SEQUENCESTEP_FINAL_RANGE,
715 			&seqTimeoutMicroSecs);
716 	}
717 
718 	if (Status == VL53L0X_ERROR_NONE) {
719 		VL53L0X_SETDEVICESPECIFICPARAMETER(
720 			Dev,
721 			FinalRangeTimeoutMicroSecs,
722 			seqTimeoutMicroSecs);
723 	}
724 
725 	LOG_FUNCTION_END(Status);
726 	return Status;
727 }
728 
VL53L0X_WaitDeviceBooted(VL53L0X_DEV Dev)729 VL53L0X_Error VL53L0X_WaitDeviceBooted(VL53L0X_DEV Dev)
730 {
731 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
732 	LOG_FUNCTION_START("");
733 
734 	/* not implemented on VL53L0X */
735 
736 	LOG_FUNCTION_END(Status);
737 	return Status;
738 }
739 
VL53L0X_ResetDevice(VL53L0X_DEV Dev)740 VL53L0X_Error VL53L0X_ResetDevice(VL53L0X_DEV Dev)
741 {
742 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
743 	uint8_t Byte;
744 	LOG_FUNCTION_START("");
745 
746 	/* Set reset bit */
747 	Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SOFT_RESET_GO2_SOFT_RESET_N,
748 		0x00);
749 
750 	/* Wait for some time */
751 	if (Status == VL53L0X_ERROR_NONE) {
752 		do {
753 			Status = VL53L0X_RdByte(Dev,
754 			VL53L0X_REG_IDENTIFICATION_MODEL_ID, &Byte);
755 		} while (Byte != 0x00);
756 	}
757 
758 	VL53L0X_PollingDelay(Dev);
759 
760 	/* Release reset */
761 	Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SOFT_RESET_GO2_SOFT_RESET_N,
762 		0x01);
763 
764 	/* Wait until correct boot-up of the device */
765 	if (Status == VL53L0X_ERROR_NONE) {
766 		do {
767 			Status = VL53L0X_RdByte(Dev,
768 			VL53L0X_REG_IDENTIFICATION_MODEL_ID, &Byte);
769 		} while (Byte == 0x00);
770 	}
771 
772 	VL53L0X_PollingDelay(Dev);
773 
774 	/* Set PAL State to VL53L0X_STATE_POWERDOWN */
775 	if (Status == VL53L0X_ERROR_NONE)
776 		PALDevDataSet(Dev, PalState, VL53L0X_STATE_POWERDOWN);
777 
778 
779 	LOG_FUNCTION_END(Status);
780 	return Status;
781 }
782 /* End Group PAL Init Functions */
783 
784 /* Group PAL Parameters Functions */
VL53L0X_SetDeviceParameters(VL53L0X_DEV Dev,const VL53L0X_DeviceParameters_t * pDeviceParameters)785 VL53L0X_Error VL53L0X_SetDeviceParameters(VL53L0X_DEV Dev,
786 	const VL53L0X_DeviceParameters_t *pDeviceParameters)
787 {
788 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
789 	int i;
790 	LOG_FUNCTION_START("");
791 	Status = VL53L0X_SetDeviceMode(Dev, pDeviceParameters->DeviceMode);
792 
793 	if (Status == VL53L0X_ERROR_NONE)
794 		Status = VL53L0X_SetInterMeasurementPeriodMilliSeconds(Dev,
795 			pDeviceParameters->InterMeasurementPeriodMilliSeconds);
796 
797 
798 	if (Status == VL53L0X_ERROR_NONE)
799 		Status = VL53L0X_SetXTalkCompensationRateMegaCps(Dev,
800 			pDeviceParameters->XTalkCompensationRateMegaCps);
801 
802 
803 	if (Status == VL53L0X_ERROR_NONE)
804 		Status = VL53L0X_SetOffsetCalibrationDataMicroMeter(Dev,
805 			pDeviceParameters->RangeOffsetMicroMeters);
806 
807 
808 	for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
809 		if (Status == VL53L0X_ERROR_NONE)
810 			Status |= VL53L0X_SetLimitCheckEnable(Dev, i,
811 				pDeviceParameters->LimitChecksEnable[i]);
812 		else
813 			break;
814 
815 		if (Status == VL53L0X_ERROR_NONE)
816 			Status |= VL53L0X_SetLimitCheckValue(Dev, i,
817 				pDeviceParameters->LimitChecksValue[i]);
818 		else
819 			break;
820 
821 	}
822 
823 	if (Status == VL53L0X_ERROR_NONE)
824 		Status = VL53L0X_SetWrapAroundCheckEnable(Dev,
825 			pDeviceParameters->WrapAroundCheckEnable);
826 
827 	if (Status == VL53L0X_ERROR_NONE)
828 		Status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev,
829 			pDeviceParameters->MeasurementTimingBudgetMicroSeconds);
830 
831 
832 	LOG_FUNCTION_END(Status);
833 	return Status;
834 }
835 
VL53L0X_GetDeviceParameters(VL53L0X_DEV Dev,VL53L0X_DeviceParameters_t * pDeviceParameters)836 VL53L0X_Error VL53L0X_GetDeviceParameters(VL53L0X_DEV Dev,
837 	VL53L0X_DeviceParameters_t *pDeviceParameters)
838 {
839 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
840 	int i;
841 
842 	LOG_FUNCTION_START("");
843 
844 	Status = VL53L0X_GetDeviceMode(Dev, &(pDeviceParameters->DeviceMode));
845 
846 	if (Status == VL53L0X_ERROR_NONE)
847 		Status = VL53L0X_GetInterMeasurementPeriodMilliSeconds(Dev,
848 		&(pDeviceParameters->InterMeasurementPeriodMilliSeconds));
849 
850 
851 	if (Status == VL53L0X_ERROR_NONE)
852 		pDeviceParameters->XTalkCompensationEnable = 0;
853 
854 	if (Status == VL53L0X_ERROR_NONE)
855 		Status = VL53L0X_GetXTalkCompensationRateMegaCps(Dev,
856 			&(pDeviceParameters->XTalkCompensationRateMegaCps));
857 
858 
859 	if (Status == VL53L0X_ERROR_NONE)
860 		Status = VL53L0X_GetOffsetCalibrationDataMicroMeter(Dev,
861 			&(pDeviceParameters->RangeOffsetMicroMeters));
862 
863 
864 	if (Status == VL53L0X_ERROR_NONE) {
865 		for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
866 			/* get first the values, then the enables.
867 			 * VL53L0X_GetLimitCheckValue will modify the enable
868 			 * flags
869 			 */
870 			if (Status == VL53L0X_ERROR_NONE) {
871 				Status |= VL53L0X_GetLimitCheckValue(Dev, i,
872 				&(pDeviceParameters->LimitChecksValue[i]));
873 			} else {
874 				break;
875 			}
876 			if (Status == VL53L0X_ERROR_NONE) {
877 				Status |= VL53L0X_GetLimitCheckEnable(Dev, i,
878 				&(pDeviceParameters->LimitChecksEnable[i]));
879 			} else {
880 				break;
881 			}
882 		}
883 	}
884 
885 	if (Status == VL53L0X_ERROR_NONE) {
886 		Status = VL53L0X_GetWrapAroundCheckEnable(Dev,
887 			&(pDeviceParameters->WrapAroundCheckEnable));
888 	}
889 
890 	/* Need to be done at the end as it uses VCSELPulsePeriod */
891 	if (Status == VL53L0X_ERROR_NONE) {
892 		Status = VL53L0X_GetMeasurementTimingBudgetMicroSeconds(Dev,
893 		&(pDeviceParameters->MeasurementTimingBudgetMicroSeconds));
894 	}
895 
896 	LOG_FUNCTION_END(Status);
897 	return Status;
898 }
899 
VL53L0X_SetDeviceMode(VL53L0X_DEV Dev,VL53L0X_DeviceModes DeviceMode)900 VL53L0X_Error VL53L0X_SetDeviceMode(VL53L0X_DEV Dev, VL53L0X_DeviceModes DeviceMode)
901 {
902 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
903 
904 	LOG_FUNCTION_START("%d", (int)DeviceMode);
905 
906 	switch (DeviceMode) {
907 	case VL53L0X_DEVICEMODE_SINGLE_RANGING:
908 	case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING:
909 	case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING:
910 	case VL53L0X_DEVICEMODE_GPIO_DRIVE:
911 	case VL53L0X_DEVICEMODE_GPIO_OSC:
912 		/* Supported modes */
913 		VL53L0X_SETPARAMETERFIELD(Dev, DeviceMode, DeviceMode);
914 		break;
915 	default:
916 		/* Unsupported mode */
917 		Status = VL53L0X_ERROR_MODE_NOT_SUPPORTED;
918 	}
919 
920 	LOG_FUNCTION_END(Status);
921 	return Status;
922 }
923 
VL53L0X_GetDeviceMode(VL53L0X_DEV Dev,VL53L0X_DeviceModes * pDeviceMode)924 VL53L0X_Error VL53L0X_GetDeviceMode(VL53L0X_DEV Dev,
925 	VL53L0X_DeviceModes *pDeviceMode)
926 {
927 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
928 	LOG_FUNCTION_START("");
929 
930 	VL53L0X_GETPARAMETERFIELD(Dev, DeviceMode, *pDeviceMode);
931 
932 	LOG_FUNCTION_END(Status);
933 	return Status;
934 }
935 
VL53L0X_SetRangeFractionEnable(VL53L0X_DEV Dev,uint8_t Enable)936 VL53L0X_Error VL53L0X_SetRangeFractionEnable(VL53L0X_DEV Dev,	uint8_t Enable)
937 {
938 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
939 
940 	LOG_FUNCTION_START("%d", (int)Enable);
941 
942 	Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_RANGE_CONFIG, Enable);
943 
944 	if (Status == VL53L0X_ERROR_NONE)
945 		PALDevDataSet(Dev, RangeFractionalEnable, Enable);
946 
947 	LOG_FUNCTION_END(Status);
948 	return Status;
949 }
950 
VL53L0X_GetFractionEnable(VL53L0X_DEV Dev,uint8_t * pEnabled)951 VL53L0X_Error VL53L0X_GetFractionEnable(VL53L0X_DEV Dev, uint8_t *pEnabled)
952 {
953 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
954 	LOG_FUNCTION_START("");
955 
956 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_RANGE_CONFIG, pEnabled);
957 
958 	if (Status == VL53L0X_ERROR_NONE)
959 		*pEnabled = (*pEnabled & 1);
960 
961 	LOG_FUNCTION_END(Status);
962 	return Status;
963 }
964 
VL53L0X_SetHistogramMode(VL53L0X_DEV Dev,VL53L0X_HistogramModes HistogramMode)965 VL53L0X_Error VL53L0X_SetHistogramMode(VL53L0X_DEV Dev,
966 	VL53L0X_HistogramModes HistogramMode)
967 {
968 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
969 	LOG_FUNCTION_START("");
970 
971 	/* not implemented on VL53L0X */
972 
973 	LOG_FUNCTION_END(Status);
974 	return Status;
975 }
976 
VL53L0X_GetHistogramMode(VL53L0X_DEV Dev,VL53L0X_HistogramModes * pHistogramMode)977 VL53L0X_Error VL53L0X_GetHistogramMode(VL53L0X_DEV Dev,
978 	VL53L0X_HistogramModes *pHistogramMode)
979 {
980 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
981 	LOG_FUNCTION_START("");
982 
983 	/* not implemented on VL53L0X */
984 
985 	LOG_FUNCTION_END(Status);
986 	return Status;
987 }
988 
VL53L0X_SetMeasurementTimingBudgetMicroSeconds(VL53L0X_DEV Dev,uint32_t MeasurementTimingBudgetMicroSeconds)989 VL53L0X_Error VL53L0X_SetMeasurementTimingBudgetMicroSeconds(VL53L0X_DEV Dev,
990 	uint32_t MeasurementTimingBudgetMicroSeconds)
991 {
992 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
993 	LOG_FUNCTION_START("");
994 
995 	Status = VL53L0X_set_measurement_timing_budget_micro_seconds(Dev,
996 		MeasurementTimingBudgetMicroSeconds);
997 
998 	LOG_FUNCTION_END(Status);
999 
1000 	return Status;
1001 }
1002 
VL53L0X_GetMeasurementTimingBudgetMicroSeconds(VL53L0X_DEV Dev,uint32_t * pMeasurementTimingBudgetMicroSeconds)1003 VL53L0X_Error VL53L0X_GetMeasurementTimingBudgetMicroSeconds(VL53L0X_DEV Dev,
1004 	uint32_t *pMeasurementTimingBudgetMicroSeconds)
1005 {
1006 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1007 	LOG_FUNCTION_START("");
1008 
1009 	Status = VL53L0X_get_measurement_timing_budget_micro_seconds(Dev,
1010 		pMeasurementTimingBudgetMicroSeconds);
1011 
1012 	LOG_FUNCTION_END(Status);
1013 	return Status;
1014 }
1015 
VL53L0X_SetVcselPulsePeriod(VL53L0X_DEV Dev,VL53L0X_VcselPeriod VcselPeriodType,uint8_t VCSELPulsePeriodPCLK)1016 VL53L0X_Error VL53L0X_SetVcselPulsePeriod(VL53L0X_DEV Dev,
1017 	VL53L0X_VcselPeriod VcselPeriodType, uint8_t VCSELPulsePeriodPCLK)
1018 {
1019 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1020 	LOG_FUNCTION_START("");
1021 
1022 	Status = VL53L0X_set_vcsel_pulse_period(Dev, VcselPeriodType,
1023 		VCSELPulsePeriodPCLK);
1024 
1025 	LOG_FUNCTION_END(Status);
1026 	return Status;
1027 }
1028 
VL53L0X_GetVcselPulsePeriod(VL53L0X_DEV Dev,VL53L0X_VcselPeriod VcselPeriodType,uint8_t * pVCSELPulsePeriodPCLK)1029 VL53L0X_Error VL53L0X_GetVcselPulsePeriod(VL53L0X_DEV Dev,
1030 	VL53L0X_VcselPeriod VcselPeriodType, uint8_t *pVCSELPulsePeriodPCLK)
1031 {
1032 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1033 	LOG_FUNCTION_START("");
1034 
1035 	Status = VL53L0X_get_vcsel_pulse_period(Dev, VcselPeriodType,
1036 		pVCSELPulsePeriodPCLK);
1037 
1038 	LOG_FUNCTION_END(Status);
1039 	return Status;
1040 }
1041 
VL53L0X_SetSequenceStepEnable(VL53L0X_DEV Dev,VL53L0X_SequenceStepId SequenceStepId,uint8_t SequenceStepEnabled)1042 VL53L0X_Error VL53L0X_SetSequenceStepEnable(VL53L0X_DEV Dev,
1043 	VL53L0X_SequenceStepId SequenceStepId, uint8_t SequenceStepEnabled)
1044 {
1045 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1046 	uint8_t SequenceConfig = 0;
1047 	uint8_t SequenceConfigNew = 0;
1048 	uint32_t MeasurementTimingBudgetMicroSeconds;
1049 	LOG_FUNCTION_START("");
1050 
1051 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
1052 		&SequenceConfig);
1053 
1054 	SequenceConfigNew = SequenceConfig;
1055 
1056 	if (Status == VL53L0X_ERROR_NONE) {
1057 		if (SequenceStepEnabled == 1) {
1058 
1059 			/* Enable requested sequence step
1060 			 */
1061 			switch (SequenceStepId) {
1062 			case VL53L0X_SEQUENCESTEP_TCC:
1063 				SequenceConfigNew |= 0x10;
1064 				break;
1065 			case VL53L0X_SEQUENCESTEP_DSS:
1066 				SequenceConfigNew |= 0x28;
1067 				break;
1068 			case VL53L0X_SEQUENCESTEP_MSRC:
1069 				SequenceConfigNew |= 0x04;
1070 				break;
1071 			case VL53L0X_SEQUENCESTEP_PRE_RANGE:
1072 				SequenceConfigNew |= 0x40;
1073 				break;
1074 			case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
1075 				SequenceConfigNew |= 0x80;
1076 				break;
1077 			default:
1078 				Status = VL53L0X_ERROR_INVALID_PARAMS;
1079 			}
1080 		} else {
1081 			/* Disable requested sequence step
1082 			 */
1083 			switch (SequenceStepId) {
1084 			case VL53L0X_SEQUENCESTEP_TCC:
1085 				SequenceConfigNew &= 0xef;
1086 				break;
1087 			case VL53L0X_SEQUENCESTEP_DSS:
1088 				SequenceConfigNew &= 0xd7;
1089 				break;
1090 			case VL53L0X_SEQUENCESTEP_MSRC:
1091 				SequenceConfigNew &= 0xfb;
1092 				break;
1093 			case VL53L0X_SEQUENCESTEP_PRE_RANGE:
1094 				SequenceConfigNew &= 0xbf;
1095 				break;
1096 			case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
1097 				SequenceConfigNew &= 0x7f;
1098 				break;
1099 			default:
1100 				Status = VL53L0X_ERROR_INVALID_PARAMS;
1101 			}
1102 		}
1103 	}
1104 
1105 	if (SequenceConfigNew != SequenceConfig) {
1106 		/* Apply New Setting */
1107 		if (Status == VL53L0X_ERROR_NONE) {
1108 			Status = VL53L0X_WrByte(Dev,
1109 			VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, SequenceConfigNew);
1110 		}
1111 		if (Status == VL53L0X_ERROR_NONE)
1112 			PALDevDataSet(Dev, SequenceConfig, SequenceConfigNew);
1113 
1114 
1115 		/* Recalculate timing budget */
1116 		if (Status == VL53L0X_ERROR_NONE) {
1117 			VL53L0X_GETPARAMETERFIELD(Dev,
1118 				MeasurementTimingBudgetMicroSeconds,
1119 				MeasurementTimingBudgetMicroSeconds);
1120 
1121 			VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev,
1122 				MeasurementTimingBudgetMicroSeconds);
1123 		}
1124 	}
1125 
1126 	LOG_FUNCTION_END(Status);
1127 
1128 	return Status;
1129 }
1130 
sequence_step_enabled(VL53L0X_DEV Dev,VL53L0X_SequenceStepId SequenceStepId,uint8_t SequenceConfig,uint8_t * pSequenceStepEnabled)1131 VL53L0X_Error sequence_step_enabled(VL53L0X_DEV Dev,
1132 	VL53L0X_SequenceStepId SequenceStepId, uint8_t SequenceConfig,
1133 	uint8_t *pSequenceStepEnabled)
1134 {
1135 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1136 	*pSequenceStepEnabled = 0;
1137 	LOG_FUNCTION_START("");
1138 
1139 	switch (SequenceStepId) {
1140 	case VL53L0X_SEQUENCESTEP_TCC:
1141 		*pSequenceStepEnabled = (SequenceConfig & 0x10) >> 4;
1142 		break;
1143 	case VL53L0X_SEQUENCESTEP_DSS:
1144 		*pSequenceStepEnabled = (SequenceConfig & 0x08) >> 3;
1145 		break;
1146 	case VL53L0X_SEQUENCESTEP_MSRC:
1147 		*pSequenceStepEnabled = (SequenceConfig & 0x04) >> 2;
1148 		break;
1149 	case VL53L0X_SEQUENCESTEP_PRE_RANGE:
1150 		*pSequenceStepEnabled = (SequenceConfig & 0x40) >> 6;
1151 		break;
1152 	case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
1153 		*pSequenceStepEnabled = (SequenceConfig & 0x80) >> 7;
1154 		break;
1155 	default:
1156 		Status = VL53L0X_ERROR_INVALID_PARAMS;
1157 	}
1158 
1159 	LOG_FUNCTION_END(Status);
1160 	return Status;
1161 }
1162 
VL53L0X_GetSequenceStepEnable(VL53L0X_DEV Dev,VL53L0X_SequenceStepId SequenceStepId,uint8_t * pSequenceStepEnabled)1163 VL53L0X_Error VL53L0X_GetSequenceStepEnable(VL53L0X_DEV Dev,
1164 	VL53L0X_SequenceStepId SequenceStepId, uint8_t *pSequenceStepEnabled)
1165 {
1166 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1167 	uint8_t SequenceConfig = 0;
1168 	LOG_FUNCTION_START("");
1169 
1170 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
1171 		&SequenceConfig);
1172 
1173 	if (Status == VL53L0X_ERROR_NONE) {
1174 		Status = sequence_step_enabled(Dev, SequenceStepId,
1175 			SequenceConfig, pSequenceStepEnabled);
1176 	}
1177 
1178 	LOG_FUNCTION_END(Status);
1179 	return Status;
1180 }
1181 
VL53L0X_GetSequenceStepEnables(VL53L0X_DEV Dev,VL53L0X_SchedulerSequenceSteps_t * pSchedulerSequenceSteps)1182 VL53L0X_Error VL53L0X_GetSequenceStepEnables(VL53L0X_DEV Dev,
1183 	VL53L0X_SchedulerSequenceSteps_t *pSchedulerSequenceSteps)
1184 {
1185 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1186 	uint8_t SequenceConfig = 0;
1187 	LOG_FUNCTION_START("");
1188 
1189 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
1190 		&SequenceConfig);
1191 
1192 	if (Status == VL53L0X_ERROR_NONE) {
1193 		Status = sequence_step_enabled(Dev,
1194 		VL53L0X_SEQUENCESTEP_TCC, SequenceConfig,
1195 			&pSchedulerSequenceSteps->TccOn);
1196 	}
1197 	if (Status == VL53L0X_ERROR_NONE) {
1198 		Status = sequence_step_enabled(Dev,
1199 		VL53L0X_SEQUENCESTEP_DSS, SequenceConfig,
1200 			&pSchedulerSequenceSteps->DssOn);
1201 	}
1202 	if (Status == VL53L0X_ERROR_NONE) {
1203 		Status = sequence_step_enabled(Dev,
1204 		VL53L0X_SEQUENCESTEP_MSRC, SequenceConfig,
1205 			&pSchedulerSequenceSteps->MsrcOn);
1206 	}
1207 	if (Status == VL53L0X_ERROR_NONE) {
1208 		Status = sequence_step_enabled(Dev,
1209 		VL53L0X_SEQUENCESTEP_PRE_RANGE, SequenceConfig,
1210 			&pSchedulerSequenceSteps->PreRangeOn);
1211 	}
1212 	if (Status == VL53L0X_ERROR_NONE) {
1213 		Status = sequence_step_enabled(Dev,
1214 		VL53L0X_SEQUENCESTEP_FINAL_RANGE, SequenceConfig,
1215 			&pSchedulerSequenceSteps->FinalRangeOn);
1216 	}
1217 
1218 	LOG_FUNCTION_END(Status);
1219 	return Status;
1220 }
1221 
VL53L0X_GetNumberOfSequenceSteps(VL53L0X_DEV Dev,uint8_t * pNumberOfSequenceSteps)1222 VL53L0X_Error VL53L0X_GetNumberOfSequenceSteps(VL53L0X_DEV Dev,
1223 	uint8_t *pNumberOfSequenceSteps)
1224 {
1225 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1226 	LOG_FUNCTION_START("");
1227 
1228 	*pNumberOfSequenceSteps = VL53L0X_SEQUENCESTEP_NUMBER_OF_CHECKS;
1229 
1230 	LOG_FUNCTION_END(Status);
1231 	return Status;
1232 }
1233 
VL53L0X_GetSequenceStepsInfo(VL53L0X_SequenceStepId SequenceStepId,char * pSequenceStepsString)1234 VL53L0X_Error VL53L0X_GetSequenceStepsInfo(VL53L0X_SequenceStepId SequenceStepId,
1235 	char *pSequenceStepsString)
1236 {
1237 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1238 	LOG_FUNCTION_START("");
1239 
1240 	Status = VL53L0X_get_sequence_steps_info(
1241 			SequenceStepId,
1242 			pSequenceStepsString);
1243 
1244 	LOG_FUNCTION_END(Status);
1245 
1246 	return Status;
1247 }
1248 
VL53L0X_SetSequenceStepTimeout(VL53L0X_DEV Dev,VL53L0X_SequenceStepId SequenceStepId,FixPoint1616_t TimeOutMilliSecs)1249 VL53L0X_Error VL53L0X_SetSequenceStepTimeout(VL53L0X_DEV Dev,
1250 	VL53L0X_SequenceStepId SequenceStepId, FixPoint1616_t TimeOutMilliSecs)
1251 {
1252 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1253 	VL53L0X_Error Status1 = VL53L0X_ERROR_NONE;
1254 	uint32_t TimeoutMicroSeconds = ((TimeOutMilliSecs * 1000) + 0x8000)
1255 		>> 16;
1256 	uint32_t MeasurementTimingBudgetMicroSeconds;
1257 	FixPoint1616_t OldTimeOutMicroSeconds;
1258 
1259 	LOG_FUNCTION_START("");
1260 
1261 	/* Read back the current value in case we need to revert back to this.
1262 	 */
1263 	Status = get_sequence_step_timeout(Dev, SequenceStepId,
1264 		&OldTimeOutMicroSeconds);
1265 
1266 	if (Status == VL53L0X_ERROR_NONE) {
1267 		Status = set_sequence_step_timeout(Dev, SequenceStepId,
1268 			TimeoutMicroSeconds);
1269 	}
1270 
1271 	if (Status == VL53L0X_ERROR_NONE) {
1272 		VL53L0X_GETPARAMETERFIELD(Dev,
1273 			MeasurementTimingBudgetMicroSeconds,
1274 			MeasurementTimingBudgetMicroSeconds);
1275 
1276 		/* At this point we don't know if the requested value is valid,
1277 		 therefore proceed to update the entire timing budget and
1278 		 if this fails, revert back to the previous value.
1279 		 */
1280 		Status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev,
1281 			MeasurementTimingBudgetMicroSeconds);
1282 
1283 		if (Status != VL53L0X_ERROR_NONE) {
1284 			Status1 = set_sequence_step_timeout(Dev, SequenceStepId,
1285 				OldTimeOutMicroSeconds);
1286 
1287 			if (Status1 == VL53L0X_ERROR_NONE) {
1288 				Status1 =
1289 				VL53L0X_SetMeasurementTimingBudgetMicroSeconds(
1290 					Dev,
1291 					MeasurementTimingBudgetMicroSeconds);
1292 			}
1293 
1294 			Status = Status1;
1295 		}
1296 	}
1297 
1298 	LOG_FUNCTION_END(Status);
1299 
1300 	return Status;
1301 }
1302 
VL53L0X_GetSequenceStepTimeout(VL53L0X_DEV Dev,VL53L0X_SequenceStepId SequenceStepId,FixPoint1616_t * pTimeOutMilliSecs)1303 VL53L0X_Error VL53L0X_GetSequenceStepTimeout(VL53L0X_DEV Dev,
1304 	VL53L0X_SequenceStepId SequenceStepId, FixPoint1616_t *pTimeOutMilliSecs)
1305 {
1306 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1307 	uint32_t TimeoutMicroSeconds;
1308 	LOG_FUNCTION_START("");
1309 
1310 	Status = get_sequence_step_timeout(Dev, SequenceStepId,
1311 		&TimeoutMicroSeconds);
1312 	if (Status == VL53L0X_ERROR_NONE) {
1313 		TimeoutMicroSeconds <<= 8;
1314 		*pTimeOutMilliSecs = (TimeoutMicroSeconds + 500)/1000;
1315 		*pTimeOutMilliSecs <<= 8;
1316 	}
1317 
1318 	LOG_FUNCTION_END(Status);
1319 	return Status;
1320 }
1321 
VL53L0X_SetInterMeasurementPeriodMilliSeconds(VL53L0X_DEV Dev,uint32_t InterMeasurementPeriodMilliSeconds)1322 VL53L0X_Error VL53L0X_SetInterMeasurementPeriodMilliSeconds(VL53L0X_DEV Dev,
1323 	uint32_t InterMeasurementPeriodMilliSeconds)
1324 {
1325 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1326 	uint16_t osc_calibrate_val;
1327 	uint32_t IMPeriodMilliSeconds;
1328 
1329 	LOG_FUNCTION_START("");
1330 
1331 	Status = VL53L0X_RdWord(Dev, VL53L0X_REG_OSC_CALIBRATE_VAL,
1332 		&osc_calibrate_val);
1333 
1334 	if (Status == VL53L0X_ERROR_NONE) {
1335 		if (osc_calibrate_val != 0) {
1336 			IMPeriodMilliSeconds =
1337 				InterMeasurementPeriodMilliSeconds
1338 					* osc_calibrate_val;
1339 		} else {
1340 			IMPeriodMilliSeconds =
1341 				InterMeasurementPeriodMilliSeconds;
1342 		}
1343 		Status = VL53L0X_WrDWord(Dev,
1344 		VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD,
1345 			IMPeriodMilliSeconds);
1346 	}
1347 
1348 	if (Status == VL53L0X_ERROR_NONE) {
1349 		VL53L0X_SETPARAMETERFIELD(Dev,
1350 			InterMeasurementPeriodMilliSeconds,
1351 			InterMeasurementPeriodMilliSeconds);
1352 	}
1353 
1354 	LOG_FUNCTION_END(Status);
1355 	return Status;
1356 }
1357 
VL53L0X_GetInterMeasurementPeriodMilliSeconds(VL53L0X_DEV Dev,uint32_t * pInterMeasurementPeriodMilliSeconds)1358 VL53L0X_Error VL53L0X_GetInterMeasurementPeriodMilliSeconds(VL53L0X_DEV Dev,
1359 	uint32_t *pInterMeasurementPeriodMilliSeconds)
1360 {
1361 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1362 	uint16_t osc_calibrate_val;
1363 	uint32_t IMPeriodMilliSeconds;
1364 
1365 	LOG_FUNCTION_START("");
1366 
1367 	Status = VL53L0X_RdWord(Dev, VL53L0X_REG_OSC_CALIBRATE_VAL,
1368 		&osc_calibrate_val);
1369 
1370 	if (Status == VL53L0X_ERROR_NONE) {
1371 		Status = VL53L0X_RdDWord(Dev,
1372 		VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD,
1373 			&IMPeriodMilliSeconds);
1374 	}
1375 
1376 	if (Status == VL53L0X_ERROR_NONE) {
1377 		if (osc_calibrate_val != 0) {
1378 			*pInterMeasurementPeriodMilliSeconds =
1379 				IMPeriodMilliSeconds / osc_calibrate_val;
1380 		}
1381 		VL53L0X_SETPARAMETERFIELD(Dev,
1382 			InterMeasurementPeriodMilliSeconds,
1383 			*pInterMeasurementPeriodMilliSeconds);
1384 	}
1385 
1386 	LOG_FUNCTION_END(Status);
1387 	return Status;
1388 }
1389 
VL53L0X_SetXTalkCompensationEnable(VL53L0X_DEV Dev,uint8_t XTalkCompensationEnable)1390 VL53L0X_Error VL53L0X_SetXTalkCompensationEnable(VL53L0X_DEV Dev,
1391 	uint8_t XTalkCompensationEnable)
1392 {
1393 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1394 	FixPoint1616_t TempFix1616;
1395 	uint16_t LinearityCorrectiveGain;
1396 
1397 	LOG_FUNCTION_START("");
1398 
1399 	LinearityCorrectiveGain = PALDevDataGet(Dev, LinearityCorrectiveGain);
1400 
1401 	if ((XTalkCompensationEnable == 0)
1402 		|| (LinearityCorrectiveGain != 1000)) {
1403 		TempFix1616 = 0;
1404 	} else {
1405 		VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps,
1406 			TempFix1616);
1407 	}
1408 
1409 	/* the following register has a format 3.13 */
1410 	Status = VL53L0X_WrWord(Dev,
1411 	VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS,
1412 		VL53L0X_FIXPOINT1616TOFIXPOINT313(TempFix1616));
1413 
1414 	if (Status == VL53L0X_ERROR_NONE) {
1415 		if (XTalkCompensationEnable == 0) {
1416 			VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationEnable,
1417 				0);
1418 		} else {
1419 			VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationEnable,
1420 				1);
1421 		}
1422 	}
1423 
1424 	LOG_FUNCTION_END(Status);
1425 	return Status;
1426 }
1427 
VL53L0X_GetXTalkCompensationEnable(VL53L0X_DEV Dev,uint8_t * pXTalkCompensationEnable)1428 VL53L0X_Error VL53L0X_GetXTalkCompensationEnable(VL53L0X_DEV Dev,
1429 	uint8_t *pXTalkCompensationEnable)
1430 {
1431 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1432 	uint8_t Temp8;
1433 	LOG_FUNCTION_START("");
1434 
1435 	VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationEnable, Temp8);
1436 	*pXTalkCompensationEnable = Temp8;
1437 
1438 	LOG_FUNCTION_END(Status);
1439 	return Status;
1440 }
1441 
VL53L0X_SetXTalkCompensationRateMegaCps(VL53L0X_DEV Dev,FixPoint1616_t XTalkCompensationRateMegaCps)1442 VL53L0X_Error VL53L0X_SetXTalkCompensationRateMegaCps(VL53L0X_DEV Dev,
1443 	FixPoint1616_t XTalkCompensationRateMegaCps)
1444 {
1445 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1446 	uint8_t Temp8;
1447 	uint16_t LinearityCorrectiveGain;
1448 	uint16_t data;
1449 	LOG_FUNCTION_START("");
1450 
1451 	VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationEnable, Temp8);
1452 	LinearityCorrectiveGain = PALDevDataGet(Dev, LinearityCorrectiveGain);
1453 
1454 	if (Temp8 == 0) { /* disabled write only internal value */
1455 		VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps,
1456 			XTalkCompensationRateMegaCps);
1457 	} else {
1458 		/* the following register has a format 3.13 */
1459 		if (LinearityCorrectiveGain == 1000) {
1460 			data = VL53L0X_FIXPOINT1616TOFIXPOINT313(
1461 				XTalkCompensationRateMegaCps);
1462 		} else {
1463 			data = 0;
1464 		}
1465 
1466 		Status = VL53L0X_WrWord(Dev,
1467 		VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, data);
1468 
1469 		if (Status == VL53L0X_ERROR_NONE) {
1470 			VL53L0X_SETPARAMETERFIELD(Dev,
1471 				XTalkCompensationRateMegaCps,
1472 				XTalkCompensationRateMegaCps);
1473 		}
1474 	}
1475 
1476 	LOG_FUNCTION_END(Status);
1477 	return Status;
1478 }
1479 
VL53L0X_GetXTalkCompensationRateMegaCps(VL53L0X_DEV Dev,FixPoint1616_t * pXTalkCompensationRateMegaCps)1480 VL53L0X_Error VL53L0X_GetXTalkCompensationRateMegaCps(VL53L0X_DEV Dev,
1481 	FixPoint1616_t *pXTalkCompensationRateMegaCps)
1482 {
1483 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1484 	uint16_t Value;
1485 	FixPoint1616_t TempFix1616;
1486 
1487 	LOG_FUNCTION_START("");
1488 
1489 	Status = VL53L0X_RdWord(Dev,
1490 	VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, (uint16_t *)&Value);
1491 	if (Status == VL53L0X_ERROR_NONE) {
1492 		if (Value == 0) {
1493 			/* the Xtalk is disabled return value from memory */
1494 			VL53L0X_GETPARAMETERFIELD(Dev,
1495 				XTalkCompensationRateMegaCps, TempFix1616);
1496 			*pXTalkCompensationRateMegaCps = TempFix1616;
1497 			VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationEnable,
1498 				0);
1499 		} else {
1500 			TempFix1616 = VL53L0X_FIXPOINT313TOFIXPOINT1616(Value);
1501 			*pXTalkCompensationRateMegaCps = TempFix1616;
1502 			VL53L0X_SETPARAMETERFIELD(Dev,
1503 				XTalkCompensationRateMegaCps, TempFix1616);
1504 			VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationEnable,
1505 				1);
1506 		}
1507 	}
1508 
1509 	LOG_FUNCTION_END(Status);
1510 	return Status;
1511 }
1512 
VL53L0X_SetRefCalibration(VL53L0X_DEV Dev,uint8_t VhvSettings,uint8_t PhaseCal)1513 VL53L0X_Error VL53L0X_SetRefCalibration(VL53L0X_DEV Dev, uint8_t VhvSettings,
1514 	uint8_t PhaseCal)
1515 {
1516 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1517 	LOG_FUNCTION_START("");
1518 
1519 	Status = VL53L0X_set_ref_calibration(Dev, VhvSettings, PhaseCal);
1520 
1521 	LOG_FUNCTION_END(Status);
1522 	return Status;
1523 }
1524 
VL53L0X_GetRefCalibration(VL53L0X_DEV Dev,uint8_t * pVhvSettings,uint8_t * pPhaseCal)1525 VL53L0X_Error VL53L0X_GetRefCalibration(VL53L0X_DEV Dev, uint8_t *pVhvSettings,
1526 	uint8_t *pPhaseCal)
1527 {
1528 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1529 	LOG_FUNCTION_START("");
1530 
1531 	Status = VL53L0X_get_ref_calibration(Dev, pVhvSettings, pPhaseCal);
1532 
1533 	LOG_FUNCTION_END(Status);
1534 	return Status;
1535 }
1536 
1537 /*
1538  * CHECK LIMIT FUNCTIONS
1539  */
1540 
VL53L0X_GetNumberOfLimitCheck(uint16_t * pNumberOfLimitCheck)1541 VL53L0X_Error VL53L0X_GetNumberOfLimitCheck(uint16_t *pNumberOfLimitCheck)
1542 {
1543 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1544 	LOG_FUNCTION_START("");
1545 
1546 	*pNumberOfLimitCheck = VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS;
1547 
1548 	LOG_FUNCTION_END(Status);
1549 	return Status;
1550 }
1551 
VL53L0X_GetLimitCheckInfo(VL53L0X_DEV Dev,uint16_t LimitCheckId,char * pLimitCheckString)1552 VL53L0X_Error VL53L0X_GetLimitCheckInfo(VL53L0X_DEV Dev, uint16_t LimitCheckId,
1553 	char *pLimitCheckString)
1554 {
1555 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1556 
1557 	LOG_FUNCTION_START("");
1558 
1559 	Status = VL53L0X_get_limit_check_info(Dev, LimitCheckId,
1560 		pLimitCheckString);
1561 
1562 	LOG_FUNCTION_END(Status);
1563 	return Status;
1564 }
1565 
VL53L0X_GetLimitCheckStatus(VL53L0X_DEV Dev,uint16_t LimitCheckId,uint8_t * pLimitCheckStatus)1566 VL53L0X_Error VL53L0X_GetLimitCheckStatus(VL53L0X_DEV Dev, uint16_t LimitCheckId,
1567 	uint8_t *pLimitCheckStatus)
1568 {
1569 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1570 	uint8_t Temp8;
1571 
1572 	LOG_FUNCTION_START("");
1573 
1574 	if (LimitCheckId >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) {
1575 		Status = VL53L0X_ERROR_INVALID_PARAMS;
1576 	} else {
1577 
1578 		VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
1579 			LimitCheckId, Temp8);
1580 
1581 		*pLimitCheckStatus = Temp8;
1582 
1583 	}
1584 
1585 	LOG_FUNCTION_END(Status);
1586 	return Status;
1587 }
1588 
VL53L0X_SetLimitCheckEnable(VL53L0X_DEV Dev,uint16_t LimitCheckId,uint8_t LimitCheckEnable)1589 VL53L0X_Error VL53L0X_SetLimitCheckEnable(VL53L0X_DEV Dev, uint16_t LimitCheckId,
1590 	uint8_t LimitCheckEnable)
1591 {
1592 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1593 	FixPoint1616_t TempFix1616 = 0;
1594 	uint8_t LimitCheckEnableInt = 0;
1595 	uint8_t LimitCheckDisable = 0;
1596 	uint8_t Temp8;
1597 
1598 	LOG_FUNCTION_START("");
1599 
1600 	if (LimitCheckId >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) {
1601 		Status = VL53L0X_ERROR_INVALID_PARAMS;
1602 	} else {
1603 		if (LimitCheckEnable == 0) {
1604 			TempFix1616 = 0;
1605 			LimitCheckEnableInt = 0;
1606 			LimitCheckDisable = 1;
1607 
1608 		} else {
1609 			VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1610 				LimitCheckId, TempFix1616);
1611 			LimitCheckDisable = 0;
1612 			/* this to be sure to have either 0 or 1 */
1613 			LimitCheckEnableInt = 1;
1614 		}
1615 
1616 		switch (LimitCheckId) {
1617 
1618 		case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
1619 			/* internal computation: */
1620 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
1621 				VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
1622 				LimitCheckEnableInt);
1623 
1624 			break;
1625 
1626 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
1627 
1628 			Status = VL53L0X_WrWord(Dev,
1629 			VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT,
1630 				VL53L0X_FIXPOINT1616TOFIXPOINT97(TempFix1616));
1631 
1632 			break;
1633 
1634 		case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:
1635 
1636 			/* internal computation: */
1637 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
1638 				VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
1639 				LimitCheckEnableInt);
1640 
1641 			break;
1642 
1643 		case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:
1644 
1645 			/* internal computation: */
1646 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
1647 				VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
1648 				LimitCheckEnableInt);
1649 
1650 			break;
1651 
1652 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
1653 
1654 			Temp8 = (uint8_t)(LimitCheckDisable << 1);
1655 			Status = VL53L0X_UpdateByte(Dev,
1656 				VL53L0X_REG_MSRC_CONFIG_CONTROL,
1657 				0xFE, Temp8);
1658 
1659 			break;
1660 
1661 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
1662 
1663 			Temp8 = (uint8_t)(LimitCheckDisable << 4);
1664 			Status = VL53L0X_UpdateByte(Dev,
1665 				VL53L0X_REG_MSRC_CONFIG_CONTROL,
1666 				0xEF, Temp8);
1667 
1668 			break;
1669 
1670 
1671 		default:
1672 			Status = VL53L0X_ERROR_INVALID_PARAMS;
1673 
1674 		}
1675 
1676 	}
1677 
1678 	if (Status == VL53L0X_ERROR_NONE) {
1679 		if (LimitCheckEnable == 0) {
1680 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
1681 				LimitCheckId, 0);
1682 		} else {
1683 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
1684 				LimitCheckId, 1);
1685 		}
1686 	}
1687 
1688 	LOG_FUNCTION_END(Status);
1689 	return Status;
1690 }
1691 
VL53L0X_GetLimitCheckEnable(VL53L0X_DEV Dev,uint16_t LimitCheckId,uint8_t * pLimitCheckEnable)1692 VL53L0X_Error VL53L0X_GetLimitCheckEnable(VL53L0X_DEV Dev, uint16_t LimitCheckId,
1693 	uint8_t *pLimitCheckEnable)
1694 {
1695 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1696 	uint8_t Temp8;
1697 
1698 	LOG_FUNCTION_START("");
1699 
1700 	if (LimitCheckId >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) {
1701 		Status = VL53L0X_ERROR_INVALID_PARAMS;
1702 		*pLimitCheckEnable = 0;
1703 	} else {
1704 		VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
1705 			LimitCheckId, Temp8);
1706 		*pLimitCheckEnable = Temp8;
1707 	}
1708 
1709 	LOG_FUNCTION_END(Status);
1710 	return Status;
1711 }
1712 
VL53L0X_SetLimitCheckValue(VL53L0X_DEV Dev,uint16_t LimitCheckId,FixPoint1616_t LimitCheckValue)1713 VL53L0X_Error VL53L0X_SetLimitCheckValue(VL53L0X_DEV Dev, uint16_t LimitCheckId,
1714 	FixPoint1616_t LimitCheckValue)
1715 {
1716 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1717 	uint8_t Temp8;
1718 
1719 	LOG_FUNCTION_START("");
1720 
1721 	VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable, LimitCheckId,
1722 		Temp8);
1723 
1724 	if (Temp8 == 0) { /* disabled write only internal value */
1725 		VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1726 			LimitCheckId, LimitCheckValue);
1727 	} else {
1728 
1729 		switch (LimitCheckId) {
1730 
1731 		case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
1732 			/* internal computation: */
1733 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1734 				VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
1735 				LimitCheckValue);
1736 			break;
1737 
1738 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
1739 
1740 			Status = VL53L0X_WrWord(Dev,
1741 			VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT,
1742 				VL53L0X_FIXPOINT1616TOFIXPOINT97(
1743 					LimitCheckValue));
1744 
1745 			break;
1746 
1747 		case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:
1748 
1749 			/* internal computation: */
1750 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1751 				VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
1752 				LimitCheckValue);
1753 
1754 			break;
1755 
1756 		case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:
1757 
1758 			/* internal computation: */
1759 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1760 				VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
1761 				LimitCheckValue);
1762 
1763 			break;
1764 
1765 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
1766 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
1767 
1768 			Status = VL53L0X_WrWord(Dev,
1769 				VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT,
1770 				VL53L0X_FIXPOINT1616TOFIXPOINT97(
1771 					LimitCheckValue));
1772 
1773 			break;
1774 
1775 		default:
1776 			Status = VL53L0X_ERROR_INVALID_PARAMS;
1777 
1778 		}
1779 
1780 		if (Status == VL53L0X_ERROR_NONE) {
1781 			VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1782 				LimitCheckId, LimitCheckValue);
1783 		}
1784 	}
1785 
1786 	LOG_FUNCTION_END(Status);
1787 	return Status;
1788 }
1789 
VL53L0X_GetLimitCheckValue(VL53L0X_DEV Dev,uint16_t LimitCheckId,FixPoint1616_t * pLimitCheckValue)1790 VL53L0X_Error VL53L0X_GetLimitCheckValue(VL53L0X_DEV Dev, uint16_t LimitCheckId,
1791 	FixPoint1616_t *pLimitCheckValue)
1792 {
1793 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1794 	uint8_t EnableZeroValue = 0;
1795 	uint16_t Temp16;
1796 	FixPoint1616_t TempFix1616=0;
1797 
1798 	LOG_FUNCTION_START("");
1799 
1800 	switch (LimitCheckId) {
1801 
1802 	case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
1803 		/* internal computation: */
1804 		VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1805 			VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, TempFix1616);
1806 		EnableZeroValue = 0;
1807 		break;
1808 
1809 	case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
1810 		Status = VL53L0X_RdWord(Dev,
1811 		VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT,
1812 			&Temp16);
1813 		if (Status == VL53L0X_ERROR_NONE)
1814 			TempFix1616 = VL53L0X_FIXPOINT97TOFIXPOINT1616(Temp16);
1815 
1816 
1817 		EnableZeroValue = 1;
1818 		break;
1819 
1820 	case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:
1821 		/* internal computation: */
1822 		VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1823 			VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, TempFix1616);
1824 		EnableZeroValue = 0;
1825 		break;
1826 
1827 	case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:
1828 		/* internal computation: */
1829 		VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
1830 			VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, TempFix1616);
1831 		EnableZeroValue = 0;
1832 		break;
1833 
1834 	case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
1835 	case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
1836 		Status = VL53L0X_RdWord(Dev,
1837 			VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT,
1838 			&Temp16);
1839 		if (Status == VL53L0X_ERROR_NONE)
1840 			TempFix1616 = VL53L0X_FIXPOINT97TOFIXPOINT1616(Temp16);
1841 
1842 
1843 		EnableZeroValue = 0;
1844 		break;
1845 
1846 	default:
1847 		Status = VL53L0X_ERROR_INVALID_PARAMS;
1848 
1849 	}
1850 
1851 	if (Status == VL53L0X_ERROR_NONE) {
1852 
1853 		if (EnableZeroValue == 1) {
1854 
1855 			if (TempFix1616 == 0) {
1856 				/* disabled: return value from memory */
1857 				VL53L0X_GETARRAYPARAMETERFIELD(Dev,
1858 					LimitChecksValue, LimitCheckId,
1859 					TempFix1616);
1860 				*pLimitCheckValue = TempFix1616;
1861 				VL53L0X_SETARRAYPARAMETERFIELD(Dev,
1862 					LimitChecksEnable, LimitCheckId, 0);
1863 			} else {
1864 				*pLimitCheckValue = TempFix1616;
1865 				VL53L0X_SETARRAYPARAMETERFIELD(Dev,
1866 					LimitChecksValue, LimitCheckId,
1867 					TempFix1616);
1868 				VL53L0X_SETARRAYPARAMETERFIELD(Dev,
1869 					LimitChecksEnable, LimitCheckId, 1);
1870 			}
1871 		} else {
1872 			*pLimitCheckValue = TempFix1616;
1873 		}
1874 	}
1875 
1876 	LOG_FUNCTION_END(Status);
1877 	return Status;
1878 
1879 }
1880 
VL53L0X_GetLimitCheckCurrent(VL53L0X_DEV Dev,uint16_t LimitCheckId,FixPoint1616_t * pLimitCheckCurrent)1881 VL53L0X_Error VL53L0X_GetLimitCheckCurrent(VL53L0X_DEV Dev, uint16_t LimitCheckId,
1882 	FixPoint1616_t *pLimitCheckCurrent)
1883 {
1884 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1885 	VL53L0X_RangingMeasurementData_t LastRangeDataBuffer;
1886 
1887 	LOG_FUNCTION_START("");
1888 
1889 	if (LimitCheckId >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) {
1890 		Status = VL53L0X_ERROR_INVALID_PARAMS;
1891 	} else {
1892 		switch (LimitCheckId) {
1893 		case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
1894 			/* Need to run a ranging to have the latest values */
1895 			*pLimitCheckCurrent = PALDevDataGet(Dev, SigmaEstimate);
1896 
1897 			break;
1898 
1899 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
1900 			/* Need to run a ranging to have the latest values */
1901 			LastRangeDataBuffer = PALDevDataGet(Dev,
1902 				LastRangeMeasure);
1903 			*pLimitCheckCurrent =
1904 				LastRangeDataBuffer.SignalRateRtnMegaCps;
1905 
1906 			break;
1907 
1908 		case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:
1909 			/* Need to run a ranging to have the latest values */
1910 			*pLimitCheckCurrent = PALDevDataGet(Dev,
1911 				LastSignalRefMcps);
1912 
1913 			break;
1914 
1915 		case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:
1916 			/* Need to run a ranging to have the latest values */
1917 			LastRangeDataBuffer = PALDevDataGet(Dev,
1918 				LastRangeMeasure);
1919 			*pLimitCheckCurrent =
1920 				LastRangeDataBuffer.SignalRateRtnMegaCps;
1921 
1922 			break;
1923 
1924 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
1925 			/* Need to run a ranging to have the latest values */
1926 			LastRangeDataBuffer = PALDevDataGet(Dev,
1927 				LastRangeMeasure);
1928 			*pLimitCheckCurrent =
1929 				LastRangeDataBuffer.SignalRateRtnMegaCps;
1930 
1931 			break;
1932 
1933 		case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
1934 			/* Need to run a ranging to have the latest values */
1935 			LastRangeDataBuffer = PALDevDataGet(Dev,
1936 				LastRangeMeasure);
1937 			*pLimitCheckCurrent =
1938 				LastRangeDataBuffer.SignalRateRtnMegaCps;
1939 
1940 			break;
1941 
1942 		default:
1943 			Status = VL53L0X_ERROR_INVALID_PARAMS;
1944 		}
1945 	}
1946 
1947 	LOG_FUNCTION_END(Status);
1948 	return Status;
1949 
1950 }
1951 
1952 /*
1953  * WRAPAROUND Check
1954  */
VL53L0X_SetWrapAroundCheckEnable(VL53L0X_DEV Dev,uint8_t WrapAroundCheckEnable)1955 VL53L0X_Error VL53L0X_SetWrapAroundCheckEnable(VL53L0X_DEV Dev,
1956 	uint8_t WrapAroundCheckEnable)
1957 {
1958 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1959 	uint8_t Byte;
1960 	uint8_t WrapAroundCheckEnableInt;
1961 
1962 	LOG_FUNCTION_START("");
1963 
1964 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &Byte);
1965 	if (WrapAroundCheckEnable == 0) {
1966 		/* Disable wraparound */
1967 		Byte = Byte & 0x7F;
1968 		WrapAroundCheckEnableInt = 0;
1969 	} else {
1970 		/*Enable wraparound */
1971 		Byte = Byte | 0x80;
1972 		WrapAroundCheckEnableInt = 1;
1973 	}
1974 
1975 	Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, Byte);
1976 
1977 	if (Status == VL53L0X_ERROR_NONE) {
1978 		PALDevDataSet(Dev, SequenceConfig, Byte);
1979 		VL53L0X_SETPARAMETERFIELD(Dev, WrapAroundCheckEnable,
1980 			WrapAroundCheckEnableInt);
1981 	}
1982 
1983 	LOG_FUNCTION_END(Status);
1984 	return Status;
1985 }
1986 
VL53L0X_GetWrapAroundCheckEnable(VL53L0X_DEV Dev,uint8_t * pWrapAroundCheckEnable)1987 VL53L0X_Error VL53L0X_GetWrapAroundCheckEnable(VL53L0X_DEV Dev,
1988 	uint8_t *pWrapAroundCheckEnable)
1989 {
1990 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
1991 	uint8_t data;
1992 
1993 	LOG_FUNCTION_START("");
1994 
1995 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &data);
1996 	if (Status == VL53L0X_ERROR_NONE) {
1997 		PALDevDataSet(Dev, SequenceConfig, data);
1998 		if (data & (0x01 << 7))
1999 			*pWrapAroundCheckEnable = 0x01;
2000 		else
2001 			*pWrapAroundCheckEnable = 0x00;
2002 	}
2003 	if (Status == VL53L0X_ERROR_NONE) {
2004 		VL53L0X_SETPARAMETERFIELD(Dev, WrapAroundCheckEnable,
2005 			*pWrapAroundCheckEnable);
2006 	}
2007 
2008 	LOG_FUNCTION_END(Status);
2009 	return Status;
2010 }
2011 
VL53L0X_SetDmaxCalParameters(VL53L0X_DEV Dev,uint16_t RangeMilliMeter,FixPoint1616_t SignalRateRtnMegaCps)2012 VL53L0X_Error VL53L0X_SetDmaxCalParameters(VL53L0X_DEV Dev,
2013 	uint16_t RangeMilliMeter, FixPoint1616_t SignalRateRtnMegaCps)
2014 {
2015 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2016 	FixPoint1616_t SignalRateRtnMegaCpsTemp = 0;
2017 
2018 	LOG_FUNCTION_START("");
2019 
2020 	/* Check if one of input parameter is zero, in that case the
2021 	 * value are get from NVM */
2022 	if ((RangeMilliMeter == 0) || (SignalRateRtnMegaCps == 0)) {
2023 		/* NVM parameters */
2024 		/* Run VL53L0X_get_info_from_device wit option 4 to get
2025 		 * signal rate at 400 mm if the value have been already
2026 		 * get this function will return with no access to device */
2027 		VL53L0X_get_info_from_device(Dev, 4);
2028 
2029 		SignalRateRtnMegaCpsTemp = VL53L0X_GETDEVICESPECIFICPARAMETER(
2030 			Dev, SignalRateMeasFixed400mm);
2031 
2032 		PALDevDataSet(Dev, DmaxCalRangeMilliMeter, 400);
2033 		PALDevDataSet(Dev, DmaxCalSignalRateRtnMegaCps,
2034 			SignalRateRtnMegaCpsTemp);
2035 	} else {
2036 		/* User parameters */
2037 		PALDevDataSet(Dev, DmaxCalRangeMilliMeter, RangeMilliMeter);
2038 		PALDevDataSet(Dev, DmaxCalSignalRateRtnMegaCps,
2039 			SignalRateRtnMegaCps);
2040 	}
2041 
2042 	LOG_FUNCTION_END(Status);
2043 	return Status;
2044 }
2045 
VL53L0X_GetDmaxCalParameters(VL53L0X_DEV Dev,uint16_t * pRangeMilliMeter,FixPoint1616_t * pSignalRateRtnMegaCps)2046 VL53L0X_Error VL53L0X_GetDmaxCalParameters(VL53L0X_DEV Dev,
2047 	uint16_t *pRangeMilliMeter, FixPoint1616_t *pSignalRateRtnMegaCps)
2048 {
2049 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2050 
2051 	LOG_FUNCTION_START("");
2052 
2053 	*pRangeMilliMeter = PALDevDataGet(Dev, DmaxCalRangeMilliMeter);
2054 	*pSignalRateRtnMegaCps = PALDevDataGet(Dev,
2055 		DmaxCalSignalRateRtnMegaCps);
2056 
2057 	LOG_FUNCTION_END(Status);
2058 	return Status;
2059 }
2060 
2061 /* End Group PAL Parameters Functions */
2062 
2063 /* Group PAL Measurement Functions */
VL53L0X_PerformSingleMeasurement(VL53L0X_DEV Dev)2064 VL53L0X_Error VL53L0X_PerformSingleMeasurement(VL53L0X_DEV Dev)
2065 {
2066 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2067 	VL53L0X_DeviceModes DeviceMode;
2068 
2069 	LOG_FUNCTION_START("");
2070 
2071 	/* Get Current DeviceMode */
2072 	Status = VL53L0X_GetDeviceMode(Dev, &DeviceMode);
2073 
2074 	/* Start immediately to run a single ranging measurement in case of
2075 	 * single ranging or single histogram */
2076 	if (Status == VL53L0X_ERROR_NONE
2077 		&& DeviceMode == VL53L0X_DEVICEMODE_SINGLE_RANGING)
2078 		Status = VL53L0X_StartMeasurement(Dev);
2079 
2080 
2081 	if (Status == VL53L0X_ERROR_NONE)
2082 		Status = VL53L0X_measurement_poll_for_completion(Dev);
2083 
2084 
2085 	/* Change PAL State in case of single ranging or single histogram */
2086 	if (Status == VL53L0X_ERROR_NONE
2087 		&& DeviceMode == VL53L0X_DEVICEMODE_SINGLE_RANGING)
2088 		PALDevDataSet(Dev, PalState, VL53L0X_STATE_IDLE);
2089 
2090 
2091 	LOG_FUNCTION_END(Status);
2092 	return Status;
2093 }
2094 
VL53L0X_PerformSingleHistogramMeasurement(VL53L0X_DEV Dev,VL53L0X_HistogramMeasurementData_t * pHistogramMeasurementData)2095 VL53L0X_Error VL53L0X_PerformSingleHistogramMeasurement(VL53L0X_DEV Dev,
2096 	VL53L0X_HistogramMeasurementData_t *pHistogramMeasurementData)
2097 {
2098 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
2099 	LOG_FUNCTION_START("");
2100 
2101 	/* not implemented on VL53L0X */
2102 
2103 	LOG_FUNCTION_END(Status);
2104 	return Status;
2105 }
2106 
VL53L0X_PerformRefCalibration(VL53L0X_DEV Dev,uint8_t * pVhvSettings,uint8_t * pPhaseCal)2107 VL53L0X_Error VL53L0X_PerformRefCalibration(VL53L0X_DEV Dev, uint8_t *pVhvSettings,
2108 	uint8_t *pPhaseCal)
2109 {
2110 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2111 	LOG_FUNCTION_START("");
2112 
2113 	Status = VL53L0X_perform_ref_calibration(Dev, pVhvSettings,
2114 		pPhaseCal, 1);
2115 
2116 	LOG_FUNCTION_END(Status);
2117 	return Status;
2118 }
2119 
VL53L0X_PerformXTalkMeasurement(VL53L0X_DEV Dev,uint32_t TimeoutMs,FixPoint1616_t * pXtalkPerSpad,uint8_t * pAmbientTooHigh)2120 VL53L0X_Error VL53L0X_PerformXTalkMeasurement(VL53L0X_DEV Dev,
2121 	uint32_t TimeoutMs, FixPoint1616_t *pXtalkPerSpad,
2122 	uint8_t *pAmbientTooHigh)
2123 {
2124 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
2125 	LOG_FUNCTION_START("");
2126 
2127 	/* not implemented on VL53L0X */
2128 
2129 	LOG_FUNCTION_END(Status);
2130 	return Status;
2131 }
2132 
VL53L0X_PerformXTalkCalibration(VL53L0X_DEV Dev,FixPoint1616_t XTalkCalDistance,FixPoint1616_t * pXTalkCompensationRateMegaCps)2133 VL53L0X_Error VL53L0X_PerformXTalkCalibration(VL53L0X_DEV Dev,
2134 	FixPoint1616_t XTalkCalDistance,
2135 	FixPoint1616_t *pXTalkCompensationRateMegaCps)
2136 {
2137 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2138 	LOG_FUNCTION_START("");
2139 
2140 	Status = VL53L0X_perform_xtalk_calibration(Dev, XTalkCalDistance,
2141 		pXTalkCompensationRateMegaCps);
2142 
2143 	LOG_FUNCTION_END(Status);
2144 	return Status;
2145 }
2146 
VL53L0X_PerformOffsetCalibration(VL53L0X_DEV Dev,FixPoint1616_t CalDistanceMilliMeter,int32_t * pOffsetMicroMeter)2147 VL53L0X_Error VL53L0X_PerformOffsetCalibration(VL53L0X_DEV Dev,
2148 	FixPoint1616_t CalDistanceMilliMeter, int32_t *pOffsetMicroMeter)
2149 {
2150 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2151 	LOG_FUNCTION_START("");
2152 
2153 	Status = VL53L0X_perform_offset_calibration(Dev, CalDistanceMilliMeter,
2154 		pOffsetMicroMeter);
2155 
2156 	LOG_FUNCTION_END(Status);
2157 	return Status;
2158 }
2159 
VL53L0X_CheckAndLoadInterruptSettings(VL53L0X_DEV Dev,uint8_t StartNotStopFlag)2160 VL53L0X_Error VL53L0X_CheckAndLoadInterruptSettings(VL53L0X_DEV Dev,
2161 	uint8_t StartNotStopFlag)
2162 {
2163 	uint8_t InterruptConfig;
2164 	FixPoint1616_t ThresholdLow;
2165 	FixPoint1616_t ThresholdHigh;
2166 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2167 
2168 	InterruptConfig = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev,
2169 		Pin0GpioFunctionality);
2170 
2171 	if ((InterruptConfig ==
2172 		VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW) ||
2173 		(InterruptConfig ==
2174 		VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH) ||
2175 		(InterruptConfig ==
2176 		VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT)) {
2177 
2178 		Status = VL53L0X_GetInterruptThresholds(Dev,
2179 			VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,
2180 			&ThresholdLow, &ThresholdHigh);
2181 
2182 		if (((ThresholdLow > 255*65536) ||
2183 			(ThresholdHigh > 255*65536)) &&
2184 			(Status == VL53L0X_ERROR_NONE)) {
2185 
2186 			if (StartNotStopFlag != 0) {
2187 				Status = VL53L0X_load_tuning_settings(Dev,
2188 					InterruptThresholdSettings);
2189 			} else {
2190 				Status |= VL53L0X_WrByte(Dev, 0xFF, 0x04);
2191 				Status |= VL53L0X_WrByte(Dev, 0x70, 0x00);
2192 				Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00);
2193 				Status |= VL53L0X_WrByte(Dev, 0x80, 0x00);
2194 			}
2195 
2196 		}
2197 
2198 
2199 	}
2200 
2201 	return Status;
2202 
2203 }
2204 
2205 
VL53L0X_StartMeasurement(VL53L0X_DEV Dev)2206 VL53L0X_Error VL53L0X_StartMeasurement(VL53L0X_DEV Dev)
2207 {
2208 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2209 	VL53L0X_DeviceModes DeviceMode;
2210 	uint8_t Byte;
2211 	uint8_t StartStopByte = VL53L0X_REG_SYSRANGE_MODE_START_STOP;
2212 	uint32_t LoopNb;
2213 	LOG_FUNCTION_START("");
2214 
2215 	/* Get Current DeviceMode */
2216 	VL53L0X_GetDeviceMode(Dev, &DeviceMode);
2217 
2218 	Status = VL53L0X_WrByte(Dev, 0x80, 0x01);
2219 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
2220 	Status = VL53L0X_WrByte(Dev, 0x00, 0x00);
2221 	Status = VL53L0X_WrByte(Dev, 0x91, PALDevDataGet(Dev, StopVariable));
2222 	Status = VL53L0X_WrByte(Dev, 0x00, 0x01);
2223 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x00);
2224 	Status = VL53L0X_WrByte(Dev, 0x80, 0x00);
2225 
2226 	switch (DeviceMode) {
2227 	case VL53L0X_DEVICEMODE_SINGLE_RANGING:
2228 		Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSRANGE_START, 0x01);
2229 
2230 		Byte = StartStopByte;
2231 		if (Status == VL53L0X_ERROR_NONE) {
2232 			/* Wait until start bit has been cleared */
2233 			LoopNb = 0;
2234 			do {
2235 				if (LoopNb > 0)
2236 					Status = VL53L0X_RdByte(Dev,
2237 					VL53L0X_REG_SYSRANGE_START, &Byte);
2238 				LoopNb = LoopNb + 1;
2239 			} while (((Byte & StartStopByte) == StartStopByte)
2240 				&& (Status == VL53L0X_ERROR_NONE)
2241 				&& (LoopNb < VL53L0X_DEFAULT_MAX_LOOP));
2242 
2243 			if (LoopNb >= VL53L0X_DEFAULT_MAX_LOOP)
2244 				Status = VL53L0X_ERROR_TIME_OUT;
2245 
2246 		}
2247 
2248 		break;
2249 	case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING:
2250 		/* Back-to-back mode */
2251 
2252 		/* Check if need to apply interrupt settings */
2253 		if (Status == VL53L0X_ERROR_NONE)
2254 			Status = VL53L0X_CheckAndLoadInterruptSettings(Dev, 1);
2255 
2256 		Status = VL53L0X_WrByte(Dev,
2257 		VL53L0X_REG_SYSRANGE_START,
2258 		VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK);
2259 		if (Status == VL53L0X_ERROR_NONE) {
2260 			/* Set PAL State to Running */
2261 			PALDevDataSet(Dev, PalState, VL53L0X_STATE_RUNNING);
2262 		}
2263 		break;
2264 	case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING:
2265 		/* Continuous mode */
2266 		/* Check if need to apply interrupt settings */
2267 		if (Status == VL53L0X_ERROR_NONE)
2268 			Status = VL53L0X_CheckAndLoadInterruptSettings(Dev, 1);
2269 
2270 		Status = VL53L0X_WrByte(Dev,
2271 		VL53L0X_REG_SYSRANGE_START,
2272 		VL53L0X_REG_SYSRANGE_MODE_TIMED);
2273 
2274 		if (Status == VL53L0X_ERROR_NONE) {
2275 			/* Set PAL State to Running */
2276 			PALDevDataSet(Dev, PalState, VL53L0X_STATE_RUNNING);
2277 		}
2278 		break;
2279 	default:
2280 		/* Selected mode not supported */
2281 		Status = VL53L0X_ERROR_MODE_NOT_SUPPORTED;
2282 	}
2283 
2284 
2285 	LOG_FUNCTION_END(Status);
2286 	return Status;
2287 }
2288 
VL53L0X_StopMeasurement(VL53L0X_DEV Dev)2289 VL53L0X_Error VL53L0X_StopMeasurement(VL53L0X_DEV Dev)
2290 {
2291 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2292 	LOG_FUNCTION_START("");
2293 
2294 	Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSRANGE_START,
2295 	VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT);
2296 
2297 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
2298 	Status = VL53L0X_WrByte(Dev, 0x00, 0x00);
2299 	Status = VL53L0X_WrByte(Dev, 0x91, 0x00);
2300 	Status = VL53L0X_WrByte(Dev, 0x00, 0x01);
2301 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x00);
2302 
2303 	if (Status == VL53L0X_ERROR_NONE) {
2304 		/* Set PAL State to Idle */
2305 		PALDevDataSet(Dev, PalState, VL53L0X_STATE_IDLE);
2306 	}
2307 
2308 	/* Check if need to apply interrupt settings */
2309 	if (Status == VL53L0X_ERROR_NONE)
2310 		Status = VL53L0X_CheckAndLoadInterruptSettings(Dev, 0);
2311 
2312 	LOG_FUNCTION_END(Status);
2313 	return Status;
2314 }
2315 
VL53L0X_GetMeasurementDataReady(VL53L0X_DEV Dev,uint8_t * pMeasurementDataReady)2316 VL53L0X_Error VL53L0X_GetMeasurementDataReady(VL53L0X_DEV Dev,
2317 	uint8_t *pMeasurementDataReady)
2318 {
2319 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2320 	uint8_t SysRangeStatusRegister;
2321 	uint8_t InterruptConfig;
2322 	uint32_t InterruptMask;
2323 	LOG_FUNCTION_START("");
2324 
2325 	InterruptConfig = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev,
2326 		Pin0GpioFunctionality);
2327 
2328 	if (InterruptConfig ==
2329 		VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) {
2330 		Status = VL53L0X_GetInterruptMaskStatus(Dev, &InterruptMask);
2331 		if (InterruptMask ==
2332 		VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY)
2333 			*pMeasurementDataReady = 1;
2334 		else
2335 			*pMeasurementDataReady = 0;
2336 	} else {
2337 		Status = VL53L0X_RdByte(Dev, VL53L0X_REG_RESULT_RANGE_STATUS,
2338 			&SysRangeStatusRegister);
2339 		if (Status == VL53L0X_ERROR_NONE) {
2340 			if (SysRangeStatusRegister & 0x01)
2341 				*pMeasurementDataReady = 1;
2342 			else
2343 				*pMeasurementDataReady = 0;
2344 		}
2345 	}
2346 
2347 	LOG_FUNCTION_END(Status);
2348 	return Status;
2349 }
2350 
VL53L0X_WaitDeviceReadyForNewMeasurement(VL53L0X_DEV Dev,uint32_t MaxLoop)2351 VL53L0X_Error VL53L0X_WaitDeviceReadyForNewMeasurement(VL53L0X_DEV Dev,
2352 	uint32_t MaxLoop)
2353 {
2354 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
2355 	LOG_FUNCTION_START("");
2356 
2357 	/* not implemented for VL53L0X */
2358 
2359 	LOG_FUNCTION_END(Status);
2360 	return Status;
2361 }
2362 
2363 
VL53L0X_GetRangingMeasurementData(VL53L0X_DEV Dev,VL53L0X_RangingMeasurementData_t * pRangingMeasurementData)2364 VL53L0X_Error VL53L0X_GetRangingMeasurementData(VL53L0X_DEV Dev,
2365 	VL53L0X_RangingMeasurementData_t *pRangingMeasurementData)
2366 {
2367 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2368 	uint8_t DeviceRangeStatus;
2369 	uint8_t RangeFractionalEnable;
2370 	uint8_t PalRangeStatus;
2371 	uint8_t XTalkCompensationEnable;
2372 	uint16_t AmbientRate;
2373 	FixPoint1616_t SignalRate;
2374 	uint16_t XTalkCompensationRateMegaCps;
2375 	uint16_t EffectiveSpadRtnCount;
2376 	uint16_t tmpuint16;
2377 	uint16_t XtalkRangeMilliMeter;
2378 	uint16_t LinearityCorrectiveGain;
2379 	uint8_t localBuffer[12];
2380 	VL53L0X_RangingMeasurementData_t LastRangeDataBuffer;
2381 
2382 	LOG_FUNCTION_START("");
2383 
2384 	/*
2385 	 * use multi read even if some registers are not useful, result will
2386 	 * be more efficient
2387 	 * start reading at 0x14 dec20
2388 	 * end reading at 0x21 dec33 total 14 bytes to read
2389 	 */
2390 	Status = VL53L0X_ReadMulti(Dev, 0x14, localBuffer, 12);
2391 
2392 	if (Status == VL53L0X_ERROR_NONE) {
2393 
2394 		pRangingMeasurementData->ZoneId = 0; /* Only one zone */
2395 		pRangingMeasurementData->TimeStamp = 0; /* Not Implemented */
2396 
2397 		tmpuint16 = VL53L0X_MAKEUINT16(localBuffer[11], localBuffer[10]);
2398 		/* cut1.1 if SYSTEM__RANGE_CONFIG if 1 range is 2bits fractional
2399 		 *(format 11.2) else no fractional
2400 		 */
2401 
2402 		pRangingMeasurementData->MeasurementTimeUsec = 0;
2403 
2404 		SignalRate = VL53L0X_FIXPOINT97TOFIXPOINT1616(
2405 			VL53L0X_MAKEUINT16(localBuffer[7], localBuffer[6]));
2406 		/* peak_signal_count_rate_rtn_mcps */
2407 		pRangingMeasurementData->SignalRateRtnMegaCps = SignalRate;
2408 
2409 		AmbientRate = VL53L0X_MAKEUINT16(localBuffer[9], localBuffer[8]);
2410 		pRangingMeasurementData->AmbientRateRtnMegaCps =
2411 			VL53L0X_FIXPOINT97TOFIXPOINT1616(AmbientRate);
2412 
2413 		EffectiveSpadRtnCount = VL53L0X_MAKEUINT16(localBuffer[3],
2414 			localBuffer[2]);
2415 		/* EffectiveSpadRtnCount is 8.8 format */
2416 		pRangingMeasurementData->EffectiveSpadRtnCount =
2417 			EffectiveSpadRtnCount;
2418 
2419 		DeviceRangeStatus = localBuffer[0];
2420 
2421 		/* Get Linearity Corrective Gain */
2422 		LinearityCorrectiveGain = PALDevDataGet(Dev,
2423 			LinearityCorrectiveGain);
2424 
2425 		/* Get ranging configuration */
2426 		RangeFractionalEnable = PALDevDataGet(Dev,
2427 			RangeFractionalEnable);
2428 
2429 		if (LinearityCorrectiveGain != 1000) {
2430 
2431 			tmpuint16 = (uint16_t)((LinearityCorrectiveGain
2432 				* tmpuint16 + 500) / 1000);
2433 
2434 			/* Implement Xtalk */
2435 			VL53L0X_GETPARAMETERFIELD(Dev,
2436 				XTalkCompensationRateMegaCps,
2437 				XTalkCompensationRateMegaCps);
2438 			VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationEnable,
2439 				XTalkCompensationEnable);
2440 
2441 			if (XTalkCompensationEnable) {
2442 
2443 				if ((SignalRate
2444 					- ((XTalkCompensationRateMegaCps
2445 					* EffectiveSpadRtnCount) >> 8))
2446 					<= 0) {
2447 					if (RangeFractionalEnable)
2448 						XtalkRangeMilliMeter = 8888;
2449 					else
2450 						XtalkRangeMilliMeter = 8888
2451 							<< 2;
2452 				} else {
2453 					XtalkRangeMilliMeter =
2454 					(tmpuint16 * SignalRate)
2455 						/ (SignalRate
2456 						- ((XTalkCompensationRateMegaCps
2457 						* EffectiveSpadRtnCount)
2458 						>> 8));
2459 				}
2460 
2461 				tmpuint16 = XtalkRangeMilliMeter;
2462 			}
2463 
2464 		}
2465 
2466 		if (RangeFractionalEnable) {
2467 			pRangingMeasurementData->RangeMilliMeter =
2468 				(uint16_t)((tmpuint16) >> 2);
2469 			pRangingMeasurementData->RangeFractionalPart =
2470 				(uint8_t)((tmpuint16 & 0x03) << 6);
2471 		} else {
2472 			pRangingMeasurementData->RangeMilliMeter = tmpuint16;
2473 			pRangingMeasurementData->RangeFractionalPart = 0;
2474 		}
2475 
2476 		/*
2477 		 * For a standard definition of RangeStatus, this should
2478 		 * return 0 in case of good result after a ranging
2479 		 * The range status depends on the device so call a device
2480 		 * specific function to obtain the right Status.
2481 		 */
2482 		Status |= VL53L0X_get_pal_range_status(Dev, DeviceRangeStatus,
2483 			SignalRate, EffectiveSpadRtnCount,
2484 			pRangingMeasurementData, &PalRangeStatus);
2485 
2486 		if (Status == VL53L0X_ERROR_NONE)
2487 			pRangingMeasurementData->RangeStatus = PalRangeStatus;
2488 
2489 	}
2490 
2491 	if (Status == VL53L0X_ERROR_NONE) {
2492 		/* Copy last read data into Dev buffer */
2493 		LastRangeDataBuffer = PALDevDataGet(Dev, LastRangeMeasure);
2494 
2495 		LastRangeDataBuffer.RangeMilliMeter =
2496 			pRangingMeasurementData->RangeMilliMeter;
2497 		LastRangeDataBuffer.RangeFractionalPart =
2498 			pRangingMeasurementData->RangeFractionalPart;
2499 		LastRangeDataBuffer.RangeDMaxMilliMeter =
2500 			pRangingMeasurementData->RangeDMaxMilliMeter;
2501 		LastRangeDataBuffer.MeasurementTimeUsec =
2502 			pRangingMeasurementData->MeasurementTimeUsec;
2503 		LastRangeDataBuffer.SignalRateRtnMegaCps =
2504 			pRangingMeasurementData->SignalRateRtnMegaCps;
2505 		LastRangeDataBuffer.AmbientRateRtnMegaCps =
2506 			pRangingMeasurementData->AmbientRateRtnMegaCps;
2507 		LastRangeDataBuffer.EffectiveSpadRtnCount =
2508 			pRangingMeasurementData->EffectiveSpadRtnCount;
2509 		LastRangeDataBuffer.RangeStatus =
2510 			pRangingMeasurementData->RangeStatus;
2511 
2512 		PALDevDataSet(Dev, LastRangeMeasure, LastRangeDataBuffer);
2513 	}
2514 
2515 	LOG_FUNCTION_END(Status);
2516 	return Status;
2517 }
2518 
VL53L0X_GetMeasurementRefSignal(VL53L0X_DEV Dev,FixPoint1616_t * pMeasurementRefSignal)2519 VL53L0X_Error VL53L0X_GetMeasurementRefSignal(VL53L0X_DEV Dev,
2520 	FixPoint1616_t *pMeasurementRefSignal)
2521 {
2522 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2523 	uint8_t SignalRefClipLimitCheckEnable = 0;
2524 	LOG_FUNCTION_START("");
2525 
2526 	Status = VL53L0X_GetLimitCheckEnable(Dev,
2527 			VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
2528 			&SignalRefClipLimitCheckEnable);
2529 	if (SignalRefClipLimitCheckEnable != 0) {
2530 		*pMeasurementRefSignal = PALDevDataGet(Dev, LastSignalRefMcps);
2531 	} else {
2532 		Status = VL53L0X_ERROR_INVALID_COMMAND;
2533 	}
2534 	LOG_FUNCTION_END(Status);
2535 
2536 	return Status;
2537 }
2538 
VL53L0X_GetHistogramMeasurementData(VL53L0X_DEV Dev,VL53L0X_HistogramMeasurementData_t * pHistogramMeasurementData)2539 VL53L0X_Error VL53L0X_GetHistogramMeasurementData(VL53L0X_DEV Dev,
2540 	VL53L0X_HistogramMeasurementData_t *pHistogramMeasurementData)
2541 {
2542 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
2543 	LOG_FUNCTION_START("");
2544 
2545 	LOG_FUNCTION_END(Status);
2546 	return Status;
2547 }
2548 
VL53L0X_PerformSingleRangingMeasurement(VL53L0X_DEV Dev,VL53L0X_RangingMeasurementData_t * pRangingMeasurementData)2549 VL53L0X_Error VL53L0X_PerformSingleRangingMeasurement(VL53L0X_DEV Dev,
2550 	VL53L0X_RangingMeasurementData_t *pRangingMeasurementData)
2551 {
2552 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2553 
2554 	LOG_FUNCTION_START("");
2555 
2556 	/* This function will do a complete single ranging
2557 	 * Here we fix the mode! */
2558 	Status = VL53L0X_SetDeviceMode(Dev, VL53L0X_DEVICEMODE_SINGLE_RANGING);
2559 
2560 	if (Status == VL53L0X_ERROR_NONE)
2561 		Status = VL53L0X_PerformSingleMeasurement(Dev);
2562 
2563 
2564 	if (Status == VL53L0X_ERROR_NONE)
2565 		Status = VL53L0X_GetRangingMeasurementData(Dev,
2566 			pRangingMeasurementData);
2567 
2568 
2569 	if (Status == VL53L0X_ERROR_NONE)
2570 		Status = VL53L0X_ClearInterruptMask(Dev, 0);
2571 
2572 
2573 	LOG_FUNCTION_END(Status);
2574 	return Status;
2575 }
2576 
VL53L0X_SetNumberOfROIZones(VL53L0X_DEV Dev,uint8_t NumberOfROIZones)2577 VL53L0X_Error VL53L0X_SetNumberOfROIZones(VL53L0X_DEV Dev,
2578 	uint8_t NumberOfROIZones)
2579 {
2580 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2581 
2582 	LOG_FUNCTION_START("");
2583 
2584 	if (NumberOfROIZones != 1)
2585 		Status = VL53L0X_ERROR_INVALID_PARAMS;
2586 
2587 
2588 	LOG_FUNCTION_END(Status);
2589 	return Status;
2590 }
2591 
VL53L0X_GetNumberOfROIZones(VL53L0X_DEV Dev,uint8_t * pNumberOfROIZones)2592 VL53L0X_Error VL53L0X_GetNumberOfROIZones(VL53L0X_DEV Dev,
2593 	uint8_t *pNumberOfROIZones)
2594 {
2595 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2596 
2597 	LOG_FUNCTION_START("");
2598 
2599 	*pNumberOfROIZones = 1;
2600 
2601 	LOG_FUNCTION_END(Status);
2602 	return Status;
2603 }
2604 
VL53L0X_GetMaxNumberOfROIZones(VL53L0X_DEV Dev,uint8_t * pMaxNumberOfROIZones)2605 VL53L0X_Error VL53L0X_GetMaxNumberOfROIZones(VL53L0X_DEV Dev,
2606 	uint8_t *pMaxNumberOfROIZones)
2607 {
2608 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2609 
2610 	LOG_FUNCTION_START("");
2611 
2612 	*pMaxNumberOfROIZones = 1;
2613 
2614 	LOG_FUNCTION_END(Status);
2615 	return Status;
2616 }
2617 
2618 /* End Group PAL Measurement Functions */
2619 
VL53L0X_SetGpioConfig(VL53L0X_DEV Dev,uint8_t Pin,VL53L0X_DeviceModes DeviceMode,VL53L0X_GpioFunctionality Functionality,VL53L0X_InterruptPolarity Polarity)2620 VL53L0X_Error VL53L0X_SetGpioConfig(VL53L0X_DEV Dev, uint8_t Pin,
2621 	VL53L0X_DeviceModes DeviceMode, VL53L0X_GpioFunctionality Functionality,
2622 	VL53L0X_InterruptPolarity Polarity)
2623 {
2624 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2625 	uint8_t data;
2626 
2627 	LOG_FUNCTION_START("");
2628 
2629 	if (Pin != 0) {
2630 		Status = VL53L0X_ERROR_GPIO_NOT_EXISTING;
2631 	} else if (DeviceMode == VL53L0X_DEVICEMODE_GPIO_DRIVE) {
2632 		if (Polarity == VL53L0X_INTERRUPTPOLARITY_LOW)
2633 			data = 0x10;
2634 		else
2635 			data = 1;
2636 
2637 		Status = VL53L0X_WrByte(Dev,
2638 		VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, data);
2639 
2640 	} else if (DeviceMode == VL53L0X_DEVICEMODE_GPIO_OSC) {
2641 
2642 		Status |= VL53L0X_WrByte(Dev, 0xff, 0x01);
2643 		Status |= VL53L0X_WrByte(Dev, 0x00, 0x00);
2644 
2645 		Status |= VL53L0X_WrByte(Dev, 0xff, 0x00);
2646 		Status |= VL53L0X_WrByte(Dev, 0x80, 0x01);
2647 		Status |= VL53L0X_WrByte(Dev, 0x85, 0x02);
2648 
2649 		Status |= VL53L0X_WrByte(Dev, 0xff, 0x04);
2650 		Status |= VL53L0X_WrByte(Dev, 0xcd, 0x00);
2651 		Status |= VL53L0X_WrByte(Dev, 0xcc, 0x11);
2652 
2653 		Status |= VL53L0X_WrByte(Dev, 0xff, 0x07);
2654 		Status |= VL53L0X_WrByte(Dev, 0xbe, 0x00);
2655 
2656 		Status |= VL53L0X_WrByte(Dev, 0xff, 0x06);
2657 		Status |= VL53L0X_WrByte(Dev, 0xcc, 0x09);
2658 
2659 		Status |= VL53L0X_WrByte(Dev, 0xff, 0x00);
2660 		Status |= VL53L0X_WrByte(Dev, 0xff, 0x01);
2661 		Status |= VL53L0X_WrByte(Dev, 0x00, 0x00);
2662 
2663 	} else {
2664 
2665 		if (Status == VL53L0X_ERROR_NONE) {
2666 			switch (Functionality) {
2667 			case VL53L0X_GPIOFUNCTIONALITY_OFF:
2668 				data = 0x00;
2669 				break;
2670 			case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW:
2671 				data = 0x01;
2672 				break;
2673 			case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH:
2674 				data = 0x02;
2675 				break;
2676 			case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT:
2677 				data = 0x03;
2678 				break;
2679 			case VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY:
2680 				data = 0x04;
2681 				break;
2682 			default:
2683 				Status =
2684 				VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED;
2685 			}
2686 		}
2687 
2688 		if (Status == VL53L0X_ERROR_NONE)
2689 			Status = VL53L0X_WrByte(Dev,
2690 			VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, data);
2691 
2692 		if (Status == VL53L0X_ERROR_NONE) {
2693 			if (Polarity == VL53L0X_INTERRUPTPOLARITY_LOW)
2694 				data = 0;
2695 			else
2696 				data = (uint8_t)(1 << 4);
2697 
2698 			Status = VL53L0X_UpdateByte(Dev,
2699 			VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, 0xEF, data);
2700 		}
2701 
2702 		if (Status == VL53L0X_ERROR_NONE)
2703 			VL53L0X_SETDEVICESPECIFICPARAMETER(Dev,
2704 				Pin0GpioFunctionality, Functionality);
2705 
2706 		if (Status == VL53L0X_ERROR_NONE)
2707 			Status = VL53L0X_ClearInterruptMask(Dev, 0);
2708 
2709 	}
2710 
2711 	LOG_FUNCTION_END(Status);
2712 	return Status;
2713 }
2714 
VL53L0X_GetGpioConfig(VL53L0X_DEV Dev,uint8_t Pin,VL53L0X_DeviceModes * pDeviceMode,VL53L0X_GpioFunctionality * pFunctionality,VL53L0X_InterruptPolarity * pPolarity)2715 VL53L0X_Error VL53L0X_GetGpioConfig(VL53L0X_DEV Dev, uint8_t Pin,
2716 	VL53L0X_DeviceModes *pDeviceMode,
2717 	VL53L0X_GpioFunctionality *pFunctionality,
2718 	VL53L0X_InterruptPolarity *pPolarity)
2719 {
2720 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2721 	VL53L0X_GpioFunctionality GpioFunctionality = VL53L0X_GPIOFUNCTIONALITY_OFF;
2722 	uint8_t data;
2723 
2724 	LOG_FUNCTION_START("");
2725 
2726 	/* pDeviceMode not managed by Ewok it return the current mode */
2727 
2728 	Status = VL53L0X_GetDeviceMode(Dev, pDeviceMode);
2729 
2730 	if (Status == VL53L0X_ERROR_NONE) {
2731 		if (Pin != 0) {
2732 			Status = VL53L0X_ERROR_GPIO_NOT_EXISTING;
2733 		} else {
2734 			Status = VL53L0X_RdByte(Dev,
2735 			VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, &data);
2736 		}
2737 	}
2738 
2739 	if (Status == VL53L0X_ERROR_NONE) {
2740 		switch (data & 0x07) {
2741 		case 0x00:
2742 			GpioFunctionality = VL53L0X_GPIOFUNCTIONALITY_OFF;
2743 			break;
2744 		case 0x01:
2745 			GpioFunctionality =
2746 			VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW;
2747 			break;
2748 		case 0x02:
2749 			GpioFunctionality =
2750 			VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH;
2751 			break;
2752 		case 0x03:
2753 			GpioFunctionality =
2754 			VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT;
2755 			break;
2756 		case 0x04:
2757 			GpioFunctionality =
2758 			VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY;
2759 			break;
2760 		default:
2761 			Status = VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED;
2762 		}
2763 	}
2764 
2765 	if (Status == VL53L0X_ERROR_NONE)
2766 		Status = VL53L0X_RdByte(Dev, VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH,
2767 			&data);
2768 
2769 	if (Status == VL53L0X_ERROR_NONE) {
2770 		if ((data & (uint8_t)(1 << 4)) == 0)
2771 			*pPolarity = VL53L0X_INTERRUPTPOLARITY_LOW;
2772 		else
2773 			*pPolarity = VL53L0X_INTERRUPTPOLARITY_HIGH;
2774 	}
2775 
2776 	if (Status == VL53L0X_ERROR_NONE) {
2777 		*pFunctionality = GpioFunctionality;
2778 		VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, Pin0GpioFunctionality,
2779 			GpioFunctionality);
2780 	}
2781 
2782 	LOG_FUNCTION_END(Status);
2783 	return Status;
2784 }
2785 
VL53L0X_SetInterruptThresholds(VL53L0X_DEV Dev,VL53L0X_DeviceModes DeviceMode,FixPoint1616_t ThresholdLow,FixPoint1616_t ThresholdHigh)2786 VL53L0X_Error VL53L0X_SetInterruptThresholds(VL53L0X_DEV Dev,
2787 	VL53L0X_DeviceModes DeviceMode, FixPoint1616_t ThresholdLow,
2788 	FixPoint1616_t ThresholdHigh)
2789 {
2790 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2791 	uint16_t Threshold16;
2792 	LOG_FUNCTION_START("");
2793 
2794 	/* no dependency on DeviceMode for Ewok */
2795 	/* Need to divide by 2 because the FW will apply a x2 */
2796 	Threshold16 = (uint16_t)((ThresholdLow >> 17) & 0x00fff);
2797 	Status = VL53L0X_WrWord(Dev, VL53L0X_REG_SYSTEM_THRESH_LOW, Threshold16);
2798 
2799 	if (Status == VL53L0X_ERROR_NONE) {
2800 		/* Need to divide by 2 because the FW will apply a x2 */
2801 		Threshold16 = (uint16_t)((ThresholdHigh >> 17) & 0x00fff);
2802 		Status = VL53L0X_WrWord(Dev, VL53L0X_REG_SYSTEM_THRESH_HIGH,
2803 			Threshold16);
2804 	}
2805 
2806 	LOG_FUNCTION_END(Status);
2807 	return Status;
2808 }
2809 
VL53L0X_GetInterruptThresholds(VL53L0X_DEV Dev,VL53L0X_DeviceModes DeviceMode,FixPoint1616_t * pThresholdLow,FixPoint1616_t * pThresholdHigh)2810 VL53L0X_Error VL53L0X_GetInterruptThresholds(VL53L0X_DEV Dev,
2811 	VL53L0X_DeviceModes DeviceMode, FixPoint1616_t *pThresholdLow,
2812 	FixPoint1616_t *pThresholdHigh)
2813 {
2814 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2815 	uint16_t Threshold16;
2816 	LOG_FUNCTION_START("");
2817 
2818 	/* no dependency on DeviceMode for Ewok */
2819 
2820 	Status = VL53L0X_RdWord(Dev, VL53L0X_REG_SYSTEM_THRESH_LOW, &Threshold16);
2821 	/* Need to multiply by 2 because the FW will apply a x2 */
2822 	*pThresholdLow = (FixPoint1616_t)((0x00fff & Threshold16) << 17);
2823 
2824 	if (Status == VL53L0X_ERROR_NONE) {
2825 		Status = VL53L0X_RdWord(Dev, VL53L0X_REG_SYSTEM_THRESH_HIGH,
2826 			&Threshold16);
2827 		/* Need to multiply by 2 because the FW will apply a x2 */
2828 		*pThresholdHigh =
2829 			(FixPoint1616_t)((0x00fff & Threshold16) << 17);
2830 	}
2831 
2832 	LOG_FUNCTION_END(Status);
2833 	return Status;
2834 }
2835 
VL53L0X_GetStopCompletedStatus(VL53L0X_DEV Dev,uint32_t * pStopStatus)2836 VL53L0X_Error VL53L0X_GetStopCompletedStatus(VL53L0X_DEV Dev,
2837 	uint32_t *pStopStatus)
2838 {
2839 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2840 	uint8_t Byte = 0;
2841 	LOG_FUNCTION_START("");
2842 
2843 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
2844 
2845 	if (Status == VL53L0X_ERROR_NONE)
2846 		Status = VL53L0X_RdByte(Dev, 0x04, &Byte);
2847 
2848 	if (Status == VL53L0X_ERROR_NONE)
2849 		Status = VL53L0X_WrByte(Dev, 0xFF, 0x0);
2850 
2851 	*pStopStatus = Byte;
2852 
2853 	if (Byte == 0) {
2854 		Status = VL53L0X_WrByte(Dev, 0x80, 0x01);
2855 		Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
2856 		Status = VL53L0X_WrByte(Dev, 0x00, 0x00);
2857 		Status = VL53L0X_WrByte(Dev, 0x91,
2858 			PALDevDataGet(Dev, StopVariable));
2859 		Status = VL53L0X_WrByte(Dev, 0x00, 0x01);
2860 		Status = VL53L0X_WrByte(Dev, 0xFF, 0x00);
2861 		Status = VL53L0X_WrByte(Dev, 0x80, 0x00);
2862 	}
2863 
2864 	LOG_FUNCTION_END(Status);
2865 	return Status;
2866 }
2867 
2868 /* Group PAL Interrupt Functions */
VL53L0X_ClearInterruptMask(VL53L0X_DEV Dev,uint32_t InterruptMask)2869 VL53L0X_Error VL53L0X_ClearInterruptMask(VL53L0X_DEV Dev, uint32_t InterruptMask)
2870 {
2871 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2872 	uint8_t LoopCount;
2873 	uint8_t Byte;
2874 	LOG_FUNCTION_START("");
2875 
2876 	/* clear bit 0 range interrupt, bit 1 error interrupt */
2877 	LoopCount = 0;
2878 	do {
2879 		Status = VL53L0X_WrByte(Dev,
2880 			VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x01);
2881 		Status |= VL53L0X_WrByte(Dev,
2882 			VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x00);
2883 		Status |= VL53L0X_RdByte(Dev,
2884 			VL53L0X_REG_RESULT_INTERRUPT_STATUS, &Byte);
2885 		LoopCount++;
2886 	} while (((Byte & 0x07) != 0x00)
2887 			&& (LoopCount < 3)
2888 			&& (Status == VL53L0X_ERROR_NONE));
2889 
2890 
2891 	if (LoopCount >= 3)
2892 		Status = VL53L0X_ERROR_INTERRUPT_NOT_CLEARED;
2893 
2894 	LOG_FUNCTION_END(Status);
2895 	return Status;
2896 }
2897 
VL53L0X_GetInterruptMaskStatus(VL53L0X_DEV Dev,uint32_t * pInterruptMaskStatus)2898 VL53L0X_Error VL53L0X_GetInterruptMaskStatus(VL53L0X_DEV Dev,
2899 	uint32_t *pInterruptMaskStatus)
2900 {
2901 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2902 	uint8_t Byte;
2903 	LOG_FUNCTION_START("");
2904 
2905 	Status = VL53L0X_RdByte(Dev, VL53L0X_REG_RESULT_INTERRUPT_STATUS, &Byte);
2906 	*pInterruptMaskStatus = Byte & 0x07;
2907 
2908 	if (Byte & 0x18)
2909 		Status = VL53L0X_ERROR_RANGE_ERROR;
2910 
2911 	LOG_FUNCTION_END(Status);
2912 	return Status;
2913 }
2914 
VL53L0X_EnableInterruptMask(VL53L0X_DEV Dev,uint32_t InterruptMask)2915 VL53L0X_Error VL53L0X_EnableInterruptMask(VL53L0X_DEV Dev, uint32_t InterruptMask)
2916 {
2917 	VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED;
2918 	LOG_FUNCTION_START("");
2919 
2920 	/* not implemented for VL53L0X */
2921 
2922 	LOG_FUNCTION_END(Status);
2923 	return Status;
2924 }
2925 
2926 /* End Group PAL Interrupt Functions */
2927 
2928 /* Group SPAD functions */
2929 
VL53L0X_SetSpadAmbientDamperThreshold(VL53L0X_DEV Dev,uint16_t SpadAmbientDamperThreshold)2930 VL53L0X_Error VL53L0X_SetSpadAmbientDamperThreshold(VL53L0X_DEV Dev,
2931 	uint16_t SpadAmbientDamperThreshold)
2932 {
2933 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2934 	LOG_FUNCTION_START("");
2935 
2936 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
2937 	Status |= VL53L0X_WrWord(Dev, 0x40, SpadAmbientDamperThreshold);
2938 	Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00);
2939 
2940 	LOG_FUNCTION_END(Status);
2941 	return Status;
2942 }
2943 
VL53L0X_GetSpadAmbientDamperThreshold(VL53L0X_DEV Dev,uint16_t * pSpadAmbientDamperThreshold)2944 VL53L0X_Error VL53L0X_GetSpadAmbientDamperThreshold(VL53L0X_DEV Dev,
2945 	uint16_t *pSpadAmbientDamperThreshold)
2946 {
2947 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2948 	LOG_FUNCTION_START("");
2949 
2950 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
2951 	Status |= VL53L0X_RdWord(Dev, 0x40, pSpadAmbientDamperThreshold);
2952 	Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00);
2953 
2954 	LOG_FUNCTION_END(Status);
2955 	return Status;
2956 }
2957 
VL53L0X_SetSpadAmbientDamperFactor(VL53L0X_DEV Dev,uint16_t SpadAmbientDamperFactor)2958 VL53L0X_Error VL53L0X_SetSpadAmbientDamperFactor(VL53L0X_DEV Dev,
2959 	uint16_t SpadAmbientDamperFactor)
2960 {
2961 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2962 	uint8_t Byte;
2963 	LOG_FUNCTION_START("");
2964 
2965 	Byte = (uint8_t)(SpadAmbientDamperFactor & 0x00FF);
2966 
2967 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
2968 	Status |= VL53L0X_WrByte(Dev, 0x42, Byte);
2969 	Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00);
2970 
2971 	LOG_FUNCTION_END(Status);
2972 	return Status;
2973 }
2974 
VL53L0X_GetSpadAmbientDamperFactor(VL53L0X_DEV Dev,uint16_t * pSpadAmbientDamperFactor)2975 VL53L0X_Error VL53L0X_GetSpadAmbientDamperFactor(VL53L0X_DEV Dev,
2976 	uint16_t *pSpadAmbientDamperFactor)
2977 {
2978 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
2979 	uint8_t Byte;
2980 	LOG_FUNCTION_START("");
2981 
2982 	Status = VL53L0X_WrByte(Dev, 0xFF, 0x01);
2983 	Status |= VL53L0X_RdByte(Dev, 0x42, &Byte);
2984 	Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00);
2985 	*pSpadAmbientDamperFactor = (uint16_t)Byte;
2986 
2987 	LOG_FUNCTION_END(Status);
2988 	return Status;
2989 }
2990 
2991 /* END Group SPAD functions */
2992 
2993 /*****************************************************************************
2994  * Internal functions
2995  *****************************************************************************/
2996 
VL53L0X_SetReferenceSpads(VL53L0X_DEV Dev,uint32_t count,uint8_t isApertureSpads)2997 VL53L0X_Error VL53L0X_SetReferenceSpads(VL53L0X_DEV Dev, uint32_t count,
2998 	uint8_t isApertureSpads)
2999 {
3000 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
3001 	LOG_FUNCTION_START("");
3002 
3003 	Status = VL53L0X_set_reference_spads(Dev, count, isApertureSpads);
3004 
3005 	LOG_FUNCTION_END(Status);
3006 
3007 	return Status;
3008 }
3009 
VL53L0X_GetReferenceSpads(VL53L0X_DEV Dev,uint32_t * pSpadCount,uint8_t * pIsApertureSpads)3010 VL53L0X_Error VL53L0X_GetReferenceSpads(VL53L0X_DEV Dev, uint32_t *pSpadCount,
3011 	uint8_t *pIsApertureSpads)
3012 {
3013 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
3014 	LOG_FUNCTION_START("");
3015 
3016 	Status = VL53L0X_get_reference_spads(Dev, pSpadCount, pIsApertureSpads);
3017 
3018 	LOG_FUNCTION_END(Status);
3019 
3020 	return Status;
3021 }
3022 
VL53L0X_PerformRefSpadManagement(VL53L0X_DEV Dev,uint32_t * refSpadCount,uint8_t * isApertureSpads)3023 VL53L0X_Error VL53L0X_PerformRefSpadManagement(VL53L0X_DEV Dev,
3024 	uint32_t *refSpadCount, uint8_t *isApertureSpads)
3025 {
3026 	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
3027 	LOG_FUNCTION_START("");
3028 
3029 	Status = VL53L0X_perform_ref_spad_management(Dev, refSpadCount,
3030 		isApertureSpads);
3031 
3032 	LOG_FUNCTION_END(Status);
3033 
3034 	return Status;
3035 }
3036