ST Expansion SW Team / VL53L1CB

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   VL53L1CB_noshield_1sensor_polls_auton VL53L1CB_noshield_1sensor_interrupt_auton X_NUCLEO_53L1A2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53l1_api.c Source File

vl53l1_api.c

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