Statistics
| Branch: | Tag: | Revision:

amiro-lld / drivers / VL53L1X / v1 / api / core / vl53l1_api.c @ f0dd1ac4

History | View | Annotate | Download (78.039 KB)

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