ST Expansion SW Team / VL53L1

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   X_NUCLEO_53L1CB

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;
00642     uint32_t phasecal_config_timeout_us;
00643     uint32_t mm_config_timeout_us;
00644     uint32_t lld_range_config_timeout_us;
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;
00750     uint32_t MmTimeoutUs;
00751     uint32_t PhaseCalTimeoutUs;
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;
00855     uint8_t Mm2Enabled;
00856     uint32_t TimingGuard;
00857     uint32_t divisor;
00858     uint32_t TimingBudget;
00859     uint32_t MmTimeoutUs;
00860     VL53L1_PresetModes PresetMode;
00861     uint32_t PhaseCalTimeoutUs;
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         Status = VL53L1_ERROR_INVALID_PARAMS;
01175         break;
01176     }
01177     if (Status == VL53L1_ERROR_NONE)
01178         Status = VL53L1_set_dmax_mode(Dev, dmax_mode);
01179 
01180     LOG_FUNCTION_END(Status);
01181     return Status;
01182 }
01183 
01184 
01185 VL53L1_Error VL53L1_GetDmaxMode(VL53L1_DEV Dev,
01186     VL53L1_DeviceDmaxModes *pDmaxMode)
01187 {
01188     VL53L1_Error  Status = VL53L1_ERROR_NONE;
01189     VL53L1_DeviceDmaxMode dmax_mode;
01190 
01191     LOG_FUNCTION_START("");
01192 
01193     Status = VL53L1_get_dmax_mode(Dev, &dmax_mode);
01194     if (Status == VL53L1_ERROR_NONE) {
01195         switch (dmax_mode) {
01196         case VL53L1_DEVICEDMAXMODE__FMT_CAL_DATA:
01197             *pDmaxMode = VL53L1_DMAXMODE_FMT_CAL_DATA;
01198             break;
01199         case VL53L1_DEVICEDMAXMODE__CUST_CAL_DATA:
01200             *pDmaxMode = VL53L1_DMAXMODE_CUSTCAL_DATA;
01201             break;
01202         case VL53L1_DEVICEDMAXMODE__PER_ZONE_CAL_DATA:
01203             *pDmaxMode = VL53L1_DMAXMODE_PER_ZONE_CAL_DATA;
01204             break;
01205         default:
01206             *pDmaxMode = VL53L1_DEVICEDMAXMODE__CUST_CAL_DATA;
01207             Status = VL53L1_ERROR_NOT_IMPLEMENTED;
01208             break;
01209         }
01210     }
01211 
01212     LOG_FUNCTION_END(Status);
01213     return Status;
01214 }
01215 
01216 
01217 
01218 
01219 
01220 
01221 VL53L1_Error VL53L1_GetNumberOfLimitCheck(uint16_t *pNumberOfLimitCheck)
01222 {
01223     VL53L1_Error Status = VL53L1_ERROR_NONE;
01224 
01225     LOG_FUNCTION_START("");
01226 
01227     *pNumberOfLimitCheck = VL53L1_CHECKENABLE_NUMBER_OF_CHECKS;
01228 
01229     LOG_FUNCTION_END(Status);
01230     return Status;
01231 }
01232 
01233 VL53L1_Error VL53L1_GetLimitCheckInfo(uint16_t LimitCheckId,
01234     char *pLimitCheckString)
01235 {
01236     VL53L1_Error Status = VL53L1_ERROR_NONE;
01237 
01238     LOG_FUNCTION_START("");
01239 
01240     Status = VL53L1_get_limit_check_info(LimitCheckId,
01241         pLimitCheckString);
01242 
01243     LOG_FUNCTION_END(Status);
01244     return Status;
01245 }
01246 
01247 VL53L1_Error VL53L1_GetLimitCheckStatus(VL53L1_DEV Dev, uint16_t LimitCheckId,
01248     uint8_t *pLimitCheckStatus)
01249 {
01250     VL53L1_Error Status = VL53L1_ERROR_NONE;
01251     uint8_t Temp8;
01252 
01253     LOG_FUNCTION_START("");
01254 
01255     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01256         Status = VL53L1_ERROR_INVALID_PARAMS;
01257     } else {
01258         VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
01259             LimitCheckId, Temp8);
01260         *pLimitCheckStatus = Temp8;
01261     }
01262 
01263     LOG_FUNCTION_END(Status);
01264     return Status;
01265 }
01266 
01267 static VL53L1_Error SetLimitValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
01268         FixPoint1616_t value)
01269 {
01270     VL53L1_Error Status = VL53L1_ERROR_NONE;
01271     uint16_t tmpuint16;
01272 
01273     LOG_FUNCTION_START("");
01274 
01275     switch (LimitCheckId) {
01276     case VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE:
01277         tmpuint16 = VL53L1_FIXPOINT1616TOFIXPOINT142(value);
01278         VL53L1_set_lite_sigma_threshold(Dev, tmpuint16);
01279         break;
01280     case VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
01281         tmpuint16 = VL53L1_FIXPOINT1616TOFIXPOINT97(value);
01282         VL53L1_set_lite_min_count_rate(Dev, tmpuint16);
01283         break;
01284     default:
01285         Status = VL53L1_ERROR_INVALID_PARAMS;
01286     }
01287 
01288     LOG_FUNCTION_END(Status);
01289     return Status;
01290 }
01291 
01292 
01293 VL53L1_Error VL53L1_SetLimitCheckEnable(VL53L1_DEV Dev, uint16_t LimitCheckId,
01294     uint8_t LimitCheckEnable)
01295 {
01296     VL53L1_Error Status = VL53L1_ERROR_NONE;
01297     FixPoint1616_t TempFix1616 = 0;
01298 
01299     LOG_FUNCTION_START("");
01300 
01301 
01302     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01303         Status = VL53L1_ERROR_INVALID_PARAMS;
01304     } else {
01305 
01306         if (LimitCheckEnable == 0)
01307             TempFix1616 = 0;
01308         else
01309             VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
01310                 LimitCheckId, TempFix1616);
01311 
01312         Status = SetLimitValue(Dev, LimitCheckId, TempFix1616);
01313     }
01314 
01315     if (Status == VL53L1_ERROR_NONE)
01316         VL53L1_SETARRAYPARAMETERFIELD(Dev,
01317             LimitChecksEnable,
01318             LimitCheckId,
01319             ((LimitCheckEnable == 0) ? 0 : 1));
01320 
01321 
01322 
01323     LOG_FUNCTION_END(Status);
01324     return Status;
01325 }
01326 
01327 VL53L1_Error VL53L1_GetLimitCheckEnable(VL53L1_DEV Dev, uint16_t LimitCheckId,
01328     uint8_t *pLimitCheckEnable)
01329 {
01330     VL53L1_Error Status = VL53L1_ERROR_NONE;
01331     uint8_t Temp8;
01332 
01333     LOG_FUNCTION_START("");
01334 
01335     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01336         Status = VL53L1_ERROR_INVALID_PARAMS;
01337         *pLimitCheckEnable = 0;
01338     } else {
01339         VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
01340             LimitCheckId, Temp8);
01341         *pLimitCheckEnable = Temp8;
01342     }
01343 
01344 
01345     LOG_FUNCTION_END(Status);
01346     return Status;
01347 }
01348 
01349 VL53L1_Error VL53L1_SetLimitCheckValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
01350     FixPoint1616_t LimitCheckValue)
01351 {
01352     VL53L1_Error Status = VL53L1_ERROR_NONE;
01353     uint8_t LimitChecksEnable;
01354 
01355     LOG_FUNCTION_START("");
01356 
01357     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01358         Status = VL53L1_ERROR_INVALID_PARAMS;
01359     } else {
01360 
01361         VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable,
01362                 LimitCheckId,
01363                 LimitChecksEnable);
01364 
01365         if (LimitChecksEnable == 0) {
01366 
01367             VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue,
01368                 LimitCheckId, LimitCheckValue);
01369         } else {
01370 
01371             Status = SetLimitValue(Dev, LimitCheckId,
01372                     LimitCheckValue);
01373 
01374             if (Status == VL53L1_ERROR_NONE) {
01375                 VL53L1_SETARRAYPARAMETERFIELD(Dev,
01376                     LimitChecksValue,
01377                     LimitCheckId, LimitCheckValue);
01378             }
01379         }
01380     }
01381 
01382     LOG_FUNCTION_END(Status);
01383     return Status;
01384 }
01385 
01386 VL53L1_Error VL53L1_GetLimitCheckValue(VL53L1_DEV Dev, uint16_t LimitCheckId,
01387     FixPoint1616_t *pLimitCheckValue)
01388 {
01389     VL53L1_Error Status = VL53L1_ERROR_NONE;
01390     uint16_t MinCountRate;
01391     FixPoint1616_t TempFix1616;
01392     uint16_t SigmaThresh;
01393 
01394     LOG_FUNCTION_START("");
01395 
01396     switch (LimitCheckId) {
01397     case VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE:
01398         Status = VL53L1_get_lite_sigma_threshold(Dev, &SigmaThresh);
01399         TempFix1616 = VL53L1_FIXPOINT142TOFIXPOINT1616(SigmaThresh);
01400         break;
01401     case VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
01402         Status = VL53L1_get_lite_min_count_rate(Dev, &MinCountRate);
01403         TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(MinCountRate);
01404         break;
01405     default:
01406         Status = VL53L1_ERROR_INVALID_PARAMS;
01407     }
01408 
01409     if (Status == VL53L1_ERROR_NONE) {
01410 
01411         if (TempFix1616 == 0) {
01412 
01413             VL53L1_GETARRAYPARAMETERFIELD(Dev,
01414                 LimitChecksValue, LimitCheckId,
01415                 TempFix1616);
01416             *pLimitCheckValue = TempFix1616;
01417             VL53L1_SETARRAYPARAMETERFIELD(Dev,
01418                 LimitChecksEnable, LimitCheckId, 0);
01419         } else {
01420             *pLimitCheckValue = TempFix1616;
01421             VL53L1_SETARRAYPARAMETERFIELD(Dev,
01422                 LimitChecksValue, LimitCheckId,
01423                 TempFix1616);
01424             VL53L1_SETARRAYPARAMETERFIELD(Dev,
01425                 LimitChecksEnable, LimitCheckId, 1);
01426         }
01427     }
01428     LOG_FUNCTION_END(Status);
01429     return Status;
01430 
01431 }
01432 
01433 VL53L1_Error VL53L1_GetLimitCheckCurrent(VL53L1_DEV Dev, uint16_t LimitCheckId,
01434     FixPoint1616_t *pLimitCheckCurrent)
01435 {
01436     VL53L1_Error Status = VL53L1_ERROR_NONE;
01437     FixPoint1616_t TempFix1616 = 0;
01438 
01439     LOG_FUNCTION_START("");
01440 
01441     if (LimitCheckId >= VL53L1_CHECKENABLE_NUMBER_OF_CHECKS) {
01442         Status = VL53L1_ERROR_INVALID_PARAMS;
01443     } else {
01444         VL53L1_GETARRAYPARAMETERFIELD(Dev, LimitChecksCurrent,
01445             LimitCheckId, TempFix1616);
01446         *pLimitCheckCurrent = TempFix1616;
01447     }
01448 
01449     LOG_FUNCTION_END(Status);
01450     return Status;
01451 
01452 }
01453 
01454 
01455 
01456 
01457 
01458 
01459 
01460 
01461 VL53L1_Error VL53L1_GetMaxNumberOfROI(VL53L1_DEV Dev,
01462     uint8_t *pMaxNumberOfROI)
01463 {
01464     VL53L1_Error Status = VL53L1_ERROR_NONE;
01465     VL53L1_PresetModes PresetMode;
01466 
01467     LOG_FUNCTION_START("");
01468 
01469     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
01470 
01471 
01472     if (PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING)
01473         *pMaxNumberOfROI = VL53L1_MAX_USER_ZONES;
01474     else
01475         *pMaxNumberOfROI = 1;
01476 
01477     LOG_FUNCTION_END(Status);
01478     return Status;
01479 }
01480 
01481 VL53L1_Error VL53L1_SetROI(VL53L1_DEV Dev,
01482         VL53L1_RoiConfig_t *pRoiConfig)
01483 {
01484     VL53L1_Error Status = VL53L1_ERROR_NONE;
01485     VL53L1_PresetModes PresetMode;
01486     uint8_t MaxNumberOfROI = 1;
01487     VL53L1_zone_config_t  zone_cfg;
01488     VL53L1_UserRoi_t CurrROI;
01489     uint8_t  i;
01490     uint8_t  x_centre;
01491     uint8_t  y_centre;
01492     uint8_t  width, height;
01493 
01494     LOG_FUNCTION_START("");
01495 
01496 
01497     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
01498 
01499 
01500     if (PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING)
01501         MaxNumberOfROI = VL53L1_MAX_USER_ZONES;
01502 
01503     if ((pRoiConfig->NumberOfRoi  > MaxNumberOfROI) ||
01504             (pRoiConfig->NumberOfRoi  < 1))
01505         Status = VL53L1_ERROR_INVALID_PARAMS;
01506 
01507     if (Status == VL53L1_ERROR_NONE) {
01508 
01509 
01510         zone_cfg.max_zones = MaxNumberOfROI;
01511         zone_cfg.active_zones = pRoiConfig->NumberOfRoi  - 1;
01512 
01513         for (i = 0; i < pRoiConfig->NumberOfRoi ; i++) {
01514             CurrROI = pRoiConfig->UserRois [i];
01515 
01516             Status = CheckValidRectRoi(CurrROI);
01517             if (Status != VL53L1_ERROR_NONE)
01518                 break;
01519 
01520             x_centre = (CurrROI.BotRightX  + CurrROI.TopLeftX   + 1)
01521                     / 2;
01522             y_centre = (CurrROI.TopLeftY   + CurrROI.BotRightY  + 1)
01523                     / 2;
01524             width =     (CurrROI.BotRightX  - CurrROI.TopLeftX );
01525             height =    (CurrROI.TopLeftY   - CurrROI.BotRightY );
01526             if ((width < 3) || (height < 3)) {
01527                 Status = VL53L1_ERROR_INVALID_PARAMS;
01528                 break;
01529             }
01530             zone_cfg.user_zones[i].x_centre = x_centre;
01531             zone_cfg.user_zones[i].y_centre = y_centre;
01532             zone_cfg.user_zones[i].width = width;
01533             zone_cfg.user_zones[i].height = height;
01534         }
01535     }
01536 
01537     if (Status == VL53L1_ERROR_NONE)
01538         Status = VL53L1_set_zone_config(Dev, &zone_cfg);
01539 
01540     LOG_FUNCTION_END(Status);
01541     return Status;
01542 }
01543 
01544 VL53L1_Error VL53L1_GetROI(VL53L1_DEV Dev,
01545         VL53L1_RoiConfig_t *pRoiConfig)
01546 {
01547     VL53L1_Error Status = VL53L1_ERROR_NONE;
01548     VL53L1_zone_config_t      zone_cfg;
01549     uint8_t  i;
01550     uint8_t  TopLeftX;
01551     uint8_t  TopLeftY;
01552     uint8_t  BotRightX;
01553     uint8_t  BotRightY;
01554 
01555     LOG_FUNCTION_START("");
01556 
01557     VL53L1_get_zone_config(Dev, &zone_cfg);
01558 
01559     pRoiConfig->NumberOfRoi  = zone_cfg.active_zones + 1;
01560 
01561     for (i = 0; i < pRoiConfig->NumberOfRoi ; i++) {
01562         TopLeftX = (2 * zone_cfg.user_zones[i].x_centre -
01563             zone_cfg.user_zones[i].width) >> 1;
01564         TopLeftY = (2 * zone_cfg.user_zones[i].y_centre +
01565             zone_cfg.user_zones[i].height) >> 1;
01566         BotRightX = (2 * zone_cfg.user_zones[i].x_centre +
01567             zone_cfg.user_zones[i].width) >> 1;
01568         BotRightY = (2 * zone_cfg.user_zones[i].y_centre -
01569             zone_cfg.user_zones[i].height) >> 1;
01570         pRoiConfig->UserRois [i].TopLeftX  = TopLeftX;
01571         pRoiConfig->UserRois [i].TopLeftY  = TopLeftY;
01572         pRoiConfig->UserRois [i].BotRightX  = BotRightX;
01573         pRoiConfig->UserRois [i].BotRightY  = BotRightY;
01574     }
01575 
01576     LOG_FUNCTION_END(Status);
01577     return Status;
01578 }
01579 
01580 
01581 
01582 
01583 
01584 
01585 
01586 VL53L1_Error VL53L1_GetNumberOfSequenceSteps(VL53L1_DEV Dev,
01587     uint8_t *pNumberOfSequenceSteps)
01588 {
01589     VL53L1_Error Status = VL53L1_ERROR_NONE;
01590 
01591     SUPPRESS_UNUSED_WARNING(Dev);
01592 
01593     LOG_FUNCTION_START("");
01594 
01595     *pNumberOfSequenceSteps = VL53L1_SEQUENCESTEP_NUMBER_OF_ITEMS;
01596 
01597     LOG_FUNCTION_END(Status);
01598     return Status;
01599 }
01600 
01601 VL53L1_Error VL53L1_GetSequenceStepsInfo(VL53L1_SequenceStepId SequenceStepId,
01602     char *pSequenceStepsString)
01603 {
01604     VL53L1_Error Status = VL53L1_ERROR_NONE;
01605 
01606     LOG_FUNCTION_START("");
01607 
01608     Status = VL53L1_get_sequence_steps_info(
01609             SequenceStepId,
01610             pSequenceStepsString);
01611 
01612     LOG_FUNCTION_END(Status);
01613 
01614     return Status;
01615 }
01616 
01617 VL53L1_Error VL53L1_SetSequenceStepEnable(VL53L1_DEV Dev,
01618     VL53L1_SequenceStepId SequenceStepId, uint8_t SequenceStepEnabled)
01619 {
01620     VL53L1_Error Status = VL53L1_ERROR_NONE;
01621     uint32_t MeasurementTimingBudgetMicroSeconds;
01622 
01623     LOG_FUNCTION_START("");
01624 
01625 
01626 
01627     Status = VL53L1_set_sequence_config_bit(Dev,
01628         (VL53L1_DeviceSequenceConfig)SequenceStepId,
01629         SequenceStepEnabled);
01630 
01631 
01632     if (Status == VL53L1_ERROR_NONE) {
01633 
01634 
01635         MeasurementTimingBudgetMicroSeconds = VL53L1DevDataGet(Dev,
01636             CurrentParameters.MeasurementTimingBudgetMicroSeconds);
01637 
01638         VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev,
01639             MeasurementTimingBudgetMicroSeconds);
01640     }
01641 
01642     LOG_FUNCTION_END(Status);
01643 
01644     return Status;
01645 }
01646 
01647 
01648 VL53L1_Error VL53L1_GetSequenceStepEnable(VL53L1_DEV Dev,
01649     VL53L1_SequenceStepId SequenceStepId, uint8_t *pSequenceStepEnabled)
01650 {
01651     VL53L1_Error Status = VL53L1_ERROR_NONE;
01652 
01653     LOG_FUNCTION_START("");
01654 
01655     Status = VL53L1_get_sequence_config_bit(Dev,
01656         (VL53L1_DeviceSequenceConfig)SequenceStepId,
01657         pSequenceStepEnabled);
01658 
01659     LOG_FUNCTION_END(Status);
01660     return Status;
01661 }
01662 
01663 
01664 
01665 
01666 
01667 
01668 
01669 
01670 
01671 
01672 VL53L1_Error VL53L1_StartMeasurement(VL53L1_DEV Dev)
01673 {
01674 #define TIMED_MODE_TIMING_GUARD_MILLISECONDS 4
01675     VL53L1_Error Status = VL53L1_ERROR_NONE;
01676     uint8_t DeviceMeasurementMode;
01677     VL53L1_State CurrPalState;
01678     VL53L1_Error lStatus;
01679     uint32_t MTBus, IMPms;
01680     uint8_t i;
01681     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01682 
01683 
01684     LOG_FUNCTION_START("");
01685     VL53L1_load_patch(Dev);
01686     for (i = 0; i < VL53L1_MAX_RANGE_RESULTS; i++) {
01687         pdev->PreviousRangeMilliMeter[i] = 0;
01688         pdev->PreviousRangeStatus[i] = 255;
01689         pdev->PreviousExtendedRange[i] = 0;
01690     }
01691     pdev->PreviousStreamCount = 0;
01692     CurrPalState = VL53L1DevDataGet(Dev, PalState);
01693     switch (CurrPalState) {
01694     case VL53L1_STATE_IDLE:
01695         Status = VL53L1_ERROR_NONE;
01696         break;
01697     case VL53L1_STATE_POWERDOWN:
01698     case VL53L1_STATE_WAIT_STATICINIT:
01699     case VL53L1_STATE_STANDBY:
01700     case VL53L1_STATE_RUNNING:
01701     case VL53L1_STATE_RESET:
01702     case VL53L1_STATE_UNKNOWN:
01703     case VL53L1_STATE_ERROR:
01704         Status = VL53L1_ERROR_INVALID_COMMAND;
01705         break;
01706     default:
01707         Status = VL53L1_ERROR_UNDEFINED;
01708     }
01709 
01710     DeviceMeasurementMode = VL53L1DevDataGet(Dev, LLData.measurement_mode);
01711 
01712 
01713     if ((Status == VL53L1_ERROR_NONE) &&
01714         (DeviceMeasurementMode == VL53L1_DEVICEMEASUREMENTMODE_TIMED)) {
01715         lStatus = VL53L1_GetMeasurementTimingBudgetMicroSeconds(Dev,
01716                 &MTBus);
01717 
01718         MTBus /= 1000;
01719         lStatus = VL53L1_GetInterMeasurementPeriodMilliSeconds(Dev,
01720                 &IMPms);
01721 
01722         SUPPRESS_UNUSED_WARNING(lStatus);
01723         if (IMPms < MTBus + TIMED_MODE_TIMING_GUARD_MILLISECONDS)
01724             Status = VL53L1_ERROR_INVALID_PARAMS;
01725     }
01726 
01727     if (Status == VL53L1_ERROR_NONE)
01728         Status = VL53L1_init_and_start_range(
01729                 Dev,
01730                 DeviceMeasurementMode,
01731                 VL53L1_DEVICECONFIGLEVEL_FULL);
01732 
01733 
01734     if (Status == VL53L1_ERROR_NONE)
01735         VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_RUNNING);
01736 
01737 
01738     LOG_FUNCTION_END(Status);
01739     return Status;
01740 }
01741 
01742 VL53L1_Error VL53L1_StopMeasurement(VL53L1_DEV Dev)
01743 {
01744     VL53L1_Error Status = VL53L1_ERROR_NONE;
01745 
01746     LOG_FUNCTION_START("");
01747 
01748     Status = VL53L1_stop_range(Dev);
01749     VL53L1_unload_patch(Dev);
01750 
01751     if (Status == VL53L1_ERROR_NONE)
01752         VL53L1DevDataSet(Dev, PalState, VL53L1_STATE_IDLE);
01753 
01754     LOG_FUNCTION_END(Status);
01755     return Status;
01756 }
01757 
01758 
01759 VL53L1_Error VL53L1_ClearInterruptAndStartMeasurement(VL53L1_DEV Dev)
01760 {
01761     VL53L1_Error Status = VL53L1_ERROR_NONE;
01762     uint8_t DeviceMeasurementMode;
01763 
01764     LOG_FUNCTION_START("");
01765 
01766     DeviceMeasurementMode = VL53L1DevDataGet(Dev, LLData.measurement_mode);
01767 
01768     Status = VL53L1_clear_interrupt_and_enable_next_range(Dev,
01769             DeviceMeasurementMode);
01770 
01771     LOG_FUNCTION_END(Status);
01772     return Status;
01773 }
01774 
01775 
01776 VL53L1_Error VL53L1_GetMeasurementDataReady(VL53L1_DEV Dev,
01777     uint8_t *pMeasurementDataReady)
01778 {
01779     VL53L1_Error Status = VL53L1_ERROR_NONE;
01780 
01781     LOG_FUNCTION_START("");
01782 
01783     Status = VL53L1_is_new_data_ready(Dev, pMeasurementDataReady);
01784 
01785     LOG_FUNCTION_END(Status);
01786     return Status;
01787 }
01788 
01789 VL53L1_Error VL53L1_WaitMeasurementDataReady(VL53L1_DEV Dev)
01790 {
01791     VL53L1_Error Status = VL53L1_ERROR_NONE;
01792 
01793     LOG_FUNCTION_START("");
01794 
01795 
01796 
01797     Status = VL53L1_poll_for_range_completion(Dev,
01798             VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
01799 
01800     LOG_FUNCTION_END(Status);
01801     return Status;
01802 }
01803 
01804 static void GenNewPresetMode(int16_t RefRange,
01805         VL53L1_DistanceModes InternalDistanceMode,
01806         VL53L1_DistanceModes *pNewDistanceMode)
01807 {
01808     uint16_t HRLI = 600;
01809     uint16_t HRLH = 700;
01810     uint16_t MRLI = 1400;
01811     uint16_t MRLH = 1500;
01812 
01813     switch (InternalDistanceMode) {
01814     case VL53L1_DISTANCEMODE_SHORT:
01815 
01816         if (RefRange > MRLH)
01817             *pNewDistanceMode = VL53L1_DISTANCEMODE_LONG;
01818         else if (RefRange > HRLH)
01819             *pNewDistanceMode = VL53L1_DISTANCEMODE_MEDIUM;
01820         break;
01821     case VL53L1_DISTANCEMODE_MEDIUM:
01822 
01823         if (RefRange > MRLH)
01824             *pNewDistanceMode = VL53L1_DISTANCEMODE_LONG;
01825         else if (RefRange < HRLI)
01826             *pNewDistanceMode = VL53L1_DISTANCEMODE_SHORT;
01827         break;
01828     default:
01829 
01830         if (RefRange < HRLI)
01831             *pNewDistanceMode = VL53L1_DISTANCEMODE_SHORT;
01832         else if (RefRange < MRLI)
01833             *pNewDistanceMode = VL53L1_DISTANCEMODE_MEDIUM;
01834         break;
01835     }
01836 }
01837 
01838 static void CheckAndChangeDistanceMode(VL53L1_DEV Dev,
01839         VL53L1_TargetRangeData_t *pRangeData,
01840         int16_t Ambient100DmaxMm,
01841         VL53L1_DistanceModes *pNewDistanceMode
01842 )
01843 {
01844     VL53L1_DistanceModes DistanceMode;
01845     uint8_t RangeStatus = pRangeData->RangeStatus ;
01846     uint8_t DmaxValid;
01847     int32_t MinAmbient = BDTable[VL53L1_TUNING_MIN_AMBIENT_DMAX_VALID];
01848     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01849     int32_t  tmpint32;
01850 
01851 
01852     switch (RangeStatus) {
01853     case VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL:
01854     case VL53L1_RANGESTATUS_WRAP_TARGET_FAIL:
01855     case VL53L1_RANGESTATUS_RANGE_VALID_MERGED_PULSE:
01856     case VL53L1_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL:
01857     case VL53L1_RANGESTATUS_SYNCRONISATION_INT:
01858     case VL53L1_RANGESTATUS_NONE:
01859         return;
01860     default:
01861 
01862         break;
01863     }
01864 
01865     DmaxValid = 1;
01866     tmpint32 = pdev->hist_data.VL53L1_p_004;
01867     if ((tmpint32 < MinAmbient) || (Ambient100DmaxMm == 0))
01868         DmaxValid = 0;
01869 
01870     DistanceMode = VL53L1DevDataGet(Dev,
01871             CurrentParameters.DistanceMode);
01872 
01873     *pNewDistanceMode = DistanceMode;
01874 
01875     if (RangeStatus == VL53L1_RANGESTATUS_RANGE_VALID)
01876         GenNewPresetMode(pRangeData->RangeMilliMeter ,
01877                 DistanceMode, pNewDistanceMode);
01878     else {
01879         if (DmaxValid)
01880             GenNewPresetMode(Ambient100DmaxMm,
01881                     DistanceMode, pNewDistanceMode);
01882         else
01883             *pNewDistanceMode = VL53L1_DISTANCEMODE_LONG;
01884     }
01885 }
01886 
01887 static uint8_t ComputeRQL(uint8_t active_results,
01888         uint8_t FilteredRangeStatus,
01889         VL53L1_range_data_t *presults_data)
01890 {
01891     int16_t T_Wide = 150;
01892     int16_t SRL = 300;
01893     uint16_t SRAS = 30;
01894     FixPoint1616_t RAS;
01895     FixPoint1616_t SRQL;
01896     FixPoint1616_t GI =   7713587;
01897     FixPoint1616_t GGm =  3198157;
01898     FixPoint1616_t LRAP = 6554;
01899     FixPoint1616_t partial;
01900     uint8_t finalvalue;
01901     uint8_t returnvalue;
01902 
01903     if (active_results == 0)
01904         returnvalue = 0;
01905     else if (((presults_data->max_range_mm -
01906             presults_data->min_range_mm) >= T_Wide) ||
01907         (FilteredRangeStatus == VL53L1_DEVICEERROR_PHASECONSISTENCY))
01908         returnvalue = 50;
01909     else {
01910         if (presults_data->median_range_mm < SRL)
01911             RAS = SRAS * 65536;
01912         else
01913             RAS = LRAP * presults_data->median_range_mm;
01914 
01915 
01916         if (RAS != 0) {
01917             partial = (GGm * presults_data->VL53L1_p_005);
01918             partial = partial + (RAS >> 1);
01919             partial = partial / RAS;
01920             partial = partial * 65536;
01921             if (partial <= GI)
01922                 SRQL = GI - partial;
01923             else
01924                 SRQL = 50 * 65536;
01925         } else
01926             SRQL = 100 * 65536;
01927 
01928         finalvalue = (uint8_t)(SRQL >> 16);
01929         returnvalue = MAX(50, MIN(100, finalvalue));
01930     }
01931 
01932     return returnvalue;
01933 }
01934 
01935 
01936 static uint8_t ConvertStatusLite(uint8_t FilteredRangeStatus)
01937 {
01938     uint8_t RangeStatus;
01939 
01940     switch (FilteredRangeStatus) {
01941     case VL53L1_DEVICEERROR_GPHSTREAMCOUNT0READY:
01942         RangeStatus = VL53L1_RANGESTATUS_SYNCRONISATION_INT;
01943         break;
01944     case VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK:
01945         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL;
01946         break;
01947     case VL53L1_DEVICEERROR_RANGEPHASECHECK:
01948         RangeStatus = VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL;
01949         break;
01950     case VL53L1_DEVICEERROR_MSRCNOTARGET:
01951         RangeStatus = VL53L1_RANGESTATUS_SIGNAL_FAIL;
01952         break;
01953     case VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK:
01954         RangeStatus = VL53L1_RANGESTATUS_SIGMA_FAIL;
01955         break;
01956     case VL53L1_DEVICEERROR_PHASECONSISTENCY:
01957         RangeStatus = VL53L1_RANGESTATUS_WRAP_TARGET_FAIL;
01958         break;
01959     case VL53L1_DEVICEERROR_RANGEIGNORETHRESHOLD:
01960         RangeStatus = VL53L1_RANGESTATUS_XTALK_SIGNAL_FAIL;
01961         break;
01962     case VL53L1_DEVICEERROR_MINCLIP:
01963         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_MIN_RANGE_CLIPPED;
01964         break;
01965     case VL53L1_DEVICEERROR_RANGECOMPLETE:
01966         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID;
01967         break;
01968     default:
01969         RangeStatus = VL53L1_RANGESTATUS_NONE;
01970     }
01971 
01972     return RangeStatus;
01973 }
01974 
01975 
01976 static uint8_t ConvertStatusHisto(uint8_t FilteredRangeStatus)
01977 {
01978     uint8_t RangeStatus;
01979 
01980     switch (FilteredRangeStatus) {
01981     case VL53L1_DEVICEERROR_RANGEPHASECHECK:
01982         RangeStatus = VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL;
01983         break;
01984     case VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK:
01985         RangeStatus = VL53L1_RANGESTATUS_SIGMA_FAIL;
01986         break;
01987     case VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK:
01988         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL;
01989         break;
01990     case VL53L1_DEVICEERROR_PHASECONSISTENCY:
01991         RangeStatus = VL53L1_RANGESTATUS_WRAP_TARGET_FAIL;
01992         break;
01993     case VL53L1_DEVICEERROR_PREV_RANGE_NO_TARGETS:
01994         RangeStatus = VL53L1_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL;
01995         break;
01996     case VL53L1_DEVICEERROR_EVENTCONSISTENCY:
01997         RangeStatus = VL53L1_RANGESTATUS_WRAP_TARGET_FAIL;
01998         break;
01999     case VL53L1_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE:
02000         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID_MERGED_PULSE;
02001         break;
02002     case VL53L1_DEVICEERROR_RANGECOMPLETE:
02003         RangeStatus = VL53L1_RANGESTATUS_RANGE_VALID;
02004         break;
02005     default:
02006         RangeStatus = VL53L1_RANGESTATUS_NONE;
02007     }
02008 
02009     return RangeStatus;
02010 }
02011 
02012 static VL53L1_Error SetSimpleData(VL53L1_DEV Dev,
02013     uint8_t active_results, uint8_t device_status,
02014     VL53L1_range_data_t *presults_data,
02015     VL53L1_RangingMeasurementData_t *pRangeData)
02016 {
02017     VL53L1_Error Status = VL53L1_ERROR_NONE;
02018     uint8_t FilteredRangeStatus;
02019     uint8_t SigmaLimitflag;
02020     uint8_t SignalLimitflag;
02021     uint8_t Temp8Enable;
02022     uint8_t Temp8;
02023     FixPoint1616_t AmbientRate;
02024     FixPoint1616_t SignalRate;
02025     FixPoint1616_t TempFix1616;
02026     FixPoint1616_t LimitCheckValue;
02027     VL53L1_PresetModes PresetMode;
02028     int16_t Range;
02029 
02030     pRangeData->TimeStamp  = presults_data->time_stamp;
02031 
02032     FilteredRangeStatus = presults_data->range_status & 0x1F;
02033 
02034     pRangeData->RangeQualityLevel  = ComputeRQL(active_results,
02035                     FilteredRangeStatus,
02036                     presults_data);
02037 
02038     SignalRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
02039         presults_data->peak_signal_count_rate_mcps);
02040     pRangeData->SignalRateRtnMegaCps 
02041         = SignalRate;
02042 
02043     AmbientRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
02044         presults_data->ambient_count_rate_mcps);
02045     pRangeData->AmbientRateRtnMegaCps  = AmbientRate;
02046 
02047     pRangeData->EffectiveSpadRtnCount  =
02048         presults_data->VL53L1_p_006;
02049 
02050     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02051             presults_data->VL53L1_p_005);
02052 
02053     pRangeData->SigmaMilliMeter  = TempFix1616;
02054 
02055     pRangeData->RangeMilliMeter  = presults_data->median_range_mm;
02056 
02057     pRangeData->RangeFractionalPart  = 0;
02058 
02059 
02060     switch (device_status) {
02061     case VL53L1_DEVICEERROR_MULTCLIPFAIL:
02062     case VL53L1_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
02063     case VL53L1_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
02064     case VL53L1_DEVICEERROR_NOVHVVALUEFOUND:
02065         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_HARDWARE_FAIL;
02066         break;
02067     case VL53L1_DEVICEERROR_USERROICLIP:
02068         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_MIN_RANGE_FAIL;
02069         break;
02070     default:
02071         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_RANGE_VALID;
02072     }
02073 
02074 
02075     if (pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) {
02076         PresetMode = VL53L1DevDataGet(Dev,
02077                 CurrentParameters.PresetMode);
02078         if ((PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING) ||
02079             (PresetMode == VL53L1_PRESETMODE_RANGING) ||
02080             (PresetMode == VL53L1_PRESETMODE_PROXY_RANGING_MODE))
02081             pRangeData->RangeStatus  =
02082                 ConvertStatusHisto(FilteredRangeStatus);
02083         else
02084             pRangeData->RangeStatus  =
02085                 ConvertStatusLite(FilteredRangeStatus);
02086     }
02087 
02088 
02089     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02090             presults_data->VL53L1_p_005);
02091     VL53L1_SETARRAYPARAMETERFIELD(Dev,
02092         LimitChecksCurrent, VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02093         TempFix1616);
02094 
02095     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02096             presults_data->peak_signal_count_rate_mcps);
02097     VL53L1_SETARRAYPARAMETERFIELD(Dev,
02098         LimitChecksCurrent, VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02099         TempFix1616);
02100 
02101 
02102 
02103     VL53L1_GetLimitCheckValue(Dev,
02104             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02105             &LimitCheckValue);
02106 
02107     SigmaLimitflag = (FilteredRangeStatus ==
02108             VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK)
02109             ? 1 : 0;
02110 
02111     VL53L1_GetLimitCheckEnable(Dev,
02112             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02113             &Temp8Enable);
02114 
02115     Temp8 = ((Temp8Enable == 1) && (SigmaLimitflag == 1)) ? 1 : 0;
02116     VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
02117             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE, Temp8);
02118 
02119 
02120     VL53L1_GetLimitCheckValue(Dev,
02121             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02122             &LimitCheckValue);
02123 
02124     SignalLimitflag = (FilteredRangeStatus ==
02125             VL53L1_DEVICEERROR_MSRCNOTARGET)
02126             ? 1 : 0;
02127 
02128     VL53L1_GetLimitCheckEnable(Dev,
02129             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02130             &Temp8Enable);
02131 
02132     Temp8 = ((Temp8Enable == 1) && (SignalLimitflag == 1)) ? 1 : 0;
02133     VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
02134             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, Temp8);
02135 
02136     Range = pRangeData->RangeMilliMeter ;
02137     if ((pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) &&
02138         (Range < 0)) {
02139         if (Range < BDTable[VL53L1_TUNING_PROXY_MIN])
02140             pRangeData->RangeStatus  =
02141                     VL53L1_RANGESTATUS_RANGE_INVALID;
02142         else
02143             pRangeData->RangeMilliMeter  = 0;
02144     }
02145 
02146     return Status;
02147 }
02148 
02149 static VL53L1_Error SetTargetData(VL53L1_DEV Dev,
02150     uint8_t active_results, uint8_t streamcount, uint8_t iteration,
02151     uint8_t device_status, VL53L1_range_data_t *presults_data,
02152     VL53L1_TargetRangeData_t *pRangeData)
02153 {
02154     VL53L1_Error Status = VL53L1_ERROR_NONE;
02155     VL53L1_LLDriverData_t *pdev =
02156             VL53L1DevStructGetLLDriverHandle(Dev);
02157     VL53L1_tuning_parm_storage_t *tp =
02158             &(pdev->tuning_parms);
02159     uint8_t sequency;
02160     uint8_t FilteredRangeStatus;
02161     uint8_t SigmaLimitflag;
02162     uint8_t SignalLimitflag;
02163     uint8_t Temp8Enable;
02164     uint8_t Temp8;
02165     FixPoint1616_t AmbientRate;
02166     FixPoint1616_t SignalRate;
02167     FixPoint1616_t TempFix1616;
02168     FixPoint1616_t LimitCheckValue;
02169     VL53L1_PresetModes PresetMode;
02170     int16_t Range, RangeDiff, RangeMillimeterInit;
02171     int32_t ExtendedRangeEnabled = 0;
02172     uint8_t uwr_status;
02173     int16_t AddOffset;
02174 
02175     FilteredRangeStatus = presults_data->range_status & 0x1F;
02176 
02177     pRangeData->RangeQualityLevel  = ComputeRQL(active_results,
02178                     FilteredRangeStatus,
02179                     presults_data);
02180 
02181     SignalRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
02182         presults_data->peak_signal_count_rate_mcps);
02183     pRangeData->SignalRateRtnMegaCps 
02184         = SignalRate;
02185 
02186     AmbientRate = VL53L1_FIXPOINT97TOFIXPOINT1616(
02187         presults_data->ambient_count_rate_mcps);
02188     pRangeData->AmbientRateRtnMegaCps  = AmbientRate;
02189 
02190     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02191             presults_data->VL53L1_p_005);
02192 
02193     pRangeData->SigmaMilliMeter  = TempFix1616;
02194 
02195     pRangeData->RangeMilliMeter  = presults_data->median_range_mm;
02196     pRangeData->RangeMaxMilliMeter  = presults_data->max_range_mm;
02197     pRangeData->RangeMinMilliMeter  = presults_data->min_range_mm;
02198 
02199     pRangeData->RangeFractionalPart  = 0;
02200 
02201 
02202     switch (device_status) {
02203     case VL53L1_DEVICEERROR_MULTCLIPFAIL:
02204     case VL53L1_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
02205     case VL53L1_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
02206     case VL53L1_DEVICEERROR_NOVHVVALUEFOUND:
02207         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_HARDWARE_FAIL;
02208         break;
02209     case VL53L1_DEVICEERROR_USERROICLIP:
02210         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_MIN_RANGE_FAIL;
02211         break;
02212     default:
02213         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_RANGE_VALID;
02214     }
02215 
02216 
02217     if ((pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) &&
02218         (active_results == 0)) {
02219         pRangeData->RangeStatus  = VL53L1_RANGESTATUS_NONE;
02220         pRangeData->SignalRateRtnMegaCps  = 0;
02221         pRangeData->SigmaMilliMeter  = 0;
02222         pRangeData->RangeMilliMeter  = 8191;
02223         pRangeData->RangeMaxMilliMeter  = 8191;
02224         pRangeData->RangeMinMilliMeter  = 8191;
02225     }
02226 
02227 
02228     if (pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) {
02229         PresetMode = VL53L1DevDataGet(Dev,
02230                 CurrentParameters.PresetMode);
02231         if ((PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING) ||
02232             (PresetMode == VL53L1_PRESETMODE_RANGING) ||
02233             (PresetMode == VL53L1_PRESETMODE_PROXY_RANGING_MODE))
02234             pRangeData->RangeStatus  =
02235                 ConvertStatusHisto(FilteredRangeStatus);
02236         else
02237             pRangeData->RangeStatus  =
02238                 ConvertStatusLite(FilteredRangeStatus);
02239     }
02240 
02241 
02242     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02243             presults_data->VL53L1_p_005);
02244     VL53L1_SETARRAYPARAMETERFIELD(Dev,
02245         LimitChecksCurrent, VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02246         TempFix1616);
02247 
02248     TempFix1616 = VL53L1_FIXPOINT97TOFIXPOINT1616(
02249             presults_data->peak_signal_count_rate_mcps);
02250     VL53L1_SETARRAYPARAMETERFIELD(Dev,
02251         LimitChecksCurrent, VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02252         TempFix1616);
02253 
02254 
02255 
02256     VL53L1_GetLimitCheckValue(Dev,
02257             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02258             &LimitCheckValue);
02259 
02260     SigmaLimitflag = (FilteredRangeStatus ==
02261             VL53L1_DEVICEERROR_SIGMATHRESHOLDCHECK)
02262             ? 1 : 0;
02263 
02264     VL53L1_GetLimitCheckEnable(Dev,
02265             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,
02266             &Temp8Enable);
02267 
02268     Temp8 = ((Temp8Enable == 1) && (SigmaLimitflag == 1)) ? 1 : 0;
02269     VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
02270             VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE, Temp8);
02271 
02272 
02273     VL53L1_GetLimitCheckValue(Dev,
02274             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02275             &LimitCheckValue);
02276 
02277     SignalLimitflag = (FilteredRangeStatus ==
02278             VL53L1_DEVICEERROR_MSRCNOTARGET)
02279             ? 1 : 0;
02280 
02281     VL53L1_GetLimitCheckEnable(Dev,
02282             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
02283             &Temp8Enable);
02284 
02285     Temp8 = ((Temp8Enable == 1) && (SignalLimitflag == 1)) ? 1 : 0;
02286     VL53L1_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus,
02287             VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, Temp8);
02288 
02289     Range = pRangeData->RangeMilliMeter ;
02290     if ((pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID) &&
02291         (Range < 0)) {
02292         if (Range < BDTable[VL53L1_TUNING_PROXY_MIN])
02293             pRangeData->RangeStatus  =
02294                     VL53L1_RANGESTATUS_RANGE_INVALID;
02295         else
02296             pRangeData->RangeMilliMeter  = 0;
02297     }
02298 
02299 
02300 
02301     VL53L1_get_tuning_parm(Dev, VL53L1_TUNINGPARM_UWR_ENABLE,
02302             &ExtendedRangeEnabled);
02303 
02304     sequency = streamcount % 2;
02305     uwr_status = 0;
02306     RangeMillimeterInit = pRangeData->RangeMilliMeter ;
02307     AddOffset = 0;
02308 
02309     pRangeData->ExtendedRange  = 0;
02310 
02311     if (ExtendedRangeEnabled &&
02312         (pRangeData->RangeStatus  ==
02313             VL53L1_RANGESTATUS_WRAP_TARGET_FAIL ||
02314             pRangeData->RangeStatus  ==
02315             VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL)
02316         && (pdev->PreviousRangeStatus[iteration] ==
02317             VL53L1_RANGESTATUS_WRAP_TARGET_FAIL ||
02318             pdev->PreviousRangeStatus[iteration] ==
02319             VL53L1_RANGESTATUS_OUTOFBOUNDS_FAIL ||
02320             (pdev->PreviousRangeStatus[iteration] ==
02321             VL53L1_RANGESTATUS_RANGE_VALID &&
02322             pdev->PreviousExtendedRange[iteration] == 1)))
02323     {
02324         if (((pdev->PreviousStreamCount) ==
02325             (pdev->hist_data.result__stream_count - 1 ))
02326         || ((pdev->PreviousStreamCount) ==
02327             (pdev->hist_data.result__stream_count + 127)))
02328         {
02329         RangeDiff = pRangeData->RangeMilliMeter  -
02330             pdev->PreviousRangeMilliMeter[iteration];
02331 
02332         uwr_status = 1;
02333         switch (pdev->preset_mode) {
02334             case VL53L1_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
02335 
02336                 uwr_status = 0;
02337                 break;
02338 
02339             case VL53L1_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE:
02340                 if (RangeDiff > tp->tp_uwr_med_z_1_min &&
02341                     RangeDiff < tp->tp_uwr_med_z_1_max &&
02342                     sequency == 1) {
02343                     AddOffset =
02344                     tp->tp_uwr_med_corr_z_1_rangeb;
02345                 }
02346                 else
02347                 if (RangeDiff < -tp->tp_uwr_med_z_1_min &&
02348                     RangeDiff > -tp->tp_uwr_med_z_1_max &&
02349                     sequency == 0) {
02350                     AddOffset =
02351                     tp->tp_uwr_med_corr_z_1_rangea;
02352                 }
02353                 else
02354                 if (RangeDiff > tp->tp_uwr_med_z_2_min &&
02355                     RangeDiff < tp->tp_uwr_med_z_2_max &&
02356                     sequency == 0) {
02357                     AddOffset =
02358                     tp->tp_uwr_med_corr_z_2_rangea;
02359                 }
02360                 else
02361                 if (RangeDiff < -tp->tp_uwr_med_z_2_min &&
02362                     RangeDiff > -tp->tp_uwr_med_z_2_max &&
02363                     sequency == 1) {
02364                     AddOffset =
02365                     tp->tp_uwr_med_corr_z_2_rangeb;
02366                 }
02367                 else
02368                 if (RangeDiff > tp->tp_uwr_med_z_3_min &&
02369                     RangeDiff < tp->tp_uwr_med_z_3_max &&
02370                     sequency == 1) {
02371                     AddOffset =
02372                     tp->tp_uwr_med_corr_z_3_rangeb;
02373                 }
02374                 else
02375                 if (RangeDiff < -tp->tp_uwr_med_z_3_min &&
02376                     RangeDiff > -tp->tp_uwr_med_z_3_max &&
02377                     sequency == 0) {
02378                     AddOffset =
02379                     tp->tp_uwr_med_corr_z_3_rangea;
02380                 }
02381                 else
02382                 if (RangeDiff > tp->tp_uwr_med_z_4_min &&
02383                     RangeDiff < tp->tp_uwr_med_z_4_max &&
02384                     sequency == 0) {
02385                     AddOffset =
02386                     tp->tp_uwr_med_corr_z_4_rangea;
02387                 }
02388                 else
02389                 if (RangeDiff < -tp->tp_uwr_med_z_4_min &&
02390                     RangeDiff > -tp->tp_uwr_med_z_4_max &&
02391                     sequency == 1) {
02392                     AddOffset =
02393                     tp->tp_uwr_med_corr_z_4_rangeb;
02394                 }
02395                 else
02396                 if (RangeDiff < tp->tp_uwr_med_z_5_max &&
02397                     RangeDiff > tp->tp_uwr_med_z_5_min) {
02398                     AddOffset =
02399                     tp->tp_uwr_med_corr_z_5_rangea;
02400                 }
02401                 else
02402                 if (RangeDiff > tp->tp_uwr_med_z_6_min &&
02403                     RangeDiff < tp->tp_uwr_med_z_6_max &&
02404                     sequency == 1) {
02405                     AddOffset =
02406                     tp->tp_uwr_med_corr_z_6_rangeb;
02407                 }
02408                 else
02409                 if (RangeDiff < -tp->tp_uwr_med_z_6_min &&
02410                     RangeDiff > -tp->tp_uwr_med_z_6_max &&
02411                     sequency == 0) {
02412                     AddOffset =
02413                     tp->tp_uwr_med_corr_z_6_rangea;
02414                 }
02415                 else
02416 
02417 
02418 
02419 
02420 
02421 
02422 
02423 
02424 
02425 
02426 
02427                     uwr_status = 0;
02428                 break;
02429 
02430             case VL53L1_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE:
02431                 if (RangeDiff > tp->tp_uwr_lng_z_1_min &&
02432                     RangeDiff < tp->tp_uwr_lng_z_1_max &&
02433                     sequency == 0) {
02434                     AddOffset =
02435                     tp->tp_uwr_lng_corr_z_1_rangea;
02436                 }
02437                 else
02438                 if (RangeDiff < -tp->tp_uwr_lng_z_1_min &&
02439                     RangeDiff > -tp->tp_uwr_lng_z_1_max &&
02440                     sequency == 1) {
02441                     AddOffset =
02442                     tp->tp_uwr_lng_corr_z_1_rangeb;
02443                 }
02444                 else
02445                 if (RangeDiff > tp->tp_uwr_lng_z_2_min &&
02446                     RangeDiff < tp->tp_uwr_lng_z_2_max &&
02447                     sequency == 1) {
02448                     AddOffset =
02449                     tp->tp_uwr_lng_corr_z_2_rangeb;
02450                 }
02451                 else
02452                 if (RangeDiff < -tp->tp_uwr_lng_z_2_min &&
02453                     RangeDiff > -tp->tp_uwr_lng_z_2_max &&
02454                     sequency == 0) {
02455                     AddOffset =
02456                     tp->tp_uwr_lng_corr_z_2_rangea;
02457                 }
02458                 else
02459                 if (RangeDiff < tp->tp_uwr_lng_z_3_max &&
02460                     RangeDiff > tp->tp_uwr_lng_z_3_min) {
02461                     AddOffset =
02462                     tp->tp_uwr_lng_corr_z_3_rangea;
02463                 }
02464                 else
02465                 if (RangeDiff > tp->tp_uwr_lng_z_4_min &&
02466                     RangeDiff < tp->tp_uwr_lng_z_4_max &&
02467                     sequency == 1) {
02468                     AddOffset =
02469                     tp->tp_uwr_lng_corr_z_4_rangeb;
02470                 }
02471                 else
02472                 if (RangeDiff < -tp->tp_uwr_lng_z_4_min &&
02473                     RangeDiff > -tp->tp_uwr_lng_z_4_max &&
02474                     sequency == 0) {
02475                     AddOffset =
02476                     tp->tp_uwr_lng_corr_z_4_rangea;
02477                 }
02478                 else
02479                     uwr_status = 0;
02480                 break;
02481 
02482             default:
02483                 uwr_status = 0;
02484                 break;
02485             }
02486         }
02487 
02488         if (uwr_status) {
02489             pRangeData->RangeMilliMeter  += AddOffset;
02490             pRangeData->RangeMinMilliMeter  += AddOffset;
02491             pRangeData->RangeMaxMilliMeter  += AddOffset;
02492             pRangeData->ExtendedRange  = 1;
02493             pRangeData->RangeStatus  = 0;
02494         }
02495 
02496     }
02497 
02498     pdev->PreviousRangeMilliMeter[iteration] = RangeMillimeterInit;
02499     pdev->PreviousRangeStatus[iteration] = pRangeData->RangeStatus ;
02500     pdev->PreviousExtendedRange[iteration] = pRangeData->ExtendedRange ;
02501 
02502     return Status;
02503 }
02504 
02505 static uint8_t GetOutputDataIndex(VL53L1_DEV Dev,
02506     VL53L1_range_results_t *presults)
02507 {
02508     uint8_t i;
02509     uint8_t index = 0;
02510     VL53L1_OutputModes OutputMode;
02511 
02512     OutputMode = VL53L1DevDataGet(Dev, CurrentParameters.OutputMode);
02513 
02514 
02515     if (OutputMode == VL53L1_OUTPUTMODE_NEAREST)
02516         return 0;
02517 
02518 
02519     for (i = 1; i < presults->active_results; i++) {
02520         if (presults->VL53L1_p_002[i].peak_signal_count_rate_mcps >
02521         presults->VL53L1_p_002[index].peak_signal_count_rate_mcps)
02522             index = i;
02523     }
02524 
02525     return index;
02526 }
02527 
02528 VL53L1_Error VL53L1_GetRangingMeasurementData(VL53L1_DEV Dev,
02529     VL53L1_RangingMeasurementData_t *pRangingMeasurementData)
02530 {
02531     VL53L1_Error Status = VL53L1_ERROR_NONE;
02532     VL53L1_LLDriverData_t *pdev =
02533             VL53L1DevStructGetLLDriverHandle(Dev);
02534     VL53L1_range_results_t *presults =
02535             (VL53L1_range_results_t *) pdev->wArea1;
02536     VL53L1_range_data_t *presults_data;
02537     VL53L1_PresetModes PresetMode;
02538     uint8_t index = 0;
02539 
02540     LOG_FUNCTION_START("");
02541 
02542 
02543     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
02544 
02545     if (PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING) {
02546         Status = VL53L1_ERROR_MODE_NOT_SUPPORTED;
02547         LOG_FUNCTION_END(Status);
02548         return Status;
02549     }
02550 
02551 
02552     memset(pRangingMeasurementData, 0xFF,
02553         sizeof(VL53L1_RangingMeasurementData_t));
02554 
02555 
02556     Status = VL53L1_get_device_results(
02557             Dev,
02558             VL53L1_DEVICERESULTSLEVEL_FULL,
02559             presults);
02560 
02561     if (Status == VL53L1_ERROR_NONE) {
02562         pRangingMeasurementData->StreamCount  = presults->stream_count;
02563 
02564 
02565         index = GetOutputDataIndex(Dev, presults);
02566         presults_data = &(presults->VL53L1_p_002[index]);
02567         Status = SetSimpleData(Dev, presults->active_results,
02568                 presults->device_status,
02569                 presults_data,
02570                 pRangingMeasurementData);
02571     }
02572 
02573     LOG_FUNCTION_END(Status);
02574     return Status;
02575 }
02576 
02577 static VL53L1_Error SetMeasurementData(VL53L1_DEV Dev,
02578     VL53L1_range_results_t *presults,
02579     VL53L1_MultiRangingData_t *pMultiRangingData)
02580 {
02581     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
02582     uint8_t i;
02583     uint8_t iteration;
02584     VL53L1_TargetRangeData_t *pRangeData;
02585     VL53L1_range_data_t *presults_data;
02586     int16_t dmax_min;
02587     VL53L1_Error Status = VL53L1_ERROR_NONE;
02588     uint8_t Furthest_idx = 0;
02589     int16_t Furthest_range = 0;
02590     uint8_t ActiveResults, amb_idx;
02591 
02592     pMultiRangingData->NumberOfObjectsFound  = presults->active_results;
02593     pMultiRangingData->RoiNumber  = presults->zone_id;
02594     pMultiRangingData->HasXtalkValueChanged  =
02595             presults->smudge_corrector_data.new_xtalk_applied_flag;
02596     dmax_min = MIN(presults->wrap_dmax_mm,
02597             presults->VL53L1_p_007[DMAX_REFLECTANCE_IDX]);
02598     pMultiRangingData->DmaxMilliMeter  = dmax_min;
02599 
02600 
02601     pMultiRangingData->TimeStamp  = 0;
02602 
02603     pMultiRangingData->StreamCount  = presults->stream_count;
02604 
02605     pMultiRangingData->RecommendedDistanceMode  =
02606         VL53L1DevDataGet(Dev, CurrentParameters.DistanceMode);
02607     ActiveResults = presults->active_results;
02608     if (ActiveResults < 1)
02609 
02610         iteration = 1;
02611     else
02612         iteration = ActiveResults;
02613     for (i = 0; i < iteration; i++) {
02614         pRangeData = &(pMultiRangingData->RangeData [i]);
02615 
02616         presults_data = &(presults->VL53L1_p_002[i]);
02617         if (Status == VL53L1_ERROR_NONE)
02618             Status = SetTargetData(Dev, ActiveResults,
02619                     pMultiRangingData->StreamCount ,
02620                     i,
02621                     presults->device_status,
02622                     presults_data,
02623                     pRangeData);
02624 
02625         pMultiRangingData->EffectiveSpadRtnCount  =
02626                 presults_data->VL53L1_p_006;
02627 
02628         if ((pRangeData->RangeStatus  == VL53L1_RANGESTATUS_RANGE_VALID)
02629             && (pRangeData->RangeMilliMeter  > Furthest_range)) {
02630             Furthest_range = pRangeData->RangeMilliMeter ;
02631             Furthest_idx = i;
02632         }
02633     }
02634     pdev->PreviousStreamCount = pdev->hist_data.result__stream_count;
02635     for (i = iteration; i < VL53L1_MAX_RANGE_RESULTS; i++) {
02636         pdev->PreviousRangeMilliMeter[i] = 0;
02637         pdev->PreviousRangeStatus[i] = 255;
02638         pdev->PreviousExtendedRange[i] = 0;
02639     }
02640 
02641     if ((Status == VL53L1_ERROR_NONE) && (ActiveResults > 0)) {
02642         pRangeData = &(pMultiRangingData->RangeData [Furthest_idx]);
02643         amb_idx = VL53L1_MAX_AMBIENT_DMAX_VALUES-1;
02644         CheckAndChangeDistanceMode(Dev, pRangeData,
02645             presults->VL53L1_p_007[amb_idx],
02646             &pMultiRangingData->RecommendedDistanceMode );
02647     }
02648 
02649     return Status;
02650 }
02651 
02652 VL53L1_Error VL53L1_GetMultiRangingData(VL53L1_DEV Dev,
02653         VL53L1_MultiRangingData_t *pMultiRangingData)
02654 {
02655     VL53L1_Error Status = VL53L1_ERROR_NONE;
02656     VL53L1_LLDriverData_t *pdev =
02657             VL53L1DevStructGetLLDriverHandle(Dev);
02658     VL53L1_range_results_t *presults =
02659             (VL53L1_range_results_t *) pdev->wArea1;
02660 
02661     LOG_FUNCTION_START("");
02662 
02663 
02664     memset(pMultiRangingData, 0xFF,
02665         sizeof(VL53L1_MultiRangingData_t));
02666 
02667 
02668     Status = VL53L1_get_device_results(
02669                 Dev,
02670                 VL53L1_DEVICERESULTSLEVEL_FULL,
02671                 presults);
02672 
02673 
02674     if (Status == VL53L1_ERROR_NONE) {
02675         switch (presults->rd_device_state) {
02676         case VL53L1_DEVICESTATE_RANGING_GATHER_DATA:
02677             pMultiRangingData->RoiStatus  =
02678                     VL53L1_ROISTATUS_VALID_NOT_LAST;
02679             break;
02680         case VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA:
02681             pMultiRangingData->RoiStatus  =
02682                     VL53L1_ROISTATUS_VALID_LAST;
02683             break;
02684         default:
02685             pMultiRangingData->RoiStatus  =
02686                     VL53L1_ROISTATUS_NOT_VALID;
02687         }
02688 
02689         Status = SetMeasurementData(Dev,
02690                     presults,
02691                     pMultiRangingData);
02692 
02693     }
02694 
02695     LOG_FUNCTION_END(Status);
02696     return Status;
02697 }
02698 
02699 VL53L1_Error VL53L1_GetAdditionalData(VL53L1_DEV Dev,
02700         VL53L1_AdditionalData_t *pAdditionalData)
02701 {
02702     VL53L1_Error Status = VL53L1_ERROR_NONE;
02703 
02704     LOG_FUNCTION_START("");
02705 
02706     Status = VL53L1_get_additional_data(Dev, pAdditionalData);
02707 
02708     LOG_FUNCTION_END(Status);
02709     return Status;
02710 }
02711 
02712 
02713 
02714 
02715 
02716 
02717 VL53L1_Error VL53L1_SetTuningParameter(VL53L1_DEV Dev,
02718         uint16_t TuningParameterId, int32_t TuningParameterValue)
02719 {
02720     VL53L1_Error Status = VL53L1_ERROR_NONE;
02721 
02722     LOG_FUNCTION_START("");
02723 
02724     if (TuningParameterId ==
02725         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS)
02726         return VL53L1_ERROR_INVALID_PARAMS;
02727 
02728     if (TuningParameterId >= 32768)
02729         Status = VL53L1_set_tuning_parm(Dev,
02730             TuningParameterId,
02731             TuningParameterValue);
02732     else {
02733         if (TuningParameterId < VL53L1_TUNING_MAX_TUNABLE_KEY)
02734             BDTable[TuningParameterId] = TuningParameterValue;
02735         else
02736             Status = VL53L1_ERROR_INVALID_PARAMS;
02737     }
02738 
02739     LOG_FUNCTION_END(Status);
02740     return Status;
02741 }
02742 
02743 VL53L1_Error VL53L1_GetTuningParameter(VL53L1_DEV Dev,
02744         uint16_t TuningParameterId, int32_t *pTuningParameterValue)
02745 {
02746     VL53L1_Error Status = VL53L1_ERROR_NONE;
02747 
02748     LOG_FUNCTION_START("");
02749 
02750     if (TuningParameterId >= 32768)
02751         Status = VL53L1_get_tuning_parm(Dev,
02752             TuningParameterId,
02753             pTuningParameterValue);
02754     else {
02755         if (TuningParameterId < VL53L1_TUNING_MAX_TUNABLE_KEY)
02756             *pTuningParameterValue = BDTable[TuningParameterId];
02757         else
02758             Status = VL53L1_ERROR_INVALID_PARAMS;
02759     }
02760 
02761     LOG_FUNCTION_END(Status);
02762     return Status;
02763 }
02764 
02765 
02766 VL53L1_Error VL53L1_PerformRefSpadManagement(VL53L1_DEV Dev)
02767 {
02768 #ifdef VL53L1_NOCALIB
02769     VL53L1_Error Status = VL53L1_ERROR_NOT_SUPPORTED;
02770 
02771     SUPPRESS_UNUSED_WARNING(Dev);
02772 
02773     LOG_FUNCTION_START("");
02774 #else
02775     VL53L1_Error Status = VL53L1_ERROR_NONE;
02776     VL53L1_Error RawStatus;
02777     uint8_t dcrbuffer[24];
02778     uint8_t *commbuf;
02779     uint8_t numloc[2] = {5, 3};
02780     VL53L1_LLDriverData_t *pdev;
02781     VL53L1_customer_nvm_managed_t *pc;
02782     VL53L1_PresetModes PresetMode;
02783 
02784     LOG_FUNCTION_START("");
02785 
02786     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
02787     pc = &pdev->customer;
02788 
02789     if (Status == VL53L1_ERROR_NONE) {
02790         PresetMode = VL53L1DevDataGet(Dev,
02791                 CurrentParameters.PresetMode);
02792         Status = VL53L1_run_ref_spad_char(Dev, &RawStatus);
02793 
02794         if (Status == VL53L1_ERROR_NONE)
02795             Status = VL53L1_SetPresetMode(Dev, PresetMode);
02796     }
02797 
02798     if (Status == VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH) {
02799 
02800         Status = VL53L1_read_nvm_raw_data(Dev,
02801                 (uint8_t)(0xA0 >> 2),
02802                 (uint8_t)(24 >> 2),
02803                 dcrbuffer);
02804 
02805         if (Status == VL53L1_ERROR_NONE)
02806             Status = VL53L1_WriteMulti(Dev,
02807                 VL53L1_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS,
02808                 numloc, 2);
02809 
02810         if (Status == VL53L1_ERROR_NONE) {
02811             pc->ref_spad_man__num_requested_ref_spads = numloc[0];
02812             pc->ref_spad_man__ref_location = numloc[1];
02813         }
02814 
02815         if (Status == VL53L1_ERROR_NONE)
02816             commbuf = &dcrbuffer[16];
02817 
02818 
02819 
02820         if (Status == VL53L1_ERROR_NONE)
02821             Status = VL53L1_WriteMulti(Dev,
02822                 VL53L1_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
02823                 commbuf, 6);
02824 
02825         if (Status == VL53L1_ERROR_NONE) {
02826             pc->global_config__spad_enables_ref_0 = commbuf[0];
02827             pc->global_config__spad_enables_ref_1 = commbuf[1];
02828             pc->global_config__spad_enables_ref_2 = commbuf[2];
02829             pc->global_config__spad_enables_ref_3 = commbuf[3];
02830             pc->global_config__spad_enables_ref_4 = commbuf[4];
02831             pc->global_config__spad_enables_ref_5 = commbuf[5];
02832         }
02833 
02834     }
02835 
02836 #endif
02837 
02838     LOG_FUNCTION_END(Status);
02839     return Status;
02840 }
02841 
02842 VL53L1_Error VL53L1_SmudgeCorrectionEnable(VL53L1_DEV Dev,
02843         VL53L1_SmudgeCorrectionModes Mode)
02844 {
02845     VL53L1_Error Status = VL53L1_ERROR_NONE;
02846     VL53L1_Error s1 = VL53L1_ERROR_NONE;
02847     VL53L1_Error s2 = VL53L1_ERROR_NONE;
02848     VL53L1_Error s3 = VL53L1_ERROR_NONE;
02849 
02850     LOG_FUNCTION_START("");
02851 
02852     switch (Mode) {
02853     case VL53L1_SMUDGE_CORRECTION_NONE:
02854         s1 = VL53L1_dynamic_xtalk_correction_disable(Dev);
02855         s2 = VL53L1_dynamic_xtalk_correction_apply_disable(Dev);
02856         s3 = VL53L1_dynamic_xtalk_correction_single_apply_disable(Dev);
02857         break;
02858     case VL53L1_SMUDGE_CORRECTION_CONTINUOUS:
02859         s1 = VL53L1_dynamic_xtalk_correction_enable(Dev);
02860         s2 = VL53L1_dynamic_xtalk_correction_apply_enable(Dev);
02861         s3 = VL53L1_dynamic_xtalk_correction_single_apply_disable(Dev);
02862         break;
02863     case VL53L1_SMUDGE_CORRECTION_SINGLE:
02864         s1 = VL53L1_dynamic_xtalk_correction_enable(Dev);
02865         s2 = VL53L1_dynamic_xtalk_correction_apply_enable(Dev);
02866         s3 = VL53L1_dynamic_xtalk_correction_single_apply_enable(Dev);
02867         break;
02868     case VL53L1_SMUDGE_CORRECTION_DEBUG:
02869         s1 = VL53L1_dynamic_xtalk_correction_enable(Dev);
02870         s2 = VL53L1_dynamic_xtalk_correction_apply_disable(Dev);
02871         s3 = VL53L1_dynamic_xtalk_correction_single_apply_disable(Dev);
02872         break;
02873     default:
02874         Status = VL53L1_ERROR_INVALID_PARAMS;
02875         break;
02876     }
02877 
02878     if (Status == VL53L1_ERROR_NONE) {
02879         Status = s1;
02880         if (Status == VL53L1_ERROR_NONE)
02881             Status = s2;
02882         if (Status == VL53L1_ERROR_NONE)
02883             Status = s3;
02884     }
02885 
02886     LOG_FUNCTION_END(Status);
02887     return Status;
02888 }
02889 
02890 VL53L1_Error VL53L1_SetXTalkCompensationEnable(VL53L1_DEV Dev,
02891     uint8_t XTalkCompensationEnable)
02892 {
02893     VL53L1_Error Status = VL53L1_ERROR_NONE;
02894 
02895     LOG_FUNCTION_START("");
02896 
02897     if (XTalkCompensationEnable == 0)
02898         Status = VL53L1_disable_xtalk_compensation(Dev);
02899     else
02900         Status = VL53L1_enable_xtalk_compensation(Dev);
02901 
02902     LOG_FUNCTION_END(Status);
02903     return Status;
02904 }
02905 
02906 
02907 VL53L1_Error VL53L1_GetXTalkCompensationEnable(VL53L1_DEV Dev,
02908     uint8_t *pXTalkCompensationEnable)
02909 {
02910     VL53L1_Error Status = VL53L1_ERROR_NONE;
02911 
02912     LOG_FUNCTION_START("");
02913 
02914     VL53L1_get_xtalk_compensation_enable(
02915         Dev,
02916         pXTalkCompensationEnable);
02917 
02918     LOG_FUNCTION_END(Status);
02919     return Status;
02920 }
02921 
02922 
02923 VL53L1_Error VL53L1_PerformXTalkCalibration(VL53L1_DEV Dev,
02924         uint8_t CalibrationOption)
02925 {
02926     VL53L1_Error Status = VL53L1_ERROR_NONE;
02927     VL53L1_Error UStatus;
02928     int16_t CalDistanceMm;
02929     VL53L1_xtalk_calibration_results_t xtalk;
02930 
02931     VL53L1_CalibrationData_t caldata;
02932     VL53L1_LLDriverData_t *pLLData;
02933     int i;
02934     uint32_t *pPlaneOffsetKcps;
02935     uint32_t Margin =
02936             BDTable[VL53L1_TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN];
02937     uint32_t DefaultOffset =
02938             BDTable[VL53L1_TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET];
02939     uint32_t *pLLDataPlaneOffsetKcps;
02940     uint32_t sum = 0;
02941     uint8_t binok = 0;
02942     int32_t merge;
02943 
02944     LOG_FUNCTION_START("");
02945 
02946     pPlaneOffsetKcps =
02947     &caldata.customer.algo__crosstalk_compensation_plane_offset_kcps;
02948     pLLData = VL53L1DevStructGetLLDriverHandle(Dev);
02949     pLLDataPlaneOffsetKcps =
02950     &pLLData->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps;
02951     VL53L1_get_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE, &merge);
02952 
02953     VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE, 0);
02954     switch (CalibrationOption) {
02955     case VL53L1_XTALKCALIBRATIONMODE_NO_TARGET:
02956         Status = VL53L1_run_xtalk_extraction(Dev, &UStatus);
02957 
02958         if (Status == VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL)
02959             VL53L1_xtalk_cal_data_init(Dev);
02960         break;
02961     case VL53L1_XTALKCALIBRATIONMODE_SINGLE_TARGET:
02962         Status = SingleTargetXTalkCalibration(Dev);
02963         break;
02964     case VL53L1_XTALKCALIBRATIONMODE_FULL_ROI:
02965         CalDistanceMm = (int16_t)
02966         BDTable[VL53L1_TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM];
02967 
02968         VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE,
02969                 merge);
02970         Status = VL53L1_run_hist_xtalk_extraction(Dev, CalDistanceMm,
02971                 &UStatus);
02972 
02973         VL53L1_GetCalibrationData(Dev, &caldata);
02974         for (i = 0; i < VL53L1_XTALK_HISTO_BINS; i++) {
02975             sum += caldata.xtalkhisto.xtalk_shape.bin_data[i];
02976             if (caldata.xtalkhisto.xtalk_shape.bin_data[i] > 0)
02977                 binok++;
02978         }
02979         if ((UStatus ==
02980             VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL) ||
02981             (sum > (1024 + Margin)) || (sum < (1024 - Margin)) ||
02982             (binok < 3)) {
02983             *pPlaneOffsetKcps = DefaultOffset;
02984             *pLLDataPlaneOffsetKcps = DefaultOffset;
02985             caldata.xtalkhisto.xtalk_shape.bin_data[0] = 307;
02986             caldata.xtalkhisto.xtalk_shape.bin_data[1] = 410;
02987             caldata.xtalkhisto.xtalk_shape.bin_data[2] = 410;
02988             caldata.xtalkhisto.xtalk_shape.bin_data[3] = 307;
02989             for (i = 4; i < VL53L1_XTALK_HISTO_BINS; i++)
02990                 caldata.xtalkhisto.xtalk_shape.bin_data[i] = 0;
02991             for (i = 0; i < VL53L1_BIN_REC_SIZE; i++)
02992                 caldata.algo__xtalk_cpo_HistoMerge_kcps[i] =
02993                     DefaultOffset + DefaultOffset * i;
02994             VL53L1_SetCalibrationData(Dev, &caldata);
02995         }
02996 
02997         break;
02998     default:
02999         Status = VL53L1_ERROR_INVALID_PARAMS;
03000     }
03001     VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE, merge);
03002 
03003     if (Status == VL53L1_ERROR_NONE) {
03004         Status = VL53L1_get_current_xtalk_settings(Dev, &xtalk);
03005         Status = VL53L1_set_tuning_parm(Dev,
03006             VL53L1_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS,
03007             xtalk.algo__crosstalk_compensation_plane_offset_kcps);
03008     }
03009 
03010     LOG_FUNCTION_END(Status);
03011     return Status;
03012 }
03013 
03014 VL53L1_Error VL53L1_SetOffsetCalibrationMode(VL53L1_DEV Dev,
03015         VL53L1_OffsetCalibrationModes OffsetCalibrationMode)
03016 {
03017     VL53L1_Error Status = VL53L1_ERROR_NONE;
03018     VL53L1_OffsetCalibrationMode   offset_cal_mode;
03019 
03020     LOG_FUNCTION_START("");
03021 
03022     if (OffsetCalibrationMode == VL53L1_OFFSETCALIBRATIONMODE_STANDARD) {
03023         offset_cal_mode =
03024             VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD;
03025     } else if (OffsetCalibrationMode ==
03026             VL53L1_OFFSETCALIBRATIONMODE_PRERANGE_ONLY) {
03027         offset_cal_mode =
03028         VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY;
03029     } else if (OffsetCalibrationMode ==
03030             VL53L1_OFFSETCALIBRATIONMODE_MULTI_ZONE) {
03031         offset_cal_mode =
03032                 VL53L1_OFFSETCALIBRATIONMODE__PER_ZONE;
03033     } else {
03034         Status = VL53L1_ERROR_INVALID_PARAMS;
03035     }
03036 
03037     if (Status == VL53L1_ERROR_NONE)
03038         Status =  VL53L1_set_offset_calibration_mode(Dev,
03039                 offset_cal_mode);
03040 
03041     LOG_FUNCTION_END(Status);
03042     return Status;
03043 }
03044 
03045 VL53L1_Error VL53L1_SetOffsetCorrectionMode(VL53L1_DEV Dev,
03046         VL53L1_OffsetCorrectionModes OffsetCorrectionMode)
03047 {
03048     VL53L1_Error Status = VL53L1_ERROR_NONE;
03049     VL53L1_OffsetCorrectionMode   offset_cor_mode;
03050 
03051     LOG_FUNCTION_START("");
03052 
03053     if (OffsetCorrectionMode == VL53L1_OFFSETCORRECTIONMODE_STANDARD) {
03054         offset_cor_mode =
03055                 VL53L1_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS;
03056     } else if (OffsetCorrectionMode ==
03057             VL53L1_OFFSETCORRECTIONMODE_PERZONE) {
03058         offset_cor_mode =
03059                 VL53L1_OFFSETCORRECTIONMODE__PER_ZONE_OFFSETS;
03060     } else if (OffsetCorrectionMode ==
03061             VL53L1_OFFSETCORRECTIONMODE_PERVCSEL) {
03062         offset_cor_mode =
03063                 VL53L1_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS;
03064     } else {
03065         Status = VL53L1_ERROR_INVALID_PARAMS;
03066     }
03067 
03068     if (Status == VL53L1_ERROR_NONE)
03069         Status =  VL53L1_set_offset_correction_mode(Dev,
03070                 offset_cor_mode);
03071 
03072     LOG_FUNCTION_END(Status);
03073     return Status;
03074 }
03075 
03076 VL53L1_Error VL53L1_PerformOffsetCalibration(VL53L1_DEV Dev,
03077     int32_t CalDistanceMilliMeter, FixPoint1616_t CalReflectancePercent)
03078 {
03079     VL53L1_Error Status = VL53L1_ERROR_NONE;
03080     VL53L1_Error UnfilteredStatus;
03081     VL53L1_OffsetCalibrationMode   offset_cal_mode;
03082     uint16_t CalReflectancePercent_int;
03083 
03084     VL53L1_DevicePresetModes      device_preset_mode;
03085     VL53L1_DeviceZonePreset       zone_preset;
03086     VL53L1_zone_config_t         zone_cfg;
03087     int32_t MergeEnabled;
03088 
03089     LOG_FUNCTION_START("");
03090 
03091     CalReflectancePercent_int =
03092             VL53L1_FIXPOINT1616TOFIXPOINT72(CalReflectancePercent);
03093 
03094     if (Status == VL53L1_ERROR_NONE)
03095         Status =  VL53L1_get_offset_calibration_mode(Dev,
03096                 &offset_cal_mode);
03097 
03098     if (Status != VL53L1_ERROR_NONE) {
03099         LOG_FUNCTION_END(Status);
03100         return Status;
03101     }
03102 
03103 
03104     if ((offset_cal_mode ==
03105         VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD) ||
03106         (offset_cal_mode ==
03107         VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY
03108         )) {
03109         if (Status == VL53L1_ERROR_NONE)
03110             Status = VL53L1_run_offset_calibration(
03111                     Dev,
03112                     (int16_t)CalDistanceMilliMeter,
03113                     CalReflectancePercent_int,
03114                     &UnfilteredStatus);
03115 
03116     } else if (offset_cal_mode ==
03117             VL53L1_OFFSETCALIBRATIONMODE__PER_ZONE) {
03118         VL53L1_get_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE,
03119                 &MergeEnabled);
03120         VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE, 0);
03121         device_preset_mode =
03122             VL53L1_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_LONG_RANGE;
03123         zone_preset = VL53L1_DEVICEZONEPRESET_CUSTOM;
03124 
03125         Status = VL53L1_get_zone_config(Dev, &zone_cfg);
03126         if (Status == VL53L1_ERROR_NONE)
03127             Status = VL53L1_run_zone_calibration(
03128                     Dev,
03129                     device_preset_mode,
03130                     zone_preset,
03131                     &zone_cfg,
03132                     (int16_t)CalDistanceMilliMeter,
03133                     CalReflectancePercent_int,
03134                     &UnfilteredStatus);
03135         VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE,
03136                 MergeEnabled);
03137 
03138     } else {
03139         Status = VL53L1_ERROR_INVALID_PARAMS;
03140     }
03141     LOG_FUNCTION_END(Status);
03142     return Status;
03143 }
03144 
03145 VL53L1_Error VL53L1_PerformOffsetSimpleCalibration(VL53L1_DEV Dev,
03146     int32_t CalDistanceMilliMeter)
03147 {
03148     VL53L1_Error Status = VL53L1_ERROR_NONE;
03149     int32_t sum_ranging;
03150     uint8_t offset_meas;
03151     int16_t Max, UnderMax, OverMax, Repeat;
03152     int32_t total_count, inloopcount;
03153     int32_t IncRounding;
03154     int16_t meanDistance_mm;
03155     int16_t offset;
03156     VL53L1_RangingMeasurementData_t RangingMeasurementData;
03157     VL53L1_LLDriverData_t *pdev;
03158     uint8_t goodmeas;
03159     VL53L1_Error SmudgeStatus = VL53L1_ERROR_NONE;
03160     uint8_t smudge_corr_en;
03161 
03162     LOG_FUNCTION_START("");
03163 
03164     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03165 
03166     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
03167     SmudgeStatus = VL53L1_dynamic_xtalk_correction_disable(Dev);
03168 
03169     pdev->customer.algo__part_to_part_range_offset_mm = 0;
03170     pdev->customer.mm_config__inner_offset_mm = 0;
03171     pdev->customer.mm_config__outer_offset_mm = 0;
03172     memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
03173     Repeat = BDTable[VL53L1_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
03174     Max = BDTable[
03175         VL53L1_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
03176     UnderMax = 1 + (Max / 2);
03177     OverMax = Max + (Max / 2);
03178     sum_ranging = 0;
03179     total_count = 0;
03180 
03181     while ((Repeat > 0) && (Status == VL53L1_ERROR_NONE)) {
03182         Status = VL53L1_StartMeasurement(Dev);
03183 
03184         if (Status == VL53L1_ERROR_NONE) {
03185             VL53L1_WaitMeasurementDataReady(Dev);
03186             VL53L1_GetRangingMeasurementData(Dev,
03187                 &RangingMeasurementData);
03188             VL53L1_ClearInterruptAndStartMeasurement(Dev);
03189         }
03190 
03191         inloopcount = 0;
03192         offset_meas = 0;
03193         while ((Status == VL53L1_ERROR_NONE) && (inloopcount < Max) &&
03194                 (offset_meas < OverMax)) {
03195             Status = VL53L1_WaitMeasurementDataReady(Dev);
03196             if (Status == VL53L1_ERROR_NONE)
03197                 Status = VL53L1_GetRangingMeasurementData(Dev,
03198                         &RangingMeasurementData);
03199             goodmeas = (RangingMeasurementData.RangeStatus  ==
03200                     VL53L1_RANGESTATUS_RANGE_VALID);
03201             if ((Status == VL53L1_ERROR_NONE) && goodmeas) {
03202                 sum_ranging = sum_ranging +
03203                     RangingMeasurementData.RangeMilliMeter ;
03204                 inloopcount++;
03205             }
03206             Status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
03207             offset_meas++;
03208         }
03209         total_count += inloopcount;
03210 
03211 
03212         if (inloopcount < UnderMax)
03213             Status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
03214 
03215         VL53L1_StopMeasurement(Dev);
03216 
03217         Repeat--;
03218 
03219     }
03220 
03221     if ((SmudgeStatus == VL53L1_ERROR_NONE) && (smudge_corr_en == 1))
03222         SmudgeStatus = VL53L1_dynamic_xtalk_correction_enable(Dev);
03223 
03224     if ((sum_ranging < 0) ||
03225         (sum_ranging > ((int32_t) total_count * 0xffff)))
03226         Status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
03227 
03228     if ((Status == VL53L1_ERROR_NONE) && (total_count > 0)) {
03229         IncRounding = total_count / 2;
03230         meanDistance_mm = (int16_t)((sum_ranging + IncRounding)
03231                 / total_count);
03232         offset = (int16_t)CalDistanceMilliMeter - meanDistance_mm;
03233         pdev->customer.algo__part_to_part_range_offset_mm = 0;
03234         pdev->customer.mm_config__inner_offset_mm = offset;
03235         pdev->customer.mm_config__outer_offset_mm = offset;
03236 
03237         Status = VL53L1_set_customer_nvm_managed(Dev,
03238                 &(pdev->customer));
03239     }
03240 
03241     LOG_FUNCTION_END(Status);
03242     return Status;
03243 }
03244 
03245 VL53L1_Error VL53L1_PerformOffsetZeroDistanceCalibration(VL53L1_DEV Dev)
03246 {
03247     #define START_OFFSET 50
03248     VL53L1_Error Status = VL53L1_ERROR_NONE;
03249     int32_t sum_ranging;
03250     uint8_t offset_meas;
03251     int16_t Max, UnderMax, OverMax, Repeat;
03252     int32_t total_count, inloopcount;
03253     int32_t IncRounding;
03254     int16_t meanDistance_mm;
03255     int16_t offset, ZeroDistanceOffset;
03256     VL53L1_RangingMeasurementData_t RangingMeasurementData;
03257     VL53L1_LLDriverData_t *pdev;
03258     uint8_t goodmeas;
03259     VL53L1_Error SmudgeStatus = VL53L1_ERROR_NONE;
03260     uint8_t smudge_corr_en;
03261 
03262     LOG_FUNCTION_START("");
03263 
03264     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03265     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
03266     SmudgeStatus = VL53L1_dynamic_xtalk_correction_disable(Dev);
03267     pdev->customer.algo__part_to_part_range_offset_mm = 0;
03268     pdev->customer.mm_config__inner_offset_mm = START_OFFSET;
03269     pdev->customer.mm_config__outer_offset_mm = START_OFFSET;
03270     memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
03271     ZeroDistanceOffset = BDTable[
03272         VL53L1_TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR];
03273     Repeat = BDTable[VL53L1_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
03274     Max = BDTable[
03275         VL53L1_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
03276     UnderMax = 1 + (Max / 2);
03277     OverMax = Max + (Max / 2);
03278     sum_ranging = 0;
03279     total_count = 0;
03280 
03281     while ((Repeat > 0) && (Status == VL53L1_ERROR_NONE)) {
03282         Status = VL53L1_StartMeasurement(Dev);
03283         if (Status == VL53L1_ERROR_NONE) {
03284             VL53L1_WaitMeasurementDataReady(Dev);
03285             VL53L1_GetRangingMeasurementData(Dev,
03286                 &RangingMeasurementData);
03287             VL53L1_ClearInterruptAndStartMeasurement(Dev);
03288         }
03289         inloopcount = 0;
03290         offset_meas = 0;
03291         while ((Status == VL53L1_ERROR_NONE) && (inloopcount < Max) &&
03292                 (offset_meas < OverMax)) {
03293             Status = VL53L1_WaitMeasurementDataReady(Dev);
03294             if (Status == VL53L1_ERROR_NONE)
03295                 Status = VL53L1_GetRangingMeasurementData(Dev,
03296                     &RangingMeasurementData);
03297             goodmeas = (RangingMeasurementData.RangeStatus  ==
03298                     VL53L1_RANGESTATUS_RANGE_VALID);
03299             if ((Status == VL53L1_ERROR_NONE) && goodmeas) {
03300                 sum_ranging = sum_ranging +
03301                     RangingMeasurementData.RangeMilliMeter ;
03302                 inloopcount++;
03303             }
03304             Status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
03305             offset_meas++;
03306         }
03307         total_count += inloopcount;
03308         if (inloopcount < UnderMax)
03309             Status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
03310         VL53L1_StopMeasurement(Dev);
03311         Repeat--;
03312     }
03313     if ((SmudgeStatus == VL53L1_ERROR_NONE) && (smudge_corr_en == 1))
03314         SmudgeStatus = VL53L1_dynamic_xtalk_correction_enable(Dev);
03315     if ((sum_ranging < 0) ||
03316         (sum_ranging > ((int32_t) total_count * 0xffff)))
03317         Status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
03318 
03319     if ((Status == VL53L1_ERROR_NONE) && (total_count > 0)) {
03320         IncRounding = total_count / 2;
03321         meanDistance_mm = (int16_t)
03322             ((sum_ranging + IncRounding) / total_count);
03323         offset = START_OFFSET - meanDistance_mm + ZeroDistanceOffset;
03324         pdev->customer.algo__part_to_part_range_offset_mm = 0;
03325         pdev->customer.mm_config__inner_offset_mm = offset;
03326         pdev->customer.mm_config__outer_offset_mm = offset;
03327         Status = VL53L1_set_customer_nvm_managed(Dev,
03328             &(pdev->customer));
03329     }
03330 
03331     LOG_FUNCTION_END(Status);
03332     return Status;
03333 }
03334 
03335 VL53L1_Error VL53L1_SetCalibrationData(VL53L1_DEV Dev,
03336         VL53L1_CalibrationData_t *pCalibrationData)
03337 {
03338     VL53L1_Error Status = VL53L1_ERROR_NONE;
03339     VL53L1_CustomerNvmManaged_t          *pC;
03340     VL53L1_calibration_data_t            cal_data;
03341     uint32_t x, IncomeVersion, CurrentVersion;
03342     uint8_t CalStopsOn_cal_peak_rate_map = 0;
03343     VL53L1_xtalk_calibration_results_t xtalk;
03344     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03345 
03346     LOG_FUNCTION_START("");
03347 
03348     cal_data.struct_version = pCalibrationData->struct_version -
03349             VL53L1_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
03350 
03351     IncomeVersion = pCalibrationData->struct_version;
03352     CurrentVersion = VL53L1_LL_CALIBRATION_DATA_STRUCT_VERSION +
03353         VL53L1_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
03354 
03355     if ((IncomeVersion < CurrentVersion) &&
03356         ((IncomeVersion & 0xFFFFFF0F) ==
03357          (CurrentVersion & 0xFFFFFF0F))) {
03358         cal_data.struct_version =
03359             VL53L1_LL_CALIBRATION_DATA_STRUCT_VERSION;
03360         CalStopsOn_cal_peak_rate_map = 1;
03361 
03362         pdev->tuning_parms.tp_hist_merge = 0;
03363     }
03364 
03365 
03366 
03367     memcpy(
03368         &(cal_data.fmt_dmax_cal),
03369         &(pCalibrationData->fmt_dmax_cal),
03370         sizeof(VL53L1_dmax_calibration_data_t));
03371 
03372 
03373     memcpy(
03374         &(cal_data.cust_dmax_cal),
03375         &(pCalibrationData->cust_dmax_cal),
03376         sizeof(VL53L1_dmax_calibration_data_t));
03377 
03378 
03379     memcpy(
03380         &(cal_data.add_off_cal_data),
03381         &(pCalibrationData->add_off_cal_data),
03382         sizeof(VL53L1_additional_offset_cal_data_t));
03383 
03384 
03385     memcpy(
03386         &(cal_data.optical_centre),
03387         &(pCalibrationData->optical_centre),
03388         sizeof(VL53L1_optical_centre_t));
03389 
03390 
03391     memcpy(
03392         &(cal_data.xtalkhisto),
03393         &(pCalibrationData->xtalkhisto),
03394         sizeof(VL53L1_xtalk_histogram_data_t));
03395 
03396 
03397     memcpy(
03398         &(cal_data.gain_cal),
03399         &(pCalibrationData->gain_cal),
03400         sizeof(VL53L1_gain_calibration_data_t));
03401 
03402 
03403     memcpy(
03404         &(cal_data.cal_peak_rate_map),
03405         &(pCalibrationData->cal_peak_rate_map),
03406         sizeof(VL53L1_cal_peak_rate_map_t));
03407 
03408 
03409     if (!CalStopsOn_cal_peak_rate_map)
03410         memcpy(
03411         &(cal_data.per_vcsel_cal_data),
03412         &(pCalibrationData->per_vcsel_cal_data),
03413         sizeof(VL53L1_per_vcsel_period_offset_cal_data_t));
03414     else {
03415         cal_data.per_vcsel_cal_data.short_a_offset_mm =
03416         cal_data.per_vcsel_cal_data.short_b_offset_mm =
03417         cal_data.per_vcsel_cal_data.medium_a_offset_mm =
03418         cal_data.per_vcsel_cal_data.medium_b_offset_mm =
03419         cal_data.per_vcsel_cal_data.long_a_offset_mm =
03420         cal_data.per_vcsel_cal_data.long_b_offset_mm = 0;
03421     }
03422 
03423     pC = &pCalibrationData->customer;
03424     x = pC->algo__crosstalk_compensation_plane_offset_kcps;
03425     cal_data.customer.algo__crosstalk_compensation_plane_offset_kcps =
03426         (uint16_t)(x&0x0000FFFF);
03427 
03428     cal_data.customer.global_config__spad_enables_ref_0 =
03429         pC->global_config__spad_enables_ref_0;
03430     cal_data.customer.global_config__spad_enables_ref_1 =
03431         pC->global_config__spad_enables_ref_1;
03432     cal_data.customer.global_config__spad_enables_ref_2 =
03433         pC->global_config__spad_enables_ref_2;
03434     cal_data.customer.global_config__spad_enables_ref_3 =
03435         pC->global_config__spad_enables_ref_3;
03436     cal_data.customer.global_config__spad_enables_ref_4 =
03437         pC->global_config__spad_enables_ref_4;
03438     cal_data.customer.global_config__spad_enables_ref_5 =
03439         pC->global_config__spad_enables_ref_5;
03440     cal_data.customer.global_config__ref_en_start_select =
03441         pC->global_config__ref_en_start_select;
03442     cal_data.customer.ref_spad_man__num_requested_ref_spads =
03443         pC->ref_spad_man__num_requested_ref_spads;
03444     cal_data.customer.ref_spad_man__ref_location =
03445         pC->ref_spad_man__ref_location;
03446     cal_data.customer.algo__crosstalk_compensation_x_plane_gradient_kcps =
03447         pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
03448     cal_data.customer.algo__crosstalk_compensation_y_plane_gradient_kcps =
03449         pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
03450     cal_data.customer.ref_spad_char__total_rate_target_mcps =
03451         pC->ref_spad_char__total_rate_target_mcps;
03452     cal_data.customer.algo__part_to_part_range_offset_mm =
03453         pC->algo__part_to_part_range_offset_mm;
03454     cal_data.customer.mm_config__inner_offset_mm =
03455         pC->mm_config__inner_offset_mm;
03456     cal_data.customer.mm_config__outer_offset_mm =
03457         pC->mm_config__outer_offset_mm;
03458 
03459     Status = VL53L1_set_part_to_part_data(Dev, &cal_data);
03460     if (Status != VL53L1_ERROR_NONE)
03461         goto ENDFUNC;
03462 
03463     Status = VL53L1_get_current_xtalk_settings(Dev, &xtalk);
03464 
03465     if (Status != VL53L1_ERROR_NONE)
03466         goto ENDFUNC;
03467 
03468     xtalk.algo__crosstalk_compensation_plane_offset_kcps = x;
03469 
03470     Status = VL53L1_set_tuning_parm(Dev,
03471             VL53L1_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS,
03472             x);
03473 
03474 
03475     if (!CalStopsOn_cal_peak_rate_map)
03476         memcpy(
03477         &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]),
03478         &(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]),
03479         sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
03480     else
03481         memset(
03482         &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]), 0,
03483         sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
03484 
03485     Status = VL53L1_set_current_xtalk_settings(Dev, &xtalk);
03486 
03487 ENDFUNC:
03488     LOG_FUNCTION_END(Status);
03489     return Status;
03490 
03491 }
03492 
03493 VL53L1_Error VL53L1_GetCalibrationData(VL53L1_DEV Dev,
03494         VL53L1_CalibrationData_t  *pCalibrationData)
03495 {
03496     VL53L1_Error Status = VL53L1_ERROR_NONE;
03497     VL53L1_calibration_data_t      cal_data;
03498     VL53L1_CustomerNvmManaged_t         *pC;
03499     VL53L1_customer_nvm_managed_t       *pC2;
03500     VL53L1_xtalk_calibration_results_t xtalk;
03501     uint32_t                          tmp;
03502     VL53L1_PresetModes PresetMode;
03503 
03504     LOG_FUNCTION_START("");
03505 
03506 
03507     Status = VL53L1_get_part_to_part_data(Dev, &cal_data);
03508 
03509     pCalibrationData->struct_version = cal_data.struct_version +
03510             VL53L1_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
03511 
03512 
03513     memcpy(
03514         &(pCalibrationData->fmt_dmax_cal),
03515         &(cal_data.fmt_dmax_cal),
03516         sizeof(VL53L1_dmax_calibration_data_t));
03517 
03518 
03519     memcpy(
03520         &(pCalibrationData->cust_dmax_cal),
03521         &(cal_data.cust_dmax_cal),
03522         sizeof(VL53L1_dmax_calibration_data_t));
03523 
03524 
03525     memcpy(
03526         &(pCalibrationData->add_off_cal_data),
03527         &(cal_data.add_off_cal_data),
03528         sizeof(VL53L1_additional_offset_cal_data_t));
03529 
03530 
03531     memcpy(
03532         &(pCalibrationData->optical_centre),
03533         &(cal_data.optical_centre),
03534         sizeof(VL53L1_optical_centre_t));
03535 
03536 
03537     memcpy(
03538         &(pCalibrationData->xtalkhisto),
03539         &(cal_data.xtalkhisto),
03540         sizeof(VL53L1_xtalk_histogram_data_t));
03541 
03542     memcpy(
03543         &(pCalibrationData->gain_cal),
03544         &(cal_data.gain_cal),
03545         sizeof(VL53L1_gain_calibration_data_t));
03546 
03547 
03548     memcpy(
03549         &(pCalibrationData->cal_peak_rate_map),
03550         &(cal_data.cal_peak_rate_map),
03551         sizeof(VL53L1_cal_peak_rate_map_t));
03552 
03553 
03554     memcpy(
03555         &(pCalibrationData->per_vcsel_cal_data),
03556         &(cal_data.per_vcsel_cal_data),
03557         sizeof(VL53L1_per_vcsel_period_offset_cal_data_t));
03558 
03559     pC = &pCalibrationData->customer;
03560     pC2 = &cal_data.customer;
03561     pC->global_config__spad_enables_ref_0 =
03562         pC2->global_config__spad_enables_ref_0;
03563     pC->global_config__spad_enables_ref_1 =
03564         pC2->global_config__spad_enables_ref_1;
03565     pC->global_config__spad_enables_ref_2 =
03566         pC2->global_config__spad_enables_ref_2;
03567     pC->global_config__spad_enables_ref_3 =
03568         pC2->global_config__spad_enables_ref_3;
03569     pC->global_config__spad_enables_ref_4 =
03570         pC2->global_config__spad_enables_ref_4;
03571     pC->global_config__spad_enables_ref_5 =
03572         pC2->global_config__spad_enables_ref_5;
03573     pC->global_config__ref_en_start_select =
03574         pC2->global_config__ref_en_start_select;
03575     pC->ref_spad_man__num_requested_ref_spads =
03576         pC2->ref_spad_man__num_requested_ref_spads;
03577     pC->ref_spad_man__ref_location =
03578         pC2->ref_spad_man__ref_location;
03579     pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
03580         pC2->algo__crosstalk_compensation_x_plane_gradient_kcps;
03581     pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
03582         pC2->algo__crosstalk_compensation_y_plane_gradient_kcps;
03583     pC->ref_spad_char__total_rate_target_mcps =
03584         pC2->ref_spad_char__total_rate_target_mcps;
03585     pC->algo__part_to_part_range_offset_mm =
03586         pC2->algo__part_to_part_range_offset_mm;
03587     pC->mm_config__inner_offset_mm =
03588         pC2->mm_config__inner_offset_mm;
03589     pC->mm_config__outer_offset_mm =
03590         pC2->mm_config__outer_offset_mm;
03591 
03592     pC->algo__crosstalk_compensation_plane_offset_kcps =
03593         (uint32_t)(
03594             pC2->algo__crosstalk_compensation_plane_offset_kcps);
03595 
03596     PresetMode = VL53L1DevDataGet(Dev, CurrentParameters.PresetMode);
03597 
03598     if ((PresetMode == VL53L1_PRESETMODE_RANGING) ||
03599         (PresetMode == VL53L1_PRESETMODE_MULTIZONES_SCANNING) ||
03600         (PresetMode == VL53L1_PRESETMODE_PROXY_RANGING_MODE)
03601         ) {
03602 
03603         Status = VL53L1_get_current_xtalk_settings(Dev, &xtalk);
03604 
03605         if (Status != VL53L1_ERROR_NONE)
03606             goto ENDFUNC;
03607 
03608         tmp = xtalk.algo__crosstalk_compensation_plane_offset_kcps;
03609         pC->algo__crosstalk_compensation_plane_offset_kcps = tmp;
03610         tmp = xtalk.algo__crosstalk_compensation_x_plane_gradient_kcps;
03611         pC->algo__crosstalk_compensation_x_plane_gradient_kcps = tmp;
03612         tmp = xtalk.algo__crosstalk_compensation_y_plane_gradient_kcps;
03613         pC->algo__crosstalk_compensation_y_plane_gradient_kcps = tmp;
03614 
03615         memcpy(&(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]),
03616         &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]),
03617         sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
03618     }
03619 ENDFUNC:
03620     LOG_FUNCTION_END(Status);
03621     return Status;
03622 }
03623 
03624 
03625 VL53L1_Error VL53L1_SetZoneCalibrationData(VL53L1_DEV Dev,
03626         VL53L1_ZoneCalibrationData_t *pZoneCalibrationData)
03627 {
03628     VL53L1_Error Status = VL53L1_ERROR_NONE;
03629 
03630     LOG_FUNCTION_START("");
03631 
03632     Status = VL53L1_set_zone_calibration_data(Dev, pZoneCalibrationData);
03633 
03634     LOG_FUNCTION_END(Status);
03635     return Status;
03636 
03637 }
03638 
03639 VL53L1_Error VL53L1_GetZoneCalibrationData(VL53L1_DEV Dev,
03640         VL53L1_ZoneCalibrationData_t  *pZoneCalibrationData)
03641 {
03642     VL53L1_Error Status = VL53L1_ERROR_NONE;
03643 
03644     LOG_FUNCTION_START("");
03645 
03646     Status = VL53L1_get_zone_calibration_data(Dev, pZoneCalibrationData);
03647 
03648     LOG_FUNCTION_END(Status);
03649     return Status;
03650 }
03651 
03652 VL53L1_Error VL53L1_GetOpticalCenter(VL53L1_DEV Dev,
03653         FixPoint1616_t *pOpticalCenterX,
03654         FixPoint1616_t *pOpticalCenterY)
03655 {
03656     VL53L1_Error Status = VL53L1_ERROR_NONE;
03657     VL53L1_calibration_data_t  CalibrationData;
03658 
03659     LOG_FUNCTION_START("");
03660 
03661     *pOpticalCenterX = 0;
03662     *pOpticalCenterY = 0;
03663     Status = VL53L1_get_part_to_part_data(Dev, &CalibrationData);
03664     if (Status == VL53L1_ERROR_NONE) {
03665         *pOpticalCenterX = VL53L1_FIXPOINT44TOFIXPOINT1616(
03666                 CalibrationData.optical_centre.x_centre);
03667         *pOpticalCenterY = VL53L1_FIXPOINT44TOFIXPOINT1616(
03668                 CalibrationData.optical_centre.y_centre);
03669     }
03670 
03671     LOG_FUNCTION_END(Status);
03672     return Status;
03673 }
03674 
03675 
03676 
03677 
03678 
03679 
03680 VL53L1_Error VL53L1_SetThresholdConfig(VL53L1_DEV Dev,
03681         VL53L1_DetectionConfig_t *pConfig)
03682 {
03683 #define BADTHRESBOUNDS(T) \
03684     (((T.CrossMode == VL53L1_THRESHOLD_OUT_OF_WINDOW) || \
03685     (T.CrossMode == VL53L1_THRESHOLD_IN_WINDOW)) && (T.Low > T.High))
03686 
03687     VL53L1_Error Status = VL53L1_ERROR_NONE;
03688     VL53L1_GPIO_interrupt_config_t Cfg;
03689     uint16_t g;
03690     FixPoint1616_t gain, high1616, low1616;
03691     VL53L1_LLDriverData_t *pdev;
03692 
03693     LOG_FUNCTION_START("");
03694 
03695     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03696 
03697     Status = VL53L1_get_GPIO_interrupt_config(Dev, &Cfg);
03698     if (Status != VL53L1_ERROR_NONE)
03699         return Status;
03700 
03701     if (pConfig->DetectionMode  == VL53L1_DETECTION_NORMAL_RUN) {
03702         Cfg.intr_new_measure_ready = 1;
03703         Status = VL53L1_set_GPIO_interrupt_config_struct(Dev,
03704                 Cfg);
03705     } else {
03706         if (BADTHRESBOUNDS(pConfig->Distance ))
03707             Status = VL53L1_ERROR_INVALID_PARAMS;
03708         if ((Status == VL53L1_ERROR_NONE) &&
03709                 (BADTHRESBOUNDS(pConfig->Rate )))
03710             Status = VL53L1_ERROR_INVALID_PARAMS;
03711         if (Status == VL53L1_ERROR_NONE) {
03712             Cfg.intr_new_measure_ready = 0;
03713             Cfg.intr_no_target = pConfig->IntrNoTarget ;
03714 
03715             g = pdev->gain_cal.standard_ranging_gain_factor;
03716             if (g != 0) {
03717 
03718                 gain = (FixPoint1616_t) ((uint32_t)g << 5);
03719                 high1616 = (FixPoint1616_t) ((uint32_t)
03720                         pConfig->Distance .High  << 16);
03721                 low1616 = (FixPoint1616_t) ((uint32_t)
03722                         pConfig->Distance .Low  << 16);
03723 
03724                 high1616 = (high1616 + 32768) / gain;
03725                 low1616 = (low1616 + 32768) / gain;
03726                 Cfg.threshold_distance_high = (uint16_t)
03727                         (high1616 & 0xFFFF);
03728                 Cfg.threshold_distance_low = (uint16_t)
03729                         (low1616 & 0xFFFF);
03730             }
03731             Cfg.threshold_rate_high =
03732                 VL53L1_FIXPOINT1616TOFIXPOINT97(
03733                         pConfig->Rate .High );
03734             Cfg.threshold_rate_low =
03735                 VL53L1_FIXPOINT1616TOFIXPOINT97(
03736                         pConfig->Rate .Low );
03737 
03738             Cfg.intr_mode_distance = ConvertModeToLLD(
03739                     &Status,
03740                     pConfig->Distance .CrossMode);
03741             if (Status == VL53L1_ERROR_NONE)
03742                 Cfg.intr_mode_rate = ConvertModeToLLD(
03743                     &Status,
03744                     pConfig->Rate .CrossMode);
03745         }
03746 
03747 
03748         if (Status == VL53L1_ERROR_NONE) {
03749             Cfg.intr_combined_mode = 1;
03750             switch (pConfig->DetectionMode ) {
03751             case VL53L1_DETECTION_DISTANCE_ONLY:
03752                 Cfg.threshold_rate_high = 0;
03753                 Cfg.threshold_rate_low = 0;
03754                 break;
03755             case VL53L1_DETECTION_RATE_ONLY:
03756                 Cfg.threshold_distance_high = 0;
03757                 Cfg.threshold_distance_low = 0;
03758                 break;
03759             case VL53L1_DETECTION_DISTANCE_OR_RATE:
03760 
03761                 break;
03762             case VL53L1_DETECTION_DISTANCE_AND_RATE:
03763                 Cfg.intr_combined_mode = 0;
03764                 break;
03765             default:
03766                 Status = VL53L1_ERROR_INVALID_PARAMS;
03767             }
03768         }
03769 
03770         if (Status == VL53L1_ERROR_NONE)
03771             Status =
03772             VL53L1_set_GPIO_interrupt_config_struct(Dev, Cfg);
03773 
03774     }
03775 
03776     LOG_FUNCTION_END(Status);
03777     return Status;
03778 }
03779 
03780 
03781 VL53L1_Error VL53L1_GetThresholdConfig(VL53L1_DEV Dev,
03782         VL53L1_DetectionConfig_t *pConfig)
03783 {
03784     VL53L1_Error Status = VL53L1_ERROR_NONE;
03785     VL53L1_GPIO_interrupt_config_t Cfg;
03786 
03787     LOG_FUNCTION_START("");
03788 
03789     Status = VL53L1_get_GPIO_interrupt_config(Dev, &Cfg);
03790 
03791     if (Status != VL53L1_ERROR_NONE) {
03792         LOG_FUNCTION_END(Status);
03793         return Status;
03794     }
03795 
03796     pConfig->IntrNoTarget  = Cfg.intr_no_target;
03797     pConfig->Distance .High  = Cfg.threshold_distance_high;
03798     pConfig->Distance .Low  = Cfg.threshold_distance_low;
03799     pConfig->Rate .High  =
03800         VL53L1_FIXPOINT97TOFIXPOINT1616(
03801                 Cfg.threshold_rate_high);
03802     pConfig->Rate .Low  =
03803         VL53L1_FIXPOINT97TOFIXPOINT1616(Cfg.threshold_rate_low);
03804     pConfig->Distance .CrossMode =
03805         ConvertModeFromLLD(&Status, Cfg.intr_mode_distance);
03806     if (Status == VL53L1_ERROR_NONE)
03807         pConfig->Rate .CrossMode =
03808             ConvertModeFromLLD(&Status, Cfg.intr_mode_rate);
03809 
03810     if (Cfg.intr_new_measure_ready == 1) {
03811         pConfig->DetectionMode  = VL53L1_DETECTION_NORMAL_RUN;
03812     } else {
03813 
03814         if (Status == VL53L1_ERROR_NONE) {
03815             if (Cfg.intr_combined_mode == 0)
03816                 pConfig->DetectionMode  =
03817                 VL53L1_DETECTION_DISTANCE_AND_RATE;
03818             else {
03819                 if ((Cfg.threshold_distance_high == 0) &&
03820                     (Cfg.threshold_distance_low == 0))
03821                     pConfig->DetectionMode  =
03822                     VL53L1_DETECTION_RATE_ONLY;
03823                 else if ((Cfg.threshold_rate_high == 0) &&
03824                     (Cfg.threshold_rate_low == 0))
03825                     pConfig->DetectionMode  =
03826                     VL53L1_DETECTION_DISTANCE_ONLY;
03827                 else
03828                     pConfig->DetectionMode  =
03829                     VL53L1_DETECTION_DISTANCE_OR_RATE;
03830             }
03831         }
03832     }
03833 
03834     LOG_FUNCTION_END(Status);
03835     return Status;
03836 }
03837 
03838 
03839 
03840 
03841 VL53L1_Error VL53L1_PerformOffsetPerVcselCalibration(VL53L1_DEV Dev,
03842     int32_t CalDistanceMilliMeter)
03843 {
03844     VL53L1_Error Status = VL53L1_ERROR_NONE;
03845     int32_t sum_ranging_range_A, sum_ranging_range_B;
03846     uint8_t offset_meas_range_A, offset_meas_range_B;
03847     int16_t Max, UnderMax, OverMax, Repeat;
03848     int32_t inloopcount;
03849     int32_t IncRounding;
03850     int16_t meanDistance_mm;
03851     VL53L1_RangingMeasurementData_t RangingMeasurementData;
03852     VL53L1_LLDriverData_t *pdev;
03853     uint8_t goodmeas;
03854     VL53L1_PresetModes currentMode;
03855     VL53L1_DistanceModes currentDist;
03856     VL53L1_DistanceModes DistMode[3] = {VL53L1_DISTANCEMODE_SHORT,
03857             VL53L1_DISTANCEMODE_MEDIUM, VL53L1_DISTANCEMODE_LONG};
03858     int16_t offsetA[3];
03859     int16_t offsetB[3];
03860 
03861     VL53L1_Error SmudgeStatus = VL53L1_ERROR_NONE;
03862     uint8_t smudge_corr_en, isc;
03863 
03864     LOG_FUNCTION_START("");
03865 
03866     pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03867 
03868     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
03869     SmudgeStatus = VL53L1_dynamic_xtalk_correction_disable(Dev);
03870 
03871     pdev->customer.algo__part_to_part_range_offset_mm = 0;
03872     pdev->customer.mm_config__inner_offset_mm = 0;
03873     pdev->customer.mm_config__outer_offset_mm = 0;
03874     pdev->customer.mm_config__outer_offset_mm = 0;
03875     memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
03876 
03877     Repeat = 0;
03878     Max = 2 * BDTable[
03879         VL53L1_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
03880     UnderMax = 1 + (Max / 2);
03881     OverMax = Max + (Max / 2);
03882 
03883     Status = VL53L1_GetPresetMode(Dev, &currentMode);
03884     Status = VL53L1_GetDistanceMode(Dev, &currentDist);
03885 
03886     while ((Repeat < 3) && (Status == VL53L1_ERROR_NONE)) {
03887         Status = VL53L1_SetDistanceMode(Dev, DistMode[Repeat]);
03888         Status = VL53L1_StartMeasurement(Dev);
03889 
03890         if (Status == VL53L1_ERROR_NONE) {
03891             VL53L1_WaitMeasurementDataReady(Dev);
03892             VL53L1_GetRangingMeasurementData(Dev,
03893                     &RangingMeasurementData);
03894             VL53L1_ClearInterruptAndStartMeasurement(Dev);
03895         }
03896 
03897         inloopcount = 0;
03898         offset_meas_range_A = 0;
03899         sum_ranging_range_A = 0;
03900         offset_meas_range_B = 0;
03901         sum_ranging_range_B = 0;
03902         while ((Status == VL53L1_ERROR_NONE) && (inloopcount < Max) &&
03903                 (inloopcount < OverMax)) {
03904             Status = VL53L1_WaitMeasurementDataReady(Dev);
03905             if (Status == VL53L1_ERROR_NONE)
03906                 Status = VL53L1_GetRangingMeasurementData(Dev,
03907                         &RangingMeasurementData);
03908             goodmeas = (RangingMeasurementData.RangeStatus  ==
03909                     VL53L1_RANGESTATUS_RANGE_VALID);
03910             isc = pdev->ll_state.cfg_internal_stream_count;
03911             if ((Status == VL53L1_ERROR_NONE) && goodmeas) {
03912                 if (isc & 0x01) {
03913                     sum_ranging_range_A +=
03914                     RangingMeasurementData.RangeMilliMeter ;
03915                     offset_meas_range_A++;
03916                 } else {
03917                     sum_ranging_range_B +=
03918                     RangingMeasurementData.RangeMilliMeter ;
03919                     offset_meas_range_B++;
03920                 }
03921                 inloopcount = offset_meas_range_A +
03922                     offset_meas_range_B;
03923             }
03924             Status = VL53L1_ClearInterruptAndStartMeasurement(Dev);
03925         }
03926 
03927 
03928         if (inloopcount < UnderMax)
03929             Status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
03930 
03931         VL53L1_StopMeasurement(Dev);
03932 
03933 
03934         if ((sum_ranging_range_A < 0) ||
03935             (sum_ranging_range_B < 0) ||
03936             (sum_ranging_range_A >
03937                 ((int32_t) offset_meas_range_A * 0xffff)) ||
03938             (sum_ranging_range_B >
03939                 ((int32_t) offset_meas_range_B * 0xffff))) {
03940             Status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
03941         }
03942 
03943         if ((Status == VL53L1_ERROR_NONE) &&
03944             (offset_meas_range_A > 0)) {
03945             IncRounding = offset_meas_range_A / 2;
03946             meanDistance_mm = (int16_t)
03947                 ((sum_ranging_range_A + IncRounding)
03948                 / offset_meas_range_A);
03949             offsetA[Repeat] = (int16_t)
03950                 CalDistanceMilliMeter - meanDistance_mm;
03951         }
03952 
03953         if ((Status == VL53L1_ERROR_NONE) &&
03954             (offset_meas_range_B > 0)) {
03955             IncRounding = offset_meas_range_B / 2;
03956             meanDistance_mm = (int16_t)
03957                 ((sum_ranging_range_B + IncRounding)
03958                 / offset_meas_range_B);
03959             offsetB[Repeat] = (int16_t)
03960                 CalDistanceMilliMeter - meanDistance_mm;
03961         }
03962         Repeat++;
03963     }
03964 
03965     if ((SmudgeStatus == VL53L1_ERROR_NONE) && (smudge_corr_en == 1))
03966         SmudgeStatus = VL53L1_dynamic_xtalk_correction_enable(Dev);
03967 
03968     if (Status == VL53L1_ERROR_NONE) {
03969         pdev->per_vcsel_cal_data.short_a_offset_mm  = offsetA[0];
03970         pdev->per_vcsel_cal_data.short_b_offset_mm  = offsetB[0];
03971         pdev->per_vcsel_cal_data.medium_a_offset_mm = offsetA[1];
03972         pdev->per_vcsel_cal_data.medium_b_offset_mm = offsetB[1];
03973         pdev->per_vcsel_cal_data.long_a_offset_mm   = offsetA[2];
03974         pdev->per_vcsel_cal_data.long_b_offset_mm   = offsetB[2];
03975     }
03976 
03977     VL53L1_SetPresetMode(Dev, currentMode);
03978     VL53L1_SetDistanceMode(Dev, currentDist);
03979 
03980     LOG_FUNCTION_END(Status);
03981     return Status;
03982 }
03983 
03984