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