Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: X_NUCLEO_COMMON ST_INTERFACES
Dependents: VL53L3CX_NoShield_1Sensor_poll_Mb06x VL53L3_NoShield_1Sensor_polling_Mb63 X_NUCLEO_53L3A2 53L3A2_Ranging
vl53lx_api_calibration.c
00001 00002 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 00003 /****************************************************************************** 00004 * Copyright (c) 2020, STMicroelectronics - All Rights Reserved 00005 00006 This file is part of VL53LX and is dual licensed, 00007 either GPL-2.0+ 00008 or 'BSD 3-clause "New" or "Revised" License' , at your option. 00009 ****************************************************************************** 00010 */ 00011 00012 00013 00014 00015 00016 #include "vl53lx_platform.h" 00017 #include "vl53lx_platform_ipp.h" 00018 #include "vl53lx_ll_def.h" 00019 #include "vl53lx_ll_device.h" 00020 #include "vl53lx_register_map.h" 00021 #include "vl53lx_register_funcs.h" 00022 #include "vl53lx_register_settings.h" 00023 #include "vl53lx_hist_map.h" 00024 #include "vl53lx_hist_structs.h" 00025 #include "vl53lx_core.h" 00026 #include "vl53lx_wait.h" 00027 #include "vl53lx_api_preset_modes.h" 00028 #include "vl53lx_silicon_core.h" 00029 #include "vl53lx_api_core.h" 00030 #include "vl53lx_api_calibration.h" 00031 00032 #ifdef VL53LX_LOG_ENABLE 00033 #include "vl53lx_api_debug.h" 00034 #endif 00035 00036 00037 #define LOG_FUNCTION_START(fmt, ...) \ 00038 _LOG_FUNCTION_START(VL53LX_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__) 00039 #define LOG_FUNCTION_END(status, ...) \ 00040 _LOG_FUNCTION_END(VL53LX_TRACE_MODULE_CORE, status, ##__VA_ARGS__) 00041 #define LOG_FUNCTION_END_FMT(status, fmt, ...) \ 00042 _LOG_FUNCTION_END_FMT(VL53LX_TRACE_MODULE_CORE, status, \ 00043 fmt, ##__VA_ARGS__) 00044 00045 #define trace_print(level, ...) \ 00046 _LOG_TRACE_PRINT(VL53LX_TRACE_MODULE_CORE, \ 00047 level, VL53LX_TRACE_FUNCTION_NONE, ##__VA_ARGS__) 00048 00049 00050 VL53LX_Error VL53LX_run_ref_spad_char( 00051 VL53LX_DEV Dev, 00052 VL53LX_Error *pcal_status) 00053 { 00054 00055 00056 VL53LX_Error status = VL53LX_ERROR_NONE; 00057 VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); 00058 00059 uint8_t comms_buffer[6]; 00060 00061 VL53LX_refspadchar_config_t *prefspadchar = &(pdev->refspadchar); 00062 00063 LOG_FUNCTION_START(""); 00064 00065 00066 00067 if (status == VL53LX_ERROR_NONE) 00068 status = VL53LX_enable_powerforce(Dev); 00069 00070 00071 00072 if (status == VL53LX_ERROR_NONE) 00073 status = 00074 VL53LX_set_ref_spad_char_config( 00075 Dev, 00076 prefspadchar->VL53LX_p_005, 00077 prefspadchar->timeout_us, 00078 prefspadchar->target_count_rate_mcps, 00079 prefspadchar->max_count_rate_limit_mcps, 00080 prefspadchar->min_count_rate_limit_mcps, 00081 pdev->stat_nvm.osc_measured__fast_osc__frequency); 00082 00083 00084 00085 if (status == VL53LX_ERROR_NONE) 00086 status = VL53LX_run_device_test( 00087 Dev, 00088 prefspadchar->device_test_mode); 00089 00090 00091 00092 if (status == VL53LX_ERROR_NONE) 00093 status = 00094 VL53LX_ReadMulti( 00095 Dev, 00096 VL53LX_REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS, 00097 comms_buffer, 00098 2); 00099 00100 if (status == VL53LX_ERROR_NONE) { 00101 pdev->dbg_results.ref_spad_char_result__num_actual_ref_spads = 00102 comms_buffer[0]; 00103 pdev->dbg_results.ref_spad_char_result__ref_location = 00104 comms_buffer[1]; 00105 } 00106 00107 00108 00109 if (status == VL53LX_ERROR_NONE) 00110 status = 00111 VL53LX_WriteMulti( 00112 Dev, 00113 VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS, 00114 comms_buffer, 00115 2); 00116 00117 if (status == VL53LX_ERROR_NONE) { 00118 pdev->customer.ref_spad_man__num_requested_ref_spads = 00119 comms_buffer[0]; 00120 pdev->customer.ref_spad_man__ref_location = 00121 comms_buffer[1]; 00122 } 00123 00124 00125 00126 if (status == VL53LX_ERROR_NONE) 00127 status = 00128 VL53LX_ReadMulti( 00129 Dev, 00130 VL53LX_RESULT__SPARE_0_SD1, 00131 comms_buffer, 00132 6); 00133 00134 00135 00136 if (status == VL53LX_ERROR_NONE) 00137 status = 00138 VL53LX_WriteMulti( 00139 Dev, 00140 VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, 00141 comms_buffer, 00142 6); 00143 00144 if (status == VL53LX_ERROR_NONE) { 00145 pdev->customer.global_config__spad_enables_ref_0 = 00146 comms_buffer[0]; 00147 pdev->customer.global_config__spad_enables_ref_1 = 00148 comms_buffer[1]; 00149 pdev->customer.global_config__spad_enables_ref_2 = 00150 comms_buffer[2]; 00151 pdev->customer.global_config__spad_enables_ref_3 = 00152 comms_buffer[3]; 00153 pdev->customer.global_config__spad_enables_ref_4 = 00154 comms_buffer[4]; 00155 pdev->customer.global_config__spad_enables_ref_5 = 00156 comms_buffer[5]; 00157 } 00158 00159 #ifdef VL53LX_LOG_ENABLE 00160 00161 if (status == VL53LX_ERROR_NONE) 00162 VL53LX_print_customer_nvm_managed( 00163 &(pdev->customer), 00164 "run_ref_spad_char():pdev->lldata.customer.", 00165 VL53LX_TRACE_MODULE_REF_SPAD_CHAR); 00166 #endif 00167 00168 if (status == VL53LX_ERROR_NONE) { 00169 00170 switch (pdev->sys_results.result__range_status) { 00171 00172 case VL53LX_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS: 00173 status = VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS; 00174 break; 00175 00176 case VL53LX_DEVICEERROR_REFSPADCHARMORETHANTARGET: 00177 status = VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH; 00178 break; 00179 00180 case VL53LX_DEVICEERROR_REFSPADCHARLESSTHANTARGET: 00181 status = VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW; 00182 break; 00183 } 00184 } 00185 00186 00187 00188 *pcal_status = status; 00189 00190 00191 00192 IGNORE_STATUS( 00193 IGNORE_REF_SPAD_CHAR_NOT_ENOUGH_SPADS, 00194 VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS, 00195 status); 00196 00197 IGNORE_STATUS( 00198 IGNORE_REF_SPAD_CHAR_RATE_TOO_HIGH, 00199 VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH, 00200 status); 00201 00202 IGNORE_STATUS( 00203 IGNORE_REF_SPAD_CHAR_RATE_TOO_LOW, 00204 VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW, 00205 status); 00206 00207 00208 LOG_FUNCTION_END(status); 00209 00210 return status; 00211 } 00212 00213 00214 VL53LX_Error VL53LX_get_and_avg_xtalk_samples( 00215 VL53LX_DEV Dev, 00216 uint8_t num_of_samples, 00217 uint8_t measurement_mode, 00218 int16_t xtalk_filter_thresh_max_mm, 00219 int16_t xtalk_filter_thresh_min_mm, 00220 uint16_t xtalk_max_valid_rate_kcps, 00221 uint8_t xtalk_result_id, 00222 uint8_t xtalk_histo_id, 00223 VL53LX_xtalk_range_results_t *pXR, 00224 VL53LX_histogram_bin_data_t *psum_histo, 00225 VL53LX_histogram_bin_data_t *pavg_histo) 00226 { 00227 00228 00229 00230 VL53LX_Error status = VL53LX_ERROR_NONE; 00231 VL53LX_LLDriverData_t *pdev = 00232 VL53LXDevStructGetLLDriverHandle(Dev); 00233 00234 #ifdef VL53LX_LOG_ENABLE 00235 VL53LX_LLDriverResults_t *pres = 00236 VL53LXDevStructGetLLResultsHandle(Dev); 00237 #endif 00238 00239 VL53LX_range_results_t *prs = 00240 (VL53LX_range_results_t *) pdev->wArea1; 00241 00242 VL53LX_range_data_t *prange_data; 00243 VL53LX_xtalk_range_data_t *pxtalk_range_data; 00244 00245 uint8_t i = 0; 00246 uint8_t j = 0; 00247 uint8_t zone_id = 0; 00248 uint8_t final_zone = pdev->zone_cfg.active_zones+1; 00249 uint8_t valid_result; 00250 00251 uint8_t smudge_corr_en = 0; 00252 00253 00254 00255 00256 smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled; 00257 00258 status = VL53LX_dynamic_xtalk_correction_disable(Dev); 00259 00260 00261 VL53LX_load_patch(Dev); 00262 00263 00264 00265 if (status == VL53LX_ERROR_NONE) 00266 status = 00267 VL53LX_init_and_start_range( 00268 Dev, 00269 measurement_mode, 00270 VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); 00271 00272 00273 for (i = 0; i <= (final_zone*num_of_samples); i++) { 00274 00275 00276 00277 if (status == VL53LX_ERROR_NONE) 00278 status = VL53LX_wait_for_range_completion(Dev); 00279 00280 00281 00282 if (status == VL53LX_ERROR_NONE) 00283 status = 00284 VL53LX_get_device_results( 00285 Dev, 00286 VL53LX_DEVICERESULTSLEVEL_FULL, 00287 prs); 00288 00289 00290 00291 if (status == VL53LX_ERROR_NONE && 00292 pdev->ll_state.rd_device_state != 00293 VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) { 00294 00295 zone_id = pdev->ll_state.rd_zone_id + xtalk_result_id; 00296 prange_data = &(prs->VL53LX_p_003[0]); 00297 00298 00299 if (prs->active_results > 1) { 00300 for (j = 1; 00301 j < prs->active_results; j++) { 00302 if (prs->VL53LX_p_003[j].median_range_mm 00303 < 00304 prange_data->median_range_mm) 00305 prange_data = 00306 &(prs->VL53LX_p_003[j]); 00307 00308 } 00309 } 00310 00311 pxtalk_range_data = &(pXR->VL53LX_p_003[zone_id]); 00312 00313 00314 00315 if ((prs->active_results > 0) && 00316 (prange_data->median_range_mm < 00317 xtalk_filter_thresh_max_mm) && 00318 (prange_data->median_range_mm > 00319 xtalk_filter_thresh_min_mm) && 00320 (prange_data->VL53LX_p_009 < 00321 (uint32_t)(xtalk_max_valid_rate_kcps * 16))) 00322 valid_result = 1; 00323 else 00324 valid_result = 0; 00325 00326 if (valid_result == 1) { 00327 00328 pxtalk_range_data->no_of_samples++; 00329 00330 pxtalk_range_data->rate_per_spad_kcps_sum += 00331 prange_data->VL53LX_p_009; 00332 00333 pxtalk_range_data->signal_total_events_sum += 00334 prange_data->VL53LX_p_010; 00335 00336 pxtalk_range_data->sigma_mm_sum += 00337 (uint32_t)prange_data->VL53LX_p_002; 00338 00339 00340 00341 pxtalk_range_data->median_phase_sum += 00342 (uint32_t)prange_data->VL53LX_p_011; 00343 00344 00345 00346 00347 } 00348 00349 if ((valid_result == 1) && (zone_id >= 4)) { 00350 status = VL53LX_sum_histogram_data( 00351 &(pdev->hist_data), 00352 psum_histo); 00353 00354 00355 00356 if (prange_data->VL53LX_p_012 < 00357 pXR->central_histogram__window_start) 00358 pXR->central_histogram__window_start = 00359 prange_data->VL53LX_p_012; 00360 00361 00362 if (prange_data->VL53LX_p_013 > 00363 pXR->central_histogram__window_end) 00364 pXR->central_histogram__window_end = 00365 prange_data->VL53LX_p_013; 00366 00367 } 00368 00369 } 00370 00371 00372 00373 #ifdef VL53LX_LOG_ENABLE 00374 if (status == VL53LX_ERROR_NONE) { 00375 VL53LX_print_range_results( 00376 &(pres->range_results), 00377 "pres->range_results.", 00378 VL53LX_TRACE_MODULE_CORE); 00379 } 00380 #endif 00381 00382 00383 00384 if (status == VL53LX_ERROR_NONE) 00385 status = VL53LX_wait_for_firmware_ready(Dev); 00386 00387 00388 00389 if (status == VL53LX_ERROR_NONE) 00390 status = 00391 VL53LX_clear_interrupt_and_enable_next_range( 00392 Dev, 00393 measurement_mode); 00394 00395 00396 } 00397 00398 00399 00400 00401 if (status == VL53LX_ERROR_NONE) 00402 status = VL53LX_stop_range(Dev); 00403 00404 VL53LX_unload_patch(Dev); 00405 00406 00407 00408 for (i = 0; i < (pdev->zone_cfg.active_zones+1); i++) { 00409 00410 pxtalk_range_data = &(pXR->VL53LX_p_003[i+xtalk_result_id]); 00411 00412 if (pxtalk_range_data->no_of_samples > 0) { 00413 pxtalk_range_data->rate_per_spad_kcps_avg = 00414 pxtalk_range_data->rate_per_spad_kcps_sum / 00415 (uint32_t)pxtalk_range_data->no_of_samples; 00416 00417 pxtalk_range_data->signal_total_events_avg = 00418 pxtalk_range_data->signal_total_events_sum / 00419 (int32_t)pxtalk_range_data->no_of_samples; 00420 00421 pxtalk_range_data->sigma_mm_avg = 00422 pxtalk_range_data->sigma_mm_sum / 00423 (uint32_t)pxtalk_range_data->no_of_samples; 00424 00425 00426 00427 pxtalk_range_data->median_phase_avg = 00428 pxtalk_range_data->median_phase_sum / 00429 (uint32_t)pxtalk_range_data->no_of_samples; 00430 00431 00432 00433 } else { 00434 pxtalk_range_data->rate_per_spad_kcps_avg = 00435 pxtalk_range_data->rate_per_spad_kcps_sum; 00436 pxtalk_range_data->signal_total_events_avg = 00437 pxtalk_range_data->signal_total_events_sum; 00438 pxtalk_range_data->sigma_mm_avg = 00439 pxtalk_range_data->sigma_mm_sum; 00440 00441 00442 00443 pxtalk_range_data->median_phase_avg = 00444 pxtalk_range_data->median_phase_sum; 00445 00446 00447 } 00448 } 00449 00450 00451 00452 memcpy(pavg_histo, &(pdev->hist_data), 00453 sizeof(VL53LX_histogram_bin_data_t)); 00454 00455 00456 00457 if (status == VL53LX_ERROR_NONE) { 00458 00459 pxtalk_range_data = &(pXR->VL53LX_p_003[xtalk_histo_id]); 00460 00461 status = VL53LX_avg_histogram_data( 00462 pxtalk_range_data->no_of_samples, 00463 psum_histo, 00464 pavg_histo); 00465 } 00466 00467 00468 00469 00470 if (status == VL53LX_ERROR_NONE) { 00471 if (smudge_corr_en == 1) 00472 status = VL53LX_dynamic_xtalk_correction_enable(Dev); 00473 } 00474 00475 00476 LOG_FUNCTION_END(status); 00477 00478 return status; 00479 00480 } 00481 00482 00483 VL53LX_Error VL53LX_run_phasecal_average( 00484 VL53LX_DEV Dev, 00485 uint8_t measurement_mode, 00486 uint8_t phasecal_result__vcsel_start, 00487 uint16_t phasecal_num_of_samples, 00488 VL53LX_range_results_t *prange_results, 00489 uint16_t *pphasecal_result__reference_phase, 00490 uint16_t *pzero_distance_phase) 00491 { 00492 00493 00494 VL53LX_Error status = VL53LX_ERROR_NONE; 00495 VL53LX_LLDriverData_t *pdev = 00496 VL53LXDevStructGetLLDriverHandle(Dev); 00497 00498 uint16_t i = 0; 00499 uint16_t m = 0; 00500 uint32_t samples = 0; 00501 00502 uint32_t period = 0; 00503 uint32_t VL53LX_p_014 = 0; 00504 uint32_t phasecal_result__reference_phase = 0; 00505 uint32_t zero_distance_phase = 0; 00506 00507 00508 VL53LX_load_patch(Dev); 00509 00510 for (m = 0; m < phasecal_num_of_samples; m++) { 00511 00512 00513 00514 if (status == VL53LX_ERROR_NONE) 00515 status = 00516 VL53LX_init_and_start_range( 00517 Dev, 00518 measurement_mode, 00519 VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); 00520 00521 for (i = 0; i <= 1; i++) { 00522 00523 00524 00525 if (status == VL53LX_ERROR_NONE) 00526 status = 00527 VL53LX_wait_for_range_completion(Dev); 00528 00529 00530 00531 if (status == VL53LX_ERROR_NONE) 00532 status = 00533 VL53LX_get_device_results( 00534 Dev, 00535 VL53LX_DEVICERESULTSLEVEL_FULL, 00536 prange_results); 00537 00538 00539 00540 if (status == VL53LX_ERROR_NONE) 00541 status = 00542 VL53LX_wait_for_firmware_ready(Dev); 00543 00544 00545 00546 if (status == VL53LX_ERROR_NONE) 00547 status = 00548 VL53LX_clear_interrupt_and_enable_next_range( 00549 Dev, 00550 measurement_mode); 00551 } 00552 00553 00554 00555 if (status == VL53LX_ERROR_NONE) 00556 status = VL53LX_stop_range(Dev); 00557 00558 00559 00560 if (status == VL53LX_ERROR_NONE) 00561 status = VL53LX_WaitUs(Dev, 1000); 00562 00563 00564 00565 if (status == VL53LX_ERROR_NONE) { 00566 00567 samples++; 00568 00569 00570 period = 2048 * 00571 (uint32_t)VL53LX_decode_vcsel_period( 00572 pdev->hist_data.VL53LX_p_005); 00573 00574 VL53LX_p_014 = period; 00575 VL53LX_p_014 += (uint32_t)( 00576 pdev->hist_data.phasecal_result__reference_phase); 00577 VL53LX_p_014 += 00578 (2048 * 00579 (uint32_t)phasecal_result__vcsel_start); 00580 VL53LX_p_014 -= (2048 * 00581 (uint32_t)pdev->hist_data.cal_config__vcsel_start); 00582 00583 VL53LX_p_014 = VL53LX_p_014 % period; 00584 00585 phasecal_result__reference_phase += (uint32_t)( 00586 pdev->hist_data.phasecal_result__reference_phase); 00587 00588 zero_distance_phase += (uint32_t)VL53LX_p_014; 00589 } 00590 } 00591 VL53LX_unload_patch(Dev); 00592 00593 00594 00595 if (status == VL53LX_ERROR_NONE && samples > 0) { 00596 00597 phasecal_result__reference_phase += (samples >> 1); 00598 phasecal_result__reference_phase /= samples; 00599 00600 zero_distance_phase += (samples >> 1); 00601 zero_distance_phase /= samples; 00602 00603 *pphasecal_result__reference_phase = 00604 (uint16_t)phasecal_result__reference_phase; 00605 *pzero_distance_phase = 00606 (uint16_t)zero_distance_phase; 00607 } 00608 00609 return status; 00610 } 00611 00612 00613 VL53LX_Error VL53LX_run_device_test( 00614 VL53LX_DEV Dev, 00615 VL53LX_DeviceTestMode device_test_mode) 00616 { 00617 00618 00619 VL53LX_Error status = VL53LX_ERROR_NONE; 00620 VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); 00621 00622 uint8_t comms_buffer[2]; 00623 uint8_t gpio_hv_mux__ctrl = 0; 00624 00625 LOG_FUNCTION_START(""); 00626 00627 00628 00629 if (status == VL53LX_ERROR_NONE) 00630 status = 00631 VL53LX_RdByte( 00632 Dev, 00633 VL53LX_GPIO_HV_MUX__CTRL, 00634 &gpio_hv_mux__ctrl); 00635 00636 if (status == VL53LX_ERROR_NONE) 00637 pdev->stat_cfg.gpio_hv_mux__ctrl = gpio_hv_mux__ctrl; 00638 00639 00640 if (status == VL53LX_ERROR_NONE) 00641 status = VL53LX_start_test( 00642 Dev, 00643 device_test_mode); 00644 00645 00646 if (status == VL53LX_ERROR_NONE) 00647 status = VL53LX_wait_for_test_completion(Dev); 00648 00649 00650 if (status == VL53LX_ERROR_NONE) 00651 status = 00652 VL53LX_ReadMulti( 00653 Dev, 00654 VL53LX_RESULT__RANGE_STATUS, 00655 comms_buffer, 00656 2); 00657 00658 if (status == VL53LX_ERROR_NONE) { 00659 pdev->sys_results.result__range_status = comms_buffer[0]; 00660 pdev->sys_results.result__report_status = comms_buffer[1]; 00661 } 00662 00663 00664 00665 pdev->sys_results.result__range_status &= 00666 VL53LX_RANGE_STATUS__RANGE_STATUS_MASK; 00667 00668 if (status == VL53LX_ERROR_NONE) { 00669 trace_print( 00670 VL53LX_TRACE_LEVEL_INFO, 00671 " Device Test Complete:\n\t%-32s = %3u\n\t%-32s = %3u\n", 00672 "result__range_status", 00673 pdev->sys_results.result__range_status, 00674 "result__report_status", 00675 pdev->sys_results.result__report_status); 00676 00677 00678 if (status == VL53LX_ERROR_NONE) 00679 status = VL53LX_clear_interrupt(Dev); 00680 } 00681 00682 00683 00684 if (status == VL53LX_ERROR_NONE) 00685 status = 00686 VL53LX_start_test( 00687 Dev, 00688 0x00); 00689 00690 LOG_FUNCTION_END(status); 00691 00692 return status; 00693 } 00694 00695 00696 void VL53LX_hist_xtalk_extract_data_init( 00697 VL53LX_hist_xtalk_extract_data_t *pxtalk_data) 00698 { 00699 00700 00701 int32_t lb = 0; 00702 00703 pxtalk_data->sample_count = 0U; 00704 pxtalk_data->pll_period_mm = 0U; 00705 pxtalk_data->peak_duration_us_sum = 0U; 00706 pxtalk_data->effective_spad_count_sum = 0U; 00707 pxtalk_data->zero_distance_phase_sum = 0U; 00708 pxtalk_data->zero_distance_phase_avg = 0U; 00709 pxtalk_data->event_scaler_sum = 0U; 00710 pxtalk_data->event_scaler_avg = 4096U; 00711 pxtalk_data->signal_events_sum = 0; 00712 pxtalk_data->xtalk_rate_kcps_per_spad = 0U; 00713 pxtalk_data->VL53LX_p_012 = 0U; 00714 pxtalk_data->VL53LX_p_013 = 0U; 00715 pxtalk_data->target_start = 0U; 00716 00717 for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) 00718 pxtalk_data->bin_data_sums[lb] = 0; 00719 00720 } 00721 00722 00723 VL53LX_Error VL53LX_hist_xtalk_extract_update( 00724 int16_t target_distance_mm, 00725 uint16_t target_width_oversize, 00726 VL53LX_histogram_bin_data_t *phist_bins, 00727 VL53LX_hist_xtalk_extract_data_t *pxtalk_data) 00728 { 00729 00730 00731 VL53LX_Error status = VL53LX_ERROR_NONE; 00732 00733 LOG_FUNCTION_START(""); 00734 00735 status = 00736 VL53LX_hist_xtalk_extract_calc_window( 00737 target_distance_mm, 00738 target_width_oversize, 00739 phist_bins, 00740 pxtalk_data); 00741 00742 if (status == VL53LX_ERROR_NONE) { 00743 status = 00744 VL53LX_hist_xtalk_extract_calc_event_sums( 00745 phist_bins, 00746 pxtalk_data); 00747 } 00748 00749 LOG_FUNCTION_END(status); 00750 00751 return status; 00752 } 00753 00754 00755 VL53LX_Error VL53LX_hist_xtalk_extract_fini( 00756 VL53LX_histogram_bin_data_t *phist_bins, 00757 VL53LX_hist_xtalk_extract_data_t *pxtalk_data, 00758 VL53LX_xtalk_calibration_results_t *pxtalk_cal, 00759 VL53LX_xtalk_histogram_shape_t *pxtalk_shape) 00760 { 00761 00762 00763 VL53LX_Error status = VL53LX_ERROR_NONE; 00764 VL53LX_xtalk_calibration_results_t *pX = pxtalk_cal; 00765 00766 LOG_FUNCTION_START(""); 00767 00768 if (pxtalk_data->sample_count > 0) { 00769 00770 00771 pxtalk_data->event_scaler_avg = pxtalk_data->event_scaler_sum; 00772 pxtalk_data->event_scaler_avg += 00773 (pxtalk_data->sample_count >> 1); 00774 pxtalk_data->event_scaler_avg /= pxtalk_data->sample_count; 00775 00776 00777 00778 status = 00779 VL53LX_hist_xtalk_extract_calc_rate_per_spad( 00780 pxtalk_data); 00781 00782 00783 00784 if (status == VL53LX_ERROR_NONE) { 00785 00786 00787 pxtalk_data->zero_distance_phase_avg = 00788 pxtalk_data->zero_distance_phase_sum; 00789 pxtalk_data->zero_distance_phase_avg += 00790 (pxtalk_data->sample_count >> 1); 00791 pxtalk_data->zero_distance_phase_avg /= 00792 pxtalk_data->sample_count; 00793 00794 00795 status = 00796 VL53LX_hist_xtalk_extract_calc_shape( 00797 pxtalk_data, 00798 pxtalk_shape); 00799 00800 00801 00802 00803 pxtalk_shape->phasecal_result__vcsel_start = 00804 phist_bins->phasecal_result__vcsel_start; 00805 pxtalk_shape->cal_config__vcsel_start = 00806 phist_bins->cal_config__vcsel_start; 00807 pxtalk_shape->vcsel_width = 00808 phist_bins->vcsel_width; 00809 pxtalk_shape->VL53LX_p_015 = 00810 phist_bins->VL53LX_p_015; 00811 } 00812 00813 00814 if (status == VL53LX_ERROR_NONE) { 00815 00816 00817 pX->algo__crosstalk_compensation_plane_offset_kcps = 00818 pxtalk_data->xtalk_rate_kcps_per_spad; 00819 pX->algo__crosstalk_compensation_x_plane_gradient_kcps 00820 = 0U; 00821 pX->algo__crosstalk_compensation_y_plane_gradient_kcps 00822 = 0U; 00823 00824 } 00825 } 00826 00827 LOG_FUNCTION_END(status); 00828 00829 return status; 00830 } 00831 00832 00833 VL53LX_Error VL53LX_run_hist_xtalk_extraction( 00834 VL53LX_DEV Dev, 00835 int16_t cal_distance_mm, 00836 VL53LX_Error *pcal_status) 00837 { 00838 00839 00840 #define OVERSIZE 4 00841 VL53LX_Error status = VL53LX_ERROR_NONE; 00842 VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); 00843 VL53LX_xtalkextract_config_t *pX = &(pdev->xtalk_extract_cfg); 00844 VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg); 00845 VL53LX_xtalk_calibration_results_t *pXC = &(pdev->xtalk_cal); 00846 00847 00848 00849 uint8_t smudge_corr_en = 0; 00850 uint8_t i = 0; 00851 int8_t k = 0; 00852 uint8_t nbloops; 00853 int32_t initMergeSize = 0; 00854 int32_t MergeEnabled = 0; 00855 uint32_t deltaXtalk; 00856 uint32_t stepXtalk; 00857 uint32_t XtalkMin; 00858 uint32_t XtalkMax; 00859 uint8_t measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; 00860 int8_t MaxId; 00861 uint8_t histo_merge_nb; 00862 uint8_t wait_for_accumulation; 00863 VL53LX_range_results_t *prange_results = 00864 (VL53LX_range_results_t *) pdev->wArea1; 00865 uint8_t Very1stRange = 0; 00866 00867 LOG_FUNCTION_START(""); 00868 00869 00870 00871 if (status == VL53LX_ERROR_NONE) 00872 status = 00873 VL53LX_set_preset_mode( 00874 Dev, 00875 VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE, 00876 pX->dss_config__target_total_rate_mcps, 00877 pX->phasecal_config_timeout_us, 00878 pX->mm_config_timeout_us, 00879 pX->range_config_timeout_us, 00880 100); 00881 00882 00883 00884 if (status == VL53LX_ERROR_NONE) 00885 status = VL53LX_disable_xtalk_compensation(Dev); 00886 00887 00888 00889 smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled; 00890 00891 if (status == VL53LX_ERROR_NONE) 00892 status = VL53LX_dynamic_xtalk_correction_disable(Dev); 00893 00894 00895 VL53LX_load_patch(Dev); 00896 00897 VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, 00898 &initMergeSize); 00899 VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE, 00900 &MergeEnabled); 00901 memset(&pdev->xtalk_cal, 0, sizeof(pdev->xtalk_cal)); 00902 00903 if (status == VL53LX_ERROR_NONE) 00904 status = VL53LX_init_and_start_range( 00905 Dev, measurement_mode, 00906 VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); 00907 00908 MaxId = pdev->tuning_parms.tp_hist_merge_max_size - 1; 00909 nbloops = (MergeEnabled == 0 ? 1 : 2); 00910 for (k = 0; k < nbloops; k++) { 00911 00912 VL53LX_hist_xtalk_extract_data_init( 00913 &(pdev->xtalk_extract)); 00914 VL53LX_set_tuning_parm(Dev, 00915 VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, 00916 k * MaxId + 1); 00917 00918 for (i = 0; i <= pX->num_of_samples; i++) { 00919 if (status == VL53LX_ERROR_NONE) 00920 status = VL53LX_wait_for_range_completion(Dev); 00921 if (status == VL53LX_ERROR_NONE) 00922 status = VL53LX_get_device_results(Dev, 00923 VL53LX_DEVICERESULTSLEVEL_FULL, 00924 prange_results); 00925 Very1stRange = 00926 (pdev->ll_state.rd_device_state == 00927 VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC); 00928 00929 VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb); 00930 wait_for_accumulation = ((k != 0) && 00931 (MergeEnabled) && 00932 (status == VL53LX_ERROR_NONE) && 00933 (histo_merge_nb < 00934 pdev->tuning_parms.tp_hist_merge_max_size)); 00935 if (wait_for_accumulation) 00936 i = 0; 00937 else { 00938 if ((status == VL53LX_ERROR_NONE) && 00939 (!Very1stRange)) { 00940 status = 00941 VL53LX_hist_xtalk_extract_update( 00942 cal_distance_mm, 00943 OVERSIZE, 00944 &(pdev->hist_data), 00945 &(pdev->xtalk_extract)); 00946 } 00947 } 00948 00949 if (status == VL53LX_ERROR_NONE) 00950 status = VL53LX_wait_for_firmware_ready(Dev); 00951 if (status == VL53LX_ERROR_NONE) 00952 status = 00953 VL53LX_clear_interrupt_and_enable_next_range( 00954 Dev, measurement_mode); 00955 00956 00957 if (status == VL53LX_ERROR_NONE) 00958 status = 00959 VL53LX_hist_xtalk_extract_fini( 00960 &(pdev->hist_data), 00961 &(pdev->xtalk_extract), 00962 &(pdev->xtalk_cal), 00963 &(pdev->xtalk_shapes.xtalk_shape)); 00964 if (status != VL53LX_ERROR_NONE) 00965 goto LOOPOUT; 00966 pXC->algo__xtalk_cpo_HistoMerge_kcps[k * MaxId] = 00967 pXC->algo__crosstalk_compensation_plane_offset_kcps; 00968 } 00969 } 00970 00971 LOOPOUT: 00972 00973 VL53LX_stop_range(Dev); 00974 00975 VL53LX_set_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, 00976 initMergeSize); 00977 VL53LX_unload_patch(Dev); 00978 00979 if (status != VL53LX_ERROR_NONE) 00980 status = VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL; 00981 else if ((MergeEnabled == 1) && (MaxId > 0)) { 00982 XtalkMin = pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0]; 00983 XtalkMax = 00984 pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[MaxId]; 00985 pdev->xtalk_cal. 00986 algo__crosstalk_compensation_plane_offset_kcps = XtalkMin; 00987 if (XtalkMax > XtalkMin) { 00988 deltaXtalk = XtalkMax - XtalkMin; 00989 stepXtalk = deltaXtalk / MaxId; 00990 for (k = 1; k < MaxId; k++) 00991 pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[k] = 00992 XtalkMin + stepXtalk * k; 00993 } else 00994 status = 00995 VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL; 00996 } 00997 00998 if (status == VL53LX_ERROR_NONE) { 00999 pC->algo__crosstalk_compensation_x_plane_gradient_kcps = 01000 pXC->algo__crosstalk_compensation_x_plane_gradient_kcps; 01001 pC->algo__crosstalk_compensation_y_plane_gradient_kcps = 01002 pXC->algo__crosstalk_compensation_y_plane_gradient_kcps; 01003 pC->algo__crosstalk_compensation_plane_offset_kcps = 01004 pXC->algo__crosstalk_compensation_plane_offset_kcps; 01005 } 01006 01007 01008 pdev->xtalk_results.cal_status = status; 01009 *pcal_status = pdev->xtalk_results.cal_status; 01010 01011 01012 status = VL53LX_enable_xtalk_compensation(Dev); 01013 if (smudge_corr_en == 1) 01014 status = VL53LX_dynamic_xtalk_correction_enable(Dev); 01015 01016 #ifdef VL53LX_LOG_ENABLE 01017 01018 01019 01020 VL53LX_print_customer_nvm_managed( 01021 &(pdev->customer), 01022 "run_xtalk_extraction():pdev->lldata.customer.", 01023 VL53LX_TRACE_MODULE_XTALK_DATA); 01024 01025 VL53LX_print_xtalk_config( 01026 &(pdev->xtalk_cfg), 01027 "run_xtalk_extraction():pdev->lldata.xtalk_cfg.", 01028 VL53LX_TRACE_MODULE_XTALK_DATA); 01029 01030 VL53LX_print_xtalk_histogram_data( 01031 &(pdev->xtalk_shapes), 01032 "pdev->lldata.xtalk_shapes.", 01033 VL53LX_TRACE_MODULE_XTALK_DATA); 01034 01035 #endif 01036 01037 LOG_FUNCTION_END(status); 01038 01039 return status; 01040 } 01041
Generated on Mon Jul 18 2022 15:35:58 by
1.7.2