Initial release. Mbed library for VL53L1CB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53l1_api.c Source File

vl53l1_api.c

00001 
00002 /*******************************************************************************
00003  * Copyright (c) 2020, STMicroelectronics - All Rights Reserved
00004 
00005  This file is part of VL53L1 Core and is dual licensed,
00006  either 'STMicroelectronics
00007  Proprietary license'
00008  or 'BSD 3-clause "New" or "Revised" License' , at your option.
00009 
00010 ********************************************************************************
00011 
00012  'STMicroelectronics Proprietary license'
00013 
00014 ********************************************************************************
00015 
00016  License terms: STMicroelectronics Proprietary in accordance with licensing
00017  terms at www.st.com/sla0081
00018 
00019  STMicroelectronics confidential
00020  Reproduction and Communication of this document is strictly prohibited unless
00021  specifically authorized in writing by STMicroelectronics.
00022 
00023 
00024 ********************************************************************************
00025 
00026  Alternatively, VL53L1 Core may be distributed under the terms of
00027  'BSD 3-clause "New" or "Revised" License', in which case the following
00028  provisions apply instead of the ones
00029  mentioned above :
00030 
00031 ********************************************************************************
00032 
00033  License terms: BSD 3-clause "New" or "Revised" License.
00034 
00035  Redistribution and use in source and binary forms, with or without
00036  modification, are permitted provided that the following conditions are met:
00037 
00038  1. Redistributions of source code must retain the above copyright notice, this
00039  list of conditions and the following disclaimer.
00040 
00041  2. Redistributions in binary form must reproduce the above copyright notice,
00042  this list of conditions and the following disclaimer in the documentation
00043  and/or other materials provided with the distribution.
00044 
00045  3. Neither the name of the copyright holder nor the names of its contributors
00046  may be used to endorse or promote products derived from this software
00047  without specific prior written permission.
00048 
00049  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00050  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00051  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00052  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00053  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00054  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00055  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00056  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00057  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00058  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00059 
00060 
00061 ********************************************************************************
00062 
00063 */
00064 
00065 
00066 #include "vl53l1_api.h"
00067 #include "vl53l1_api_strings.h"
00068 #include "vl53l1_register_settings.h"
00069 #include "vl53l1_register_funcs.h"
00070 #include "vl53l1_core.h"
00071 #include "vl53l1_api_calibration.h"
00072 #include "vl53l1_wait.h"
00073 #include "vl53l1_preset_setup.h"
00074 #include "vl53l1_api_debug.h"
00075 #include "vl53l1_api_core.h"
00076 #include "vl53l1_nvm.h"
00077 
00078 
00079 #define ZONE_CHECK VL53L1_MAX_USER_ZONES
00080 
00081 #if ZONE_CHECK < 5
00082 #error Must define at least 5 zones in MAX_USER_ZONES constant
00083 #endif
00084 
00085 #define LOG_FUNCTION_START(fmt, ...) \
00086     _LOG_FUNCTION_START(VL53L1_TRACE_MODULE_API, fmt, ##__VA_ARGS__)
00087 #define LOG_FUNCTION_END(status, ...) \
00088     _LOG_FUNCTION_END(VL53L1_TRACE_MODULE_API, status, ##__VA_ARGS__)
00089 #define LOG_FUNCTION_END_FMT(status, fmt, ...) \
00090     _LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_API, status, \
00091             fmt, ##__VA_ARGS__)
00092 
00093 #ifdef VL53L1_LOG_ENABLE
00094 #define trace_print(level, ...) trace_print_module_function(\
00095         VL53L1_TRACE_MODULE_API, level, VL53L1_TRACE_FUNCTION_NONE, \
00096         ##__VA_ARGS__)
00097 #endif
00098 
00099 #ifndef MIN
00100 #define MIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
00101 #endif
00102 #ifndef MAX
00103 #define MAX(v1, v2) ((v1) < (v2) ? (v2) : (v1))
00104 #endif
00105 
00106 #define DMAX_REFLECTANCE_IDX 2
00107 
00108 
00109 
00110 #define LOWPOWER_AUTO_VHV_LOOP_DURATION_US 245
00111 #define LOWPOWER_AUTO_OVERHEAD_BEFORE_A_RANGING 1448
00112 #define LOWPOWER_AUTO_OVERHEAD_BETWEEN_A_B_RANGING 2100
00113 
00114 #define FDA_MAX_TIMING_BUDGET_US 550000
00115 
00116 
00117 
00118 
00119 
00120 
00121 static int32_t BDTable[VL53L1_TUNING_MAX_TUNABLE_KEY] = {
00122         TUNING_VERSION,
00123         TUNING_PROXY_MIN,
00124         TUNING_SINGLE_TARGET_XTALK_TARGET_DISTANCE_MM,
00125         TUNING_SINGLE_TARGET_XTALK_SAMPLE_NUMBER,
00126         TUNING_MIN_AMBIENT_DMAX_VALID,
00127         TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER,
00128         TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM,
00129         TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT,
00130         TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN,
00131         TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET,
00132         TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR_DEFAULT,
00133 };
00134 
00135 
00136 VL53L1_Error SingleTargetXTalkCalibration(VL53L1_DEV Dev)
00137 {
00138     VL53L1_Error Status = VL53L1_ERROR_NONE;
00139 
00140     uint32_t sum_ranging = 0;
00141     uint32_t sum_spads = 0;
00142     FixPoint1616_t sum_signalRate = 0;
00143     FixPoint1616_t total_count = 0;
00144     uint8_t xtalk_meas = 0;
00145     uint8_t xtalk_measmax =
00146         BDTable[VL53L1_TUNING_SINGLE_TARGET_XTALK_SAMPLE_NUMBER];
00147     VL53L1_RangingMeasurementData_t RMData;
00148     FixPoint1616_t xTalkStoredMeanSignalRate;
00149     FixPoint1616_t xTalkStoredMeanRange;
00150     FixPoint1616_t xTalkStoredMeanRtnSpads;
00151     uint32_t xTalkStoredMeanRtnSpadsAsInt;
00152     uint32_t xTalkCalDistanceAsInt;
00153     FixPoint1616_t XTalkCompensationRateMegaCps;
00154     uint32_t signalXTalkTotalPerSpad;
00155     VL53L1_PresetModes PresetMode;
00156     VL53L1_CalibrationData_t  CalibrationData;
00157     VL53L1_CustomerNvmManaged_t *pC;
00158 
00159 
00160     LOG_FUNCTION_START("");
00161 
00162 
00163     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
00164 
00165     if ((PresetMode != VL53L1_PRESETMODE_AUTONOMOUS) &&
00166         (PresetMode != VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS) &&
00167         (PresetMode != VL53L1_PRESETMODE_LITE_RANGING)) {
00168         Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
00169         goto ENDFUNC;
00170     }
00171 
00172 
00173     Status = VL53L1_disable_xtalk_compensation(Dev);
00174 
00175     if (Status != VL53L1_ERROR_NONE)
00176         goto ENDFUNC;
00177 
00178     Status = VL53L1_StartMeasurement(Dev);
00179 
00180     if (Status != VL53L1_ERROR_NONE)
00181         goto ENDFUNC;
00182 
00183 
00184     VL53L1_WaitMeasurementDataReady(Dev);
00185     VL53L1_GetRangingMeasurementData(Dev, &RMData);
00186     VL53L1_ClearInterruptAndStartMeasurement(Dev);
00187 
00188     sum_ranging = 0;
00189     sum_spads = 0;
00190     sum_signalRate = 0;
00191     total_count = 0;
00192     for (xtalk_meas = 0; xtalk_meas < xtalk_measmax; xtalk_meas++) {
00193         VL53L1_WaitMeasurementDataReady(Dev);
00194         VL53L1_GetRangingMeasurementData(Dev, &RMData);
00195         VL53L1_ClearInterruptAndStartMeasurement(Dev);
00196         if (RMData.RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) {
00197             sum_ranging += RMData.RangeMilliMeter ;
00198             sum_signalRate += RMData.SignalRateRtnMegaCps ;
00199             sum_spads += RMData.EffectiveSpadRtnCount  / 256;
00200             total_count++;
00201         }
00202     }
00203     Status = VL53L1_StopMeasurement(Dev);
00204 
00205     if (total_count > 0) {
00206 
00207         xTalkStoredMeanSignalRate = sum_signalRate / total_count;
00208         xTalkStoredMeanRange = (FixPoint1616_t)(sum_ranging << 16);
00209         xTalkStoredMeanRange /= total_count;
00210         xTalkStoredMeanRtnSpads = (FixPoint1616_t)(sum_spads << 16);
00211         xTalkStoredMeanRtnSpads /= total_count;
00212 
00213 
00214         xTalkStoredMeanRtnSpadsAsInt = (xTalkStoredMeanRtnSpads +
00215             0x8000) >> 16;
00216 
00217 
00218          xTalkCalDistanceAsInt = ((uint32_t)BDTable[
00219             VL53L1_TUNING_SINGLE_TARGET_XTALK_TARGET_DISTANCE_MM]);
00220         if (xTalkStoredMeanRtnSpadsAsInt == 0 ||
00221         xTalkCalDistanceAsInt == 0 ||
00222         xTalkStoredMeanRange >= (xTalkCalDistanceAsInt << 16)) {
00223             XTalkCompensationRateMegaCps = 0;
00224         } else {
00225 
00226             signalXTalkTotalPerSpad = (xTalkStoredMeanSignalRate) /
00227                 xTalkStoredMeanRtnSpadsAsInt;
00228 
00229 
00230             signalXTalkTotalPerSpad *= (((uint32_t)1 << 16) -
00231                 (xTalkStoredMeanRange / xTalkCalDistanceAsInt));
00232 
00233 
00234             XTalkCompensationRateMegaCps = (signalXTalkTotalPerSpad
00235                 + 0x8000) >> 16;
00236         }
00237 
00238 
00239         Status = VL53L1_GetCalibrationData(Dev, &CalibrationData);
00240 
00241         if (Status != VL53L1_ERROR_NONE)
00242             goto ENDFUNC;
00243 
00244         pC = &CalibrationData.customer;
00245 
00246         pC->algo__crosstalk_compensation_plane_offset_kcps =
00247             (uint32_t)(1000 * ((XTalkCompensationRateMegaCps  +
00248                 ((uint32_t)1<<6)) >> (16-9)));
00249 
00250         Status = VL53L1_SetCalibrationData(Dev, &CalibrationData);
00251 
00252         if (Status != VL53L1_ERROR_NONE)
00253             goto ENDFUNC;
00254 
00255         Status = VL53L1_enable_xtalk_compensation(Dev);
00256 
00257     } else
00258 
00259         Status = VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL;
00260 
00261 ENDFUNC:
00262     LOG_FUNCTION_END(Status);
00263     return Status;
00264 
00265 }
00266 
00267 
00268 static VL53L1_Error CheckValidRectRoi(VL53L1_UserRoi_t ROI)
00269 {
00270     VL53L1_Error Status = VL53L1_ERROR_NONE;
00271 
00272     LOG_FUNCTION_START("");
00273 
00274 
00275     if ((ROI.TopLeftX  > 15) || (ROI.TopLeftY  > 15) ||
00276         (ROI.BotRightX  > 15) || (ROI.BotRightY  > 15))
00277         Status = VL53L1_ERROR_INVALID_PARAMS;
00278 
00279     if ((ROI.TopLeftX  > ROI.BotRightX ) || (ROI.TopLeftY  < ROI.BotRightY ))
00280         Status = VL53L1_ERROR_INVALID_PARAMS;
00281 
00282     LOG_FUNCTION_END(Status);
00283     return Status;
00284 }
00285 
00286 static VL53L1_GPIO_Interrupt_Mode ConvertModeToLLD(VL53L1_Error *pStatus,
00287         VL53L1_ThresholdMode CrossMode)
00288 {
00289     VL53L1_GPIO_Interrupt_Mode Mode;
00290 
00291     switch (CrossMode) {
00292     case VL53L1_THRESHOLD_CROSSED_LOW:
00293         Mode = VL53L1_GPIOINTMODE_LEVEL_LOW;
00294         break;
00295     case VL53L1_THRESHOLD_CROSSED_HIGH:
00296         Mode = VL53L1_GPIOINTMODE_LEVEL_HIGH;
00297         break;
00298     case VL53L1_THRESHOLD_OUT_OF_WINDOW:
00299         Mode = VL53L1_GPIOINTMODE_OUT_OF_WINDOW;
00300         break;
00301     case VL53L1_THRESHOLD_IN_WINDOW:
00302         Mode = VL53L1_GPIOINTMODE_IN_WINDOW;
00303         break;
00304     default:
00305 
00306         Mode = VL53L1_GPIOINTMODE_LEVEL_HIGH;
00307         *pStatus = VL53L1_ERROR_INVALID_PARAMS;
00308     }
00309     return Mode;
00310 }
00311 
00312 static VL53L1_ThresholdMode ConvertModeFromLLD(VL53L1_Error *pStatus,
00313         VL53L1_GPIO_Interrupt_Mode CrossMode)
00314 {
00315     VL53L1_ThresholdMode Mode;
00316 
00317     switch (CrossMode) {
00318     case VL53L1_GPIOINTMODE_LEVEL_LOW:
00319         Mode = VL53L1_THRESHOLD_CROSSED_LOW;
00320         break;
00321     case VL53L1_GPIOINTMODE_LEVEL_HIGH:
00322         Mode = VL53L1_THRESHOLD_CROSSED_HIGH;
00323         break;
00324     case VL53L1_GPIOINTMODE_OUT_OF_WINDOW:
00325         Mode = VL53L1_THRESHOLD_OUT_OF_WINDOW;
00326         break;
00327     case VL53L1_GPIOINTMODE_IN_WINDOW:
00328         Mode = VL53L1_THRESHOLD_IN_WINDOW;
00329         break;
00330     default:
00331 
00332         Mode = VL53L1_THRESHOLD_CROSSED_HIGH;
00333         *pStatus = VL53L1_ERROR_UNDEFINED;
00334     }
00335     return Mode;
00336 }
00337 
00338 
00339 
00340 VL53L1_Error VL53L1_GetVersion(VL53L1_Version_t *pVersion)
00341 {
00342     VL53L1_Error Status = VL53L1_ERROR_NONE;
00343 
00344     LOG_FUNCTION_START("");
00345 
00346     pVersion->major  = VL53L1_IMPLEMENTATION_VER_MAJOR;
00347     pVersion->minor  = VL53L1_IMPLEMENTATION_VER_MINOR;
00348     pVersion->build  = VL53L1_IMPLEMENTATION_VER_SUB;
00349 
00350     pVersion->revision  = VL53L1_IMPLEMENTATION_VER_REVISION;
00351 
00352     LOG_FUNCTION_END(Status);
00353     return Status;
00354 }
00355 
00356 VL53L1_Error VL53L1_GetProductRevision(VL53L1_DEV Dev,
00357     uint8_t *pProductRevisionMajor, uint8_t *pProductRevisionMinor)
00358 {
00359     VL53L1_Error Status = VL53L1_ERROR_NONE;
00360     uint8_t revision_id;
00361     VL53L1_LLDriverData_t   *pLLData;
00362 
00363     LOG_FUNCTION_START("");
00364 
00365     pLLData =  VL53L1DevStructGetLLDriverHandle(Dev);
00366     revision_id = pLLData->nvm_copy_data.identification__revision_id;
00367     *pProductRevisionMajor = 1;
00368     *pProductRevisionMinor = (revision_id & 0xF0) >> 4;
00369 
00370     LOG_FUNCTION_END(Status);
00371     return Status;
00372 
00373 }
00374 
00375 VL53L1_Error VL53L1_GetDeviceInfo(VL53L1_DEV Dev,
00376     VL53L1_DeviceInfo_t *pVL53L1_DeviceInfo)
00377 {
00378     VL53L1_Error Status = VL53L1_ERROR_NONE;
00379     uint8_t revision_id;
00380     VL53L1_LLDriverData_t   *pLLData;
00381 
00382     LOG_FUNCTION_START("");
00383 
00384     pLLData =  VL53L1DevStructGetLLDriverHandle(Dev);
00385 
00386     strncpy(pVL53L1_DeviceInfo->ProductId , "",
00387             VL53L1_DEVINFO_STRLEN-1);
00388     pVL53L1_DeviceInfo->ProductType  =
00389             pLLData->nvm_copy_data.identification__module_type;
00390 
00391     revision_id = pLLData->nvm_copy_data.identification__revision_id;
00392     pVL53L1_DeviceInfo->ProductRevisionMajor  = 1;
00393     pVL53L1_DeviceInfo->ProductRevisionMinor  = (revision_id & 0xF0) >> 4;
00394 
00395 #ifndef VL53L1_USE_EMPTY_STRING
00396     if (pVL53L1_DeviceInfo->ProductRevisionMinor  == 0)
00397         strncpy(pVL53L1_DeviceInfo->Name ,
00398                 VL53L1_STRING_DEVICE_INFO_NAME0,
00399                 VL53L1_DEVINFO_STRLEN-1);
00400     else
00401         strncpy(pVL53L1_DeviceInfo->Name ,
00402                 VL53L1_STRING_DEVICE_INFO_NAME1,
00403                 VL53L1_DEVINFO_STRLEN-1);
00404     strncpy(pVL53L1_DeviceInfo->Type ,
00405             VL53L1_STRING_DEVICE_INFO_TYPE,
00406             VL53L1_DEVINFO_STRLEN-1);
00407 
00408     if (pVL53L1_DeviceInfo->ProductType  == 0xAA) {
00409         pVL53L1_DeviceInfo->Name [5] = '3';
00410         pVL53L1_DeviceInfo->Type [5] = '3';
00411     }
00412 #else
00413     pVL53L1_DeviceInfo->Name [0] = 0;
00414     pVL53L1_DeviceInfo->Type [0] = 0;
00415 #endif
00416 
00417     LOG_FUNCTION_END(Status);
00418     return Status;
00419 }
00420 
00421 VL53L1_Error VL53L1_GetUID(VL53L1_DEV Dev, uint64_t *pUid)
00422 {
00423     VL53L1_Error Status = VL53L1_ERROR_NONE;
00424     uint8_t fmtdata[8];
00425 
00426     LOG_FUNCTION_START("");
00427 
00428     Status = VL53L1_read_nvm_raw_data(Dev,
00429             (uint8_t)(0x1F8 >> 2),
00430             (uint8_t)(8 >> 2),
00431             fmtdata);
00432     memcpy(pUid, fmtdata, sizeof(uint64_t));
00433 
00434     LOG_FUNCTION_END(Status);
00435     return Status;
00436 }
00437 
00438 VL53L1_Error VL53L1_GetRangeStatusString(uint8_t RangeStatus,
00439     char *pRangeStatusString)
00440 {
00441     VL53L1_Error Status = VL53L1_ERROR_NONE;
00442 
00443     LOG_FUNCTION_START("");
00444 
00445     Status = VL53L1_get_range_status_string(RangeStatus,
00446         pRangeStatusString);
00447 
00448     LOG_FUNCTION_END(Status);
00449     return Status;
00450 }
00451 
00452 VL53L1_Error VL53L1_GetPalErrorString(VL53L1_Error PalErrorCode,
00453     char *pPalErrorString)
00454 {
00455     VL53L1_Error Status = VL53L1_ERROR_NONE;
00456 
00457     LOG_FUNCTION_START("");
00458 
00459     Status = VL53L1_get_pal_error_string(PalErrorCode, pPalErrorString);
00460 
00461     LOG_FUNCTION_END(Status);
00462     return Status;
00463 }
00464 
00465 VL53L1_Error VL53L1_GetPalStateString(VL53L1_State PalStateCode,
00466     char *pPalStateString)
00467 {
00468     VL53L1_Error Status = VL53L1_ERROR_NONE;
00469 
00470     LOG_FUNCTION_START("");
00471 
00472     Status = VL53L1_get_pal_state_string(PalStateCode, pPalStateString);
00473 
00474     LOG_FUNCTION_END(Status);
00475     return Status;
00476 }
00477 
00478 VL53L1_Error VL53L1_GetPalState(VL53L1_DEV Dev, VL53L1_State *pPalState)
00479 {
00480     VL53L1_Error Status = VL53L1_ERROR_NONE;
00481 
00482     LOG_FUNCTION_START("");
00483 
00484     *pPalState = VL53L1DevDataGet(Dev, PalState);
00485 
00486     LOG_FUNCTION_END(Status);
00487     return Status;
00488 }
00489 
00490 
00491 
00492 
00493 VL53L1_Error VL53L1_SetDeviceAddress(VL53L1_DEV Dev, uint8_t DeviceAddress)
00494 {
00495     VL53L1_Error Status = VL53L1_ERROR_NONE;
00496 
00497     LOG_FUNCTION_START("");
00498 
00499     Status = VL53L1_WrByte(Dev, VL53L1_I2C_SLAVE__DEVICE_ADDRESS,
00500             DeviceAddress / 2);
00501 
00502     LOG_FUNCTION_END(Status);
00503     return Status;
00504 }
00505 
00506 VL53L1_Error VL53L1_DataInit(VL53L1_DEV Dev)
00507 {
00508     VL53L1_Error Status = VL53L1_ERROR_NONE;
00509     uint8_t i;
00510     VL53L1_LLDriverData_t *pdev;
00511 
00512     LOG_FUNCTION_START("");
00513 
00514 
00515 #ifdef USE_I2C_2V8
00516     Status = VL53L1_RdByte(Dev, VL53L1_PAD_I2C_HV__EXTSUP_CONFIG, &i);
00517     if (Status == VL53L1_ERROR_NONE) {
00518         i = (i & 0xfe) | 0x01;
00519         Status = VL53L1_WrByte(Dev, VL53L1_PAD_I2C_HV__EXTSUP_CONFIG,
00520                 i);
00521     }
00522 #endif
00523 
00524     if (Status == VL53L1_ERROR_NONE)
00525         Status = VL53L1_data_init(Dev, 1);
00526 
00527     if (Status == VL53L1_ERROR_NONE) {
00528         pdev = VL53L1DevStructGetLLDriverHandle(Dev);
00529         memset(&pdev->per_vcsel_cal_data, 0,
00530                 sizeof(pdev->per_vcsel_cal_data));
00531     }
00532 
00533     if (Status == VL53L1_ERROR_NONE) {
00534         VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_WAIT_STATICINIT);
00535         VL53L1DevDataSet(Dev, CurrentParameters.PresetMode,
00536                 VL53L1_PRESETMODE_RANGING);
00537     }
00538 
00539 
00540     for (i = 0; i < VL53L1_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
00541         if (Status == VL53L1_ERROR_NONE)
00542             Status |= VL53L1_SetLimitCheckEnable(Dev, i, 1);
00543         else
00544             break;
00545 
00546     }
00547 
00548 
00549     if (Status == VL53L1_ERROR_NONE) {
00550         Status = VL53L1_set_dmax_mode(Dev,
00551                 VL53L1_DEVICEDMAXMODE__CUST_CAL_DATA);
00552     }
00553 
00554 
00555     LOG_FUNCTION_END(Status);
00556     return Status;
00557 }
00558 
00559 
00560 VL53L1_Error VL53L1_StaticInit(VL53L1_DEV Dev)
00561 {
00562     VL53L1_Error Status = VL53L1_ERROR_NONE;
00563     uint8_t  measurement_mode;
00564 
00565     LOG_FUNCTION_START("");
00566 
00567     VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_IDLE);
00568 
00569     measurement_mode  = VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
00570     VL53L1DevDataSet(Dev, LLData.measurement_mode, measurement_mode);
00571 
00572     VL53L1DevDataSet(Dev, CurrentParameters.DistanceMode,
00573             VL53L1_DISTANCEMODE_LONG);
00574     VL53L1DevDataSet(Dev, CurrentParameters.OutputMode,
00575             VL53L1_OUTPUTMODE_NEAREST);
00576     LOG_FUNCTION_END(Status);
00577     return Status;
00578 }
00579 
00580 VL53L1_Error VL53L1_WaitDeviceBooted(VL53L1_DEV Dev)
00581 {
00582     VL53L1_Error Status = VL53L1_ERROR_NONE;
00583 
00584     LOG_FUNCTION_START("");
00585 
00586     Status = VL53L1_poll_for_boot_completion(Dev,
00587             VL53L1_BOOT_COMPLETION_POLLING_TIMEOUT_MS);
00588 
00589     LOG_FUNCTION_END(Status);
00590     return Status;
00591 }
00592 
00593 
00594 
00595 
00596 static VL53L1_Error ComputeDevicePresetMode(
00597         VL53L1_PresetModes PresetMode,
00598         VL53L1_DistanceModes DistanceMode,
00599         VL53L1_DevicePresetModes *pDevicePresetMode)
00600 {
00601     VL53L1_Error Status = VL53L1_ERROR_NONE;
00602 
00603     uint8_t DistIdx;
00604     VL53L1_DevicePresetModes LightModes[3] = {
00605         VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_SHORT_RANGE,
00606         VL53L1_DEVICEPRESETMODE_STANDARD_RANGING,
00607         VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_LONG_RANGE};
00608 
00609     VL53L1_DevicePresetModes RangingModes[3] = {
00610         VL53L1_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE,
00611         VL53L1_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE,
00612         VL53L1_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE};
00613 
00614     VL53L1_DevicePresetModes ScanningModes[3] = {
00615         VL53L1_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_SHORT_RANGE,
00616         VL53L1_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE,
00617         VL53L1_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_LONG_RANGE};
00618 
00619     VL53L1_DevicePresetModes TimedModes[3] = {
00620         VL53L1_DEVICEPRESETMODE_TIMED_RANGING_SHORT_RANGE,
00621         VL53L1_DEVICEPRESETMODE_TIMED_RANGING,
00622         VL53L1_DEVICEPRESETMODE_TIMED_RANGING_LONG_RANGE};
00623 
00624     VL53L1_DevicePresetModes LowPowerTimedModes[3] = {
00625         VL53L1_DEVICEPRESETMODE_LOWPOWERAUTO_SHORT_RANGE,
00626         VL53L1_DEVICEPRESETMODE_LOWPOWERAUTO_MEDIUM_RANGE,
00627         VL53L1_DEVICEPRESETMODE_LOWPOWERAUTO_LONG_RANGE};
00628 
00629     *pDevicePresetMode = VL53L1_DEVICEPRESETMODE_STANDARD_RANGING;
00630 
00631     switch (DistanceMode) {
00632     case VL53L1_DISTANCEMODE_SHORT:
00633         DistIdx = 0;
00634         break;
00635     case VL53L1_DISTANCEMODE_MEDIUM:
00636         DistIdx = 1;
00637         break;
00638     default:
00639         DistIdx = 2;
00640     }
00641 
00642     switch (PresetMode) {
00643     case VL53L1_PRESETMODE_LITE_RANGING:
00644         *pDevicePresetMode = LightModes[DistIdx];
00645         break;
00646 
00647     case VL53L1_PRESETMODE_RANGING:
00648         *pDevicePresetMode = RangingModes[DistIdx];
00649         break;
00650 
00651     case VL53L1_PRESETMODE_MULTIZONES_SCANNING:
00652         *pDevicePresetMode = ScanningModes[DistIdx];
00653         break;
00654 
00655     case VL53L1_PRESETMODE_AUTONOMOUS:
00656         *pDevicePresetMode = TimedModes[DistIdx];
00657         break;
00658 
00659     case VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS:
00660         *pDevicePresetMode = LowPowerTimedModes[DistIdx];
00661         break;
00662     case VL53L1_PRESETMODE_OLT:
00663         *pDevicePresetMode = VL53L1_DEVICEPRESETMODE_OLT;
00664         break;
00665     case VL53L1_PRESETMODE_PROXY_RANGING_MODE:
00666         *pDevicePresetMode =
00667             VL53L1_DEVICEPRESETMODE_SPECIAL_HISTOGRAM_SHORT_RANGE;
00668         break;
00669 
00670     default:
00671 
00672         Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
00673     }
00674 
00675     return Status;
00676 }
00677 
00678 static VL53L1_Error SetPresetMode(VL53L1_DEV Dev,
00679         VL53L1_PresetModes PresetMode,
00680         VL53L1_DistanceModes DistanceMode,
00681         uint32_t inter_measurement_period_ms)
00682 {
00683     VL53L1_Error Status = VL53L1_ERROR_NONE;
00684     VL53L1_DevicePresetModes   device_preset_mode;
00685     uint8_t measurement_mode;
00686     uint16_t dss_config__target_total_rate_mcps;
00687     uint32_t phasecal_config_timeout_us;
00688     uint32_t mm_config_timeout_us;
00689     uint32_t lld_range_config_timeout_us;
00690 
00691     LOG_FUNCTION_START("%d", (int)PresetMode);
00692 
00693     if ((PresetMode == VL53L1_PRESETMODE_AUTONOMOUS) ||
00694         (PresetMode == VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS))
00695         measurement_mode  = VL53L1_DEVICEMEASUREMENTMODE_TIMED;
00696     else
00697         measurement_mode  = VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
00698 
00699 
00700     Status = ComputeDevicePresetMode(PresetMode, DistanceMode,
00701             &device_preset_mode);
00702 
00703     if (Status == VL53L1_ERROR_NONE)
00704         Status =  VL53L1_get_preset_mode_timing_cfg(Dev,
00705                 device_preset_mode,
00706                 &dss_config__target_total_rate_mcps,
00707                 &phasecal_config_timeout_us,
00708                 &mm_config_timeout_us,
00709                 &lld_range_config_timeout_us);
00710 
00711     if (Status == VL53L1_ERROR_NONE)
00712         Status = VL53L1_set_preset_mode(
00713                 Dev,
00714                 device_preset_mode,
00715                 dss_config__target_total_rate_mcps,
00716                 phasecal_config_timeout_us,
00717                 mm_config_timeout_us,
00718                 lld_range_config_timeout_us,
00719                 inter_measurement_period_ms);
00720 
00721     if (Status == VL53L1_ERROR_NONE)
00722         VL53L1DevDataSet(Dev, LLData.measurement_mode,
00723                 measurement_mode);
00724 
00725     if (Status == VL53L1_ERROR_NONE)
00726         VL53L1DevDataSet(Dev, CurrentParameters.PresetMode, PresetMode);
00727 
00728     VL53L1DevDataSet(Dev, CurrentParameters.OutputMode,
00729             VL53L1_OUTPUTMODE_NEAREST);
00730     LOG_FUNCTION_END(Status);
00731     return Status;
00732 }
00733 
00734 
00735 VL53L1_Error VL53L1_SetPresetMode(VL53L1_DEV Dev, VL53L1_PresetModes PresetMode)
00736 {
00737     VL53L1_Error Status = VL53L1_ERROR_NONE;
00738     VL53L1_DistanceModes DistanceMode = VL53L1_DISTANCEMODE_LONG;
00739 
00740     LOG_FUNCTION_START("%d", (int)PresetMode);
00741 
00742 
00743     Status = VL53L1_low_power_auto_data_init(Dev);
00744 
00745     if (PresetMode == VL53L1_PRESETMODE_PROXY_RANGING_MODE)
00746         DistanceMode = VL53L1_DISTANCEMODE_SHORT;
00747     Status = SetPresetMode(Dev,
00748             PresetMode,
00749             DistanceMode,
00750             1000);
00751 
00752     if (Status == VL53L1_ERROR_NONE) {
00753         if ((PresetMode == VL53L1_PRESETMODE_LITE_RANGING) ||
00754             (PresetMode == VL53L1_PRESETMODE_AUTONOMOUS) ||
00755             (PresetMode == VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS))
00756             Status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(
00757                 Dev, 41000);
00758         else
00759 
00760             Status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(
00761                 Dev, 33333);
00762     }
00763 
00764     if (Status == VL53L1_ERROR_NONE) {
00765 
00766         Status = VL53L1_SetInterMeasurementPeriodMilliSeconds(Dev,
00767                 1000);
00768     }
00769 
00770     LOG_FUNCTION_END(Status);
00771     return Status;
00772 }
00773 
00774 
00775 VL53L1_Error VL53L1_GetPresetMode(VL53L1_DEV Dev,
00776     VL53L1_PresetModes *pPresetMode)
00777 {
00778     VL53L1_Error Status = VL53L1_ERROR_NONE;
00779 
00780     LOG_FUNCTION_START("");
00781 
00782     *pPresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
00783 
00784     LOG_FUNCTION_END(Status);
00785     return Status;
00786 }
00787 
00788 VL53L1_Error VL53L1_SetDistanceMode(VL53L1_DEV Dev,
00789         VL53L1_DistanceModes DistanceMode)
00790 {
00791     VL53L1_Error Status = VL53L1_ERROR_NONE;
00792     VL53L1_PresetModes PresetMode;
00793     uint32_t inter_measurement_period_ms;
00794     uint32_t TimingBudget;
00795     uint32_t MmTimeoutUs;
00796     uint32_t PhaseCalTimeoutUs;
00797     VL53L1_zone_config_t zone_config;
00798 
00799     LOG_FUNCTION_START("%d", (int)DistanceMode);
00800 
00801     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
00802 
00803 
00804 
00805     if ((PresetMode == VL53L1_PRESETMODE_PROXY_RANGING_MODE) &&
00806         (DistanceMode != VL53L1_DISTANCEMODE_SHORT))
00807         return VL53L1_ERROR_INVALID_PARAMS;
00808     if ((DistanceMode != VL53L1_DISTANCEMODE_SHORT) &&
00809         (DistanceMode != VL53L1_DISTANCEMODE_MEDIUM) &&
00810         (DistanceMode != VL53L1_DISTANCEMODE_LONG))
00811         return VL53L1_ERROR_INVALID_PARAMS;
00812 
00813     if (Status == VL53L1_ERROR_NONE)
00814         Status = VL53L1_get_zone_config(Dev, &zone_config);
00815 
00816     inter_measurement_period_ms =  VL53L1DevDataGet(Dev,
00817                 LLData.inter_measurement_period_ms);
00818 
00819     if (Status == VL53L1_ERROR_NONE)
00820         Status = VL53L1_get_timeouts_us(Dev, &PhaseCalTimeoutUs,
00821             &MmTimeoutUs, &TimingBudget);
00822 
00823     if (Status == VL53L1_ERROR_NONE)
00824         Status = SetPresetMode(Dev,
00825                 PresetMode,
00826                 DistanceMode,
00827                 inter_measurement_period_ms);
00828 
00829     if (Status == VL53L1_ERROR_NONE) {
00830         VL53L1DevDataSet(Dev, CurrentParameters.DistanceMode,
00831                 DistanceMode);
00832     }
00833 
00834     if (Status == VL53L1_ERROR_NONE) {
00835         Status = VL53L1_set_timeouts_us(Dev, PhaseCalTimeoutUs,
00836             MmTimeoutUs, TimingBudget);
00837 
00838         if (Status == VL53L1_ERROR_NONE)
00839             VL53L1DevDataSet(Dev, LLData.range_config_timeout_us,
00840                 TimingBudget);
00841     }
00842 
00843     if (Status == VL53L1_ERROR_NONE)
00844         Status = VL53L1_set_zone_config(Dev, &zone_config);
00845 
00846     LOG_FUNCTION_END(Status);
00847     return Status;
00848 }
00849 
00850 VL53L1_Error VL53L1_GetDistanceMode(VL53L1_DEV Dev,
00851     VL53L1_DistanceModes *pDistanceMode)
00852 {
00853     VL53L1_Error Status = VL53L1_ERROR_NONE;
00854 
00855     LOG_FUNCTION_START("");
00856 
00857     *pDistanceMode = VL53L1DevDataGet(Dev, CurrentParameters.DistanceMode);
00858 
00859     LOG_FUNCTION_END(Status);
00860     return Status;
00861 }
00862 
00863 VL53L1_Error VL53L1_SetOutputMode(VL53L1_DEV Dev,
00864         VL53L1_OutputModes OutputMode)
00865 {
00866     VL53L1_Error Status = VL53L1_ERROR_NONE;
00867 
00868     LOG_FUNCTION_START("");
00869 
00870     if ((OutputMode != VL53L1_OUTPUTMODE_NEAREST) &&
00871         (OutputMode != VL53L1_OUTPUTMODE_STRONGEST))
00872         Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
00873     else
00874         VL53L1DevDataSet(Dev, CurrentParameters.OutputMode, OutputMode);
00875 
00876     LOG_FUNCTION_END(Status);
00877     return Status;
00878 }
00879 
00880 VL53L1_Error VL53L1_GetOutputMode(VL53L1_DEV Dev,
00881         VL53L1_OutputModes *pOutputMode)
00882 {
00883     VL53L1_Error Status = VL53L1_ERROR_NONE;
00884 
00885     LOG_FUNCTION_START("");
00886 
00887     *pOutputMode = VL53L1DevDataGet(Dev, CurrentParameters.OutputMode);
00888 
00889     LOG_FUNCTION_END(Status);
00890     return Status;
00891 }
00892 
00893 
00894 
00895 VL53L1_Error VL53L1_SetMeasurementTimingBudgetMicroSeconds(VL53L1_DEV Dev,
00896     uint32_t MeasurementTimingBudgetMicroSeconds)
00897 {
00898     VL53L1_Error Status = VL53L1_ERROR_NONE;
00899     uint8_t Mm1Enabled;
00900     uint8_t Mm2Enabled;
00901     uint32_t TimingGuard;
00902     uint32_t divisor;
00903     uint32_t TimingBudget;
00904     uint32_t MmTimeoutUs;
00905     VL53L1_PresetModes PresetMode;
00906     uint32_t PhaseCalTimeoutUs;
00907     uint32_t vhv;
00908     int32_t vhv_loops;
00909     uint32_t FDAMaxTimingBudgetUs = FDA_MAX_TIMING_BUDGET_US;
00910 
00911     LOG_FUNCTION_START("");
00912 
00913 
00914     if (MeasurementTimingBudgetMicroSeconds > 10000000)
00915         Status = VL53L1_ERROR_INVALID_PARAMS;
00916 
00917     if (Status == VL53L1_ERROR_NONE) {
00918         Status = VL53L1_GetSequenceStepEnable(Dev,
00919             VL53L1_SEQUENCESTEP_MM1, &Mm1Enabled);
00920     }
00921 
00922     if (Status == VL53L1_ERROR_NONE) {
00923         Status = VL53L1_GetSequenceStepEnable(Dev,
00924             VL53L1_SEQUENCESTEP_MM2, &Mm2Enabled);
00925     }
00926 
00927     if (Status == VL53L1_ERROR_NONE)
00928         Status = VL53L1_get_timeouts_us(Dev,
00929             &PhaseCalTimeoutUs,
00930             &MmTimeoutUs,
00931             &TimingBudget);
00932 
00933     if (Status == VL53L1_ERROR_NONE) {
00934         PresetMode = VL53L1DevDataGet(Dev,
00935                 CurrentParameters.PresetMode);
00936 
00937         TimingGuard = 0;
00938         divisor = 1;
00939         switch (PresetMode) {
00940         case VL53L1_PRESETMODE_LITE_RANGING:
00941             if ((Mm1Enabled == 1) || (Mm2Enabled == 1))
00942                 TimingGuard = 5000;
00943             else
00944                 TimingGuard = 1000;
00945         break;
00946 
00947         case VL53L1_PRESETMODE_AUTONOMOUS:
00948             FDAMaxTimingBudgetUs *= 2;
00949             if ((Mm1Enabled == 1) || (Mm2Enabled == 1))
00950                 TimingGuard = 26600;
00951             else
00952                 TimingGuard = 21600;
00953             divisor = 2;
00954         break;
00955 
00956         case VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS:
00957             FDAMaxTimingBudgetUs *= 2;
00958             vhv = LOWPOWER_AUTO_VHV_LOOP_DURATION_US;
00959             VL53L1_get_tuning_parm(Dev,
00960                 VL53L1_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND,
00961                 &vhv_loops);
00962             if (vhv_loops > 0) {
00963                 vhv += vhv_loops *
00964                     LOWPOWER_AUTO_VHV_LOOP_DURATION_US;
00965             }
00966             TimingGuard = LOWPOWER_AUTO_OVERHEAD_BEFORE_A_RANGING +
00967                 LOWPOWER_AUTO_OVERHEAD_BETWEEN_A_B_RANGING +
00968                 vhv;
00969             divisor = 2;
00970         break;
00971 
00972         case VL53L1_PRESETMODE_RANGING:
00973         case VL53L1_PRESETMODE_MULTIZONES_SCANNING:
00974         case VL53L1_PRESETMODE_PROXY_RANGING_MODE:
00975             TimingGuard = 1700;
00976             divisor = 6;
00977         break;
00978 
00979         case VL53L1_PRESETMODE_OLT:
00980             TimingGuard = MmTimeoutUs + 5000;
00981         break;
00982         default:
00983 
00984             Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
00985         }
00986 
00987         if (MeasurementTimingBudgetMicroSeconds <= TimingGuard)
00988             Status = VL53L1_ERROR_INVALID_PARAMS;
00989         else {
00990             TimingBudget = (MeasurementTimingBudgetMicroSeconds
00991                     - TimingGuard);
00992         }
00993 
00994         if (Status == VL53L1_ERROR_NONE) {
00995             if (TimingBudget > FDAMaxTimingBudgetUs)
00996                 Status = VL53L1_ERROR_INVALID_PARAMS;
00997             else {
00998                 TimingBudget /= divisor;
00999                 Status = VL53L1_set_timeouts_us(
01000                     Dev,
01001                     PhaseCalTimeoutUs,
01002                     MmTimeoutUs,
01003                     TimingBudget);
01004             }
01005 
01006             if (Status == VL53L1_ERROR_NONE)
01007                 VL53L1DevDataSet(Dev,
01008                     LLData.range_config_timeout_us,
01009                     TimingBudget);
01010         }
01011     }
01012     if (Status == VL53L1_ERROR_NONE) {
01013         VL53L1DevDataSet(Dev,
01014             CurrentParameters.MeasurementTimingBudgetMicroSeconds,
01015             MeasurementTimingBudgetMicroSeconds);
01016     }
01017 
01018     LOG_FUNCTION_END(Status);
01019     return Status;
01020 }
01021 
01022 
01023 VL53L1_Error VL53L1_GetMeasurementTimingBudgetMicroSeconds(VL53L1_DEV Dev,
01024     uint32_t *pMeasurementTimingBudgetMicroSeconds)
01025 {
01026     VL53L1_Error Status = VL53L1_ERROR_NONE;
01027     uint8_t Mm1Enabled = 0;
01028     uint8_t Mm2Enabled = 0;
01029     uint32_t  MmTimeoutUs = 0;
01030     uint32_t  RangeTimeoutUs = 0;
01031     uint32_t  MeasTimingBdg = 0;
01032     uint32_t PhaseCalTimeoutUs = 0;
01033     VL53L1_PresetModes PresetMode;
01034     uint32_t TimingGuard;
01035     uint32_t vhv;
01036     int32_t vhv_loops;
01037 
01038     LOG_FUNCTION_START("");
01039 
01040     *pMeasurementTimingBudgetMicroSeconds = 0;
01041 
01042     if (Status == VL53L1_ERROR_NONE)
01043         Status = VL53L1_GetSequenceStepEnable(Dev,
01044             VL53L1_SEQUENCESTEP_MM1, &Mm1Enabled);
01045 
01046     if (Status == VL53L1_ERROR_NONE)
01047         Status = VL53L1_GetSequenceStepEnable(Dev,
01048             VL53L1_SEQUENCESTEP_MM2, &Mm2Enabled);
01049 
01050     if (Status == VL53L1_ERROR_NONE)
01051         Status = VL53L1_get_timeouts_us(Dev,
01052             &PhaseCalTimeoutUs,
01053             &MmTimeoutUs,
01054             &RangeTimeoutUs);
01055 
01056     if (Status == VL53L1_ERROR_NONE) {
01057         PresetMode = VL53L1DevDataGet(Dev,
01058                 CurrentParameters.PresetMode);
01059 
01060         switch (PresetMode) {
01061         case VL53L1_PRESETMODE_LITE_RANGING:
01062             if ((Mm1Enabled == 1) || (Mm2Enabled == 1))
01063                 MeasTimingBdg = RangeTimeoutUs + 5000;
01064             else
01065                 MeasTimingBdg = RangeTimeoutUs + 1000;
01066 
01067         break;
01068 
01069         case VL53L1_PRESETMODE_AUTONOMOUS:
01070             if ((Mm1Enabled == 1) || (Mm2Enabled == 1))
01071                 MeasTimingBdg = 2 * RangeTimeoutUs + 26600;
01072             else
01073                 MeasTimingBdg = 2 * RangeTimeoutUs + 21600;
01074 
01075         break;
01076 
01077         case VL53L1_PRESETMODE_LOWPOWER_AUTONOMOUS:
01078             vhv = LOWPOWER_AUTO_VHV_LOOP_DURATION_US;
01079             VL53L1_get_tuning_parm(Dev,
01080                 VL53L1_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND,
01081                 &vhv_loops);
01082             if (vhv_loops > 0) {
01083                 vhv += vhv_loops *
01084                     LOWPOWER_AUTO_VHV_LOOP_DURATION_US;
01085             }
01086             TimingGuard = LOWPOWER_AUTO_OVERHEAD_BEFORE_A_RANGING +
01087                 LOWPOWER_AUTO_OVERHEAD_BETWEEN_A_B_RANGING +
01088                 vhv;
01089             MeasTimingBdg = 2 * RangeTimeoutUs + TimingGuard;
01090         break;
01091 
01092         case VL53L1_PRESETMODE_RANGING:
01093         case VL53L1_PRESETMODE_MULTIZONES_SCANNING:
01094         case VL53L1_PRESETMODE_PROXY_RANGING_MODE:
01095             MeasTimingBdg = (6 * RangeTimeoutUs) + 1700;
01096         break;
01097 
01098         case VL53L1_PRESETMODE_OLT:
01099             MeasTimingBdg = RangeTimeoutUs + MmTimeoutUs + 5000;
01100         break;
01101         default:
01102 
01103             Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
01104         }
01105     }
01106     if (Status == VL53L1_ERROR_NONE)
01107         *pMeasurementTimingBudgetMicroSeconds = MeasTimingBdg;
01108 
01109     LOG_FUNCTION_END(Status);
01110     return Status;
01111 }
01112 
01113 
01114 
01115 VL53L1_Error VL53L1_SetInterMeasurementPeriodMilliSeconds(VL53L1_DEV Dev,
01116     uint32_t InterMeasurementPeriodMilliSeconds)
01117 {
01118     VL53L1_Error Status = VL53L1_ERROR_NONE;
01119     uint32_t adjustedIMP;
01120 
01121     LOG_FUNCTION_START("");
01122 
01123 
01124     adjustedIMP = InterMeasurementPeriodMilliSeconds;
01125     adjustedIMP += (adjustedIMP * 64) / 1000;
01126 
01127     Status = VL53L1_set_inter_measurement_period_ms(Dev,
01128             adjustedIMP);
01129 
01130     LOG_FUNCTION_END(Status);
01131     return Status;
01132 }
01133 
01134 VL53L1_Error VL53L1_GetInterMeasurementPeriodMilliSeconds(VL53L1_DEV Dev,
01135     uint32_t *pInterMeasurementPeriodMilliSeconds)
01136 {
01137     VL53L1_Error Status = VL53L1_ERROR_NONE;
01138     uint32_t adjustedIMP;
01139 
01140     LOG_FUNCTION_START("");
01141 
01142     Status = VL53L1_get_inter_measurement_period_ms(Dev, &adjustedIMP);
01143 
01144     adjustedIMP -= (adjustedIMP * 64) / 1000;
01145     *pInterMeasurementPeriodMilliSeconds = adjustedIMP;
01146 
01147 
01148     LOG_FUNCTION_END(Status);
01149     return Status;
01150 }
01151 
01152 VL53L1_Error VL53L1_SetDmaxReflectance(VL53L1_DEV Dev,
01153         FixPoint1616_t DmaxReflectance)
01154 {
01155     VL53L1_Error Status = VL53L1_ERROR_NONE;
01156     VL53L1_dmax_reflectance_array_t dmax_reflectances;
01157 
01158     LOG_FUNCTION_START("");
01159 
01160     if (DmaxReflectance > 100*65536)
01161         Status = VL53L1_ERROR_INVALID_PARAMS;
01162 
01163     if (Status == VL53L1_ERROR_NONE)
01164         Status = VL53L1_get_dmax_reflectance_values(Dev,
01165                 &dmax_reflectances);
01166 
01167     if (Status == VL53L1_ERROR_NONE) {
01168         dmax_reflectances.target_reflectance_for_dmax[
01169             DMAX_REFLECTANCE_IDX] =
01170             VL53L1_FIXPOINT1616TOFIXPOINT72(DmaxReflectance);
01171         Status = VL53L1_set_dmax_reflectance_values(Dev,
01172                 &dmax_reflectances);
01173     }
01174 
01175     LOG_FUNCTION_END(Status);
01176     return Status;
01177 }
01178 
01179 VL53L1_Error VL53L1_GetDmaxReflectance(VL53L1_DEV Dev,
01180         FixPoint1616_t *pDmaxReflectance)
01181 {
01182     VL53L1_Error Status = VL53L1_ERROR_NONE;
01183     VL53L1_dmax_reflectance_array_t dmax_reflectances;
01184     uint16_t r;
01185 
01186     LOG_FUNCTION_START("");
01187     Status = VL53L1_get_dmax_reflectance_values(Dev, &dmax_reflectances);
01188     if (Status == VL53L1_ERROR_NONE) {
01189         r = dmax_reflectances.target_reflectance_for_dmax[
01190                             DMAX_REFLECTANCE_IDX];
01191         *pDmaxReflectance = VL53L1_FIXPOINT72TOFIXPOINT1616(r);
01192     }
01193 
01194     LOG_FUNCTION_END(Status);
01195     return Status;
01196 }
01197 
01198 
01199 VL53L1_Error VL53L1_SetDmaxMode(VL53L1_DEV Dev,
01200         VL53L1_DeviceDmaxModes DmaxMode)
01201 {
01202 
01203     VL53L1_Error  Status = VL53L1_ERROR_NONE;
01204     VL53L1_DeviceDmaxMode dmax_mode;
01205 
01206     LOG_FUNCTION_START("");
01207 
01208     switch (DmaxMode) {
01209     case VL53L1_DMAXMODE_FMT_CAL_DATA:
01210         dmax_mode = VL53L1_DEVICEDMAXMODE__FMT_CAL_DATA;
01211         break;
01212     case VL53L1_DMAXMODE_CUSTCAL_DATA:
01213         dmax_mode = VL53L1_DEVICEDMAXMODE__CUST_CAL_DATA;
01214         break;
01215     case VL53L1_DMAXMODE_PER_ZONE_CAL_DATA:
01216         dmax_mode = VL53L1_DEVICEDMAXMODE__PER_ZONE_CAL_DATA;
01217         break;
01218     default:
01219         Status = VL53L1_ERROR_INVALID_PARAMS;
01220         break;
01221     }
01222     if (Status == VL53L1_ERROR_NONE)
01223         Status = VL53L1_set_dmax_mode(Dev, dmax_mode);
01224 
01225     LOG_FUNCTION_END(Status);
01226     return Status;
01227 }
01228 
01229 
01230 VL53L1_Error VL53L1_GetDmaxMode(VL53L1_DEV Dev,
01231     VL53L1_DeviceDmaxModes *pDmaxMode)
01232 {
01233     VL53L1_Error  Status = VL53L1_ERROR_NONE;
01234     VL53L1_DeviceDmaxMode dmax_mode;
01235 
01236     LOG_FUNCTION_START("");
01237 
01238     Status = VL53L1_get_dmax_mode(Dev, &dmax_mode);
01239     if (Status == VL53L1_ERROR_NONE) {
01240         switch (dmax_mode) {
01241         case VL53L1_DEVICEDMAXMODE__FMT_CAL_DATA:
01242             *pDmaxMode = VL53L1_DMAXMODE_FMT_CAL_DATA;
01243             break;
01244         case VL53L1_DEVICEDMAXMODE__CUST_CAL_DATA:
01245             *pDmaxMode = VL53L1_DMAXMODE_CUSTCAL_DATA;
01246             break;
01247         case VL53L1_DEVICEDMAXMODE__PER_ZONE_CAL_DATA:
01248             *pDmaxMode = VL53L1_DMAXMODE_PER_ZONE_CAL_DATA;
01249             break;
01250         default:
01251             *pDmaxMode = VL53L1_DEVICEDMAXMODE__CUST_CAL_DATA;
01252             Status = VL53L1_ERROR_NOT_IMPLEMENTED;
01253             break;
01254         }
01255     }
01256 
01257     LOG_FUNCTION_END(Status);
01258     return Status;
01259 }
01260 
01261 
01262 
01263 
01264 
01265 
01266 VL53L1_Error VL53L1_GetNumberOfLimitCheck(uint16_t *pNumberOfLimitCheck)
01267 {
01268     VL53L1_Error Status = VL53L1_ERROR_NONE;
01269 
01270     LOG_FUNCTION_START("");
01271 
01272     *pNumberOfLimitCheck = VL53L1_CHECKENABLE_NUMBER_OF_CHECKS;
01273 
01274     LOG_FUNCTION_END(Status);
01275     return Status;
01276 }
01277 
01278 VL53L1_Error VL53L1_GetLimitCheckInfo(uint16_t LimitCheckId,
01279     char *pLimitCheckString)
01280 {
01281     VL53L1_Error Status = VL53L1_ERROR_NONE;
01282 
01283     LOG_FUNCTION_START("");
01284 
01285     Status = VL53L1_get_limit_check_info(LimitCheckId,
01286         pLimitCheckString);
01287 
01288     LOG_FUNCTION_END(Status);
01289     return Status;
01290 }
01291 
01292 VL53L1_Error VL53L1_GetLimitCheckStatus(VL53L1_DEV Dev, uint16_t LimitCheckId,
01293     uint8_t *pLimitCheckStatus)
01294 {
01295     VL53L1_Error Status = VL53L1_ERROR_NONE;
01296     uint8_t Temp8;
01297 
01298     LOG_FUNCTION_START("");
01299 
01300     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01301         Status = VL53L1_ERROR_INVALID_PARAMS;
01302     } else {
01303         VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
01304             LimitCheckId, Temp8);
01305         *pLimitCheckStatus = Temp8;
01306     }
01307 
01308     LOG_FUNCTION_END(Status);
01309     return Status;
01310 }
01311 
01312 static VL53L1_Error SetLimitValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
01313         FixPoint1616_t value)
01314 {
01315     VL53L1_Error Status = VL53L1_ERROR_NONE;
01316     uint16_t tmpuint16;
01317 
01318     LOG_FUNCTION_START("");
01319 
01320     switch (LimitCheckId) {
01321     case VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE:
01322         tmpuint16 = VL53L1_FIXPOINT1616TOFIXPOINT142(value);
01323         VL53L1_set_lite_sigma_threshold(Dev, tmpuint16);
01324         break;
01325     case VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
01326         tmpuint16 = VL53L1_FIXPOINT1616TOFIXPOINT97(value);
01327         VL53L1_set_lite_min_count_rate(Dev, tmpuint16);
01328         break;
01329     default:
01330         Status = VL53L1_ERROR_INVALID_PARAMS;
01331     }
01332 
01333     LOG_FUNCTION_END(Status);
01334     return Status;
01335 }
01336 
01337 
01338 VL53L1_Error VL53L1_SetLimitCheckEnable(VL53L1_DEV Dev, uint16_t LimitCheckId,
01339     uint8_t LimitCheckEnable)
01340 {
01341     VL53L1_Error Status = VL53L1_ERROR_NONE;
01342     FixPoint1616_t TempFix1616 = 0;
01343 
01344     LOG_FUNCTION_START("");
01345 
01346 
01347     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01348         Status = VL53L1_ERROR_INVALID_PARAMS;
01349     } else {
01350 
01351         if (LimitCheckEnable == 0)
01352             TempFix1616 = 0;
01353         else
01354             VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
01355                 LimitCheckId, TempFix1616);
01356 
01357         Status = SetLimitValue(Dev, LimitCheckId, TempFix1616);
01358     }
01359 
01360     if (Status == VL53L1_ERROR_NONE)
01361         VL53L1_SETARRAYPARAMETERFIELD(Dev,
01362             LimitChecksEnable,
01363             LimitCheckId,
01364             ((LimitCheckEnable == 0) ? 0 : 1));
01365 
01366 
01367 
01368     LOG_FUNCTION_END(Status);
01369     return Status;
01370 }
01371 
01372 VL53L1_Error VL53L1_GetLimitCheckEnable(VL53L1_DEV Dev, uint16_t LimitCheckId,
01373     uint8_t *pLimitCheckEnable)
01374 {
01375     VL53L1_Error Status = VL53L1_ERROR_NONE;
01376     uint8_t Temp8;
01377 
01378     LOG_FUNCTION_START("");
01379 
01380     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01381         Status = VL53L1_ERROR_INVALID_PARAMS;
01382         *pLimitCheckEnable = 0;
01383     } else {
01384         VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
01385             LimitCheckId, Temp8);
01386         *pLimitCheckEnable = Temp8;
01387     }
01388 
01389 
01390     LOG_FUNCTION_END(Status);
01391     return Status;
01392 }
01393 
01394 VL53L1_Error VL53L1_SetLimitCheckValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
01395     FixPoint1616_t LimitCheckValue)
01396 {
01397     VL53L1_Error Status = VL53L1_ERROR_NONE;
01398     uint8_t LimitChecksEnable;
01399 
01400     LOG_FUNCTION_START("");
01401 
01402     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01403         Status = VL53L1_ERROR_INVALID_PARAMS;
01404     } else {
01405 
01406         VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
01407                 LimitCheckId,
01408                 LimitChecksEnable);
01409 
01410         if (LimitChecksEnable == 0) {
01411 
01412             VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
01413                 LimitCheckId, LimitCheckValue);
01414         } else {
01415 
01416             Status = SetLimitValue(Dev, LimitCheckId,
01417                     LimitCheckValue);
01418 
01419             if (Status == VL53L1_ERROR_NONE) {
01420                 VL53L1_SETARRAYPARAMETERFIELD(Dev,
01421                     LimitChecksValue,
01422                     LimitCheckId, LimitCheckValue);
01423             }
01424         }
01425     }
01426 
01427     LOG_FUNCTION_END(Status);
01428     return Status;
01429 }
01430 
01431 VL53L1_Error VL53L1_GetLimitCheckValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
01432     FixPoint1616_t *pLimitCheckValue)
01433 {
01434     VL53L1_Error Status = VL53L1_ERROR_NONE;
01435     uint16_t MinCountRate;
01436     FixPoint1616_t TempFix1616;
01437     uint16_t SigmaThresh;
01438 
01439     LOG_FUNCTION_START("");
01440 
01441     switch (LimitCheckId) {
01442     case VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE:
01443         Status = VL53L1_get_lite_sigma_threshold(Dev, &SigmaThresh);
01444         TempFix1616 = VL53L1_FIXPOINT142TOFIXPOINT1616(SigmaThresh);
01445         break;
01446     case VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
01447         Status = VL53L1_get_lite_min_count_rate(Dev, &MinCountRate);
01448         TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(MinCountRate);
01449         break;
01450     default:
01451         Status = VL53L1_ERROR_INVALID_PARAMS;
01452     }
01453 
01454     if (Status == VL53L1_ERROR_NONE) {
01455 
01456         if (TempFix1616 == 0) {
01457 
01458             VL53L1_GETARRAYPARAMETERFIELD(Dev,
01459                 LimitChecksValue, LimitCheckId,
01460                 TempFix1616);
01461             *pLimitCheckValue = TempFix1616;
01462             VL53L1_SETARRAYPARAMETERFIELD(Dev,
01463                 LimitChecksEnable, LimitCheckId, 0);
01464         } else {
01465             *pLimitCheckValue = TempFix1616;
01466             VL53L1_SETARRAYPARAMETERFIELD(Dev,
01467                 LimitChecksValue, LimitCheckId,
01468                 TempFix1616);
01469             VL53L1_SETARRAYPARAMETERFIELD(Dev,
01470                 LimitChecksEnable, LimitCheckId, 1);
01471         }
01472     }
01473     LOG_FUNCTION_END(Status);
01474     return Status;
01475 
01476 }
01477 
01478 VL53L1_Error VL53L1_GetLimitCheckCurrent(VL53L1_DEV Dev, uint16_t LimitCheckId,
01479     FixPoint1616_t *pLimitCheckCurrent)
01480 {
01481     VL53L1_Error Status = VL53L1_ERROR_NONE;
01482     FixPoint1616_t TempFix1616 = 0;
01483 
01484     LOG_FUNCTION_START("");
01485 
01486     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01487         Status = VL53L1_ERROR_INVALID_PARAMS;
01488     } else {
01489         VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksCurrent,
01490             LimitCheckId, TempFix1616);
01491         *pLimitCheckCurrent = TempFix1616;
01492     }
01493 
01494     LOG_FUNCTION_END(Status);
01495     return Status;
01496 
01497 }
01498 
01499 
01500 
01501 
01502 
01503 
01504 
01505 
01506 VL53L1_Error VL53L1_GetMaxNumberOfROI(VL53L1_DEV Dev,
01507     uint8_t *pMaxNumberOfROI)
01508 {
01509     VL53L1_Error Status = VL53L1_ERROR_NONE;
01510     VL53L1_PresetModes PresetMode;
01511 
01512     LOG_FUNCTION_START("");
01513 
01514     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
01515 
01516 
01517     if (PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING)
01518         *pMaxNumberOfROI = VL53L1_MAX_USER_ZONES;
01519     else
01520         *pMaxNumberOfROI = 1;
01521 
01522     LOG_FUNCTION_END(Status);
01523     return Status;
01524 }
01525 
01526 VL53L1_Error VL53L1_SetROI(VL53L1_DEV Dev,
01527         VL53L1_RoiConfig_t *pRoiConfig)
01528 {
01529     VL53L1_Error Status = VL53L1_ERROR_NONE;
01530     VL53L1_PresetModes PresetMode;
01531     uint8_t MaxNumberOfROI = 1;
01532     VL53L1_zone_config_t  zone_cfg;
01533     VL53L1_UserRoi_t CurrROI;
01534     uint8_t  i;
01535     uint8_t  x_centre;
01536     uint8_t  y_centre;
01537     uint8_t  width, height;
01538 
01539     LOG_FUNCTION_START("");
01540 
01541 
01542     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
01543 
01544 
01545     if (PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING)
01546         MaxNumberOfROI = VL53L1_MAX_USER_ZONES;
01547 
01548     if ((pRoiConfig->NumberOfRoi  > MaxNumberOfROI) ||
01549             (pRoiConfig->NumberOfRoi  < 1))
01550         Status = VL53L1_ERROR_INVALID_PARAMS;
01551 
01552     if (Status == VL53L1_ERROR_NONE) {
01553 
01554 
01555         zone_cfg.max_zones = MaxNumberOfROI;
01556         zone_cfg.active_zones = pRoiConfig->NumberOfRoi  - 1;
01557 
01558         for (i = 0; i < pRoiConfig->NumberOfRoi ; i++) {
01559             CurrROI = pRoiConfig->UserRois [i];
01560 
01561             Status = CheckValidRectRoi(CurrROI);
01562             if (Status != VL53L1_ERROR_NONE)
01563                 break;
01564 
01565             x_centre = (CurrROI.BotRightX  + CurrROI.TopLeftX   + 1)
01566                     / 2;
01567             y_centre = (CurrROI.TopLeftY   + CurrROI.BotRightY  + 1)
01568                     / 2;
01569             width =     (CurrROI.BotRightX  - CurrROI.TopLeftX );
01570             height =    (CurrROI.TopLeftY   - CurrROI.BotRightY );
01571             if ((width < 3) || (height < 3)) {
01572                 Status = VL53L1_ERROR_INVALID_PARAMS;
01573                 break;
01574             }
01575             zone_cfg.user_zones[i].x_centre = x_centre;
01576             zone_cfg.user_zones[i].y_centre = y_centre;
01577             zone_cfg.user_zones[i].width = width;
01578             zone_cfg.user_zones[i].height = height;
01579         }
01580     }
01581 
01582     if (Status == VL53L1_ERROR_NONE)
01583         Status = VL53L1_set_zone_config(Dev, &zone_cfg);
01584 
01585     LOG_FUNCTION_END(Status);
01586     return Status;
01587 }
01588 
01589 VL53L1_Error VL53L1_GetROI(VL53L1_DEV Dev,
01590         VL53L1_RoiConfig_t *pRoiConfig)
01591 {
01592     VL53L1_Error Status = VL53L1_ERROR_NONE;
01593     VL53L1_zone_config_t      zone_cfg;
01594     uint8_t  i;
01595     uint8_t  TopLeftX;
01596     uint8_t  TopLeftY;
01597     uint8_t  BotRightX;
01598     uint8_t  BotRightY;
01599 
01600     LOG_FUNCTION_START("");
01601 
01602     VL53L1_get_zone_config(Dev, &zone_cfg);
01603 
01604     pRoiConfig->NumberOfRoi  = zone_cfg.active_zones + 1;
01605 
01606     for (i = 0; i < pRoiConfig->NumberOfRoi ; i++) {
01607         TopLeftX = (2 * zone_cfg.user_zones[i].x_centre -
01608             zone_cfg.user_zones[i].width) >> 1;
01609         TopLeftY = (2 * zone_cfg.user_zones[i].y_centre +
01610             zone_cfg.user_zones[i].height) >> 1;
01611         BotRightX = (2 * zone_cfg.user_zones[i].x_centre +
01612             zone_cfg.user_zones[i].width) >> 1;
01613         BotRightY = (2 * zone_cfg.user_zones[i].y_centre -
01614             zone_cfg.user_zones[i].height) >> 1;
01615         pRoiConfig->UserRois [i].TopLeftX  = TopLeftX;
01616         pRoiConfig->UserRois [i].TopLeftY  = TopLeftY;
01617         pRoiConfig->UserRois [i].BotRightX  = BotRightX;
01618         pRoiConfig->UserRois [i].BotRightY  = BotRightY;
01619     }
01620 
01621     LOG_FUNCTION_END(Status);
01622     return Status;
01623 }
01624 
01625 
01626 
01627 
01628 
01629 
01630 
01631 VL53L1_Error VL53L1_GetNumberOfSequenceSteps(VL53L1_DEV Dev,
01632     uint8_t *pNumberOfSequenceSteps)
01633 {
01634     VL53L1_Error Status = VL53L1_ERROR_NONE;
01635 
01636     SUPPRESS_UNUSED_WARNING(Dev);
01637 
01638     LOG_FUNCTION_START("");
01639 
01640     *pNumberOfSequenceSteps = VL53L1_SEQUENCESTEP_NUMBER_OF_ITEMS;
01641 
01642     LOG_FUNCTION_END(Status);
01643     return Status;
01644 }
01645 
01646 VL53L1_Error VL53L1_GetSequenceStepsInfo(VL53L1_SequenceStepId SequenceStepId,
01647     char *pSequenceStepsString)
01648 {
01649     VL53L1_Error Status = VL53L1_ERROR_NONE;
01650 
01651     LOG_FUNCTION_START("");
01652 
01653     Status = VL53L1_get_sequence_steps_info(
01654             SequenceStepId,
01655             pSequenceStepsString);
01656 
01657     LOG_FUNCTION_END(Status);
01658 
01659     return Status;
01660 }
01661 
01662 VL53L1_Error VL53L1_SetSequenceStepEnable(VL53L1_DEV Dev,
01663     VL53L1_SequenceStepId SequenceStepId, uint8_t SequenceStepEnabled)
01664 {
01665     VL53L1_Error Status = VL53L1_ERROR_NONE;
01666     uint32_t MeasurementTimingBudgetMicroSeconds;
01667 
01668     LOG_FUNCTION_START("");
01669 
01670 
01671 
01672     Status = VL53L1_set_sequence_config_bit(Dev,
01673         (VL53L1_DeviceSequenceConfig)SequenceStepId,
01674         SequenceStepEnabled);
01675 
01676 
01677     if (Status == VL53L1_ERROR_NONE) {
01678 
01679 
01680         MeasurementTimingBudgetMicroSeconds = VL53L1DevDataGet(Dev,
01681             CurrentParameters.MeasurementTimingBudgetMicroSeconds);
01682 
01683         VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev,
01684             MeasurementTimingBudgetMicroSeconds);
01685     }
01686 
01687     LOG_FUNCTION_END(Status);
01688 
01689     return Status;
01690 }
01691 
01692 
01693 VL53L1_Error VL53L1_GetSequenceStepEnable(VL53L1_DEV Dev,
01694     VL53L1_SequenceStepId SequenceStepId, uint8_t *pSequenceStepEnabled)
01695 {
01696     VL53L1_Error Status = VL53L1_ERROR_NONE;
01697 
01698     LOG_FUNCTION_START("");
01699 
01700     Status = VL53L1_get_sequence_config_bit(Dev,
01701         (VL53L1_DeviceSequenceConfig)SequenceStepId,
01702         pSequenceStepEnabled);
01703 
01704     LOG_FUNCTION_END(Status);
01705     return Status;
01706 }
01707 
01708 
01709 
01710 
01711 
01712 
01713 
01714 
01715 
01716 
01717 VL53L1_Error VL53L1_StartMeasurement(VL53L1_DEV Dev)
01718 {
01719 #define TIMED_MODE_TIMING_GUARD_MILLISECONDS 4
01720     VL53L1_Error Status = VL53L1_ERROR_NONE;
01721     uint8_t DeviceMeasurementMode;
01722     VL53L1_State CurrPalState;
01723     VL53L1_Error lStatus;
01724     uint32_t MTBus, IMPms;
01725     uint8_t i;
01726     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01727 
01728 
01729     LOG_FUNCTION_START("");
01730     VL53L1_load_patch(Dev);
01731     for (i = 0; i < VL53L1_MAX_RANGE_RESULTS; i++) {
01732         pdev->PreviousRangeMilliMeter[i] = 0;
01733         pdev->PreviousRangeStatus[i] = 255;
01734         pdev->PreviousExtendedRange[i] = 0;
01735     }
01736     pdev->PreviousStreamCount = 0;
01737     CurrPalState = VL53L1DevDataGet(Dev, PalState);
01738     switch (CurrPalState) {
01739     case VL53L1_STATE_IDLE:
01740         Status = VL53L1_ERROR_NONE;
01741         break;
01742     case VL53L1_STATE_POWERDOWN:
01743     case VL53L1_STATE_WAIT_STATICINIT:
01744     case VL53L1_STATE_STANDBY:
01745     case VL53L1_STATE_RUNNING:
01746     case VL53L1_STATE_RESET:
01747     case VL53L1_STATE_UNKNOWN:
01748     case VL53L1_STATE_ERROR:
01749         Status = VL53L1_ERROR_INVALID_COMMAND;
01750         break;
01751     default:
01752         Status = VL53L1_ERROR_UNDEFINED;
01753     }
01754 
01755     DeviceMeasurementMode = VL53L1DevDataGet(Dev, LLData.measurement_mode);
01756 
01757 
01758     if ((Status == VL53L1_ERROR_NONE) &&
01759         (DeviceMeasurementMode == VL53L1_DEVICEMEASUREMENTMODE_TIMED)) {
01760         lStatus = VL53L1_GetMeasurementTimingBudgetMicroSeconds(Dev,
01761                 &MTBus);
01762 
01763         MTBus /= 1000;
01764         lStatus = VL53L1_GetInterMeasurementPeriodMilliSeconds(Dev,
01765                 &IMPms);
01766 
01767         SUPPRESS_UNUSED_WARNING(lStatus);
01768         if (IMPms < MTBus + TIMED_MODE_TIMING_GUARD_MILLISECONDS)
01769             Status = VL53L1_ERROR_INVALID_PARAMS;
01770     }
01771 
01772     if (Status == VL53L1_ERROR_NONE)
01773         Status = VL53L1_init_and_start_range(
01774                 Dev,
01775                 DeviceMeasurementMode,
01776                 VL53L1_DEVICECONFIGLEVEL_FULL);
01777 
01778 
01779     if (Status == VL53L1_ERROR_NONE)
01780         VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_RUNNING);
01781 
01782 
01783     LOG_FUNCTION_END(Status);
01784     return Status;
01785 }
01786 
01787 VL53L1_Error VL53L1_StopMeasurement(VL53L1_DEV Dev)
01788 {
01789     VL53L1_Error Status = VL53L1_ERROR_NONE;
01790 
01791     LOG_FUNCTION_START("");
01792 
01793     Status = VL53L1_stop_range(Dev);
01794     VL53L1_unload_patch(Dev);
01795 
01796     if (Status == VL53L1_ERROR_NONE)
01797         VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_IDLE);
01798 
01799     LOG_FUNCTION_END(Status);
01800     return Status;
01801 }
01802 
01803 
01804 VL53L1_Error VL53L1_ClearInterruptAndStartMeasurement(VL53L1_DEV Dev)
01805 {
01806     VL53L1_Error Status = VL53L1_ERROR_NONE;
01807     uint8_t DeviceMeasurementMode;
01808 
01809     LOG_FUNCTION_START("");
01810 
01811     DeviceMeasurementMode = VL53L1DevDataGet(Dev, LLData.measurement_mode);
01812 
01813     Status = VL53L1_clear_interrupt_and_enable_next_range(Dev,
01814             DeviceMeasurementMode);
01815 
01816     LOG_FUNCTION_END(Status);
01817     return Status;
01818 }
01819 
01820 
01821 VL53L1_Error VL53L1_GetMeasurementDataReady(VL53L1_DEV Dev,
01822     uint8_t *pMeasurementDataReady)
01823 {
01824     VL53L1_Error Status = VL53L1_ERROR_NONE;
01825 
01826     LOG_FUNCTION_START("");
01827 
01828     Status = VL53L1_is_new_data_ready(Dev, pMeasurementDataReady);
01829 
01830     LOG_FUNCTION_END(Status);
01831     return Status;
01832 }
01833 
01834 VL53L1_Error VL53L1_WaitMeasurementDataReady(VL53L1_DEV Dev)
01835 {
01836     VL53L1_Error Status = VL53L1_ERROR_NONE;
01837 
01838     LOG_FUNCTION_START("");
01839 
01840 
01841 
01842     Status = VL53L1_poll_for_range_completion(Dev,
01843             VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
01844 
01845     LOG_FUNCTION_END(Status);
01846     return Status;
01847 }
01848 
01849 static void GenNewPresetMode(int16_t RefRange,
01850         VL53L1_DistanceModes InternalDistanceMode,
01851         VL53L1_DistanceModes *pNewDistanceMode)
01852 {
01853     uint16_t HRLI = 600;
01854     uint16_t HRLH = 700;
01855     uint16_t MRLI = 1400;
01856     uint16_t MRLH = 1500;
01857 
01858     switch (InternalDistanceMode) {
01859     case VL53L1_DISTANCEMODE_SHORT:
01860 
01861         if (RefRange > MRLH)
01862             *pNewDistanceMode = VL53L1_DISTANCEMODE_LONG;
01863         else if (RefRange > HRLH)
01864             *pNewDistanceMode = VL53L1_DISTANCEMODE_MEDIUM;
01865         break;
01866     case VL53L1_DISTANCEMODE_MEDIUM:
01867 
01868         if (RefRange > MRLH)
01869             *pNewDistanceMode = VL53L1_DISTANCEMODE_LONG;
01870         else if (RefRange < HRLI)
01871             *pNewDistanceMode = VL53L1_DISTANCEMODE_SHORT;
01872         break;
01873     default:
01874 
01875         if (RefRange < HRLI)
01876             *pNewDistanceMode = VL53L1_DISTANCEMODE_SHORT;
01877         else if (RefRange < MRLI)
01878             *pNewDistanceMode = VL53L1_DISTANCEMODE_MEDIUM;
01879         break;
01880     }
01881 }
01882 
01883 static void CheckAndChangeDistanceMode(VL53L1_DEV Dev,
01884         VL53L1_TargetRangeData_t *pRangeData,
01885         int16_t Ambient100DmaxMm,
01886         VL53L1_DistanceModes *pNewDistanceMode
01887 )
01888 {
01889     VL53L1_DistanceModes DistanceMode;
01890     uint8_t RangeStatus = pRangeData->RangeStatus ;
01891     uint8_t DmaxValid;
01892     int32_t MinAmbient = BDTable[VL53L1_TUNING_MIN_AMBIENT_DMAX_VALID];
01893     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01894     int32_t  tmpint32;
01895 
01896 
01897     switch (RangeStatus) {
01898     case VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL:
01899     case VL53L1_RANGESTATUS_WRAP_TARGET_FAIL:
01900     case VL53L1_RANGESTATUS_RANGE_VALID_MERGED_PULSE:
01901     case VL53L1_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL:
01902     case VL53L1_RANGESTATUS_SYNCRONISATION_INT:
01903     case VL53L1_RANGESTATUS_NONE:
01904         return;
01905     default:
01906 
01907         break;
01908     }
01909 
01910     DmaxValid = 1;
01911     tmpint32 = pdev->hist_data.VL53L1_p_004;
01912     if ((tmpint32 < MinAmbient) || (Ambient100DmaxMm == 0))
01913         DmaxValid = 0;
01914 
01915     DistanceMode = VL53L1DevDataGet(Dev,
01916             CurrentParameters.DistanceMode);
01917 
01918     *pNewDistanceMode = DistanceMode;
01919 
01920     if (RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID)
01921         GenNewPresetMode(pRangeData->RangeMilliMeter ,
01922                 DistanceMode, pNewDistanceMode);
01923     else {
01924         if (DmaxValid)
01925             GenNewPresetMode(Ambient100DmaxMm,
01926                     DistanceMode, pNewDistanceMode);
01927         else
01928             *pNewDistanceMode = VL53L1_DISTANCEMODE_LONG;
01929     }
01930 }
01931 
01932 static uint8_t ComputeRQL(uint8_t active_results,
01933         uint8_t FilteredRangeStatus,
01934         VL53L1_range_data_t *presults_data)
01935 {
01936     int16_t T_Wide = 150;
01937     int16_t SRL = 300;
01938     uint16_t SRAS = 30;
01939     FixPoint1616_t RAS;
01940     FixPoint1616_t SRQL;
01941     FixPoint1616_t GI =   7713587;
01942     FixPoint1616_t GGm =  3198157;
01943     FixPoint1616_t LRAP = 6554;
01944     FixPoint1616_t partial;
01945     uint8_t finalvalue;
01946     uint8_t returnvalue;
01947 
01948     if (active_results == 0)
01949         returnvalue = 0;
01950     else if (((presults_data->max_range_mm -
01951             presults_data->min_range_mm) >= T_Wide) ||
01952         (FilteredRangeStatus == VL53L1_DEVICEERROR_PHASECONSISTENCY))
01953         returnvalue = 50;
01954     else {
01955         if (presults_data->median_range_mm < SRL)
01956             RAS = SRAS * 65536;
01957         else
01958             RAS = LRAP * presults_data->median_range_mm;
01959 
01960 
01961         if (RAS != 0) {
01962             partial = (GGm * presults_data->VL53L1_p_005);
01963             partial = partial + (RAS >> 1);
01964             partial = partial / RAS;
01965             partial = partial * 65536;
01966             if (partial <= GI)
01967                 SRQL = GI - partial;
01968             else
01969                 SRQL = 50 * 65536;
01970         } else
01971             SRQL = 100 * 65536;
01972 
01973         finalvalue = (uint8_t)(SRQL >> 16);
01974         returnvalue = MAX(50, MIN(100, finalvalue));
01975     }
01976 
01977     return returnvalue;
01978 }
01979 
01980 
01981 static uint8_t ConvertStatusLite(uint8_t FilteredRangeStatus)
01982 {
01983     uint8_t RangeStatus;
01984 
01985     switch (FilteredRangeStatus) {
01986     case VL53L1_DEVICEERROR_GPHSTREAMCOUNT0READY:
01987         RangeStatus = VL53L1_RANGESTATUS_SYNCRONISATION_INT;
01988         break;
01989     case VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK:
01990         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL;
01991         break;
01992     case VL53L1_DEVICEERROR_RANGEPHASECHECK:
01993         RangeStatus = VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL;
01994         break;
01995     case VL53L1_DEVICEERROR_MSRCNOTARGET:
01996         RangeStatus = VL53L1_RANGESTATUS_SIGNAL_FAIL;
01997         break;
01998     case VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK:
01999         RangeStatus = VL53L1_RANGESTATUS_SIGMA_FAIL;
02000         break;
02001     case VL53L1_DEVICEERROR_PHASECONSISTENCY:
02002         RangeStatus = VL53L1_RANGESTATUS_WRAP_TARGET_FAIL;
02003         break;
02004     case VL53L1_DEVICEERROR_RANGEIGNORETHRESHOLD:
02005         RangeStatus = VL53L1_RANGESTATUS_XTALK_SIGNAL_FAIL;
02006         break;
02007     case VL53L1_DEVICEERROR_MINCLIP:
02008         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_MIN_RANGE_CLIPPED;
02009         break;
02010     case VL53L1_DEVICEERROR_RANGECOMPLETE:
02011         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID;
02012         break;
02013     default:
02014         RangeStatus = VL53L1_RANGESTATUS_NONE;
02015     }
02016 
02017     return RangeStatus;
02018 }
02019 
02020 
02021 static uint8_t ConvertStatusHisto(uint8_t FilteredRangeStatus)
02022 {
02023     uint8_t RangeStatus;
02024 
02025     switch (FilteredRangeStatus) {
02026     case VL53L1_DEVICEERROR_RANGEPHASECHECK:
02027         RangeStatus = VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL;
02028         break;
02029     case VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK:
02030         RangeStatus = VL53L1_RANGESTATUS_SIGMA_FAIL;
02031         break;
02032     case VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK:
02033         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL;
02034         break;
02035     case VL53L1_DEVICEERROR_PHASECONSISTENCY:
02036         RangeStatus = VL53L1_RANGESTATUS_WRAP_TARGET_FAIL;
02037         break;
02038     case VL53L1_DEVICEERROR_PREV_RANGE_NO_TARGETS:
02039         RangeStatus = VL53L1_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL;
02040         break;
02041     case VL53L1_DEVICEERROR_EVENTCONSISTENCY:
02042         RangeStatus = VL53L1_RANGESTATUS_WRAP_TARGET_FAIL;
02043         break;
02044     case VL53L1_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE:
02045         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_MERGED_PULSE;
02046         break;
02047     case VL53L1_DEVICEERROR_RANGECOMPLETE:
02048         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID;
02049         break;
02050     default:
02051         RangeStatus = VL53L1_RANGESTATUS_NONE;
02052     }
02053 
02054     return RangeStatus;
02055 }
02056 
02057 static VL53L1_Error SetSimpleData(VL53L1_DEV Dev,
02058     uint8_t active_results, uint8_t device_status,
02059     VL53L1_range_data_t *presults_data,
02060     VL53L1_RangingMeasurementData_t *pRangeData)
02061 {
02062     VL53L1_Error Status = VL53L1_ERROR_NONE;
02063     uint8_t FilteredRangeStatus;
02064     uint8_t SigmaLimitflag;
02065     uint8_t SignalLimitflag;
02066     uint8_t Temp8Enable;
02067     uint8_t Temp8;
02068     FixPoint1616_t AmbientRate;
02069     FixPoint1616_t SignalRate;
02070     FixPoint1616_t TempFix1616;
02071     FixPoint1616_t LimitCheckValue;
02072     VL53L1_PresetModes PresetMode;
02073     int16_t Range;
02074 
02075     pRangeData->TimeStamp  = presults_data->time_stamp;
02076 
02077     FilteredRangeStatus = presults_data->range_status & 0x1F;
02078 
02079     pRangeData->RangeQualityLevel  = ComputeRQL(active_results,
02080                     FilteredRangeStatus,
02081                     presults_data);
02082 
02083     SignalRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
02084         presults_data->peak_signal_count_rate_mcps);
02085     pRangeData->SignalRateRtnMegaCps 
02086         = SignalRate;
02087 
02088     AmbientRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
02089         presults_data->ambient_count_rate_mcps);
02090     pRangeData->AmbientRateRtnMegaCps  = AmbientRate;
02091 
02092     pRangeData->EffectiveSpadRtnCount  =
02093         presults_data->VL53L1_p_006;
02094 
02095     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02096             presults_data->VL53L1_p_005);
02097 
02098     pRangeData->SigmaMilliMeter  = TempFix1616;
02099 
02100     pRangeData->RangeMilliMeter  = presults_data->median_range_mm;
02101 
02102     pRangeData->RangeFractionalPart  = 0;
02103 
02104 
02105     switch (device_status) {
02106     case VL53L1_DEVICEERROR_MULTCLIPFAIL:
02107     case VL53L1_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
02108     case VL53L1_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
02109     case VL53L1_DEVICEERROR_NOVHVVALUEFOUND:
02110         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_HARDWARE_FAIL;
02111         break;
02112     case VL53L1_DEVICEERROR_USERROICLIP:
02113         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_MIN_RANGE_FAIL;
02114         break;
02115     default:
02116         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_RANGE_VALID;
02117     }
02118 
02119 
02120     if (pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) {
02121         PresetMode = VL53L1DevDataGet(Dev,
02122                 CurrentParameters.PresetMode);
02123         if ((PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING) ||
02124             (PresetMode == VL53L1_PRESETMODE_RANGING) ||
02125             (PresetMode == VL53L1_PRESETMODE_PROXY_RANGING_MODE))
02126             pRangeData->RangeStatus  =
02127                 ConvertStatusHisto(FilteredRangeStatus);
02128         else
02129             pRangeData->RangeStatus  =
02130                 ConvertStatusLite(FilteredRangeStatus);
02131     }
02132 
02133 
02134     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02135             presults_data->VL53L1_p_005);
02136     VL53L1_SETARRAYPARAMETERFIELD(Dev,
02137         LimitChecksCurrent, VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02138         TempFix1616);
02139 
02140     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02141             presults_data->peak_signal_count_rate_mcps);
02142     VL53L1_SETARRAYPARAMETERFIELD(Dev,
02143         LimitChecksCurrent, VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02144         TempFix1616);
02145 
02146 
02147 
02148     VL53L1_GetLimitCheckValue(Dev,
02149             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02150             &LimitCheckValue);
02151 
02152     SigmaLimitflag = (FilteredRangeStatus ==
02153             VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK)
02154             ? 1 : 0;
02155 
02156     VL53L1_GetLimitCheckEnable(Dev,
02157             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02158             &Temp8Enable);
02159 
02160     Temp8 = ((Temp8Enable == 1) && (SigmaLimitflag == 1)) ? 1 : 0;
02161     VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
02162             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE, Temp8);
02163 
02164 
02165     VL53L1_GetLimitCheckValue(Dev,
02166             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02167             &LimitCheckValue);
02168 
02169     SignalLimitflag = (FilteredRangeStatus ==
02170             VL53L1_DEVICEERROR_MSRCNOTARGET)
02171             ? 1 : 0;
02172 
02173     VL53L1_GetLimitCheckEnable(Dev,
02174             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02175             &Temp8Enable);
02176 
02177     Temp8 = ((Temp8Enable == 1) && (SignalLimitflag == 1)) ? 1 : 0;
02178     VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
02179             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, Temp8);
02180 
02181     Range = pRangeData->RangeMilliMeter ;
02182     if ((pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) &&
02183         (Range < 0)) {
02184         if (Range < BDTable[VL53L1_TUNING_PROXY_MIN])
02185             pRangeData->RangeStatus  =
02186                     VL53L1_RANGESTATUS_RANGE_INVALID;
02187         else
02188             pRangeData->RangeMilliMeter  = 0;
02189     }
02190 
02191     return Status;
02192 }
02193 
02194 static VL53L1_Error SetTargetData(VL53L1_DEV Dev,
02195     uint8_t active_results, uint8_t streamcount, uint8_t iteration,
02196     uint8_t device_status, VL53L1_range_data_t *presults_data,
02197     VL53L1_TargetRangeData_t *pRangeData)
02198 {
02199     VL53L1_Error Status = VL53L1_ERROR_NONE;
02200     VL53L1_LLDriverData_t *pdev =
02201             VL53L1DevStructGetLLDriverHandle(Dev);
02202     VL53L1_tuning_parm_storage_t *tp =
02203             &(pdev->tuning_parms);
02204     uint8_t sequency;
02205     uint8_t FilteredRangeStatus;
02206     uint8_t SigmaLimitflag;
02207     uint8_t SignalLimitflag;
02208     uint8_t Temp8Enable;
02209     uint8_t Temp8;
02210     FixPoint1616_t AmbientRate;
02211     FixPoint1616_t SignalRate;
02212     FixPoint1616_t TempFix1616;
02213     FixPoint1616_t LimitCheckValue;
02214     VL53L1_PresetModes PresetMode;
02215     int16_t Range, RangeDiff, RangeMillimeterInit;
02216     uint8_t ExtendedRangeEnabled = 0;
02217     uint8_t uwr_status;
02218     int16_t AddOffset;
02219 
02220     FilteredRangeStatus = presults_data->range_status & 0x1F;
02221 
02222     pRangeData->RangeQualityLevel  = ComputeRQL(active_results,
02223                     FilteredRangeStatus,
02224                     presults_data);
02225 
02226     SignalRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
02227         presults_data->peak_signal_count_rate_mcps);
02228     pRangeData->SignalRateRtnMegaCps 
02229         = SignalRate;
02230 
02231     AmbientRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
02232         presults_data->ambient_count_rate_mcps);
02233     pRangeData->AmbientRateRtnMegaCps  = AmbientRate;
02234 
02235     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02236             presults_data->VL53L1_p_005);
02237 
02238     pRangeData->SigmaMilliMeter  = TempFix1616;
02239 
02240     pRangeData->RangeMilliMeter  = presults_data->median_range_mm;
02241     pRangeData->RangeMaxMilliMeter  = presults_data->max_range_mm;
02242     pRangeData->RangeMinMilliMeter  = presults_data->min_range_mm;
02243 
02244     pRangeData->RangeFractionalPart  = 0;
02245 
02246 
02247     switch (device_status) {
02248     case VL53L1_DEVICEERROR_MULTCLIPFAIL:
02249     case VL53L1_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
02250     case VL53L1_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
02251     case VL53L1_DEVICEERROR_NOVHVVALUEFOUND:
02252         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_HARDWARE_FAIL;
02253         break;
02254     case VL53L1_DEVICEERROR_USERROICLIP:
02255         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_MIN_RANGE_FAIL;
02256         break;
02257     default:
02258         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_RANGE_VALID;
02259     }
02260 
02261 
02262     if ((pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) &&
02263         (active_results == 0)) {
02264         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_NONE;
02265         pRangeData->SignalRateRtnMegaCps  = 0;
02266         pRangeData->SigmaMilliMeter  = 0;
02267         pRangeData->RangeMilliMeter  = 8191;
02268         pRangeData->RangeMaxMilliMeter  = 8191;
02269         pRangeData->RangeMinMilliMeter  = 8191;
02270     }
02271 
02272 
02273     if (pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) {
02274         PresetMode = VL53L1DevDataGet(Dev,
02275                 CurrentParameters.PresetMode);
02276         if ((PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING) ||
02277             (PresetMode == VL53L1_PRESETMODE_RANGING) ||
02278             (PresetMode == VL53L1_PRESETMODE_PROXY_RANGING_MODE))
02279             pRangeData->RangeStatus  =
02280                 ConvertStatusHisto(FilteredRangeStatus);
02281         else
02282             pRangeData->RangeStatus  =
02283                 ConvertStatusLite(FilteredRangeStatus);
02284     }
02285 
02286 
02287     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02288             presults_data->VL53L1_p_005);
02289     VL53L1_SETARRAYPARAMETERFIELD(Dev,
02290         LimitChecksCurrent, VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02291         TempFix1616);
02292 
02293     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02294             presults_data->peak_signal_count_rate_mcps);
02295     VL53L1_SETARRAYPARAMETERFIELD(Dev,
02296         LimitChecksCurrent, VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02297         TempFix1616);
02298 
02299 
02300 
02301     VL53L1_GetLimitCheckValue(Dev,
02302             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02303             &LimitCheckValue);
02304 
02305     SigmaLimitflag = (FilteredRangeStatus ==
02306             VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK)
02307             ? 1 : 0;
02308 
02309     VL53L1_GetLimitCheckEnable(Dev,
02310             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02311             &Temp8Enable);
02312 
02313     Temp8 = ((Temp8Enable == 1) && (SigmaLimitflag == 1)) ? 1 : 0;
02314     VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
02315             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE, Temp8);
02316 
02317 
02318     VL53L1_GetLimitCheckValue(Dev,
02319             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02320             &LimitCheckValue);
02321 
02322     SignalLimitflag = (FilteredRangeStatus ==
02323             VL53L1_DEVICEERROR_MSRCNOTARGET)
02324             ? 1 : 0;
02325 
02326     VL53L1_GetLimitCheckEnable(Dev,
02327             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02328             &Temp8Enable);
02329 
02330     Temp8 = ((Temp8Enable == 1) && (SignalLimitflag == 1)) ? 1 : 0;
02331     VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
02332             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, Temp8);
02333 
02334     Range = pRangeData->RangeMilliMeter ;
02335     if ((pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) &&
02336         (Range < 0)) {
02337         if (Range < BDTable[VL53L1_TUNING_PROXY_MIN])
02338             pRangeData->RangeStatus  =
02339                     VL53L1_RANGESTATUS_RANGE_INVALID;
02340         else
02341             pRangeData->RangeMilliMeter  = 0;
02342     }
02343 
02344 
02345 
02346     VL53L1_get_tuning_parm(Dev, VL53L1_TUNINGPARM_UWR_ENABLE,
02347             (int32_t *)&ExtendedRangeEnabled);
02348 
02349     sequency = streamcount % 2;
02350     uwr_status = 1;
02351     RangeMillimeterInit = pRangeData->RangeMilliMeter ;
02352     AddOffset = 0;
02353 
02354     pRangeData->ExtendedRange  = 0;
02355 
02356     if (ExtendedRangeEnabled &&
02357         (pRangeData->RangeStatus  ==
02358             VL53L1_RANGESTATUS_WRAP_TARGET_FAIL ||
02359             pRangeData->RangeStatus  ==
02360             VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL)
02361         && (pdev->PreviousRangeStatus[iteration] ==
02362             VL53L1_RANGESTATUS_WRAP_TARGET_FAIL ||
02363             pdev->PreviousRangeStatus[iteration] ==
02364             VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL ||
02365             (pdev->PreviousRangeStatus[iteration] ==
02366             VL53L1_RANGESTATUS_RANGE_VALID &&
02367             pdev->PreviousExtendedRange[iteration] == 1)))
02368     {
02369         if (((pdev->PreviousStreamCount) ==
02370             (pdev->hist_data.result__stream_count - 1 ))
02371         || ((pdev->PreviousStreamCount) ==
02372             (pdev->hist_data.result__stream_count + 127)))
02373         {
02374         RangeDiff = pRangeData->RangeMilliMeter  -
02375             pdev->PreviousRangeMilliMeter[iteration];
02376 
02377         switch (pdev->preset_mode) {
02378             case VL53L1_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
02379 
02380                 uwr_status = 0;
02381                 break;
02382 
02383             case VL53L1_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE:
02384                 if (RangeDiff > tp->tp_uwr_med_z_1_min &&
02385                     RangeDiff < tp->tp_uwr_med_z_1_max &&
02386                     sequency == 1) {
02387                     AddOffset =
02388                     tp->tp_uwr_med_corr_z_1_rangeb;
02389                 }
02390                 else
02391                 if (RangeDiff < -tp->tp_uwr_med_z_1_min &&
02392                     RangeDiff > -tp->tp_uwr_med_z_1_max &&
02393                     sequency == 0) {
02394                     AddOffset =
02395                     tp->tp_uwr_med_corr_z_1_rangea;
02396                 }
02397                 else
02398                 if (RangeDiff > tp->tp_uwr_med_z_2_min &&
02399                     RangeDiff < tp->tp_uwr_med_z_2_max &&
02400                     sequency == 0) {
02401                     AddOffset =
02402                     tp->tp_uwr_med_corr_z_2_rangea;
02403                 }
02404                 else
02405                 if (RangeDiff < -tp->tp_uwr_med_z_2_min &&
02406                     RangeDiff > -tp->tp_uwr_med_z_2_max &&
02407                     sequency == 1) {
02408                     AddOffset =
02409                     tp->tp_uwr_med_corr_z_2_rangeb;
02410                 }
02411                 else
02412                 if (RangeDiff > tp->tp_uwr_med_z_3_min &&
02413                     RangeDiff < tp->tp_uwr_med_z_3_max &&
02414                     sequency == 1) {
02415                     AddOffset =
02416                     tp->tp_uwr_med_corr_z_3_rangeb;
02417                 }
02418                 else
02419                 if (RangeDiff < -tp->tp_uwr_med_z_3_min &&
02420                     RangeDiff > -tp->tp_uwr_med_z_3_max &&
02421                     sequency == 0) {
02422                     AddOffset =
02423                     tp->tp_uwr_med_corr_z_3_rangea;
02424                 }
02425                 else
02426                 if (RangeDiff > tp->tp_uwr_med_z_4_min &&
02427                     RangeDiff < tp->tp_uwr_med_z_4_max &&
02428                     sequency == 0) {
02429                     AddOffset =
02430                     tp->tp_uwr_med_corr_z_4_rangea;
02431                 }
02432                 else
02433                 if (RangeDiff < -tp->tp_uwr_med_z_4_min &&
02434                     RangeDiff > -tp->tp_uwr_med_z_4_max &&
02435                     sequency == 1) {
02436                     AddOffset =
02437                     tp->tp_uwr_med_corr_z_4_rangeb;
02438                 }
02439                 else
02440                 if (RangeDiff < tp->tp_uwr_med_z_5_max &&
02441                     RangeDiff > tp->tp_uwr_med_z_5_min) {
02442                     AddOffset =
02443                     tp->tp_uwr_med_corr_z_5_rangea;
02444                 }
02445                 else
02446                 if (RangeDiff > tp->tp_uwr_med_z_6_min &&
02447                     RangeDiff < tp->tp_uwr_med_z_6_max &&
02448                     sequency == 1) {
02449                     AddOffset =
02450                     tp->tp_uwr_med_corr_z_6_rangeb;
02451                 }
02452                 else
02453                 if (RangeDiff < -tp->tp_uwr_med_z_6_min &&
02454                     RangeDiff > -tp->tp_uwr_med_z_6_max &&
02455                     sequency == 0) {
02456                     AddOffset =
02457                     tp->tp_uwr_med_corr_z_6_rangea;
02458                 }
02459                 else
02460 
02461 
02462 
02463 
02464 
02465 
02466 
02467 
02468 
02469 
02470 
02471                     uwr_status = 0;
02472                 break;
02473 
02474             case VL53L1_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE:
02475                 if (RangeDiff > tp->tp_uwr_lng_z_1_min &&
02476                     RangeDiff < tp->tp_uwr_lng_z_1_max &&
02477                     sequency == 0) {
02478                     AddOffset =
02479                     tp->tp_uwr_lng_corr_z_1_rangea;
02480                 }
02481                 else
02482                 if (RangeDiff < -tp->tp_uwr_lng_z_1_min &&
02483                     RangeDiff > -tp->tp_uwr_lng_z_1_max &&
02484                     sequency == 1) {
02485                     AddOffset =
02486                     tp->tp_uwr_lng_corr_z_1_rangeb;
02487                 }
02488                 else
02489                 if (RangeDiff > tp->tp_uwr_lng_z_2_min &&
02490                     RangeDiff < tp->tp_uwr_lng_z_2_max &&
02491                     sequency == 1) {
02492                     AddOffset =
02493                     tp->tp_uwr_lng_corr_z_2_rangeb;
02494                 }
02495                 else
02496                 if (RangeDiff < -tp->tp_uwr_lng_z_2_min &&
02497                     RangeDiff > -tp->tp_uwr_lng_z_2_max &&
02498                     sequency == 0) {
02499                     AddOffset =
02500                     tp->tp_uwr_lng_corr_z_2_rangea;
02501                 }
02502                 else
02503                 if (RangeDiff < tp->tp_uwr_lng_z_3_max &&
02504                     RangeDiff > tp->tp_uwr_lng_z_3_min) {
02505                     AddOffset =
02506                     tp->tp_uwr_lng_corr_z_3_rangea;
02507                 }
02508                 else
02509                 if (RangeDiff > tp->tp_uwr_lng_z_4_min &&
02510                     RangeDiff < tp->tp_uwr_lng_z_4_max &&
02511                     sequency == 1) {
02512                     AddOffset =
02513                     tp->tp_uwr_lng_corr_z_4_rangeb;
02514                 }
02515                 else
02516                 if (RangeDiff < -tp->tp_uwr_lng_z_4_min &&
02517                     RangeDiff > -tp->tp_uwr_lng_z_4_max &&
02518                     sequency == 0) {
02519                     AddOffset =
02520                     tp->tp_uwr_lng_corr_z_4_rangea;
02521                 }
02522                 else
02523                     uwr_status = 0;
02524                 break;
02525 
02526             default:
02527                 uwr_status = 0;
02528                 break;
02529             }
02530         }
02531 
02532         if (uwr_status) {
02533             pRangeData->RangeMilliMeter  += AddOffset;
02534             pRangeData->RangeMinMilliMeter  += AddOffset;
02535             pRangeData->RangeMaxMilliMeter  += AddOffset;
02536             pRangeData->ExtendedRange  = 1;
02537             pRangeData->RangeStatus  = 0;
02538         }
02539 
02540     }
02541 
02542     pdev->PreviousRangeMilliMeter[iteration] = RangeMillimeterInit;
02543     pdev->PreviousRangeStatus[iteration] = pRangeData->RangeStatus ;
02544     pdev->PreviousExtendedRange[iteration] = pRangeData->ExtendedRange ;
02545     pdev->PreviousStreamCount = pdev->hist_data.result__stream_count;
02546 
02547     return Status;
02548 }
02549 
02550 static uint8_t GetOutputDataIndex(VL53L1_DEV Dev,
02551     VL53L1_range_results_t *presults)
02552 {
02553     uint8_t i;
02554     uint8_t index = 0;
02555     VL53L1_OutputModes OutputMode;
02556 
02557     OutputMode = VL53L1DevDataGet(Dev, CurrentParameters.OutputMode);
02558 
02559 
02560     if (OutputMode == VL53L1_OUTPUTMODE_NEAREST)
02561         return 0;
02562 
02563 
02564     for (i = 1; i < presults->active_results; i++) {
02565         if (presults->VL53L1_p_002[i].peak_signal_count_rate_mcps >
02566         presults->VL53L1_p_002[index].peak_signal_count_rate_mcps)
02567             index = i;
02568     }
02569 
02570     return index;
02571 }
02572 
02573 VL53L1_Error VL53L1_GetRangingMeasurementData(VL53L1_DEV Dev,
02574     VL53L1_RangingMeasurementData_t *pRangingMeasurementData)
02575 {
02576     VL53L1_Error Status = VL53L1_ERROR_NONE;
02577     VL53L1_LLDriverData_t *pdev =
02578             VL53L1DevStructGetLLDriverHandle(Dev);
02579     VL53L1_range_results_t *presults =
02580             (VL53L1_range_results_t *) pdev->wArea1;
02581     VL53L1_range_data_t *presults_data;
02582     VL53L1_PresetModes PresetMode;
02583     uint8_t index = 0;
02584 
02585     LOG_FUNCTION_START("");
02586 
02587 
02588     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
02589 
02590     if (PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING) {
02591         Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
02592         LOG_FUNCTION_END(Status);
02593         return Status;
02594     }
02595 
02596 
02597     memset(pRangingMeasurementData, 0xFF,
02598         sizeof(VL53L1_RangingMeasurementData_t));
02599 
02600 
02601     Status = VL53L1_get_device_results(
02602             Dev,
02603             VL53L1_DEVICERESULTSLEVEL_FULL,
02604             presults);
02605 
02606     if (Status == VL53L1_ERROR_NONE) {
02607         pRangingMeasurementData->StreamCount  = presults->stream_count;
02608 
02609 
02610         index = GetOutputDataIndex(Dev, presults);
02611         presults_data = &(presults->VL53L1_p_002[index]);
02612         Status = SetSimpleData(Dev, presults->active_results,
02613                 presults->device_status,
02614                 presults_data,
02615                 pRangingMeasurementData);
02616     }
02617 
02618     LOG_FUNCTION_END(Status);
02619     return Status;
02620 }
02621 
02622 static VL53L1_Error SetMeasurementData(VL53L1_DEV Dev,
02623     VL53L1_range_results_t *presults,
02624     VL53L1_MultiRangingData_t *pMultiRangingData)
02625 {
02626     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
02627     uint8_t i;
02628     uint8_t iteration;
02629     VL53L1_TargetRangeData_t *pRangeData;
02630     VL53L1_range_data_t *presults_data;
02631     int16_t dmax_min;
02632     VL53L1_Error Status = VL53L1_ERROR_NONE;
02633     uint8_t Furthest_idx = 0;
02634     int16_t Furthest_range = 0;
02635     uint8_t ActiveResults, amb_idx;
02636 
02637     pMultiRangingData->NumberOfObjectsFound  = presults->active_results;
02638     pMultiRangingData->RoiNumber  = presults->zone_id;
02639     pMultiRangingData->HasXtalkValueChanged  =
02640             presults->smudge_corrector_data.new_xtalk_applied_flag;
02641     dmax_min = MIN(presults->wrap_dmax_mm,
02642             presults->VL53L1_p_007[DMAX_REFLECTANCE_IDX]);
02643     pMultiRangingData->DmaxMilliMeter  = dmax_min;
02644 
02645 
02646     pMultiRangingData->TimeStamp  = 0;
02647 
02648     pMultiRangingData->StreamCount  = presults->stream_count;
02649 
02650     pMultiRangingData->RecommendedDistanceMode  =
02651         VL53L1DevDataGet(Dev, CurrentParameters.DistanceMode);
02652     ActiveResults = presults->active_results;
02653     if (ActiveResults < 1)
02654 
02655         iteration = 1;
02656     else
02657         iteration = ActiveResults;
02658     for (i = 0; i < iteration; i++) {
02659         pRangeData = &(pMultiRangingData->RangeData [i]);
02660 
02661         presults_data = &(presults->VL53L1_p_002[i]);
02662         if (Status == VL53L1_ERROR_NONE)
02663             Status = SetTargetData(Dev, ActiveResults,
02664                     pMultiRangingData->StreamCount ,
02665                     i,
02666                     presults->device_status,
02667                     presults_data,
02668                     pRangeData);
02669 
02670         pMultiRangingData->EffectiveSpadRtnCount  =
02671                 presults_data->VL53L1_p_006;
02672 
02673         if ((pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID)
02674             && (pRangeData->RangeMilliMeter  > Furthest_range)) {
02675             Furthest_range = pRangeData->RangeMilliMeter ;
02676             Furthest_idx = i;
02677         }
02678     }
02679     for (i = iteration; i < VL53L1_MAX_RANGE_RESULTS; i++) {
02680         pdev->PreviousRangeMilliMeter[i] = 0;
02681         pdev->PreviousRangeStatus[i] = 255;
02682         pdev->PreviousExtendedRange[i] = 0;
02683     }
02684 
02685     if ((Status == VL53L1_ERROR_NONE) && (ActiveResults > 0)) {
02686         pRangeData = &(pMultiRangingData->RangeData [Furthest_idx]);
02687         amb_idx = VL53L1_MAX_AMBIENT_DMAX_VALUES-1;
02688         CheckAndChangeDistanceMode(Dev, pRangeData,
02689             presults->VL53L1_p_007[amb_idx],
02690             &pMultiRangingData->RecommendedDistanceMode );
02691     }
02692 
02693     return Status;
02694 }
02695 
02696 VL53L1_Error VL53L1_GetMultiRangingData(VL53L1_DEV Dev,
02697         VL53L1_MultiRangingData_t *pMultiRangingData)
02698 {
02699     VL53L1_Error Status = VL53L1_ERROR_NONE;
02700     VL53L1_LLDriverData_t *pdev =
02701             VL53L1DevStructGetLLDriverHandle(Dev);
02702     VL53L1_range_results_t *presults =
02703             (VL53L1_range_results_t *) pdev->wArea1;
02704 
02705     LOG_FUNCTION_START("");
02706 
02707 
02708     memset(pMultiRangingData, 0xFF,
02709         sizeof(VL53L1_MultiRangingData_t));
02710 
02711 
02712     Status = VL53L1_get_device_results(
02713                 Dev,
02714                 VL53L1_DEVICERESULTSLEVEL_FULL,
02715                 presults);
02716 
02717 
02718     if (Status == VL53L1_ERROR_NONE) {
02719         switch (presults->rd_device_state) {
02720         case VL53L1_DEVICESTATE_RANGING_GATHER_DATA:
02721             pMultiRangingData->RoiStatus  =
02722                     VL53L1_ROISTATUS_VALID_NOT_LAST;
02723             break;
02724         case VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA:
02725             pMultiRangingData->RoiStatus  =
02726                     VL53L1_ROISTATUS_VALID_LAST;
02727             break;
02728         default:
02729             pMultiRangingData->RoiStatus  =
02730                     VL53L1_ROISTATUS_NOT_VALID;
02731         }
02732 
02733         Status = SetMeasurementData(Dev,
02734                     presults,
02735                     pMultiRangingData);
02736 
02737     }
02738 
02739     LOG_FUNCTION_END(Status);
02740     return Status;
02741 }
02742 
02743 VL53L1_Error VL53L1_GetAdditionalData(VL53L1_DEV Dev,
02744         VL53L1_AdditionalData_t *pAdditionalData)
02745 {
02746     VL53L1_Error Status = VL53L1_ERROR_NONE;
02747 
02748     LOG_FUNCTION_START("");
02749 
02750     Status = VL53L1_get_additional_data(Dev, pAdditionalData);
02751 
02752     LOG_FUNCTION_END(Status);
02753     return Status;
02754 }
02755 
02756 
02757 
02758 
02759 
02760 
02761 VL53L1_Error VL53L1_SetTuningParameter(VL53L1_DEV Dev,
02762         uint16_t TuningParameterId, int32_t TuningParameterValue)
02763 {
02764     VL53L1_Error Status = VL53L1_ERROR_NONE;
02765 
02766     LOG_FUNCTION_START("");
02767 
02768     if (TuningParameterId ==
02769         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS)
02770         return VL53L1_ERROR_INVALID_PARAMS;
02771 
02772     if (TuningParameterId >= 32768)
02773         Status = VL53L1_set_tuning_parm(Dev,
02774             TuningParameterId,
02775             TuningParameterValue);
02776     else {
02777         if (TuningParameterId < VL53L1_TUNING_MAX_TUNABLE_KEY)
02778             BDTable[TuningParameterId] = TuningParameterValue;
02779         else
02780             Status = VL53L1_ERROR_INVALID_PARAMS;
02781     }
02782 
02783     LOG_FUNCTION_END(Status);
02784     return Status;
02785 }
02786 
02787 VL53L1_Error VL53L1_GetTuningParameter(VL53L1_DEV Dev,
02788         uint16_t TuningParameterId, int32_t *pTuningParameterValue)
02789 {
02790     VL53L1_Error Status = VL53L1_ERROR_NONE;
02791 
02792     LOG_FUNCTION_START("");
02793 
02794     if (TuningParameterId >= 32768)
02795         Status = VL53L1_get_tuning_parm(Dev,
02796             TuningParameterId,
02797             pTuningParameterValue);
02798     else {
02799         if (TuningParameterId < VL53L1_TUNING_MAX_TUNABLE_KEY)
02800             *pTuningParameterValue = BDTable[TuningParameterId];
02801         else
02802             Status = VL53L1_ERROR_INVALID_PARAMS;
02803     }
02804 
02805     LOG_FUNCTION_END(Status);
02806     return Status;
02807 }
02808 
02809 
02810 VL53L1_Error VL53L1_PerformRefSpadManagement(VL53L1_DEV Dev)
02811 {
02812 #ifdef VL53L1_NOCALIB
02813     VL53L1_Error Status = VL53L1_ERROR_NOT_SUPPORTED;
02814 
02815     SUPPRESS_UNUSED_WARNING(Dev);
02816 
02817     LOG_FUNCTION_START("");
02818 #else
02819     VL53L1_Error Status = VL53L1_ERROR_NONE;
02820     VL53L1_Error RawStatus;
02821     uint8_t dcrbuffer[24];
02822     uint8_t *commbuf;
02823     uint8_t numloc[2] = {5, 3};
02824     VL53L1_LLDriverData_t *pdev;
02825     VL53L1_customer_nvm_managed_t *pc;
02826     VL53L1_PresetModes PresetMode;
02827 
02828     LOG_FUNCTION_START("");
02829 
02830     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
02831     pc = &pdev->customer;
02832 
02833     if (Status == VL53L1_ERROR_NONE) {
02834         PresetMode = VL53L1DevDataGet(Dev,
02835                 CurrentParameters.PresetMode);
02836         Status = VL53L1_run_ref_spad_char(Dev, &RawStatus);
02837 
02838         if (Status == VL53L1_ERROR_NONE)
02839             Status = VL53L1_SetPresetMode(Dev, PresetMode);
02840     }
02841 
02842     if (Status == VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH) {
02843 
02844         Status = VL53L1_read_nvm_raw_data(Dev,
02845                 (uint8_t)(0xA0 >> 2),
02846                 (uint8_t)(24 >> 2),
02847                 dcrbuffer);
02848 
02849         if (Status == VL53L1_ERROR_NONE)
02850             Status = VL53L1_WriteMulti(Dev,
02851                 VL53L1_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS,
02852                 numloc, 2);
02853 
02854         if (Status == VL53L1_ERROR_NONE) {
02855             pc->ref_spad_man__num_requested_ref_spads = numloc[0];
02856             pc->ref_spad_man__ref_location = numloc[1];
02857         }
02858 
02859         if (Status == VL53L1_ERROR_NONE)
02860             commbuf = &dcrbuffer[16];
02861 
02862 
02863 
02864         if (Status == VL53L1_ERROR_NONE)
02865             Status = VL53L1_WriteMulti(Dev,
02866                 VL53L1_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
02867                 commbuf, 6);
02868 
02869         if (Status == VL53L1_ERROR_NONE) {
02870             pc->global_config__spad_enables_ref_0 = commbuf[0];
02871             pc->global_config__spad_enables_ref_1 = commbuf[1];
02872             pc->global_config__spad_enables_ref_2 = commbuf[2];
02873             pc->global_config__spad_enables_ref_3 = commbuf[3];
02874             pc->global_config__spad_enables_ref_4 = commbuf[4];
02875             pc->global_config__spad_enables_ref_5 = commbuf[5];
02876         }
02877 
02878     }
02879 
02880 #endif
02881 
02882     LOG_FUNCTION_END(Status);
02883     return Status;
02884 }
02885 
02886 VL53L1_Error VL53L1_SmudgeCorrectionEnable(VL53L1_DEV Dev,
02887         VL53L1_SmudgeCorrectionModes Mode)
02888 {
02889     VL53L1_Error Status = VL53L1_ERROR_NONE;
02890     VL53L1_Error s1 = VL53L1_ERROR_NONE;
02891     VL53L1_Error s2 = VL53L1_ERROR_NONE;
02892     VL53L1_Error s3 = VL53L1_ERROR_NONE;
02893 
02894     LOG_FUNCTION_START("");
02895 
02896     switch (Mode) {
02897     case VL53L1_SMUDGE_CORRECTION_NONE:
02898         s1 = VL53L1_dynamic_xtalk_correction_disable(Dev);
02899         s2 = VL53L1_dynamic_xtalk_correction_apply_disable(Dev);
02900         s3 = VL53L1_dynamic_xtalk_correction_single_apply_disable(Dev);
02901         break;
02902     case VL53L1_SMUDGE_CORRECTION_CONTINUOUS:
02903         s1 = VL53L1_dynamic_xtalk_correction_enable(Dev);
02904         s2 = VL53L1_dynamic_xtalk_correction_apply_enable(Dev);
02905         s3 = VL53L1_dynamic_xtalk_correction_single_apply_disable(Dev);
02906         break;
02907     case VL53L1_SMUDGE_CORRECTION_SINGLE:
02908         s1 = VL53L1_dynamic_xtalk_correction_enable(Dev);
02909         s2 = VL53L1_dynamic_xtalk_correction_apply_enable(Dev);
02910         s3 = VL53L1_dynamic_xtalk_correction_single_apply_enable(Dev);
02911         break;
02912     case VL53L1_SMUDGE_CORRECTION_DEBUG:
02913         s1 = VL53L1_dynamic_xtalk_correction_enable(Dev);
02914         s2 = VL53L1_dynamic_xtalk_correction_apply_disable(Dev);
02915         s3 = VL53L1_dynamic_xtalk_correction_single_apply_disable(Dev);
02916         break;
02917     default:
02918         Status = VL53L1_ERROR_INVALID_PARAMS;
02919         break;
02920     }
02921 
02922     if (Status == VL53L1_ERROR_NONE) {
02923         Status = s1;
02924         if (Status == VL53L1_ERROR_NONE)
02925             Status = s2;
02926         if (Status == VL53L1_ERROR_NONE)
02927             Status = s3;
02928     }
02929 
02930     LOG_FUNCTION_END(Status);
02931     return Status;
02932 }
02933 
02934 VL53L1_Error VL53L1_SetXTalkCompensationEnable(VL53L1_DEV Dev,
02935     uint8_t XTalkCompensationEnable)
02936 {
02937     VL53L1_Error Status = VL53L1_ERROR_NONE;
02938 
02939     LOG_FUNCTION_START("");
02940 
02941     if (XTalkCompensationEnable == 0)
02942         Status = VL53L1_disable_xtalk_compensation(Dev);
02943     else
02944         Status = VL53L1_enable_xtalk_compensation(Dev);
02945 
02946     LOG_FUNCTION_END(Status);
02947     return Status;
02948 }
02949 
02950 
02951 VL53L1_Error VL53L1_GetXTalkCompensationEnable(VL53L1_DEV Dev,
02952     uint8_t *pXTalkCompensationEnable)
02953 {
02954     VL53L1_Error Status = VL53L1_ERROR_NONE;
02955 
02956     LOG_FUNCTION_START("");
02957 
02958     VL53L1_get_xtalk_compensation_enable(
02959         Dev,
02960         pXTalkCompensationEnable);
02961 
02962     LOG_FUNCTION_END(Status);
02963     return Status;
02964 }
02965 
02966 
02967 VL53L1_Error VL53L1_PerformXTalkCalibration(VL53L1_DEV Dev,
02968         uint8_t CalibrationOption)
02969 {
02970     VL53L1_Error Status = VL53L1_ERROR_NONE;
02971     VL53L1_Error UStatus;
02972     int16_t CalDistanceMm;
02973     VL53L1_xtalk_calibration_results_t xtalk;
02974 
02975     VL53L1_CalibrationData_t caldata;
02976     VL53L1_LLDriverData_t *pLLData;
02977     int i;
02978     uint32_t *pPlaneOffsetKcps;
02979     uint32_t Margin =
02980             BDTable[VL53L1_TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN];
02981     uint32_t DefaultOffset =
02982             BDTable[VL53L1_TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET];
02983     uint32_t *pLLDataPlaneOffsetKcps;
02984     uint32_t sum = 0;
02985     uint8_t binok = 0;
02986     int32_t merge;
02987 
02988     LOG_FUNCTION_START("");
02989 
02990     pPlaneOffsetKcps =
02991     &caldata.customer.algo__crosstalk_compensation_plane_offset_kcps;
02992     pLLData = VL53L1DevStructGetLLDriverHandle(Dev);
02993     pLLDataPlaneOffsetKcps =
02994     &pLLData->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps;
02995     VL53L1_get_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE, &merge);
02996 
02997     VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE, 0);
02998     switch (CalibrationOption) {
02999     case VL53L1_XTALKCALIBRATIONMODE_NO_TARGET:
03000         Status = VL53L1_run_xtalk_extraction(Dev, &UStatus);
03001 
03002         if (Status == VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL)
03003             VL53L1_xtalk_cal_data_init(Dev);
03004         break;
03005     case VL53L1_XTALKCALIBRATIONMODE_SINGLE_TARGET:
03006         Status = SingleTargetXTalkCalibration(Dev);
03007         break;
03008     case VL53L1_XTALKCALIBRATIONMODE_FULL_ROI:
03009         CalDistanceMm = (int16_t)
03010         BDTable[VL53L1_TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM];
03011 
03012         VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE,
03013                 merge);
03014         Status = VL53L1_run_hist_xtalk_extraction(Dev, CalDistanceMm,
03015                 &UStatus);
03016 
03017         VL53L1_GetCalibrationData(Dev, &caldata);
03018         for (i = 0; i < VL53L1_XTALK_HISTO_BINS; i++) {
03019             sum += caldata.xtalkhisto.xtalk_shape.bin_data[i];
03020             if (caldata.xtalkhisto.xtalk_shape.bin_data[i] > 0)
03021                 binok++;
03022         }
03023         if ((UStatus ==
03024             VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL) ||
03025             (sum > (1024 + Margin)) || (sum < (1024 - Margin)) ||
03026             (binok < 3)) {
03027             *pPlaneOffsetKcps = DefaultOffset;
03028             *pLLDataPlaneOffsetKcps = DefaultOffset;
03029             caldata.xtalkhisto.xtalk_shape.bin_data[0] = 307;
03030             caldata.xtalkhisto.xtalk_shape.bin_data[1] = 410;
03031             caldata.xtalkhisto.xtalk_shape.bin_data[2] = 410;
03032             caldata.xtalkhisto.xtalk_shape.bin_data[3] = 307;
03033             for (i = 4; i < VL53L1_XTALK_HISTO_BINS; i++)
03034                 caldata.xtalkhisto.xtalk_shape.bin_data[i] = 0;
03035             for (i = 0; i < VL53L1_BIN_REC_SIZE; i++)
03036                 caldata.algo__xtalk_cpo_HistoMerge_kcps[i] =
03037                     DefaultOffset + DefaultOffset * i;
03038             VL53L1_SetCalibrationData(Dev, &caldata);
03039         }
03040 
03041         break;
03042     default:
03043         Status = VL53L1_ERROR_INVALID_PARAMS;
03044     }
03045     VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE, merge);
03046 
03047     if (Status == VL53L1_ERROR_NONE) {
03048         Status = VL53L1_get_current_xtalk_settings(Dev, &xtalk);
03049         Status = VL53L1_set_tuning_parm(Dev,
03050             VL53L1_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS,
03051             xtalk.algo__crosstalk_compensation_plane_offset_kcps);
03052     }
03053 
03054     LOG_FUNCTION_END(Status);
03055     return Status;
03056 }
03057 
03058 VL53L1_Error VL53L1_SetOffsetCalibrationMode(VL53L1_DEV Dev,
03059         VL53L1_OffsetCalibrationModes OffsetCalibrationMode)
03060 {
03061     VL53L1_Error Status = VL53L1_ERROR_NONE;
03062     VL53L1_OffsetCalibrationMode   offset_cal_mode;
03063 
03064     LOG_FUNCTION_START("");
03065 
03066     if (OffsetCalibrationMode == VL53L1_OFFSETCALIBRATIONMODE_STANDARD) {
03067         offset_cal_mode =
03068             VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD;
03069     } else if (OffsetCalibrationMode ==
03070             VL53L1_OFFSETCALIBRATIONMODE_PRERANGE_ONLY) {
03071         offset_cal_mode =
03072         VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY;
03073     } else if (OffsetCalibrationMode ==
03074             VL53L1_OFFSETCALIBRATIONMODE_MULTI_ZONE) {
03075         offset_cal_mode =
03076                 VL53L1_OFFSETCALIBRATIONMODE__PER_ZONE;
03077     } else {
03078         Status = VL53L1_ERROR_INVALID_PARAMS;
03079     }
03080 
03081     if (Status == VL53L1_ERROR_NONE)
03082         Status =  VL53L1_set_offset_calibration_mode(Dev,
03083                 offset_cal_mode);
03084 
03085     LOG_FUNCTION_END(Status);
03086     return Status;
03087 }
03088 
03089 VL53L1_Error VL53L1_SetOffsetCorrectionMode(VL53L1_DEV Dev,
03090         VL53L1_OffsetCorrectionModes OffsetCorrectionMode)
03091 {
03092     VL53L1_Error Status = VL53L1_ERROR_NONE;
03093     VL53L1_OffsetCorrectionMode   offset_cor_mode;
03094 
03095     LOG_FUNCTION_START("");
03096 
03097     if (OffsetCorrectionMode == VL53L1_OFFSETCORRECTIONMODE_STANDARD) {
03098         offset_cor_mode =
03099                 VL53L1_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS;
03100     } else if (OffsetCorrectionMode ==
03101             VL53L1_OFFSETCORRECTIONMODE_PERZONE) {
03102         offset_cor_mode =
03103                 VL53L1_OFFSETCORRECTIONMODE__PER_ZONE_OFFSETS;
03104     } else if (OffsetCorrectionMode ==
03105             VL53L1_OFFSETCORRECTIONMODE_PERVCSEL) {
03106         offset_cor_mode =
03107                 VL53L1_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS;
03108     } else {
03109         Status = VL53L1_ERROR_INVALID_PARAMS;
03110     }
03111 
03112     if (Status == VL53L1_ERROR_NONE)
03113         Status =  VL53L1_set_offset_correction_mode(Dev,
03114                 offset_cor_mode);
03115 
03116     LOG_FUNCTION_END(Status);
03117     return Status;
03118 }
03119 
03120 VL53L1_Error VL53L1_PerformOffsetCalibration(VL53L1_DEV Dev,
03121     int32_t CalDistanceMilliMeter, FixPoint1616_t CalReflectancePercent)
03122 {
03123     VL53L1_Error Status = VL53L1_ERROR_NONE;
03124     VL53L1_Error UnfilteredStatus;
03125     VL53L1_OffsetCalibrationMode   offset_cal_mode;
03126     uint16_t CalReflectancePercent_int;
03127 
03128     VL53L1_DevicePresetModes      device_preset_mode;
03129     VL53L1_DeviceZonePreset       zone_preset;
03130     VL53L1_zone_config_t         zone_cfg;
03131     int32_t MergeEnabled;
03132 
03133     LOG_FUNCTION_START("");
03134 
03135     CalReflectancePercent_int =
03136             VL53L1_FIXPOINT1616TOFIXPOINT72(CalReflectancePercent);
03137 
03138     if (Status == VL53L1_ERROR_NONE)
03139         Status =  VL53L1_get_offset_calibration_mode(Dev,
03140                 &offset_cal_mode);
03141 
03142     if (Status != VL53L1_ERROR_NONE) {
03143         LOG_FUNCTION_END(Status);
03144         return Status;
03145     }
03146 
03147 
03148     if ((offset_cal_mode ==
03149         VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD) ||
03150         (offset_cal_mode ==
03151         VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY
03152         )) {
03153         if (Status == VL53L1_ERROR_NONE)
03154             Status = VL53L1_run_offset_calibration(
03155                     Dev,
03156                     (int16_t)CalDistanceMilliMeter,
03157                     CalReflectancePercent_int,
03158                     &UnfilteredStatus);
03159 
03160     } else if (offset_cal_mode ==
03161             VL53L1_OFFSETCALIBRATIONMODE__PER_ZONE) {
03162         VL53L1_get_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE,
03163                 &MergeEnabled);
03164         VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE, 0);
03165         device_preset_mode =
03166             VL53L1_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_LONG_RANGE;
03167         zone_preset = VL53L1_DEVICEZONEPRESET_CUSTOM;
03168 
03169         Status = VL53L1_get_zone_config(Dev, &zone_cfg);
03170         if (Status == VL53L1_ERROR_NONE)
03171             Status = VL53L1_run_zone_calibration(
03172                     Dev,
03173                     device_preset_mode,
03174                     zone_preset,
03175                     &zone_cfg,
03176                     (int16_t)CalDistanceMilliMeter,
03177                     CalReflectancePercent_int,
03178                     &UnfilteredStatus);
03179         VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE,
03180                 MergeEnabled);
03181 
03182     } else {
03183         Status = VL53L1_ERROR_INVALID_PARAMS;
03184     }
03185     LOG_FUNCTION_END(Status);
03186     return Status;
03187 }
03188 
03189 VL53L1_Error VL53L1_PerformOffsetSimpleCalibration(VL53L1_DEV Dev,
03190     int32_t CalDistanceMilliMeter)
03191 {
03192     VL53L1_Error Status = VL53L1_ERROR_NONE;
03193     int32_t sum_ranging;
03194     uint8_t offset_meas;
03195     int16_t Max, UnderMax, OverMax, Repeat;
03196     int32_t total_count, inloopcount;
03197     int32_t IncRounding;
03198     int16_t meanDistance_mm;
03199     int16_t offset;
03200     VL53L1_RangingMeasurementData_t RangingMeasurementData;
03201     VL53L1_LLDriverData_t *pdev;
03202     uint8_t goodmeas;
03203     VL53L1_Error SmudgeStatus = VL53L1_ERROR_NONE;
03204     uint8_t smudge_corr_en;
03205 
03206     LOG_FUNCTION_START("");
03207 
03208     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03209 
03210     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
03211     SmudgeStatus = VL53L1_dynamic_xtalk_correction_disable(Dev);
03212 
03213     pdev->customer.algo__part_to_part_range_offset_mm = 0;
03214     pdev->customer.mm_config__inner_offset_mm = 0;
03215     pdev->customer.mm_config__outer_offset_mm = 0;
03216     memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
03217     Repeat = BDTable[VL53L1_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
03218     Max = BDTable[
03219         VL53L1_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
03220     UnderMax = 1 + (Max / 2);
03221     OverMax = Max + (Max / 2);
03222     sum_ranging = 0;
03223     total_count = 0;
03224 
03225     while ((Repeat > 0) && (Status == VL53L1_ERROR_NONE)) {
03226         Status = VL53L1_StartMeasurement(Dev);
03227 
03228         if (Status == VL53L1_ERROR_NONE) {
03229             VL53L1_WaitMeasurementDataReady(Dev);
03230             VL53L1_GetRangingMeasurementData(Dev,
03231                 &RangingMeasurementData);
03232             VL53L1_ClearInterruptAndStartMeasurement(Dev);
03233         }
03234 
03235         inloopcount = 0;
03236         offset_meas = 0;
03237         while ((Status == VL53L1_ERROR_NONE) && (inloopcount < Max) &&
03238                 (offset_meas < OverMax)) {
03239             Status = VL53L1_WaitMeasurementDataReady(Dev);
03240             if (Status == VL53L1_ERROR_NONE)
03241                 Status = VL53L1_GetRangingMeasurementData(Dev,
03242                         &RangingMeasurementData);
03243             goodmeas = (RangingMeasurementData.RangeStatus  ==
03244                     VL53L1_RANGESTATUS_RANGE_VALID);
03245             if ((Status == VL53L1_ERROR_NONE) && goodmeas) {
03246                 sum_ranging = sum_ranging +
03247                     RangingMeasurementData.RangeMilliMeter ;
03248                 inloopcount++;
03249             }
03250             Status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
03251             offset_meas++;
03252         }
03253         total_count += inloopcount;
03254 
03255 
03256         if (inloopcount < UnderMax)
03257             Status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
03258 
03259         VL53L1_StopMeasurement(Dev);
03260 
03261         Repeat--;
03262 
03263     }
03264 
03265     if ((SmudgeStatus == VL53L1_ERROR_NONE) && (smudge_corr_en == 1))
03266         SmudgeStatus = VL53L1_dynamic_xtalk_correction_enable(Dev);
03267 
03268     if ((sum_ranging < 0) ||
03269         (sum_ranging > ((int32_t) total_count * 0xffff)))
03270         Status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
03271 
03272     if ((Status == VL53L1_ERROR_NONE) && (total_count > 0)) {
03273         IncRounding = total_count / 2;
03274         meanDistance_mm = (int16_t)((sum_ranging + IncRounding)
03275                 / total_count);
03276         offset = (int16_t)CalDistanceMilliMeter - meanDistance_mm;
03277         pdev->customer.algo__part_to_part_range_offset_mm = 0;
03278         pdev->customer.mm_config__inner_offset_mm = offset;
03279         pdev->customer.mm_config__outer_offset_mm = offset;
03280 
03281         Status = VL53L1_set_customer_nvm_managed(Dev,
03282                 &(pdev->customer));
03283     }
03284 
03285     LOG_FUNCTION_END(Status);
03286     return Status;
03287 }
03288 
03289 VL53L1_Error VL53L1_PerformOffsetZeroDistanceCalibration(VL53L1_DEV Dev)
03290 {
03291     #define START_OFFSET 50
03292     VL53L1_Error Status = VL53L1_ERROR_NONE;
03293     int32_t sum_ranging;
03294     uint8_t offset_meas;
03295     int16_t Max, UnderMax, OverMax, Repeat;
03296     int32_t total_count, inloopcount;
03297     int32_t IncRounding;
03298     int16_t meanDistance_mm;
03299     int16_t offset, ZeroDistanceOffset;
03300     VL53L1_RangingMeasurementData_t RangingMeasurementData;
03301     VL53L1_LLDriverData_t *pdev;
03302     uint8_t goodmeas;
03303     VL53L1_Error SmudgeStatus = VL53L1_ERROR_NONE;
03304     uint8_t smudge_corr_en;
03305 
03306     LOG_FUNCTION_START("");
03307 
03308     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03309     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
03310     SmudgeStatus = VL53L1_dynamic_xtalk_correction_disable(Dev);
03311     pdev->customer.algo__part_to_part_range_offset_mm = 0;
03312     pdev->customer.mm_config__inner_offset_mm = START_OFFSET;
03313     pdev->customer.mm_config__outer_offset_mm = START_OFFSET;
03314     memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
03315     ZeroDistanceOffset = BDTable[
03316         VL53L1_TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR];
03317     Repeat = BDTable[VL53L1_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
03318     Max = BDTable[
03319         VL53L1_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
03320     UnderMax = 1 + (Max / 2);
03321     OverMax = Max + (Max / 2);
03322     sum_ranging = 0;
03323     total_count = 0;
03324 
03325     while ((Repeat > 0) && (Status == VL53L1_ERROR_NONE)) {
03326         Status = VL53L1_StartMeasurement(Dev);
03327         if (Status == VL53L1_ERROR_NONE) {
03328             VL53L1_WaitMeasurementDataReady(Dev);
03329             VL53L1_GetRangingMeasurementData(Dev,
03330                 &RangingMeasurementData);
03331             VL53L1_ClearInterruptAndStartMeasurement(Dev);
03332         }
03333         inloopcount = 0;
03334         offset_meas = 0;
03335         while ((Status == VL53L1_ERROR_NONE) && (inloopcount < Max) &&
03336                 (offset_meas < OverMax)) {
03337             Status = VL53L1_WaitMeasurementDataReady(Dev);
03338             if (Status == VL53L1_ERROR_NONE)
03339                 Status = VL53L1_GetRangingMeasurementData(Dev,
03340                     &RangingMeasurementData);
03341             goodmeas = (RangingMeasurementData.RangeStatus  ==
03342                     VL53L1_RANGESTATUS_RANGE_VALID);
03343             if ((Status == VL53L1_ERROR_NONE) && goodmeas) {
03344                 sum_ranging = sum_ranging +
03345                     RangingMeasurementData.RangeMilliMeter ;
03346                 inloopcount++;
03347             }
03348             Status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
03349             offset_meas++;
03350         }
03351         total_count += inloopcount;
03352         if (inloopcount < UnderMax)
03353             Status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
03354         VL53L1_StopMeasurement(Dev);
03355         Repeat--;
03356     }
03357     if ((SmudgeStatus == VL53L1_ERROR_NONE) && (smudge_corr_en == 1))
03358         SmudgeStatus = VL53L1_dynamic_xtalk_correction_enable(Dev);
03359     if ((sum_ranging < 0) ||
03360         (sum_ranging > ((int32_t) total_count * 0xffff)))
03361         Status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
03362 
03363     if ((Status == VL53L1_ERROR_NONE) && (total_count > 0)) {
03364         IncRounding = total_count / 2;
03365         meanDistance_mm = (int16_t)
03366             ((sum_ranging + IncRounding) / total_count);
03367         offset = START_OFFSET - meanDistance_mm + ZeroDistanceOffset;
03368         pdev->customer.algo__part_to_part_range_offset_mm = 0;
03369         pdev->customer.mm_config__inner_offset_mm = offset;
03370         pdev->customer.mm_config__outer_offset_mm = offset;
03371         Status = VL53L1_set_customer_nvm_managed(Dev,
03372             &(pdev->customer));
03373     }
03374 
03375     LOG_FUNCTION_END(Status);
03376     return Status;
03377 }
03378 
03379 VL53L1_Error VL53L1_SetCalibrationData(VL53L1_DEV Dev,
03380         VL53L1_CalibrationData_t *pCalibrationData)
03381 {
03382     VL53L1_Error Status = VL53L1_ERROR_NONE;
03383     VL53L1_CustomerNvmManaged_t          *pC;
03384     VL53L1_calibration_data_t            cal_data;
03385     uint32_t x, IncomeVersion, CurrentVersion;
03386     uint8_t CalStopsOn_cal_peak_rate_map = 0;
03387     VL53L1_xtalk_calibration_results_t xtalk;
03388     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03389 
03390     LOG_FUNCTION_START("");
03391 
03392     cal_data.struct_version = pCalibrationData->struct_version -
03393             VL53L1_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
03394 
03395     IncomeVersion = pCalibrationData->struct_version;
03396     CurrentVersion = VL53L1_LL_CALIBRATION_DATA_STRUCT_VERSION +
03397         VL53L1_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
03398 
03399     if ((IncomeVersion < CurrentVersion) &&
03400         ((IncomeVersion & 0xFFFFFF0F) ==
03401          (CurrentVersion & 0xFFFFFF0F))) {
03402         cal_data.struct_version =
03403             VL53L1_LL_CALIBRATION_DATA_STRUCT_VERSION;
03404         CalStopsOn_cal_peak_rate_map = 1;
03405 
03406         pdev->tuning_parms.tp_hist_merge = 0;
03407     }
03408 
03409 
03410 
03411     memcpy(
03412         &(cal_data.fmt_dmax_cal),
03413         &(pCalibrationData->fmt_dmax_cal),
03414         sizeof(VL53L1_dmax_calibration_data_t));
03415 
03416 
03417     memcpy(
03418         &(cal_data.cust_dmax_cal),
03419         &(pCalibrationData->cust_dmax_cal),
03420         sizeof(VL53L1_dmax_calibration_data_t));
03421 
03422 
03423     memcpy(
03424         &(cal_data.add_off_cal_data),
03425         &(pCalibrationData->add_off_cal_data),
03426         sizeof(VL53L1_additional_offset_cal_data_t));
03427 
03428 
03429     memcpy(
03430         &(cal_data.optical_centre),
03431         &(pCalibrationData->optical_centre),
03432         sizeof(VL53L1_optical_centre_t));
03433 
03434 
03435     memcpy(
03436         &(cal_data.xtalkhisto),
03437         &(pCalibrationData->xtalkhisto),
03438         sizeof(VL53L1_xtalk_histogram_data_t));
03439 
03440 
03441     memcpy(
03442         &(cal_data.gain_cal),
03443         &(pCalibrationData->gain_cal),
03444         sizeof(VL53L1_gain_calibration_data_t));
03445 
03446 
03447     memcpy(
03448         &(cal_data.cal_peak_rate_map),
03449         &(pCalibrationData->cal_peak_rate_map),
03450         sizeof(VL53L1_cal_peak_rate_map_t));
03451 
03452 
03453     if (!CalStopsOn_cal_peak_rate_map)
03454         memcpy(
03455         &(cal_data.per_vcsel_cal_data),
03456         &(pCalibrationData->per_vcsel_cal_data),
03457         sizeof(VL53L1_per_vcsel_period_offset_cal_data_t));
03458     else {
03459         cal_data.per_vcsel_cal_data.short_a_offset_mm =
03460         cal_data.per_vcsel_cal_data.short_b_offset_mm =
03461         cal_data.per_vcsel_cal_data.medium_a_offset_mm =
03462         cal_data.per_vcsel_cal_data.medium_b_offset_mm =
03463         cal_data.per_vcsel_cal_data.long_a_offset_mm =
03464         cal_data.per_vcsel_cal_data.long_b_offset_mm = 0;
03465     }
03466 
03467     pC = &pCalibrationData->customer;
03468     x = pC->algo__crosstalk_compensation_plane_offset_kcps;
03469     cal_data.customer.algo__crosstalk_compensation_plane_offset_kcps =
03470         (uint16_t)(x&0x0000FFFF);
03471 
03472     cal_data.customer.global_config__spad_enables_ref_0 =
03473         pC->global_config__spad_enables_ref_0;
03474     cal_data.customer.global_config__spad_enables_ref_1 =
03475         pC->global_config__spad_enables_ref_1;
03476     cal_data.customer.global_config__spad_enables_ref_2 =
03477         pC->global_config__spad_enables_ref_2;
03478     cal_data.customer.global_config__spad_enables_ref_3 =
03479         pC->global_config__spad_enables_ref_3;
03480     cal_data.customer.global_config__spad_enables_ref_4 =
03481         pC->global_config__spad_enables_ref_4;
03482     cal_data.customer.global_config__spad_enables_ref_5 =
03483         pC->global_config__spad_enables_ref_5;
03484     cal_data.customer.global_config__ref_en_start_select =
03485         pC->global_config__ref_en_start_select;
03486     cal_data.customer.ref_spad_man__num_requested_ref_spads =
03487         pC->ref_spad_man__num_requested_ref_spads;
03488     cal_data.customer.ref_spad_man__ref_location =
03489         pC->ref_spad_man__ref_location;
03490     cal_data.customer.algo__crosstalk_compensation_x_plane_gradient_kcps =
03491         pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
03492     cal_data.customer.algo__crosstalk_compensation_y_plane_gradient_kcps =
03493         pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
03494     cal_data.customer.ref_spad_char__total_rate_target_mcps =
03495         pC->ref_spad_char__total_rate_target_mcps;
03496     cal_data.customer.algo__part_to_part_range_offset_mm =
03497         pC->algo__part_to_part_range_offset_mm;
03498     cal_data.customer.mm_config__inner_offset_mm =
03499         pC->mm_config__inner_offset_mm;
03500     cal_data.customer.mm_config__outer_offset_mm =
03501         pC->mm_config__outer_offset_mm;
03502 
03503     Status = VL53L1_set_part_to_part_data(Dev, &cal_data);
03504     if (Status != VL53L1_ERROR_NONE)
03505         goto ENDFUNC;
03506 
03507     Status = VL53L1_get_current_xtalk_settings(Dev, &xtalk);
03508 
03509     if (Status != VL53L1_ERROR_NONE)
03510         goto ENDFUNC;
03511 
03512     xtalk.algo__crosstalk_compensation_plane_offset_kcps = x;
03513 
03514     Status = VL53L1_set_tuning_parm(Dev,
03515             VL53L1_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS,
03516             x);
03517 
03518 
03519     if (!CalStopsOn_cal_peak_rate_map)
03520         memcpy(
03521         &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]),
03522         &(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]),
03523         sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
03524     else
03525         memset(
03526         &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]), 0,
03527         sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
03528 
03529     Status = VL53L1_set_current_xtalk_settings(Dev, &xtalk);
03530 
03531 ENDFUNC:
03532     LOG_FUNCTION_END(Status);
03533     return Status;
03534 
03535 }
03536 
03537 VL53L1_Error VL53L1_GetCalibrationData(VL53L1_DEV Dev,
03538         VL53L1_CalibrationData_t  *pCalibrationData)
03539 {
03540     VL53L1_Error Status = VL53L1_ERROR_NONE;
03541     VL53L1_calibration_data_t      cal_data;
03542     VL53L1_CustomerNvmManaged_t         *pC;
03543     VL53L1_customer_nvm_managed_t       *pC2;
03544     VL53L1_xtalk_calibration_results_t xtalk;
03545     uint32_t                          tmp;
03546     VL53L1_PresetModes PresetMode;
03547 
03548     LOG_FUNCTION_START("");
03549 
03550 
03551     Status = VL53L1_get_part_to_part_data(Dev, &cal_data);
03552 
03553     pCalibrationData->struct_version = cal_data.struct_version +
03554             VL53L1_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
03555 
03556 
03557     memcpy(
03558         &(pCalibrationData->fmt_dmax_cal),
03559         &(cal_data.fmt_dmax_cal),
03560         sizeof(VL53L1_dmax_calibration_data_t));
03561 
03562 
03563     memcpy(
03564         &(pCalibrationData->cust_dmax_cal),
03565         &(cal_data.cust_dmax_cal),
03566         sizeof(VL53L1_dmax_calibration_data_t));
03567 
03568 
03569     memcpy(
03570         &(pCalibrationData->add_off_cal_data),
03571         &(cal_data.add_off_cal_data),
03572         sizeof(VL53L1_additional_offset_cal_data_t));
03573 
03574 
03575     memcpy(
03576         &(pCalibrationData->optical_centre),
03577         &(cal_data.optical_centre),
03578         sizeof(VL53L1_optical_centre_t));
03579 
03580 
03581     memcpy(
03582         &(pCalibrationData->xtalkhisto),
03583         &(cal_data.xtalkhisto),
03584         sizeof(VL53L1_xtalk_histogram_data_t));
03585 
03586     memcpy(
03587         &(pCalibrationData->gain_cal),
03588         &(cal_data.gain_cal),
03589         sizeof(VL53L1_gain_calibration_data_t));
03590 
03591 
03592     memcpy(
03593         &(pCalibrationData->cal_peak_rate_map),
03594         &(cal_data.cal_peak_rate_map),
03595         sizeof(VL53L1_cal_peak_rate_map_t));
03596 
03597 
03598     memcpy(
03599         &(pCalibrationData->per_vcsel_cal_data),
03600         &(cal_data.per_vcsel_cal_data),
03601         sizeof(VL53L1_per_vcsel_period_offset_cal_data_t));
03602 
03603     pC = &pCalibrationData->customer;
03604     pC2 = &cal_data.customer;
03605     pC->global_config__spad_enables_ref_0 =
03606         pC2->global_config__spad_enables_ref_0;
03607     pC->global_config__spad_enables_ref_1 =
03608         pC2->global_config__spad_enables_ref_1;
03609     pC->global_config__spad_enables_ref_2 =
03610         pC2->global_config__spad_enables_ref_2;
03611     pC->global_config__spad_enables_ref_3 =
03612         pC2->global_config__spad_enables_ref_3;
03613     pC->global_config__spad_enables_ref_4 =
03614         pC2->global_config__spad_enables_ref_4;
03615     pC->global_config__spad_enables_ref_5 =
03616         pC2->global_config__spad_enables_ref_5;
03617     pC->global_config__ref_en_start_select =
03618         pC2->global_config__ref_en_start_select;
03619     pC->ref_spad_man__num_requested_ref_spads =
03620         pC2->ref_spad_man__num_requested_ref_spads;
03621     pC->ref_spad_man__ref_location =
03622         pC2->ref_spad_man__ref_location;
03623     pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
03624         pC2->algo__crosstalk_compensation_x_plane_gradient_kcps;
03625     pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
03626         pC2->algo__crosstalk_compensation_y_plane_gradient_kcps;
03627     pC->ref_spad_char__total_rate_target_mcps =
03628         pC2->ref_spad_char__total_rate_target_mcps;
03629     pC->algo__part_to_part_range_offset_mm =
03630         pC2->algo__part_to_part_range_offset_mm;
03631     pC->mm_config__inner_offset_mm =
03632         pC2->mm_config__inner_offset_mm;
03633     pC->mm_config__outer_offset_mm =
03634         pC2->mm_config__outer_offset_mm;
03635 
03636     pC->algo__crosstalk_compensation_plane_offset_kcps =
03637         (uint32_t)(
03638             pC2->algo__crosstalk_compensation_plane_offset_kcps);
03639 
03640     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
03641 
03642     if ((PresetMode == VL53L1_PRESETMODE_RANGING) ||
03643         (PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING) ||
03644         (PresetMode == VL53L1_PRESETMODE_PROXY_RANGING_MODE)
03645         ) {
03646 
03647         Status = VL53L1_get_current_xtalk_settings(Dev, &xtalk);
03648 
03649         if (Status != VL53L1_ERROR_NONE)
03650             goto ENDFUNC;
03651 
03652         tmp = xtalk.algo__crosstalk_compensation_plane_offset_kcps;
03653         pC->algo__crosstalk_compensation_plane_offset_kcps = tmp;
03654         tmp = xtalk.algo__crosstalk_compensation_x_plane_gradient_kcps;
03655         pC->algo__crosstalk_compensation_x_plane_gradient_kcps = tmp;
03656         tmp = xtalk.algo__crosstalk_compensation_y_plane_gradient_kcps;
03657         pC->algo__crosstalk_compensation_y_plane_gradient_kcps = tmp;
03658 
03659         memcpy(&(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]),
03660         &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]),
03661         sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
03662     }
03663 ENDFUNC:
03664     LOG_FUNCTION_END(Status);
03665     return Status;
03666 }
03667 
03668 
03669 VL53L1_Error VL53L1_SetZoneCalibrationData(VL53L1_DEV Dev,
03670         VL53L1_ZoneCalibrationData_t *pZoneCalibrationData)
03671 {
03672     VL53L1_Error Status = VL53L1_ERROR_NONE;
03673 
03674     LOG_FUNCTION_START("");
03675 
03676     Status = VL53L1_set_zone_calibration_data(Dev, pZoneCalibrationData);
03677 
03678     LOG_FUNCTION_END(Status);
03679     return Status;
03680 
03681 }
03682 
03683 VL53L1_Error VL53L1_GetZoneCalibrationData(VL53L1_DEV Dev,
03684         VL53L1_ZoneCalibrationData_t  *pZoneCalibrationData)
03685 {
03686     VL53L1_Error Status = VL53L1_ERROR_NONE;
03687 
03688     LOG_FUNCTION_START("");
03689 
03690     Status = VL53L1_get_zone_calibration_data(Dev, pZoneCalibrationData);
03691 
03692     LOG_FUNCTION_END(Status);
03693     return Status;
03694 }
03695 
03696 VL53L1_Error VL53L1_GetOpticalCenter(VL53L1_DEV Dev,
03697         FixPoint1616_t *pOpticalCenterX,
03698         FixPoint1616_t *pOpticalCenterY)
03699 {
03700     VL53L1_Error Status = VL53L1_ERROR_NONE;
03701     VL53L1_calibration_data_t  CalibrationData;
03702 
03703     LOG_FUNCTION_START("");
03704 
03705     *pOpticalCenterX = 0;
03706     *pOpticalCenterY = 0;
03707     Status = VL53L1_get_part_to_part_data(Dev, &CalibrationData);
03708     if (Status == VL53L1_ERROR_NONE) {
03709         *pOpticalCenterX = VL53L1_FIXPOINT44TOFIXPOINT1616(
03710                 CalibrationData.optical_centre.x_centre);
03711         *pOpticalCenterY = VL53L1_FIXPOINT44TOFIXPOINT1616(
03712                 CalibrationData.optical_centre.y_centre);
03713     }
03714 
03715     LOG_FUNCTION_END(Status);
03716     return Status;
03717 }
03718 
03719 
03720 
03721 
03722 
03723 
03724 VL53L1_Error VL53L1_SetThresholdConfig(VL53L1_DEV Dev,
03725         VL53L1_DetectionConfig_t *pConfig)
03726 {
03727 #define BADTHRESBOUNDS(T) \
03728     (((T.CrossMode == VL53L1_THRESHOLD_OUT_OF_WINDOW) || \
03729     (T.CrossMode == VL53L1_THRESHOLD_IN_WINDOW)) && (T.Low > T.High))
03730 
03731     VL53L1_Error Status = VL53L1_ERROR_NONE;
03732     VL53L1_GPIO_interrupt_config_t Cfg;
03733     uint16_t g;
03734     FixPoint1616_t gain, high1616, low1616;
03735     VL53L1_LLDriverData_t *pdev;
03736 
03737     LOG_FUNCTION_START("");
03738 
03739     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03740 
03741     Status = VL53L1_get_GPIO_interrupt_config(Dev, &Cfg);
03742     if (Status != VL53L1_ERROR_NONE)
03743         return Status;
03744 
03745     if (pConfig->DetectionMode  == VL53L1_DETECTION_NORMAL_RUN) {
03746         Cfg.intr_new_measure_ready = 1;
03747         Status = VL53L1_set_GPIO_interrupt_config_struct(Dev,
03748                 Cfg);
03749     } else {
03750         if (BADTHRESBOUNDS(pConfig->Distance ))
03751             Status = VL53L1_ERROR_INVALID_PARAMS;
03752         if ((Status == VL53L1_ERROR_NONE) &&
03753                 (BADTHRESBOUNDS(pConfig->Rate )))
03754             Status = VL53L1_ERROR_INVALID_PARAMS;
03755         if (Status == VL53L1_ERROR_NONE) {
03756             Cfg.intr_new_measure_ready = 0;
03757             Cfg.intr_no_target = pConfig->IntrNoTarget ;
03758 
03759             g = pdev->gain_cal.standard_ranging_gain_factor;
03760             if (g != 0) {
03761 
03762                 gain = (FixPoint1616_t) ((uint32_t)g << 5);
03763                 high1616 = (FixPoint1616_t) ((uint32_t)
03764                         pConfig->Distance .High  << 16);
03765                 low1616 = (FixPoint1616_t) ((uint32_t)
03766                         pConfig->Distance .Low  << 16);
03767 
03768                 high1616 = (high1616 + 32768) / gain;
03769                 low1616 = (low1616 + 32768) / gain;
03770                 Cfg.threshold_distance_high = (uint16_t)
03771                         (high1616 & 0xFFFF);
03772                 Cfg.threshold_distance_low = (uint16_t)
03773                         (low1616 & 0xFFFF);
03774             }
03775             Cfg.threshold_rate_high =
03776                 VL53L1_FIXPOINT1616TOFIXPOINT97(
03777                         pConfig->Rate .High );
03778             Cfg.threshold_rate_low =
03779                 VL53L1_FIXPOINT1616TOFIXPOINT97(
03780                         pConfig->Rate .Low );
03781 
03782             Cfg.intr_mode_distance = ConvertModeToLLD(
03783                     &Status,
03784                     pConfig->Distance .CrossMode);
03785             if (Status == VL53L1_ERROR_NONE)
03786                 Cfg.intr_mode_rate = ConvertModeToLLD(
03787                     &Status,
03788                     pConfig->Rate .CrossMode);
03789         }
03790 
03791 
03792         if (Status == VL53L1_ERROR_NONE) {
03793             Cfg.intr_combined_mode = 1;
03794             switch (pConfig->DetectionMode ) {
03795             case VL53L1_DETECTION_DISTANCE_ONLY:
03796                 Cfg.threshold_rate_high = 0;
03797                 Cfg.threshold_rate_low = 0;
03798                 break;
03799             case VL53L1_DETECTION_RATE_ONLY:
03800                 Cfg.threshold_distance_high = 0;
03801                 Cfg.threshold_distance_low = 0;
03802                 break;
03803             case VL53L1_DETECTION_DISTANCE_OR_RATE:
03804 
03805                 break;
03806             case VL53L1_DETECTION_DISTANCE_AND_RATE:
03807                 Cfg.intr_combined_mode = 0;
03808                 break;
03809             default:
03810                 Status = VL53L1_ERROR_INVALID_PARAMS;
03811             }
03812         }
03813 
03814         if (Status == VL53L1_ERROR_NONE)
03815             Status =
03816             VL53L1_set_GPIO_interrupt_config_struct(Dev, Cfg);
03817 
03818     }
03819 
03820     LOG_FUNCTION_END(Status);
03821     return Status;
03822 }
03823 
03824 
03825 VL53L1_Error VL53L1_GetThresholdConfig(VL53L1_DEV Dev,
03826         VL53L1_DetectionConfig_t *pConfig)
03827 {
03828     VL53L1_Error Status = VL53L1_ERROR_NONE;
03829     VL53L1_GPIO_interrupt_config_t Cfg;
03830 
03831     LOG_FUNCTION_START("");
03832 
03833     Status = VL53L1_get_GPIO_interrupt_config(Dev, &Cfg);
03834 
03835     if (Status != VL53L1_ERROR_NONE) {
03836         LOG_FUNCTION_END(Status);
03837         return Status;
03838     }
03839 
03840     pConfig->IntrNoTarget  = Cfg.intr_no_target;
03841     pConfig->Distance .High  = Cfg.threshold_distance_high;
03842     pConfig->Distance .Low  = Cfg.threshold_distance_low;
03843     pConfig->Rate .High  =
03844         VL53L1_FIXPOINT97TOFIXPOINT1616(
03845                 Cfg.threshold_rate_high);
03846     pConfig->Rate .Low  =
03847         VL53L1_FIXPOINT97TOFIXPOINT1616(Cfg.threshold_rate_low);
03848     pConfig->Distance .CrossMode =
03849         ConvertModeFromLLD(&Status, Cfg.intr_mode_distance);
03850     if (Status == VL53L1_ERROR_NONE)
03851         pConfig->Rate .CrossMode =
03852             ConvertModeFromLLD(&Status, Cfg.intr_mode_rate);
03853 
03854     if (Cfg.intr_new_measure_ready == 1) {
03855         pConfig->DetectionMode  = VL53L1_DETECTION_NORMAL_RUN;
03856     } else {
03857 
03858         if (Status == VL53L1_ERROR_NONE) {
03859             if (Cfg.intr_combined_mode == 0)
03860                 pConfig->DetectionMode  =
03861                 VL53L1_DETECTION_DISTANCE_AND_RATE;
03862             else {
03863                 if ((Cfg.threshold_distance_high == 0) &&
03864                     (Cfg.threshold_distance_low == 0))
03865                     pConfig->DetectionMode  =
03866                     VL53L1_DETECTION_RATE_ONLY;
03867                 else if ((Cfg.threshold_rate_high == 0) &&
03868                     (Cfg.threshold_rate_low == 0))
03869                     pConfig->DetectionMode  =
03870                     VL53L1_DETECTION_DISTANCE_ONLY;
03871                 else
03872                     pConfig->DetectionMode  =
03873                     VL53L1_DETECTION_DISTANCE_OR_RATE;
03874             }
03875         }
03876     }
03877 
03878     LOG_FUNCTION_END(Status);
03879     return Status;
03880 }
03881 
03882 
03883 
03884 
03885 VL53L1_Error VL53L1_PerformOffsetPerVcselCalibration(VL53L1_DEV Dev,
03886     int32_t CalDistanceMilliMeter)
03887 {
03888     VL53L1_Error Status = VL53L1_ERROR_NONE;
03889     int32_t sum_ranging_range_A, sum_ranging_range_B;
03890     uint8_t offset_meas_range_A, offset_meas_range_B;
03891     int16_t Max, UnderMax, OverMax, Repeat;
03892     int32_t inloopcount;
03893     int32_t IncRounding;
03894     int16_t meanDistance_mm;
03895     VL53L1_RangingMeasurementData_t RangingMeasurementData;
03896     VL53L1_LLDriverData_t *pdev;
03897     uint8_t goodmeas;
03898     VL53L1_PresetModes currentMode;
03899     VL53L1_DistanceModes currentDist;
03900     VL53L1_DistanceModes DistMode[3] = {VL53L1_DISTANCEMODE_SHORT,
03901             VL53L1_DISTANCEMODE_MEDIUM, VL53L1_DISTANCEMODE_LONG};
03902     int16_t offsetA[3];
03903     int16_t offsetB[3];
03904 
03905     VL53L1_Error SmudgeStatus = VL53L1_ERROR_NONE;
03906     uint8_t smudge_corr_en, isc;
03907 
03908     LOG_FUNCTION_START("");
03909 
03910     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03911 
03912     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
03913     SmudgeStatus = VL53L1_dynamic_xtalk_correction_disable(Dev);
03914 
03915     pdev->customer.algo__part_to_part_range_offset_mm = 0;
03916     pdev->customer.mm_config__inner_offset_mm = 0;
03917     pdev->customer.mm_config__outer_offset_mm = 0;
03918     pdev->customer.mm_config__outer_offset_mm = 0;
03919     memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
03920 
03921     Repeat = 0;
03922     Max = 2 * BDTable[
03923         VL53L1_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
03924     UnderMax = 1 + (Max / 2);
03925     OverMax = Max + (Max / 2);
03926 
03927     Status = VL53L1_GetPresetMode(Dev, &currentMode);
03928     Status = VL53L1_GetDistanceMode(Dev, &currentDist);
03929 
03930     while ((Repeat < 3) && (Status == VL53L1_ERROR_NONE)) {
03931         Status = VL53L1_SetDistanceMode(Dev, DistMode[Repeat]);
03932         Status = VL53L1_StartMeasurement(Dev);
03933 
03934         if (Status == VL53L1_ERROR_NONE) {
03935             VL53L1_WaitMeasurementDataReady(Dev);
03936             VL53L1_GetRangingMeasurementData(Dev,
03937                     &RangingMeasurementData);
03938             VL53L1_ClearInterruptAndStartMeasurement(Dev);
03939         }
03940 
03941         inloopcount = 0;
03942         offset_meas_range_A = 0;
03943         sum_ranging_range_A = 0;
03944         offset_meas_range_B = 0;
03945         sum_ranging_range_B = 0;
03946         while ((Status == VL53L1_ERROR_NONE) && (inloopcount < Max) &&
03947                 (inloopcount < OverMax)) {
03948             Status = VL53L1_WaitMeasurementDataReady(Dev);
03949             if (Status == VL53L1_ERROR_NONE)
03950                 Status = VL53L1_GetRangingMeasurementData(Dev,
03951                         &RangingMeasurementData);
03952             goodmeas = (RangingMeasurementData.RangeStatus  ==
03953                     VL53L1_RANGESTATUS_RANGE_VALID);
03954             isc = pdev->ll_state.cfg_internal_stream_count;
03955             if ((Status == VL53L1_ERROR_NONE) && goodmeas) {
03956                 if (isc & 0x01) {
03957                     sum_ranging_range_A +=
03958                     RangingMeasurementData.RangeMilliMeter ;
03959                     offset_meas_range_A++;
03960                 } else {
03961                     sum_ranging_range_B +=
03962                     RangingMeasurementData.RangeMilliMeter ;
03963                     offset_meas_range_B++;
03964                 }
03965                 inloopcount = offset_meas_range_A +
03966                     offset_meas_range_B;
03967             }
03968             Status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
03969         }
03970 
03971 
03972         if (inloopcount < UnderMax)
03973             Status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
03974 
03975         VL53L1_StopMeasurement(Dev);
03976 
03977 
03978         if ((sum_ranging_range_A < 0) ||
03979             (sum_ranging_range_B < 0) ||
03980             (sum_ranging_range_A >
03981                 ((int32_t) offset_meas_range_A * 0xffff)) ||
03982             (sum_ranging_range_B >
03983                 ((int32_t) offset_meas_range_B * 0xffff))) {
03984             Status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
03985         }
03986 
03987         if ((Status == VL53L1_ERROR_NONE) &&
03988             (offset_meas_range_A > 0)) {
03989             IncRounding = offset_meas_range_A / 2;
03990             meanDistance_mm = (int16_t)
03991                 ((sum_ranging_range_A + IncRounding)
03992                 / offset_meas_range_A);
03993             offsetA[Repeat] = (int16_t)
03994                 CalDistanceMilliMeter - meanDistance_mm;
03995         }
03996 
03997         if ((Status == VL53L1_ERROR_NONE) &&
03998             (offset_meas_range_B > 0)) {
03999             IncRounding = offset_meas_range_B / 2;
04000             meanDistance_mm = (int16_t)
04001                 ((sum_ranging_range_B + IncRounding)
04002                 / offset_meas_range_B);
04003             offsetB[Repeat] = (int16_t)
04004                 CalDistanceMilliMeter - meanDistance_mm;
04005         }
04006         Repeat++;
04007     }
04008 
04009     if ((SmudgeStatus == VL53L1_ERROR_NONE) && (smudge_corr_en == 1))
04010         SmudgeStatus = VL53L1_dynamic_xtalk_correction_enable(Dev);
04011 
04012     if (Status == VL53L1_ERROR_NONE) {
04013         pdev->per_vcsel_cal_data.short_a_offset_mm  = offsetA[0];
04014         pdev->per_vcsel_cal_data.short_b_offset_mm  = offsetB[0];
04015         pdev->per_vcsel_cal_data.medium_a_offset_mm = offsetA[1];
04016         pdev->per_vcsel_cal_data.medium_b_offset_mm = offsetB[1];
04017         pdev->per_vcsel_cal_data.long_a_offset_mm   = offsetA[2];
04018         pdev->per_vcsel_cal_data.long_b_offset_mm   = offsetB[2];
04019     }
04020 
04021     VL53L1_SetPresetMode(Dev, currentMode);
04022     VL53L1_SetDistanceMode(Dev, currentDist);
04023 
04024     LOG_FUNCTION_END(Status);
04025     return Status;
04026 }
04027 
04028 
04029