Initial release. Mbed library for VL53L1CB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53l1_api_calibration.c Source File

vl53l1_api_calibration.c

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