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
/*******************************************************************************
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
}