Statistics
| Branch: | Tag: | Revision:

amiro-lld / include / VL53L0X / v1 / Api_vl53l0x / core / src / vl53l0x_api.c @ 6ebebd4d

History | View | Annotate | Download (88.999 KB)

1 6ebebd4d Andre Raming
/*******************************************************************************
2
 Copyright � 2016, STMicroelectronics International N.V.
3
 All rights reserved.
4

5
 Redistribution and use in source and binary forms, with or without
6
 modification, are permitted provided that the following conditions are met:
7
 * Redistributions of source code must retain the above copyright
8
 notice, this list of conditions and the following disclaimer.
9
 * Redistributions in binary form must reproduce the above copyright
10
 notice, this list of conditions and the following disclaimer in the
11
 documentation and/or other materials provided with the distribution.
12
 * Neither the name of STMicroelectronics nor the
13
 names of its contributors may be used to endorse or promote products
14
 derived from this software without specific prior written permission.
15

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