ST Expansion SW Team / VL53L1

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   X_NUCLEO_53L1CB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53l1_api_calibration.c Source File

vl53l1_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 VL53L1 and is dual licensed,
00007  either GPL-2.0+
00008  or 'BSD 3-clause "New" or "Revised" License' , at your option.
00009  ******************************************************************************
00010  */
00011 
00012 
00013 
00014 
00015 
00016 #include "vl53l1_ll_def.h"
00017 #include "vl53l1_ll_device.h"
00018 #include "vl53l1_platform.h"
00019 #include "vl53l1_platform_ipp.h"
00020 #include "vl53l1_register_map.h"
00021 #include "vl53l1_register_funcs.h"
00022 #include "vl53l1_register_settings.h"
00023 #include "vl53l1_hist_map.h"
00024 #include "vl53l1_hist_structs.h"
00025 #include "vl53l1_core.h"
00026 #include "vl53l1_wait.h"
00027 #include "vl53l1_api_preset_modes.h"
00028 #include "vl53l1_silicon_core.h"
00029 #include "vl53l1_api_core.h"
00030 #include "vl53l1_api_calibration.h"
00031 
00032 #ifdef VL53L1_LOG_ENABLE
00033   #include "vl53l1_api_debug.h"
00034 #endif
00035 
00036 
00037 #define LOG_FUNCTION_START(fmt, ...) \
00038     _LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__)
00039 #define LOG_FUNCTION_END(status, ...) \
00040     _LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__)
00041 #define LOG_FUNCTION_END_FMT(status, fmt, ...) \
00042     _LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, status, \
00043         fmt, ##__VA_ARGS__)
00044 
00045 #define trace_print(level, ...) \
00046     _LOG_TRACE_PRINT(VL53L1_TRACE_MODULE_CORE, \
00047     level, VL53L1_TRACE_FUNCTION_NONE, ##__VA_ARGS__)
00048 
00049 
00050 VL53L1_Error VL53L1_run_ref_spad_char(
00051     VL53L1_DEV        Dev,
00052     VL53L1_Error     *pcal_status)
00053 {
00054 
00055 
00056     VL53L1_Error status = VL53L1_ERROR_NONE;
00057     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
00058 
00059     uint8_t comms_buffer[6];
00060 
00061     VL53L1_refspadchar_config_t *prefspadchar  = &(pdev->refspadchar);
00062 
00063     LOG_FUNCTION_START("");
00064 
00065 
00066 
00067     if (status == VL53L1_ERROR_NONE)
00068         status = VL53L1_enable_powerforce(Dev);
00069 
00070 
00071 
00072     if (status == VL53L1_ERROR_NONE)
00073         status =
00074         VL53L1_set_ref_spad_char_config(
00075             Dev,
00076             prefspadchar->VL53L1_p_009,
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 == VL53L1_ERROR_NONE)
00086         status = VL53L1_run_device_test(
00087                     Dev,
00088                     prefspadchar->device_test_mode);
00089 
00090 
00091 
00092     if (status == VL53L1_ERROR_NONE)
00093         status =
00094         VL53L1_ReadMulti(
00095             Dev,
00096             VL53L1_REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS,
00097             comms_buffer,
00098             2);
00099 
00100     if (status == VL53L1_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 == VL53L1_ERROR_NONE)
00110         status =
00111             VL53L1_WriteMulti(
00112                 Dev,
00113                 VL53L1_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS,
00114                 comms_buffer,
00115                 2);
00116 
00117     if (status == VL53L1_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 == VL53L1_ERROR_NONE)
00127         status =
00128             VL53L1_ReadMulti(
00129                 Dev,
00130                 VL53L1_RESULT__SPARE_0_SD1,
00131                 comms_buffer,
00132                 6);
00133 
00134 
00135 
00136     if (status == VL53L1_ERROR_NONE)
00137         status =
00138             VL53L1_WriteMulti(
00139                 Dev,
00140                 VL53L1_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
00141                 comms_buffer,
00142                 6);
00143 
00144     if (status == VL53L1_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 VL53L1_LOG_ENABLE
00160 
00161     if (status == VL53L1_ERROR_NONE)
00162         VL53L1_print_customer_nvm_managed(
00163             &(pdev->customer),
00164             "run_ref_spad_char():pdev->lldata.customer.",
00165             VL53L1_TRACE_MODULE_REF_SPAD_CHAR);
00166 #endif
00167 
00168     if (status == VL53L1_ERROR_NONE) {
00169 
00170         switch (pdev->sys_results.result__range_status) {
00171 
00172         case VL53L1_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS:
00173             status = VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS;
00174             break;
00175 
00176         case VL53L1_DEVICEERROR_REFSPADCHARMORETHANTARGET:
00177             status = VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH;
00178             break;
00179 
00180         case VL53L1_DEVICEERROR_REFSPADCHARLESSTHANTARGET:
00181             status = VL53L1_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         VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS,
00195         status);
00196 
00197     IGNORE_STATUS(
00198         IGNORE_REF_SPAD_CHAR_RATE_TOO_HIGH,
00199         VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH,
00200         status);
00201 
00202     IGNORE_STATUS(
00203         IGNORE_REF_SPAD_CHAR_RATE_TOO_LOW,
00204         VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW,
00205         status);
00206 
00207 
00208     LOG_FUNCTION_END(status);
00209 
00210     return status;
00211 }
00212 
00213 
00214 VL53L1_Error VL53L1_run_xtalk_extraction(
00215     VL53L1_DEV                          Dev,
00216     VL53L1_Error                       *pcal_status)
00217 {
00218 
00219 
00220     VL53L1_Error status        = VL53L1_ERROR_NONE;
00221     VL53L1_LLDriverData_t *pdev =
00222         VL53L1DevStructGetLLDriverHandle(Dev);
00223 
00224 
00225 
00226     VL53L1_xtalkextract_config_t *pX = &(pdev->xtalk_extract_cfg);
00227     VL53L1_xtalk_config_t *pC = &(pdev->xtalk_cfg);
00228     VL53L1_xtalk_calibration_results_t *pXC = &(pdev->xtalk_cal);
00229 
00230     uint8_t results_invalid  = 0;
00231 
00232     uint8_t i                = 0;
00233     uint16_t tmp16 = 0;
00234 
00235     uint8_t measurement_mode = VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
00236 
00237     LOG_FUNCTION_START("");
00238 
00239 
00240 
00241 
00242 
00243     VL53L1_init_histogram_bin_data_struct(
00244             0,
00245             (uint16_t)VL53L1_HISTOGRAM_BUFFER_SIZE,
00246             &(pdev->xtalk_results.central_histogram_avg));
00247 
00248     VL53L1_init_histogram_bin_data_struct(
00249             0,
00250             (uint16_t)VL53L1_HISTOGRAM_BUFFER_SIZE,
00251             &(pdev->xtalk_results.central_histogram_sum));
00252 
00253 
00254 
00255     if (status == VL53L1_ERROR_NONE)
00256         status =
00257         VL53L1_set_preset_mode(
00258         Dev,
00259         VL53L1_DEVICEPRESETMODE_HISTOGRAM_XTALK_PLANAR,
00260 
00261         pX->dss_config__target_total_rate_mcps,
00262         pX->phasecal_config_timeout_us,
00263         pX->mm_config_timeout_us,
00264         pX->range_config_timeout_us,
00265 
00266         100);
00267 
00268 
00269 
00270     if (status == VL53L1_ERROR_NONE)
00271         status = VL53L1_disable_xtalk_compensation(Dev);
00272 
00273 
00274 
00275     pdev->xtalk_results.max_results    = VL53L1_MAX_XTALK_RANGE_RESULTS;
00276     pdev->xtalk_results.active_results = pdev->zone_cfg.active_zones+1;
00277 
00278 
00279 
00280     pdev->xtalk_results.central_histogram__window_start = 0xFF;
00281     pdev->xtalk_results.central_histogram__window_end   = 0x00;
00282 
00283     pdev->xtalk_results.num_of_samples_status = 0x00;
00284     pdev->xtalk_results.zero_samples_status   = 0x00;
00285     pdev->xtalk_results.max_sigma_status      = 0x00;
00286 
00287     for (i = 0; i < pdev->xtalk_results.max_results; i++) {
00288         pdev->xtalk_results.VL53L1_p_002[i].no_of_samples           = 0;
00289         pdev->xtalk_results.VL53L1_p_002[i].signal_total_events_avg = 0;
00290         pdev->xtalk_results.VL53L1_p_002[i].signal_total_events_sum = 0;
00291         pdev->xtalk_results.VL53L1_p_002[i].rate_per_spad_kcps_sum  = 0;
00292         pdev->xtalk_results.VL53L1_p_002[i].rate_per_spad_kcps_avg  = 0;
00293         pdev->xtalk_results.VL53L1_p_002[i].sigma_mm_sum            = 0;
00294         pdev->xtalk_results.VL53L1_p_002[i].sigma_mm_avg            = 0;
00295 
00296         pdev->xtalk_results.VL53L1_p_002[i].median_phase_sum        = 0;
00297         pdev->xtalk_results.VL53L1_p_002[i].median_phase_avg        = 0;
00298 
00299     }
00300 
00301 
00302     if (status == VL53L1_ERROR_NONE) {
00303 
00304         status =
00305         VL53L1_get_and_avg_xtalk_samples(
00306         Dev,
00307 
00308         pX->num_of_samples,
00309 
00310         measurement_mode,
00311 
00312         pX->algo__crosstalk_extract_max_valid_range_mm,
00313         pX->algo__crosstalk_extract_min_valid_range_mm,
00314         pX->algo__crosstalk_extract_max_valid_rate_kcps,
00315 
00316         0x0,
00317         0x4,
00318         &(pdev->xtalk_results),
00319         &(pdev->xtalk_results.central_histogram_sum),
00320         &(pdev->xtalk_results.central_histogram_avg));
00321     }
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329     if (status == VL53L1_ERROR_NONE)
00330         if ((pdev->xtalk_results.VL53L1_p_002[4].no_of_samples == 0) ||
00331             (pdev->xtalk_results.VL53L1_p_002[4].sigma_mm_avg >
00332             ((uint32_t)pX->algo__crosstalk_extract_max_sigma_mm
00333                     << 5)))
00334             results_invalid = 0x01;
00335 
00336 
00337 
00338 #ifdef VL53L1_LOG_ENABLE
00339     if (status == VL53L1_ERROR_NONE)
00340         VL53L1_print_xtalk_range_results(
00341             &(pdev->xtalk_results),
00342             "pdev->xtalk_results",
00343             VL53L1_TRACE_MODULE_CORE);
00344 #endif
00345 
00346     if ((status == VL53L1_ERROR_NONE) && (results_invalid == 0)) {
00347 
00348         status =
00349             VL53L1_ipp_xtalk_calibration_process_data(
00350                     Dev,
00351                     &(pdev->xtalk_results),
00352                     &(pdev->xtalk_shapes),
00353                     &(pdev->xtalk_cal));
00354 
00355     }
00356     if ((status == VL53L1_ERROR_NONE) && (results_invalid == 0)) {
00357         for (i = 0; i < VL53L1_BIN_REC_SIZE; i++)
00358             pXC->algo__xtalk_cpo_HistoMerge_kcps[i] =
00359             pXC->algo__crosstalk_compensation_plane_offset_kcps;
00360         pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
00361         pXC->algo__crosstalk_compensation_x_plane_gradient_kcps;
00362         pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
00363         pXC->algo__crosstalk_compensation_y_plane_gradient_kcps;
00364         pC->algo__crosstalk_compensation_plane_offset_kcps =
00365         pXC->algo__crosstalk_compensation_plane_offset_kcps;
00366     }
00367 
00368 
00369 
00370     if (status == VL53L1_ERROR_NONE)
00371         status = VL53L1_enable_xtalk_compensation(Dev);
00372 
00373 
00374 
00375 
00376     if (status == VL53L1_ERROR_NONE) {
00377 
00378         for (i = 0; i < pdev->xtalk_results.max_results; i++) {
00379 
00380             if (pdev->xtalk_results.VL53L1_p_002[i].no_of_samples !=
00381 
00382                 pX->num_of_samples) {
00383 
00384                 pdev->xtalk_results.num_of_samples_status =
00385                 pdev->xtalk_results.num_of_samples_status |
00386                     (1 << i);
00387             }
00388 
00389             if (pdev->xtalk_results.VL53L1_p_002[i].no_of_samples ==
00390                 0x00) {
00391                 pdev->xtalk_results.zero_samples_status =
00392                 pdev->xtalk_results.zero_samples_status |
00393                     (1 << i);
00394             }
00395 
00396 
00397 
00398 
00399             tmp16 = pX->algo__crosstalk_extract_max_sigma_mm;
00400             if (pdev->xtalk_results.VL53L1_p_002[i].sigma_mm_avg >
00401                 ((uint32_t)tmp16 << 5)) {
00402                 pdev->xtalk_results.max_sigma_status =
00403                     pdev->xtalk_results.max_sigma_status |
00404                     (1 << i);
00405             }
00406 
00407         }
00408     }
00409 
00410 
00411     if (results_invalid > 0) {
00412 
00413         if (pdev->xtalk_results.VL53L1_p_002[4].no_of_samples == 0) {
00414             status = VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL;
00415         } else {
00416 
00417 
00418             if (pdev->xtalk_results.VL53L1_p_002[4].sigma_mm_avg >
00419             (((uint32_t)pX->algo__crosstalk_extract_max_sigma_mm)
00420                 << 5)) {
00421                 status =
00422                 VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
00423             }
00424 
00425         }
00426     } else {
00427 
00428         if (pdev->xtalk_results.zero_samples_status != 0x00) {
00429             status = VL53L1_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT;
00430         } else {
00431             if (pdev->xtalk_results.max_sigma_status != 0x00) {
00432                 status =
00433                 VL53L1_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT;
00434             } else {
00435                 if (pdev->xtalk_results.num_of_samples_status !=
00436                         0x00)
00437                     status =
00438                     VL53L1_WARNING_XTALK_MISSING_SAMPLES;
00439             }
00440         }
00441     }
00442 
00443 
00444 
00445     pdev->xtalk_results.cal_status = status;
00446     *pcal_status = pdev->xtalk_results.cal_status;
00447 
00448 
00449 
00450     IGNORE_STATUS(
00451         IGNORE_XTALK_EXTRACTION_NO_SAMPLE_FAIL,
00452         VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL,
00453         status);
00454 
00455     IGNORE_STATUS(
00456         IGNORE_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL,
00457         VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL,
00458         status);
00459 
00460     IGNORE_STATUS(
00461         IGNORE_XTALK_EXTRACTION_NO_SAMPLE_FOR_GRADIENT_WARN,
00462         VL53L1_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT,
00463         status);
00464 
00465     IGNORE_STATUS(
00466         IGNORE_XTALK_EXTRACTION_SIGMA_LIMIT_FOR_GRADIENT_WARN,
00467         VL53L1_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT,
00468         status);
00469 
00470     IGNORE_STATUS(
00471         IGNORE_XTALK_EXTRACTION_MISSING_SAMPLES_WARN,
00472         VL53L1_WARNING_XTALK_MISSING_SAMPLES,
00473         status);
00474 
00475 #ifdef VL53L1_LOG_ENABLE
00476 
00477 
00478 
00479     VL53L1_print_customer_nvm_managed(
00480         &(pdev->customer),
00481         "run_xtalk_extraction():pdev->lldata.customer.",
00482         VL53L1_TRACE_MODULE_XTALK_DATA);
00483 
00484     VL53L1_print_xtalk_config(
00485         &(pdev->xtalk_cfg),
00486         "run_xtalk_extraction():pdev->lldata.xtalk_cfg.",
00487         VL53L1_TRACE_MODULE_XTALK_DATA);
00488 
00489     VL53L1_print_xtalk_extract_config(
00490         &(pdev->xtalk_extract_cfg),
00491         "run_xtalk_extraction():pdev->lldata.xtalk_extract_cfg.",
00492         VL53L1_TRACE_MODULE_XTALK_DATA);
00493 
00494     VL53L1_print_histogram_bin_data(
00495         &(pdev->hist_data),
00496         "run_xtalk_extraction():pdev->lldata.hist_data.",
00497         VL53L1_TRACE_MODULE_XTALK_DATA);
00498 
00499     VL53L1_print_xtalk_histogram_data(
00500         &(pdev->xtalk_shapes),
00501         "pdev->lldata.xtalk_shapes.",
00502         VL53L1_TRACE_MODULE_XTALK_DATA);
00503 
00504     VL53L1_print_xtalk_range_results(
00505         &(pdev->xtalk_results),
00506         "run_xtalk_extraction():pdev->lldata.xtalk_results.",
00507         VL53L1_TRACE_MODULE_XTALK_DATA);
00508 
00509 #endif
00510 
00511     LOG_FUNCTION_END(status);
00512 
00513     return status;
00514 
00515 }
00516 
00517 
00518 
00519 VL53L1_Error VL53L1_get_and_avg_xtalk_samples(
00520         VL53L1_DEV                    Dev,
00521         uint8_t                       num_of_samples,
00522         uint8_t                       measurement_mode,
00523         int16_t                       xtalk_filter_thresh_max_mm,
00524         int16_t                       xtalk_filter_thresh_min_mm,
00525         uint16_t                      xtalk_max_valid_rate_kcps,
00526         uint8_t                       xtalk_result_id,
00527         uint8_t                       xtalk_histo_id,
00528         VL53L1_xtalk_range_results_t *pXR,
00529         VL53L1_histogram_bin_data_t  *psum_histo,
00530         VL53L1_histogram_bin_data_t  *pavg_histo)
00531 {
00532 
00533 
00534 
00535     VL53L1_Error status        = VL53L1_ERROR_NONE;
00536     VL53L1_LLDriverData_t *pdev =
00537         VL53L1DevStructGetLLDriverHandle(Dev);
00538 
00539 #ifdef VL53L1_LOG_ENABLE
00540     VL53L1_LLDriverResults_t *pres =
00541         VL53L1DevStructGetLLResultsHandle(Dev);
00542 #endif
00543 
00544     VL53L1_range_results_t      *prs =
00545             (VL53L1_range_results_t *) pdev->wArea1;
00546 
00547     VL53L1_range_data_t         *prange_data;
00548     VL53L1_xtalk_range_data_t   *pxtalk_range_data;
00549 
00550     uint8_t i                = 0;
00551     uint8_t j                = 0;
00552     uint8_t zone_id          = 0;
00553     uint8_t final_zone       = pdev->zone_cfg.active_zones+1;
00554     uint8_t valid_result;
00555 
00556     uint8_t smudge_corr_en   = 0;
00557 
00558 
00559 
00560 
00561     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
00562 
00563     status = VL53L1_dynamic_xtalk_correction_disable(Dev);
00564 
00565 
00566     VL53L1_load_patch(Dev);
00567 
00568 
00569 
00570     if (status == VL53L1_ERROR_NONE)
00571         status =
00572             VL53L1_init_and_start_range(
00573                 Dev,
00574                 measurement_mode,
00575                 VL53L1_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
00576 
00577 
00578     for (i = 0; i <= (final_zone*num_of_samples); i++) {
00579 
00580 
00581 
00582         if (status == VL53L1_ERROR_NONE)
00583             status = VL53L1_wait_for_range_completion(Dev);
00584 
00585 
00586 
00587         if (status == VL53L1_ERROR_NONE)
00588             status =
00589                 VL53L1_get_device_results(
00590                     Dev,
00591                     VL53L1_DEVICERESULTSLEVEL_FULL,
00592                     prs);
00593 
00594 
00595 
00596         if (status == VL53L1_ERROR_NONE &&
00597             pdev->ll_state.rd_device_state !=
00598             VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC) {
00599 
00600             zone_id = pdev->ll_state.rd_zone_id + xtalk_result_id;
00601             prange_data       = &(prs->VL53L1_p_002[0]);
00602 
00603 
00604             if (prs->active_results > 1) {
00605                 for (j = 1;
00606                 j < prs->active_results; j++) {
00607                     if (prs->VL53L1_p_002[j].median_range_mm
00608                         <
00609                         prange_data->median_range_mm)
00610                         prange_data =
00611                         &(prs->VL53L1_p_002[j]);
00612 
00613                 }
00614             }
00615 
00616             pxtalk_range_data = &(pXR->VL53L1_p_002[zone_id]);
00617 
00618 
00619 
00620             if ((prs->active_results > 0) &&
00621                 (prange_data->median_range_mm <
00622                         xtalk_filter_thresh_max_mm) &&
00623                 (prange_data->median_range_mm >
00624                         xtalk_filter_thresh_min_mm) &&
00625                 (prange_data->VL53L1_p_012 <
00626                 (uint32_t)(xtalk_max_valid_rate_kcps * 16)))
00627                 valid_result = 1;
00628             else
00629                 valid_result = 0;
00630 
00631             if (valid_result == 1) {
00632 
00633                 pxtalk_range_data->no_of_samples++;
00634 
00635                 pxtalk_range_data->rate_per_spad_kcps_sum +=
00636                     prange_data->VL53L1_p_012;
00637 
00638                 pxtalk_range_data->signal_total_events_sum +=
00639                     prange_data->VL53L1_p_013;
00640 
00641                 pxtalk_range_data->sigma_mm_sum +=
00642                     (uint32_t)prange_data->VL53L1_p_005;
00643 
00644 
00645 
00646                 pxtalk_range_data->median_phase_sum +=
00647                     (uint32_t)prange_data->VL53L1_p_014;
00648 
00649 
00650 
00651 
00652             }
00653 
00654             if ((valid_result == 1) && (zone_id >= 4)) {
00655                 status = VL53L1_sum_histogram_data(
00656                         &(pdev->hist_data),
00657                         psum_histo);
00658 
00659 
00660 
00661                 if (prange_data->VL53L1_p_015 <
00662                     pXR->central_histogram__window_start)
00663                     pXR->central_histogram__window_start =
00664                     prange_data->VL53L1_p_015;
00665 
00666 
00667                 if (prange_data->VL53L1_p_016 >
00668                     pXR->central_histogram__window_end)
00669                     pXR->central_histogram__window_end =
00670                         prange_data->VL53L1_p_016;
00671 
00672             }
00673 
00674         }
00675 
00676 
00677 
00678 #ifdef VL53L1_LOG_ENABLE
00679         if (status == VL53L1_ERROR_NONE) {
00680             VL53L1_print_range_results(
00681                     &(pres->range_results),
00682                     "pres->range_results.",
00683                     VL53L1_TRACE_MODULE_CORE);
00684         }
00685 #endif
00686 
00687 
00688 
00689         if (status == VL53L1_ERROR_NONE)
00690             status = VL53L1_wait_for_firmware_ready(Dev);
00691 
00692 
00693 
00694         if (status == VL53L1_ERROR_NONE)
00695             status =
00696                 VL53L1_clear_interrupt_and_enable_next_range(
00697                     Dev,
00698                     measurement_mode);
00699 
00700 
00701     }
00702 
00703 
00704 
00705 
00706     if (status == VL53L1_ERROR_NONE)
00707         status = VL53L1_stop_range(Dev);
00708 
00709     VL53L1_unload_patch(Dev);
00710 
00711 
00712 
00713     for (i = 0; i < (pdev->zone_cfg.active_zones+1); i++) {
00714 
00715         pxtalk_range_data = &(pXR->VL53L1_p_002[i+xtalk_result_id]);
00716 
00717         if (pxtalk_range_data->no_of_samples > 0) {
00718             pxtalk_range_data->rate_per_spad_kcps_avg =
00719             pxtalk_range_data->rate_per_spad_kcps_sum /
00720             (uint32_t)pxtalk_range_data->no_of_samples;
00721 
00722             pxtalk_range_data->signal_total_events_avg =
00723             pxtalk_range_data->signal_total_events_sum /
00724             (int32_t)pxtalk_range_data->no_of_samples;
00725 
00726             pxtalk_range_data->sigma_mm_avg =
00727             pxtalk_range_data->sigma_mm_sum /
00728             (uint32_t)pxtalk_range_data->no_of_samples;
00729 
00730 
00731 
00732             pxtalk_range_data->median_phase_avg =
00733                 pxtalk_range_data->median_phase_sum /
00734                 (uint32_t)pxtalk_range_data->no_of_samples;
00735 
00736 
00737 
00738         } else {
00739             pxtalk_range_data->rate_per_spad_kcps_avg =
00740                 pxtalk_range_data->rate_per_spad_kcps_sum;
00741             pxtalk_range_data->signal_total_events_avg =
00742                 pxtalk_range_data->signal_total_events_sum;
00743             pxtalk_range_data->sigma_mm_avg =
00744                 pxtalk_range_data->sigma_mm_sum;
00745 
00746 
00747 
00748             pxtalk_range_data->median_phase_avg =
00749                     pxtalk_range_data->median_phase_sum;
00750 
00751 
00752         }
00753     }
00754 
00755 
00756 
00757     memcpy(pavg_histo, &(pdev->hist_data),
00758             sizeof(VL53L1_histogram_bin_data_t));
00759 
00760 
00761 
00762     if (status == VL53L1_ERROR_NONE) {
00763 
00764         pxtalk_range_data = &(pXR->VL53L1_p_002[xtalk_histo_id]);
00765 
00766         status = VL53L1_avg_histogram_data(
00767             pxtalk_range_data->no_of_samples,
00768             psum_histo,
00769             pavg_histo);
00770     }
00771 
00772 
00773 
00774 
00775     if (status == VL53L1_ERROR_NONE) {
00776         if (smudge_corr_en == 1)
00777             status = VL53L1_dynamic_xtalk_correction_enable(Dev);
00778     }
00779 
00780 
00781     LOG_FUNCTION_END(status);
00782 
00783     return status;
00784 
00785 }
00786 
00787 
00788 
00789 VL53L1_Error VL53L1_run_offset_calibration(
00790     VL53L1_DEV                    Dev,
00791     int16_t                       cal_distance_mm,
00792     uint16_t                      cal_reflectance_pc,
00793     VL53L1_Error                 *pcal_status)
00794 {
00795 
00796 
00797     VL53L1_Error status        = VL53L1_ERROR_NONE;
00798     VL53L1_LLDriverData_t *pdev =
00799         VL53L1DevStructGetLLDriverHandle(Dev);
00800 
00801     VL53L1_DevicePresetModes device_preset_modes[
00802                 VL53L1_MAX_OFFSET_RANGE_RESULTS];
00803 
00804     VL53L1_range_results_t     *prange_results =
00805             (VL53L1_range_results_t *) pdev->wArea1;
00806 
00807     VL53L1_range_data_t        *pRData = NULL;
00808     VL53L1_offset_range_data_t *pfs     = NULL;
00809     VL53L1_general_config_t *pG = &(pdev->gen_cfg);
00810     VL53L1_additional_offset_cal_data_t *pAO = &(pdev->add_off_cal_data);
00811 
00812     uint8_t  i                      = 0;
00813     uint8_t  m                      = 0;
00814     uint8_t  measurement_mode       =
00815         VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
00816     uint16_t manual_effective_spads =
00817         pG->dss_config__manual_effective_spads_select;
00818 
00819     uint8_t num_of_samples[VL53L1_MAX_OFFSET_RANGE_RESULTS];
00820 
00821     uint8_t smudge_corr_en   = 0;
00822 
00823     LOG_FUNCTION_START("");
00824 
00825 
00826 
00827     switch (pdev->offset_calibration_mode) {
00828 
00829     case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM:
00830     case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY:
00831         device_preset_modes[0] =
00832             VL53L1_DEVICEPRESETMODE_HISTOGRAM_RANGING;
00833         device_preset_modes[1] =
00834             VL53L1_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM1_CAL;
00835         device_preset_modes[2] =
00836             VL53L1_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM2_CAL;
00837     break;
00838 
00839     default:
00840         device_preset_modes[0] =
00841             VL53L1_DEVICEPRESETMODE_STANDARD_RANGING;
00842         device_preset_modes[1] =
00843             VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL;
00844         device_preset_modes[2] =
00845             VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL;
00846     break;
00847     }
00848 
00849 
00850 
00851     num_of_samples[0] = pdev->offsetcal_cfg.pre_num_of_samples;
00852     num_of_samples[1] = pdev->offsetcal_cfg.mm1_num_of_samples;
00853     num_of_samples[2] = pdev->offsetcal_cfg.mm2_num_of_samples;
00854 
00855 
00856 
00857 
00858     switch (pdev->offset_calibration_mode) {
00859 
00860     case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY:
00861     case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY:
00862 
00863         pdev->offset_results.active_results  = 1;
00864 
00865     break;
00866 
00867     default:
00868 
00869         pdev->customer.mm_config__inner_offset_mm  = 0;
00870         pdev->customer.mm_config__outer_offset_mm  = 0;
00871         pdev->offset_results.active_results  =
00872             VL53L1_MAX_OFFSET_RANGE_RESULTS;
00873 
00874     break;
00875     }
00876 
00877     pdev->customer.algo__part_to_part_range_offset_mm = 0;
00878 
00879 
00880 
00881     pdev->offset_results.max_results   = VL53L1_MAX_OFFSET_RANGE_RESULTS;
00882     pdev->offset_results.cal_distance_mm       = cal_distance_mm;
00883     pdev->offset_results.cal_reflectance_pc    = cal_reflectance_pc;
00884 
00885     for (m = 0; m <  VL53L1_MAX_OFFSET_RANGE_RESULTS; m++) {
00886 
00887         pfs = &(pdev->offset_results.VL53L1_p_002[m]);
00888         pfs->preset_mode         = 0;
00889         pfs->no_of_samples       = 0;
00890         pfs->effective_spads     = 0;
00891         pfs->peak_rate_mcps      = 0;
00892         pfs->VL53L1_p_005            = 0;
00893         pfs->median_range_mm     = 0;
00894     }
00895 
00896 
00897 
00898 
00899     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
00900 
00901     status = VL53L1_dynamic_xtalk_correction_disable(Dev);
00902 
00903 
00904 
00905     for (m = 0; m < pdev->offset_results.active_results; m++) {
00906 
00907         pfs = &(pdev->offset_results.VL53L1_p_002[m]);
00908 
00909         pfs->preset_mode         = device_preset_modes[m];
00910 
00911 
00912 
00913         if (status == VL53L1_ERROR_NONE)
00914             status =
00915             VL53L1_set_preset_mode(
00916             Dev,
00917             device_preset_modes[m],
00918 
00919             pdev->offsetcal_cfg.dss_config__target_total_rate_mcps,
00920             pdev->offsetcal_cfg.phasecal_config_timeout_us,
00921             pdev->offsetcal_cfg.mm_config_timeout_us,
00922             pdev->offsetcal_cfg.range_config_timeout_us,
00923 
00924             100);
00925 
00926         pG->dss_config__manual_effective_spads_select =
00927                 manual_effective_spads;
00928 
00929 
00930         VL53L1_load_patch(Dev);
00931 
00932         if (status == VL53L1_ERROR_NONE)
00933             status =
00934             VL53L1_init_and_start_range(
00935                 Dev,
00936                 measurement_mode,
00937                 VL53L1_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
00938 
00939         for (i = 0; i <= (num_of_samples[m]+2); i++) {
00940 
00941 
00942 
00943             if (status == VL53L1_ERROR_NONE)
00944                 status =
00945                     VL53L1_wait_for_range_completion(Dev);
00946 
00947 
00948 
00949             if (status == VL53L1_ERROR_NONE)
00950                 status =
00951                     VL53L1_get_device_results(
00952                         Dev,
00953                         VL53L1_DEVICERESULTSLEVEL_FULL,
00954                         prange_results);
00955 
00956 
00957 
00958             pRData  = &(prange_results->VL53L1_p_002[0]);
00959 
00960             if ((prange_results->active_results > 0 &&
00961                 prange_results->stream_count   > 1) &&
00962                 (pRData->range_status ==
00963                 VL53L1_DEVICEERROR_RANGECOMPLETE)) {
00964 
00965                 pfs->no_of_samples++;
00966                 pfs->effective_spads +=
00967                 (uint32_t)pRData->VL53L1_p_006;
00968                 pfs->peak_rate_mcps  +=
00969                 (uint32_t)pRData->peak_signal_count_rate_mcps;
00970                 pfs->VL53L1_p_005        +=
00971                     (uint32_t)pRData->VL53L1_p_005;
00972                 pfs->median_range_mm +=
00973                     (int32_t)pRData->median_range_mm;
00974 
00975                 pfs->dss_config__roi_mode_control =
00976                 pG->dss_config__roi_mode_control;
00977                 pfs->dss_config__manual_effective_spads_select =
00978                 pG->dss_config__manual_effective_spads_select;
00979 
00980             }
00981 
00982 
00983 
00984             if (status == VL53L1_ERROR_NONE)
00985                 status =
00986                     VL53L1_wait_for_firmware_ready(Dev);
00987 
00988 
00989 
00990             if (status == VL53L1_ERROR_NONE)
00991                 status =
00992                 VL53L1_clear_interrupt_and_enable_next_range(
00993                     Dev,
00994                     measurement_mode);
00995         }
00996 
00997 
00998 
00999         if (status == VL53L1_ERROR_NONE)
01000             status = VL53L1_stop_range(Dev);
01001 
01002 
01003 
01004         if (status == VL53L1_ERROR_NONE)
01005             status = VL53L1_WaitUs(Dev, 1000);
01006         VL53L1_unload_patch(Dev);
01007 
01008 
01009         if (pfs->no_of_samples > 0) {
01010 
01011             pfs->effective_spads += (pfs->no_of_samples/2);
01012             pfs->effective_spads /= pfs->no_of_samples;
01013 
01014             pfs->peak_rate_mcps  += (pfs->no_of_samples/2);
01015             pfs->peak_rate_mcps  /= pfs->no_of_samples;
01016 
01017             pfs->VL53L1_p_005        += (pfs->no_of_samples/2);
01018             pfs->VL53L1_p_005        /= pfs->no_of_samples;
01019 
01020             pfs->median_range_mm += (pfs->no_of_samples/2);
01021             pfs->median_range_mm /= pfs->no_of_samples;
01022 
01023             pfs->range_mm_offset  =  (int32_t)cal_distance_mm;
01024             pfs->range_mm_offset -= pfs->median_range_mm;
01025 
01026 
01027             if (pfs->preset_mode ==
01028                 VL53L1_DEVICEPRESETMODE_STANDARD_RANGING)
01029                 manual_effective_spads =
01030                     (uint16_t)pfs->effective_spads;
01031         }
01032     }
01033 
01034 
01035 
01036     switch (pdev->offset_calibration_mode) {
01037 
01038     case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY:
01039     case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY:
01040 
01041 
01042         pdev->customer.mm_config__inner_offset_mm +=
01043         (int16_t)pdev->offset_results.VL53L1_p_002[0].range_mm_offset;
01044         pdev->customer.mm_config__outer_offset_mm +=
01045         (int16_t)pdev->offset_results.VL53L1_p_002[0].range_mm_offset;
01046     break;
01047 
01048     default:
01049 
01050         pdev->customer.mm_config__inner_offset_mm =
01051         (int16_t)pdev->offset_results.VL53L1_p_002[1].range_mm_offset;
01052         pdev->customer.mm_config__outer_offset_mm =
01053         (int16_t)pdev->offset_results.VL53L1_p_002[2].range_mm_offset;
01054         pdev->customer.algo__part_to_part_range_offset_mm = 0;
01055 
01056 
01057 
01058         pAO->result__mm_inner_actual_effective_spads =
01059         (uint16_t)pdev->offset_results.VL53L1_p_002[1].effective_spads;
01060         pAO->result__mm_outer_actual_effective_spads =
01061         (uint16_t)pdev->offset_results.VL53L1_p_002[2].effective_spads;
01062 
01063         pAO->result__mm_inner_peak_signal_count_rtn_mcps =
01064         (uint16_t)pdev->offset_results.VL53L1_p_002[1].peak_rate_mcps;
01065         pAO->result__mm_outer_peak_signal_count_rtn_mcps =
01066         (uint16_t)pdev->offset_results.VL53L1_p_002[2].peak_rate_mcps;
01067 
01068         break;
01069     }
01070 
01071 
01072 
01073     pdev->cust_dmax_cal.ref__actual_effective_spads =
01074         (uint16_t)pdev->offset_results.VL53L1_p_002[0].effective_spads;
01075     pdev->cust_dmax_cal.ref__peak_signal_count_rate_mcps =
01076         (uint16_t)pdev->offset_results.VL53L1_p_002[0].peak_rate_mcps;
01077 
01078 
01079     pdev->cust_dmax_cal.ref__distance_mm = cal_distance_mm * 16;
01080 
01081     pdev->cust_dmax_cal.ref_reflectance_pc = cal_reflectance_pc;
01082     pdev->cust_dmax_cal.coverglass_transmission = 0x0100;
01083 
01084 
01085 
01086     if (status == VL53L1_ERROR_NONE)
01087         status =
01088             VL53L1_set_customer_nvm_managed(
01089                 Dev,
01090                 &(pdev->customer));
01091 
01092 
01093 
01094 
01095     if (status == VL53L1_ERROR_NONE) {
01096         if (smudge_corr_en == 1)
01097             status = VL53L1_dynamic_xtalk_correction_enable(Dev);
01098     }
01099 
01100 
01101 
01102 
01103     for (m = 0; m < pdev->offset_results.active_results; m++) {
01104 
01105         pfs = &(pdev->offset_results.VL53L1_p_002[m]);
01106 
01107         if (status == VL53L1_ERROR_NONE) {
01108 
01109             pdev->offset_results.cal_report = m;
01110 
01111             if (pfs->no_of_samples < num_of_samples[m])
01112                 status =
01113                 VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES;
01114 
01115 
01116             if (m == 0 && pfs->VL53L1_p_005 >
01117                 ((uint32_t)VL53L1_OFFSET_CAL_MAX_SIGMA_MM << 5))
01118                 status =
01119                 VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
01120 
01121             if (pfs->peak_rate_mcps >
01122                 VL53L1_OFFSET_CAL_MAX_PRE_PEAK_RATE_MCPS)
01123                 status =
01124                 VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH;
01125 
01126             if (pfs->dss_config__manual_effective_spads_select <
01127                 VL53L1_OFFSET_CAL_MIN_EFFECTIVE_SPADS)
01128                 status =
01129                 VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW;
01130 
01131             if (pfs->dss_config__manual_effective_spads_select == 0)
01132                 status =
01133                 VL53L1_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL;
01134 
01135             if (pfs->no_of_samples == 0)
01136                 status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
01137         }
01138     }
01139 
01140 
01141 
01142     pdev->offset_results.cal_status = status;
01143     *pcal_status = pdev->offset_results.cal_status;
01144 
01145 
01146 
01147     IGNORE_STATUS(
01148         IGNORE_OFFSET_CAL_MISSING_SAMPLES,
01149         VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES,
01150         status);
01151 
01152     IGNORE_STATUS(
01153         IGNORE_OFFSET_CAL_SIGMA_TOO_HIGH,
01154         VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH,
01155         status);
01156 
01157     IGNORE_STATUS(
01158         IGNORE_OFFSET_CAL_RATE_TOO_HIGH,
01159         VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH,
01160         status);
01161 
01162     IGNORE_STATUS(
01163         IGNORE_OFFSET_CAL_SPAD_COUNT_TOO_LOW,
01164         VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW,
01165         status);
01166 
01167 #ifdef VL53L1_LOG_ENABLE
01168 
01169 
01170 
01171     VL53L1_print_customer_nvm_managed(
01172         &(pdev->customer),
01173         "run_offset_calibration():pdev->lldata.customer.",
01174         VL53L1_TRACE_MODULE_OFFSET_DATA);
01175 
01176     VL53L1_print_dmax_calibration_data(
01177         &(pdev->fmt_dmax_cal),
01178         "run_offset_calibration():pdev->lldata.fmt_dmax_cal.",
01179         VL53L1_TRACE_MODULE_OFFSET_DATA);
01180 
01181     VL53L1_print_dmax_calibration_data(
01182         &(pdev->cust_dmax_cal),
01183         "run_offset_calibration():pdev->lldata.cust_dmax_cal.",
01184         VL53L1_TRACE_MODULE_OFFSET_DATA);
01185 
01186     VL53L1_print_additional_offset_cal_data(
01187         &(pdev->add_off_cal_data),
01188         "run_offset_calibration():pdev->lldata.add_off_cal_data.",
01189         VL53L1_TRACE_MODULE_OFFSET_DATA);
01190 
01191     VL53L1_print_offset_range_results(
01192         &(pdev->offset_results),
01193         "run_offset_calibration():pdev->lldata.offset_results.",
01194         VL53L1_TRACE_MODULE_OFFSET_DATA);
01195 #endif
01196 
01197     LOG_FUNCTION_END(status);
01198 
01199     return status;
01200 }
01201 
01202 
01203 VL53L1_Error VL53L1_run_phasecal_average(
01204     VL53L1_DEV              Dev,
01205     uint8_t                 measurement_mode,
01206     uint8_t                 phasecal_result__vcsel_start,
01207     uint16_t                phasecal_num_of_samples,
01208     VL53L1_range_results_t *prange_results,
01209     uint16_t               *pphasecal_result__reference_phase,
01210     uint16_t               *pzero_distance_phase)
01211 {
01212 
01213 
01214     VL53L1_Error status        = VL53L1_ERROR_NONE;
01215     VL53L1_LLDriverData_t *pdev =
01216         VL53L1DevStructGetLLDriverHandle(Dev);
01217 
01218     uint16_t  i                                = 0;
01219     uint16_t  m                                = 0;
01220     uint32_t  samples                          = 0;
01221 
01222     uint32_t  period                           = 0;
01223     uint32_t  VL53L1_p_017                            = 0;
01224     uint32_t  phasecal_result__reference_phase = 0;
01225     uint32_t  zero_distance_phase              = 0;
01226 
01227 
01228     VL53L1_load_patch(Dev);
01229 
01230     for (m = 0; m < phasecal_num_of_samples; m++) {
01231 
01232 
01233 
01234         if (status == VL53L1_ERROR_NONE)
01235             status =
01236             VL53L1_init_and_start_range(
01237                 Dev,
01238                 measurement_mode,
01239                 VL53L1_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
01240 
01241         for (i = 0; i <= 1; i++) {
01242 
01243 
01244 
01245             if (status == VL53L1_ERROR_NONE)
01246                 status =
01247                     VL53L1_wait_for_range_completion(Dev);
01248 
01249 
01250 
01251             if (status == VL53L1_ERROR_NONE)
01252                 status =
01253                     VL53L1_get_device_results(
01254                         Dev,
01255                         VL53L1_DEVICERESULTSLEVEL_FULL,
01256                         prange_results);
01257 
01258 
01259 
01260             if (status == VL53L1_ERROR_NONE)
01261                 status =
01262                     VL53L1_wait_for_firmware_ready(Dev);
01263 
01264 
01265 
01266             if (status == VL53L1_ERROR_NONE)
01267                 status =
01268                 VL53L1_clear_interrupt_and_enable_next_range(
01269                     Dev,
01270                     measurement_mode);
01271         }
01272 
01273 
01274 
01275         if (status == VL53L1_ERROR_NONE)
01276             status = VL53L1_stop_range(Dev);
01277 
01278 
01279 
01280         if (status == VL53L1_ERROR_NONE)
01281             status = VL53L1_WaitUs(Dev, 1000);
01282 
01283 
01284 
01285         if (status == VL53L1_ERROR_NONE) {
01286 
01287             samples++;
01288 
01289 
01290             period = 2048 *
01291                 (uint32_t)VL53L1_decode_vcsel_period(
01292                     pdev->hist_data.VL53L1_p_009);
01293 
01294             VL53L1_p_017  = period;
01295             VL53L1_p_017 += (uint32_t)(
01296             pdev->hist_data.phasecal_result__reference_phase);
01297             VL53L1_p_017 +=
01298                 (2048 *
01299                 (uint32_t)phasecal_result__vcsel_start);
01300             VL53L1_p_017 -= (2048 *
01301             (uint32_t)pdev->hist_data.cal_config__vcsel_start);
01302 
01303             VL53L1_p_017  = VL53L1_p_017 % period;
01304 
01305             phasecal_result__reference_phase += (uint32_t)(
01306             pdev->hist_data.phasecal_result__reference_phase);
01307 
01308             zero_distance_phase += (uint32_t)VL53L1_p_017;
01309         }
01310     }
01311     VL53L1_unload_patch(Dev);
01312 
01313 
01314 
01315     if (status == VL53L1_ERROR_NONE && samples > 0) {
01316 
01317         phasecal_result__reference_phase += (samples >> 1);
01318         phasecal_result__reference_phase /= samples;
01319 
01320         zero_distance_phase += (samples >> 1);
01321         zero_distance_phase /= samples;
01322 
01323         *pphasecal_result__reference_phase =
01324             (uint16_t)phasecal_result__reference_phase;
01325         *pzero_distance_phase =
01326             (uint16_t)zero_distance_phase;
01327     }
01328 
01329     return status;
01330 }
01331 
01332 
01333 VL53L1_Error VL53L1_run_zone_calibration(
01334     VL53L1_DEV                    Dev,
01335     VL53L1_DevicePresetModes      device_preset_mode,
01336     VL53L1_DeviceZonePreset       zone_preset,
01337     VL53L1_zone_config_t         *pzone_cfg,
01338     int16_t                       cal_distance_mm,
01339     uint16_t                      cal_reflectance_pc,
01340     VL53L1_Error                 *pcal_status)
01341 {
01342 
01343 
01344     VL53L1_Error status        = VL53L1_ERROR_NONE;
01345     VL53L1_LLDriverData_t *pdev =
01346         VL53L1DevStructGetLLDriverHandle(Dev);
01347 
01348     VL53L1_LLDriverResults_t *pres =
01349         VL53L1DevStructGetLLResultsHandle(Dev);
01350 
01351     VL53L1_range_results_t         *pRR =
01352             (VL53L1_range_results_t *) pdev->wArea1;
01353     VL53L1_range_data_t            *prange_data = NULL;
01354     VL53L1_zone_calibration_data_t *pzone_data  = NULL;
01355 
01356     uint16_t  i                      = 0;
01357     uint16_t  m                      = 0;
01358 
01359     uint8_t   z                      = 0;
01360     uint8_t   measurement_mode       =
01361         VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
01362 
01363     VL53L1_OffsetCorrectionMode  offset_cor_mode =
01364             VL53L1_OFFSETCORRECTIONMODE__NONE;
01365 
01366     LOG_FUNCTION_START("");
01367 
01368 
01369 
01370     if (status == VL53L1_ERROR_NONE)
01371         status =
01372             VL53L1_set_preset_mode(
01373             Dev,
01374             device_preset_mode,
01375 
01376             pdev->zonecal_cfg.dss_config__target_total_rate_mcps,
01377             pdev->zonecal_cfg.phasecal_config_timeout_us,
01378             pdev->zonecal_cfg.mm_config_timeout_us,
01379             pdev->zonecal_cfg.range_config_timeout_us,
01380 
01381             100);
01382 
01383 
01384 
01385     if (zone_preset == VL53L1_DEVICEZONEPRESET_CUSTOM) {
01386 
01387         if (status == VL53L1_ERROR_NONE)
01388             status =
01389                 VL53L1_set_zone_config(
01390                     Dev,
01391                     pzone_cfg);
01392 
01393     } else if (zone_preset != VL53L1_DEVICEZONEPRESET_NONE) {
01394 
01395         if (status == VL53L1_ERROR_NONE)
01396             status =
01397                 VL53L1_set_zone_preset(
01398                     Dev,
01399                     zone_preset);
01400     }
01401 
01402 
01403 
01404     pres->zone_cal.preset_mode        = device_preset_mode;
01405     pres->zone_cal.zone_preset        = zone_preset;
01406 
01407     pres->zone_cal.cal_distance_mm    = cal_distance_mm * 16;
01408     pres->zone_cal.cal_reflectance_pc = cal_reflectance_pc;
01409     pres->zone_cal.max_zones          = VL53L1_MAX_USER_ZONES;
01410     pres->zone_cal.active_zones       = pdev->zone_cfg.active_zones + 1;
01411 
01412     for (i = 0; i < VL53L1_MAX_USER_ZONES; i++) {
01413         pres->zone_cal.VL53L1_p_002[i].no_of_samples   = 0;
01414         pres->zone_cal.VL53L1_p_002[i].effective_spads = 0;
01415         pres->zone_cal.VL53L1_p_002[i].peak_rate_mcps  = 0;
01416         pres->zone_cal.VL53L1_p_002[i].VL53L1_p_014    = 0;
01417         pres->zone_cal.VL53L1_p_002[i].VL53L1_p_005        = 0;
01418         pres->zone_cal.VL53L1_p_002[i].median_range_mm = 0;
01419         pres->zone_cal.VL53L1_p_002[i].range_mm_offset = 0;
01420     }
01421 
01422     pres->zone_cal.phasecal_result__reference_phase = 0;
01423     pres->zone_cal.zero_distance_phase              = 0;
01424 
01425 
01426 
01427     status =
01428         VL53L1_get_offset_correction_mode(
01429             Dev,
01430             &offset_cor_mode);
01431 
01432     if (status == VL53L1_ERROR_NONE)
01433         status =
01434             VL53L1_set_offset_correction_mode(
01435                 Dev,
01436                 VL53L1_OFFSETCORRECTIONMODE__NONE);
01437 
01438 
01439     VL53L1_load_patch(Dev);
01440 
01441     if (status == VL53L1_ERROR_NONE)
01442         status =
01443             VL53L1_init_and_start_range(
01444                 Dev,
01445                 measurement_mode,
01446                 VL53L1_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
01447 
01448 
01449 
01450 
01451     m = (pdev->zonecal_cfg.zone_num_of_samples + 2) *
01452             (uint16_t)pres->zone_cal.active_zones;
01453 
01454 
01455     for (i = 0; i <= m; i++) {
01456 
01457 
01458 
01459         if (status == VL53L1_ERROR_NONE)
01460             status =
01461                 VL53L1_wait_for_range_completion(Dev);
01462 
01463 
01464 
01465         if (status == VL53L1_ERROR_NONE)
01466             status =
01467                 VL53L1_get_device_results(
01468                     Dev,
01469                     VL53L1_DEVICERESULTSLEVEL_FULL,
01470                     pRR);
01471 
01472 
01473 
01474         prange_data  = &(pRR->VL53L1_p_002[0]);
01475 
01476         if (pRR->active_results > 0 &&
01477             i > (uint16_t)pres->zone_cal.active_zones) {
01478 
01479             if (prange_data->range_status ==
01480                 VL53L1_DEVICEERROR_RANGECOMPLETE) {
01481 
01482                 pres->zone_cal.phasecal_result__reference_phase
01483                 =
01484                 pdev->hist_data.phasecal_result__reference_phase
01485                 ;
01486                 pres->zone_cal.zero_distance_phase =
01487                     pdev->hist_data.zero_distance_phase;
01488 
01489                 pzone_data =
01490                 &(pres->zone_cal.VL53L1_p_002[pRR->zone_id]);
01491                 pzone_data->no_of_samples++;
01492                 pzone_data->effective_spads +=
01493                 (uint32_t)prange_data->VL53L1_p_006;
01494                 pzone_data->peak_rate_mcps  += (uint32_t)(
01495                 prange_data->peak_signal_count_rate_mcps);
01496                 pzone_data->VL53L1_p_014  +=
01497                 (uint32_t)prange_data->VL53L1_p_014;
01498                 pzone_data->VL53L1_p_005        +=
01499                 (uint32_t)prange_data->VL53L1_p_005;
01500                 pzone_data->median_range_mm +=
01501                 (int32_t)prange_data->median_range_mm;
01502 
01503             }
01504         }
01505 
01506 
01507 
01508         if (status == VL53L1_ERROR_NONE)
01509             status =
01510                 VL53L1_wait_for_firmware_ready(Dev);
01511 
01512 
01513 
01514         if (status == VL53L1_ERROR_NONE)
01515             status =
01516                 VL53L1_clear_interrupt_and_enable_next_range(
01517                     Dev,
01518                     measurement_mode);
01519     }
01520 
01521 
01522 
01523     if (status == VL53L1_ERROR_NONE)
01524         status = VL53L1_stop_range(Dev);
01525 
01526 
01527     if (status == VL53L1_ERROR_NONE)
01528         status = VL53L1_WaitUs(Dev, 1000);
01529     VL53L1_unload_patch(Dev);
01530 
01531 
01532     if (status == VL53L1_ERROR_NONE)
01533         status =
01534             VL53L1_run_phasecal_average(
01535             Dev,
01536             measurement_mode,
01537             pdev->hist_data.phasecal_result__vcsel_start,
01538 
01539             pdev->zonecal_cfg.phasecal_num_of_samples,
01540 
01541             pRR,
01542             &(pres->zone_cal.phasecal_result__reference_phase),
01543             &(pres->zone_cal.zero_distance_phase));
01544 
01545 
01546 
01547     if (status == VL53L1_ERROR_NONE)
01548         status =
01549             VL53L1_set_offset_correction_mode(
01550                 Dev,
01551                 offset_cor_mode);
01552 
01553 
01554 
01555     if (status == VL53L1_ERROR_NONE) {
01556 
01557         for (z = 0; z < pres->zone_cal.active_zones; z++) {
01558 
01559             pzone_data = &(pres->zone_cal.VL53L1_p_002[z]);
01560 
01561 
01562             if (pzone_data->no_of_samples > 0) {
01563 
01564                 pzone_data->effective_spads +=
01565                     (pzone_data->no_of_samples/2);
01566                 pzone_data->effective_spads /=
01567                     pzone_data->no_of_samples;
01568 
01569                 pzone_data->peak_rate_mcps  +=
01570                     (pzone_data->no_of_samples/2);
01571                 pzone_data->peak_rate_mcps  /=
01572                     pzone_data->no_of_samples;
01573 
01574                 pzone_data->VL53L1_p_014    +=
01575                     (pzone_data->no_of_samples/2);
01576                 pzone_data->VL53L1_p_014    /=
01577                     pzone_data->no_of_samples;
01578 
01579                 pzone_data->VL53L1_p_005        +=
01580                     (pzone_data->no_of_samples/2);
01581                 pzone_data->VL53L1_p_005        /=
01582                     pzone_data->no_of_samples;
01583 
01584 
01585 
01586                 pzone_data->median_range_mm =
01587                 VL53L1_range_maths(
01588                 pdev->stat_nvm.osc_measured__fast_osc__frequency
01589                 , (uint16_t)pzone_data->VL53L1_p_014,
01590                 pres->zone_cal.zero_distance_phase,
01591                 2,
01592                 0x0800,
01593                 0);
01594 
01595                 pzone_data->range_mm_offset  =
01596                         ((int32_t)cal_distance_mm) * 4;
01597                 pzone_data->range_mm_offset -=
01598                         pzone_data->median_range_mm;
01599 
01600 
01601                 if (pzone_data->no_of_samples <
01602                     pdev->zonecal_cfg.zone_num_of_samples)
01603                     status =
01604                     VL53L1_WARNING_ZONE_CAL_MISSING_SAMPLES;
01605 
01606 
01607                 if (pzone_data->VL53L1_p_005 >
01608                     ((uint32_t)VL53L1_ZONE_CAL_MAX_SIGMA_MM
01609                             << 5))
01610                     status =
01611                     VL53L1_WARNING_ZONE_CAL_SIGMA_TOO_HIGH;
01612 
01613                 if (pzone_data->peak_rate_mcps >
01614                     VL53L1_ZONE_CAL_MAX_PRE_PEAK_RATE_MCPS)
01615                     status =
01616                     VL53L1_WARNING_ZONE_CAL_RATE_TOO_HIGH;
01617 
01618             } else {
01619                 status = VL53L1_ERROR_ZONE_CAL_NO_SAMPLE_FAIL;
01620             }
01621         }
01622     }
01623 
01624 
01625 
01626     pres->zone_cal.cal_status = status;
01627     *pcal_status = pres->zone_cal.cal_status;
01628 
01629 
01630 
01631     IGNORE_STATUS(
01632         IGNORE_ZONE_CAL_MISSING_SAMPLES,
01633         VL53L1_WARNING_ZONE_CAL_MISSING_SAMPLES,
01634         status);
01635 
01636     IGNORE_STATUS(
01637         IGNORE_ZONE_CAL_SIGMA_TOO_HIGH,
01638         VL53L1_WARNING_ZONE_CAL_SIGMA_TOO_HIGH,
01639         status);
01640 
01641     IGNORE_STATUS(
01642         IGNORE_ZONE_CAL_RATE_TOO_HIGH,
01643         VL53L1_WARNING_ZONE_CAL_RATE_TOO_HIGH,
01644         status);
01645 
01646 #ifdef VL53L1_LOG_ENABLE
01647 
01648 
01649 
01650     VL53L1_print_zone_calibration_results(
01651         &(pres->zone_cal),
01652         "run_zone_calibration():pdev->llresults.zone_cal.",
01653         VL53L1_TRACE_MODULE_OFFSET_DATA);
01654 
01655 #endif
01656 
01657     LOG_FUNCTION_END(status);
01658 
01659     return status;
01660 }
01661 
01662 
01663 VL53L1_Error VL53L1_run_spad_rate_map(
01664     VL53L1_DEV                 Dev,
01665     VL53L1_DeviceTestMode      device_test_mode,
01666     VL53L1_DeviceSscArray      array_select,
01667     uint32_t                   ssc_config_timeout_us,
01668     VL53L1_spad_rate_data_t   *pspad_rate_data)
01669 {
01670 
01671 
01672 
01673     VL53L1_Error status = VL53L1_ERROR_NONE;
01674 
01675     VL53L1_LLDriverData_t *pdev =
01676         VL53L1DevStructGetLLDriverHandle(Dev);
01677 
01678     LOG_FUNCTION_START("");
01679 
01680 
01681     if (status == VL53L1_ERROR_NONE)
01682         status = VL53L1_enable_powerforce(Dev);
01683 
01684 
01685 
01686     if (status == VL53L1_ERROR_NONE) {
01687         pdev->ssc_cfg.array_select = array_select;
01688         pdev->ssc_cfg.timeout_us   = ssc_config_timeout_us;
01689         status =
01690         VL53L1_set_ssc_config(
01691             Dev,
01692             &(pdev->ssc_cfg),
01693             pdev->stat_nvm.osc_measured__fast_osc__frequency);
01694     }
01695 
01696 
01697 
01698     if (status == VL53L1_ERROR_NONE)
01699         status =
01700             VL53L1_run_device_test(
01701                 Dev,
01702                 device_test_mode);
01703 
01704 
01705 
01706     if (status == VL53L1_ERROR_NONE)
01707         status =
01708             VL53L1_get_spad_rate_data(
01709                 Dev,
01710                 pspad_rate_data);
01711 
01712     if (device_test_mode == VL53L1_DEVICETESTMODE_LCR_VCSEL_ON)
01713         pspad_rate_data->fractional_bits =  7;
01714     else
01715         pspad_rate_data->fractional_bits = 15;
01716 
01717 
01718 
01719     if (status == VL53L1_ERROR_NONE)
01720         status = VL53L1_disable_powerforce(Dev);
01721 
01722 #ifdef VL53L1_LOG_ENABLE
01723 
01724 
01725     if (status == VL53L1_ERROR_NONE) {
01726         VL53L1_print_spad_rate_data(
01727             pspad_rate_data,
01728             "run_spad_rate_map():",
01729             VL53L1_TRACE_MODULE_SPAD_RATE_MAP);
01730         VL53L1_print_spad_rate_map(
01731             pspad_rate_data,
01732             "run_spad_rate_map():",
01733             VL53L1_TRACE_MODULE_SPAD_RATE_MAP);
01734     }
01735 #endif
01736 
01737     LOG_FUNCTION_END(status);
01738 
01739     return status;
01740 }
01741 
01742 
01743 VL53L1_Error VL53L1_run_device_test(
01744     VL53L1_DEV             Dev,
01745     VL53L1_DeviceTestMode  device_test_mode)
01746 {
01747 
01748 
01749     VL53L1_Error status = VL53L1_ERROR_NONE;
01750     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01751 
01752     uint8_t      comms_buffer[2];
01753     uint8_t      gpio_hv_mux__ctrl = 0;
01754 
01755     LOG_FUNCTION_START("");
01756 
01757 
01758 
01759     if (status == VL53L1_ERROR_NONE)
01760         status =
01761             VL53L1_RdByte(
01762                 Dev,
01763                 VL53L1_GPIO_HV_MUX__CTRL,
01764                 &gpio_hv_mux__ctrl);
01765 
01766     if (status == VL53L1_ERROR_NONE)
01767         pdev->stat_cfg.gpio_hv_mux__ctrl = gpio_hv_mux__ctrl;
01768 
01769 
01770     if (status == VL53L1_ERROR_NONE)
01771         status = VL53L1_start_test(
01772                     Dev,
01773                     device_test_mode);
01774 
01775 
01776     if (status == VL53L1_ERROR_NONE)
01777         status = VL53L1_wait_for_test_completion(Dev);
01778 
01779 
01780     if (status == VL53L1_ERROR_NONE)
01781         status =
01782             VL53L1_ReadMulti(
01783                 Dev,
01784                 VL53L1_RESULT__RANGE_STATUS,
01785                 comms_buffer,
01786                 2);
01787 
01788     if (status == VL53L1_ERROR_NONE) {
01789         pdev->sys_results.result__range_status  = comms_buffer[0];
01790         pdev->sys_results.result__report_status = comms_buffer[1];
01791     }
01792 
01793 
01794 
01795     pdev->sys_results.result__range_status &=
01796         VL53L1_RANGE_STATUS__RANGE_STATUS_MASK;
01797 
01798     if (status == VL53L1_ERROR_NONE) {
01799         trace_print(
01800         VL53L1_TRACE_LEVEL_INFO,
01801         "    Device Test Complete:\n\t%-32s = %3u\n\t%-32s = %3u\n",
01802         "result__range_status",
01803         pdev->sys_results.result__range_status,
01804         "result__report_status",
01805         pdev->sys_results.result__report_status);
01806 
01807 
01808         if (status == VL53L1_ERROR_NONE)
01809             status = VL53L1_clear_interrupt(Dev);
01810     }
01811 
01812 
01813 
01814     if (status == VL53L1_ERROR_NONE)
01815         status =
01816             VL53L1_start_test(
01817                 Dev,
01818                 0x00);
01819 
01820     LOG_FUNCTION_END(status);
01821 
01822     return status;
01823 }
01824 
01825 
01826 void VL53L1_hist_xtalk_extract_data_init(
01827     VL53L1_hist_xtalk_extract_data_t *pxtalk_data)
01828 {
01829 
01830 
01831     int32_t lb = 0;
01832 
01833     pxtalk_data->sample_count             = 0U;
01834     pxtalk_data->pll_period_mm            = 0U;
01835     pxtalk_data->peak_duration_us_sum     = 0U;
01836     pxtalk_data->effective_spad_count_sum = 0U;
01837     pxtalk_data->zero_distance_phase_sum  = 0U;
01838     pxtalk_data->zero_distance_phase_avg  = 0U;
01839     pxtalk_data->event_scaler_sum         = 0U;
01840     pxtalk_data->event_scaler_avg         = 4096U;
01841     pxtalk_data->signal_events_sum        = 0;
01842     pxtalk_data->xtalk_rate_kcps_per_spad = 0U;
01843     pxtalk_data->VL53L1_p_015             = 0U;
01844     pxtalk_data->VL53L1_p_016               = 0U;
01845     pxtalk_data->target_start             = 0U;
01846 
01847     for (lb = 0; lb < VL53L1_XTALK_HISTO_BINS; lb++)
01848         pxtalk_data->bin_data_sums[lb] = 0;
01849 
01850 }
01851 
01852 
01853 VL53L1_Error VL53L1_hist_xtalk_extract_update(
01854     int16_t                             target_distance_mm,
01855     uint16_t                            target_width_oversize,
01856     VL53L1_histogram_bin_data_t        *phist_bins,
01857     VL53L1_hist_xtalk_extract_data_t   *pxtalk_data)
01858 {
01859 
01860 
01861     VL53L1_Error  status = VL53L1_ERROR_NONE;
01862 
01863     LOG_FUNCTION_START("");
01864 
01865     status =
01866         VL53L1_hist_xtalk_extract_calc_window(
01867             target_distance_mm,
01868             target_width_oversize,
01869             phist_bins,
01870             pxtalk_data);
01871 
01872     if (status == VL53L1_ERROR_NONE) {
01873         status =
01874             VL53L1_hist_xtalk_extract_calc_event_sums(
01875                 phist_bins,
01876                 pxtalk_data);
01877     }
01878 
01879     LOG_FUNCTION_END(status);
01880 
01881     return status;
01882 }
01883 
01884 
01885 VL53L1_Error VL53L1_hist_xtalk_extract_fini(
01886     VL53L1_histogram_bin_data_t        *phist_bins,
01887     VL53L1_hist_xtalk_extract_data_t   *pxtalk_data,
01888     VL53L1_xtalk_calibration_results_t *pxtalk_cal,
01889     VL53L1_xtalk_histogram_shape_t     *pxtalk_shape)
01890 {
01891 
01892 
01893     VL53L1_Error  status = VL53L1_ERROR_NONE;
01894     VL53L1_xtalk_calibration_results_t *pX = pxtalk_cal;
01895 
01896     LOG_FUNCTION_START("");
01897 
01898     if (pxtalk_data->sample_count > 0) {
01899 
01900 
01901         pxtalk_data->event_scaler_avg  = pxtalk_data->event_scaler_sum;
01902         pxtalk_data->event_scaler_avg +=
01903                 (pxtalk_data->sample_count >> 1);
01904         pxtalk_data->event_scaler_avg /=  pxtalk_data->sample_count;
01905 
01906 
01907 
01908         status =
01909             VL53L1_hist_xtalk_extract_calc_rate_per_spad(
01910                 pxtalk_data);
01911 
01912 
01913 
01914         if (status == VL53L1_ERROR_NONE) {
01915 
01916 
01917             pxtalk_data->zero_distance_phase_avg =
01918                 pxtalk_data->zero_distance_phase_sum;
01919             pxtalk_data->zero_distance_phase_avg +=
01920                     (pxtalk_data->sample_count >> 1);
01921             pxtalk_data->zero_distance_phase_avg /=
01922                     pxtalk_data->sample_count;
01923 
01924 
01925             status =
01926                 VL53L1_hist_xtalk_extract_calc_shape(
01927                     pxtalk_data,
01928                     pxtalk_shape);
01929 
01930 
01931 
01932 
01933             pxtalk_shape->phasecal_result__vcsel_start =
01934                 phist_bins->phasecal_result__vcsel_start;
01935             pxtalk_shape->cal_config__vcsel_start =
01936                 phist_bins->cal_config__vcsel_start;
01937             pxtalk_shape->vcsel_width =
01938                 phist_bins->vcsel_width;
01939             pxtalk_shape->VL53L1_p_019 =
01940                 phist_bins->VL53L1_p_019;
01941         }
01942 
01943 
01944         if (status == VL53L1_ERROR_NONE) {
01945 
01946 
01947             pX->algo__crosstalk_compensation_plane_offset_kcps =
01948                 pxtalk_data->xtalk_rate_kcps_per_spad;
01949             pX->algo__crosstalk_compensation_x_plane_gradient_kcps
01950                 = 0U;
01951             pX->algo__crosstalk_compensation_y_plane_gradient_kcps
01952                 = 0U;
01953 
01954         }
01955     }
01956 
01957     LOG_FUNCTION_END(status);
01958 
01959     return status;
01960 }
01961 
01962 
01963 VL53L1_Error   VL53L1_run_hist_xtalk_extraction(
01964     VL53L1_DEV                          Dev,
01965     int16_t                             cal_distance_mm,
01966     VL53L1_Error                       *pcal_status)
01967 {
01968 
01969 
01970     #define OVERSIZE 4
01971     VL53L1_Error status = VL53L1_ERROR_NONE;
01972     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01973     VL53L1_xtalkextract_config_t *pX = &(pdev->xtalk_extract_cfg);
01974     VL53L1_xtalk_config_t *pC = &(pdev->xtalk_cfg);
01975     VL53L1_xtalk_calibration_results_t *pXC = &(pdev->xtalk_cal);
01976 
01977 
01978 
01979     uint8_t smudge_corr_en   = 0;
01980     uint8_t i                = 0;
01981     int8_t k = 0;
01982     uint8_t nbloops;
01983     int32_t initMergeSize = 0;
01984     int32_t MergeEnabled = 0;
01985     uint32_t deltaXtalk;
01986     uint32_t stepXtalk;
01987     uint32_t XtalkMin;
01988     uint32_t XtalkMax;
01989     uint8_t measurement_mode = VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
01990     int8_t MaxId;
01991     uint8_t histo_merge_nb;
01992     uint8_t wait_for_accumulation;
01993     VL53L1_range_results_t     *prange_results =
01994         (VL53L1_range_results_t *) pdev->wArea1;
01995     uint8_t Very1stRange = 0;
01996 
01997     LOG_FUNCTION_START("");
01998 
01999 
02000 
02001     if (status == VL53L1_ERROR_NONE)
02002         status =
02003             VL53L1_set_preset_mode(
02004                 Dev,
02005                 VL53L1_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE,
02006                 pX->dss_config__target_total_rate_mcps,
02007                 pX->phasecal_config_timeout_us,
02008                 pX->mm_config_timeout_us,
02009                 pX->range_config_timeout_us,
02010                 100);
02011 
02012 
02013 
02014     if (status == VL53L1_ERROR_NONE)
02015         status = VL53L1_disable_xtalk_compensation(Dev);
02016 
02017 
02018 
02019     smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
02020 
02021     if (status == VL53L1_ERROR_NONE)
02022         status = VL53L1_dynamic_xtalk_correction_disable(Dev);
02023 
02024 
02025     VL53L1_load_patch(Dev);
02026 
02027     VL53L1_get_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE_MAX_SIZE,
02028             &initMergeSize);
02029     VL53L1_get_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE,
02030             &MergeEnabled);
02031     memset(&pdev->xtalk_cal, 0, sizeof(pdev->xtalk_cal));
02032 
02033     if (status == VL53L1_ERROR_NONE)
02034         status = VL53L1_init_and_start_range(
02035             Dev, measurement_mode,
02036             VL53L1_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
02037 
02038     MaxId = pdev->tuning_parms.tp_hist_merge_max_size - 1;
02039     nbloops = (MergeEnabled == 0 ? 1 : 2);
02040     for (k = 0; k < nbloops; k++) {
02041 
02042         VL53L1_hist_xtalk_extract_data_init(
02043                 &(pdev->xtalk_extract));
02044         VL53L1_set_tuning_parm(Dev,
02045                 VL53L1_TUNINGPARM_HIST_MERGE_MAX_SIZE,
02046                 k * MaxId + 1);
02047 
02048         for (i = 0; i <= pX->num_of_samples; i++) {
02049             if (status == VL53L1_ERROR_NONE)
02050                 status = VL53L1_wait_for_range_completion(Dev);
02051             if (status == VL53L1_ERROR_NONE)
02052                 status = VL53L1_get_device_results(Dev,
02053                     VL53L1_DEVICERESULTSLEVEL_FULL,
02054                     prange_results);
02055             Very1stRange =
02056                 (pdev->ll_state.rd_device_state ==
02057                 VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC);
02058 
02059             VL53L1_compute_histo_merge_nb(Dev, &histo_merge_nb);
02060             wait_for_accumulation = ((k != 0) &&
02061                 (MergeEnabled) &&
02062                 (status == VL53L1_ERROR_NONE) &&
02063                 (histo_merge_nb <
02064                 pdev->tuning_parms.tp_hist_merge_max_size));
02065             if (wait_for_accumulation)
02066                 i = 0;
02067             else {
02068                 if ((status == VL53L1_ERROR_NONE) &&
02069                     (!Very1stRange)) {
02070                     status =
02071                     VL53L1_hist_xtalk_extract_update(
02072                         cal_distance_mm,
02073                         OVERSIZE,
02074                         &(pdev->hist_data),
02075                         &(pdev->xtalk_extract));
02076                 }
02077             }
02078 
02079             if (status == VL53L1_ERROR_NONE)
02080                 status = VL53L1_wait_for_firmware_ready(Dev);
02081             if (status == VL53L1_ERROR_NONE)
02082                 status =
02083                 VL53L1_clear_interrupt_and_enable_next_range(
02084                     Dev, measurement_mode);
02085 
02086 
02087             if (status == VL53L1_ERROR_NONE)
02088                 status =
02089                 VL53L1_hist_xtalk_extract_fini(
02090                     &(pdev->hist_data),
02091                     &(pdev->xtalk_extract),
02092                     &(pdev->xtalk_cal),
02093                     &(pdev->xtalk_shapes.xtalk_shape));
02094             if (status != VL53L1_ERROR_NONE)
02095                 goto LOOPOUT;
02096             pXC->algo__xtalk_cpo_HistoMerge_kcps[k * MaxId] =
02097             pXC->algo__crosstalk_compensation_plane_offset_kcps;
02098         }
02099     }
02100 
02101 LOOPOUT:
02102 
02103     VL53L1_stop_range(Dev);
02104 
02105     VL53L1_set_tuning_parm(Dev, VL53L1_TUNINGPARM_HIST_MERGE_MAX_SIZE,
02106             initMergeSize);
02107     VL53L1_unload_patch(Dev);
02108 
02109     if (status != VL53L1_ERROR_NONE)
02110         status = VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
02111     else if ((MergeEnabled == 1) && (MaxId > 0)) {
02112         XtalkMin = pXC->algo__xtalk_cpo_HistoMerge_kcps[0];
02113         XtalkMax = pXC->algo__xtalk_cpo_HistoMerge_kcps[MaxId];
02114         pXC->algo__crosstalk_compensation_plane_offset_kcps =
02115                 XtalkMin;
02116         if (XtalkMax >= XtalkMin) {
02117             deltaXtalk =  XtalkMax - XtalkMin;
02118             stepXtalk = deltaXtalk / MaxId;
02119             for (k = 1; k < MaxId; k++)
02120                 pXC->algo__xtalk_cpo_HistoMerge_kcps[k] =
02121                 XtalkMin + stepXtalk * k;
02122         } else
02123             status =
02124                 VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
02125     }
02126 
02127     if (status == VL53L1_ERROR_NONE) {
02128         pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
02129         pXC->algo__crosstalk_compensation_x_plane_gradient_kcps;
02130         pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
02131         pXC->algo__crosstalk_compensation_y_plane_gradient_kcps;
02132         pC->algo__crosstalk_compensation_plane_offset_kcps =
02133         pXC->algo__crosstalk_compensation_plane_offset_kcps;
02134     }
02135 
02136 
02137     pdev->xtalk_results.cal_status = status;
02138     *pcal_status = pdev->xtalk_results.cal_status;
02139 
02140 
02141     status = VL53L1_enable_xtalk_compensation(Dev);
02142     if (smudge_corr_en == 1)
02143         status = VL53L1_dynamic_xtalk_correction_enable(Dev);
02144 
02145 #ifdef VL53L1_LOG_ENABLE
02146 
02147 
02148 
02149     VL53L1_print_customer_nvm_managed(
02150         &(pdev->customer),
02151         "run_xtalk_extraction():pdev->lldata.customer.",
02152         VL53L1_TRACE_MODULE_XTALK_DATA);
02153 
02154     VL53L1_print_xtalk_config(
02155         &(pdev->xtalk_cfg),
02156         "run_xtalk_extraction():pdev->lldata.xtalk_cfg.",
02157         VL53L1_TRACE_MODULE_XTALK_DATA);
02158 
02159     VL53L1_print_xtalk_histogram_data(
02160         &(pdev->xtalk_shapes),
02161         "pdev->lldata.xtalk_shapes.",
02162         VL53L1_TRACE_MODULE_XTALK_DATA);
02163 
02164 #endif
02165 
02166     LOG_FUNCTION_END(status);
02167 
02168     return status;
02169 }
02170