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