Initial release. Mbed library for VL53L1CB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53l1_core.c Source File

vl53l1_core.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 #include "vl53l1_ll_def.h"
00069 #include "vl53l1_ll_device.h"
00070 #include "vl53l1_platform.h"
00071 #include "vl53l1_register_map.h"
00072 #include "vl53l1_register_funcs.h"
00073 #include "vl53l1_register_settings.h"
00074 #include "vl53l1_hist_structs.h"
00075 #include "vl53l1_api_preset_modes.h"
00076 #include "vl53l1_core.h"
00077 #include "vl53l1_tuning_parm_defaults.h"
00078 
00079 
00080 
00081 #define LOG_FUNCTION_START(fmt, ...) \
00082     _LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__)
00083 #define LOG_FUNCTION_END(status, ...) \
00084     _LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__)
00085 #define LOG_FUNCTION_END_FMT(status, fmt, ...) \
00086     _LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, \
00087         status, fmt, ##__VA_ARGS__)
00088 
00089 #define trace_print(level, ...) \
00090     _LOG_TRACE_PRINT(VL53L1_TRACE_MODULE_CORE, \
00091     level, VL53L1_TRACE_FUNCTION_NONE, ##__VA_ARGS__)
00092 
00093 
00094 void  VL53L1_init_version(
00095     VL53L1_DEV        Dev)
00096 {
00097 
00098 
00099     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
00100 
00101     pdev->version.ll_major    = VL53L1_LL_API_IMPLEMENTATION_VER_MAJOR;
00102     pdev->version.ll_minor    = VL53L1_LL_API_IMPLEMENTATION_VER_MINOR;
00103     pdev->version.ll_build    = VL53L1_LL_API_IMPLEMENTATION_VER_SUB;
00104     pdev->version.ll_revision = VL53L1_LL_API_IMPLEMENTATION_VER_REVISION;
00105 }
00106 
00107 
00108 void  VL53L1_init_ll_driver_state(
00109     VL53L1_DEV         Dev,
00110     VL53L1_DeviceState device_state)
00111 {
00112 
00113 
00114     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
00115     VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
00116 
00117     pstate->cfg_device_state  = device_state;
00118     pstate->cfg_stream_count  = 0;
00119     pstate->cfg_gph_id        = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00120     pstate->cfg_timing_status = 0;
00121     pstate->cfg_zone_id       = 0;
00122 
00123     pstate->rd_device_state   = device_state;
00124     pstate->rd_stream_count   = 0;
00125     pstate->rd_gph_id         = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00126     pstate->rd_timing_status  = 0;
00127     pstate->rd_zone_id        = 0;
00128 
00129 }
00130 
00131 
00132 VL53L1_Error  VL53L1_update_ll_driver_rd_state(
00133     VL53L1_DEV         Dev)
00134 {
00135 
00136 
00137     VL53L1_Error        status  = VL53L1_ERROR_NONE;
00138     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
00139     VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
00140 
00141 
00142 
00143     LOG_FUNCTION_START("");
00144 
00145 
00146 
00147     if ((pdev->sys_ctrl.system__mode_start &
00148         VL53L1_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) {
00149 
00150         pstate->rd_device_state  = VL53L1_DEVICESTATE_SW_STANDBY;
00151         pstate->rd_stream_count  = 0;
00152         pstate->rd_internal_stream_count = 0;
00153         pstate->rd_internal_stream_count_val = 0;
00154         pstate->rd_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00155         pstate->rd_timing_status = 0;
00156         pstate->rd_zone_id       = 0;
00157 
00158     } else {
00159 
00160 
00161 
00162         if (pstate->rd_stream_count == 0xFF)
00163             pstate->rd_stream_count = 0x80;
00164         else
00165             pstate->rd_stream_count++;
00166 
00167 
00168         status = VL53L1_update_internal_stream_counters(Dev,
00169             pstate->rd_stream_count,
00170             &(pstate->rd_internal_stream_count),
00171             &(pstate->rd_internal_stream_count_val));
00172 
00173 
00174 
00175         pstate->rd_gph_id ^= VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00176 
00177 
00178 
00179         switch (pstate->rd_device_state) {
00180 
00181         case VL53L1_DEVICESTATE_SW_STANDBY:
00182 
00183             if ((pdev->dyn_cfg.system__grouped_parameter_hold &
00184                 VL53L1_GROUPEDPARAMETERHOLD_ID_MASK) > 0) {
00185                 pstate->rd_device_state =
00186                 VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC;
00187             } else {
00188                 if (pstate->rd_zone_id >=
00189                     pdev->zone_cfg.active_zones)
00190                     pstate->rd_device_state =
00191                     VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA;
00192                 else
00193                     pstate->rd_device_state =
00194                     VL53L1_DEVICESTATE_RANGING_GATHER_DATA;
00195             }
00196 
00197             pstate->rd_stream_count  = 0;
00198             pstate->rd_internal_stream_count = 0;
00199             pstate->rd_internal_stream_count_val = 0;
00200             pstate->rd_timing_status = 0;
00201             pstate->rd_zone_id       = 0;
00202 
00203             break;
00204 
00205         case VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC:
00206             pstate->rd_stream_count = 0;
00207             pstate->rd_internal_stream_count = 0;
00208             pstate->rd_internal_stream_count_val = 0;
00209             pstate->rd_zone_id      = 0;
00210             if (pstate->rd_zone_id >=
00211                 pdev->zone_cfg.active_zones)
00212                 pstate->rd_device_state =
00213                     VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA;
00214             else
00215                 pstate->rd_device_state =
00216                     VL53L1_DEVICESTATE_RANGING_GATHER_DATA;
00217 
00218             break;
00219 
00220         case VL53L1_DEVICESTATE_RANGING_GATHER_DATA:
00221             pstate->rd_zone_id++;
00222             if (pstate->rd_zone_id >=
00223                 pdev->zone_cfg.active_zones)
00224                 pstate->rd_device_state =
00225                     VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA;
00226             else
00227                 pstate->rd_device_state =
00228                     VL53L1_DEVICESTATE_RANGING_GATHER_DATA;
00229 
00230             break;
00231 
00232         case VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA:
00233             pstate->rd_zone_id        = 0;
00234             pstate->rd_timing_status ^= 0x01;
00235 
00236             if (pstate->rd_zone_id >=
00237                 pdev->zone_cfg.active_zones)
00238                 pstate->rd_device_state =
00239                     VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA;
00240             else
00241                 pstate->rd_device_state =
00242                     VL53L1_DEVICESTATE_RANGING_GATHER_DATA;
00243             break;
00244 
00245         default:
00246             pstate->rd_device_state  =
00247                 VL53L1_DEVICESTATE_SW_STANDBY;
00248             pstate->rd_stream_count  = 0;
00249             pstate->rd_internal_stream_count = 0;
00250             pstate->rd_internal_stream_count_val = 0;
00251             pstate->rd_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00252             pstate->rd_timing_status = 0;
00253             pstate->rd_zone_id       = 0;
00254             break;
00255         }
00256     }
00257 
00258 
00259 
00260     LOG_FUNCTION_END(status);
00261 
00262     return status;
00263 }
00264 
00265 
00266 VL53L1_Error VL53L1_check_ll_driver_rd_state(
00267     VL53L1_DEV         Dev)
00268 {
00269 
00270 
00271     VL53L1_Error         status = VL53L1_ERROR_NONE;
00272     VL53L1_LLDriverData_t  *pdev =
00273             VL53L1DevStructGetLLDriverHandle(Dev);
00274     VL53L1_LLDriverResults_t  *pres =
00275             VL53L1DevStructGetLLResultsHandle(Dev);
00276 
00277     VL53L1_ll_driver_state_t  *pstate       = &(pdev->ll_state);
00278     VL53L1_system_results_t   *psys_results = &(pdev->sys_results);
00279     VL53L1_histogram_bin_data_t *phist_data = &(pdev->hist_data);
00280     VL53L1_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
00281 
00282     uint8_t   device_range_status   = 0;
00283     uint8_t   device_stream_count   = 0;
00284     uint8_t   device_gph_id         = 0;
00285     uint8_t   histogram_mode        = 0;
00286     uint8_t   expected_stream_count = 0;
00287     uint8_t   expected_gph_id       = 0;
00288 
00289     LOG_FUNCTION_START("");
00290 
00291 
00292 
00293     device_range_status =
00294             psys_results->result__range_status &
00295             VL53L1_RANGE_STATUS__RANGE_STATUS_MASK;
00296 
00297     device_stream_count = psys_results->result__stream_count;
00298 
00299 
00300 
00301     histogram_mode =
00302         (pdev->sys_ctrl.system__mode_start &
00303         VL53L1_DEVICESCHEDULERMODE_HISTOGRAM) ==
00304         VL53L1_DEVICESCHEDULERMODE_HISTOGRAM;
00305 
00306 
00307     device_gph_id = (psys_results->result__interrupt_status &
00308         VL53L1_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4;
00309 
00310     if (histogram_mode)
00311         device_gph_id = (phist_data->result__interrupt_status &
00312             VL53L1_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4;
00313 
00314 
00315 
00316     if (!((pdev->sys_ctrl.system__mode_start &
00317         VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK) ==
00318         VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK))
00319         goto ENDFUNC;
00320 
00321 
00322 
00323     if (pstate->rd_device_state ==
00324         VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC) {
00325 
00326         if (histogram_mode == 0) {
00327             if (device_range_status !=
00328             VL53L1_DEVICEERROR_GPHSTREAMCOUNT0READY)
00329                 status =
00330                 VL53L1_ERROR_GPH_SYNC_CHECK_FAIL;
00331 
00332         }
00333     } else {
00334         if (pstate->rd_stream_count != device_stream_count)
00335             status = VL53L1_ERROR_STREAM_COUNT_CHECK_FAIL;
00336 
00337 
00338         if (pstate->rd_gph_id != device_gph_id)
00339             status = VL53L1_ERROR_GPH_ID_CHECK_FAIL;
00340 
00341 
00342 
00343 
00344         expected_stream_count =
00345         pZ->VL53L1_p_002[pstate->rd_zone_id].expected_stream_count;
00346         expected_gph_id =
00347         pZ->VL53L1_p_002[pstate->rd_zone_id].expected_gph_id;
00348 
00349 
00350 
00351         if (expected_stream_count != device_stream_count) {
00352 
00353 
00354             if (!((pdev->zone_cfg.active_zones == 0) &&
00355                 (device_stream_count == 255)))
00356                 status =
00357                 VL53L1_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL;
00358 
00359 
00360         }
00361 
00362 
00363 
00364         if (expected_gph_id != device_gph_id)
00365             status = VL53L1_ERROR_ZONE_GPH_ID_CHECK_FAIL;
00366 
00367     }
00368 
00369 
00370 
00371 ENDFUNC:
00372     LOG_FUNCTION_END(status);
00373     return status;
00374 }
00375 
00376 
00377 VL53L1_Error  VL53L1_update_ll_driver_cfg_state(
00378     VL53L1_DEV         Dev)
00379 {
00380 
00381 
00382     VL53L1_Error         status = VL53L1_ERROR_NONE;
00383     VL53L1_LLDriverData_t  *pdev =
00384             VL53L1DevStructGetLLDriverHandle(Dev);
00385     VL53L1_LLDriverResults_t  *pres =
00386             VL53L1DevStructGetLLResultsHandle(Dev);
00387 
00388     VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
00389     VL53L1_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
00390 
00391     uint8_t prev_cfg_zone_id;
00392     uint8_t prev_cfg_gph_id;
00393     uint8_t prev_cfg_stream_count;
00394 
00395     LOG_FUNCTION_START("");
00396 
00397 
00398 
00399 
00400 
00401     if ((pdev->sys_ctrl.system__mode_start &
00402         VL53L1_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) {
00403 
00404         pstate->cfg_device_state  = VL53L1_DEVICESTATE_SW_STANDBY;
00405         pstate->cfg_stream_count  = 0;
00406         pstate->cfg_internal_stream_count = 0;
00407         pstate->cfg_internal_stream_count_val = 0;
00408         pstate->cfg_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00409         pstate->cfg_timing_status = 0;
00410         pstate->cfg_zone_id       = 0;
00411         prev_cfg_zone_id          = 0;
00412         prev_cfg_gph_id           = 0;
00413         prev_cfg_stream_count     = 0;
00414 
00415     } else {
00416 
00417         prev_cfg_gph_id           = pstate->cfg_gph_id;
00418         prev_cfg_zone_id          = pstate->cfg_zone_id;
00419         prev_cfg_stream_count     = pstate->cfg_stream_count;
00420 
00421 
00422 
00423         if (pstate->cfg_stream_count == 0xFF)
00424             pstate->cfg_stream_count = 0x80;
00425         else
00426             pstate->cfg_stream_count++;
00427 
00428 
00429         status = VL53L1_update_internal_stream_counters(
00430             Dev,
00431             pstate->cfg_stream_count,
00432             &(pstate->cfg_internal_stream_count),
00433             &(pstate->cfg_internal_stream_count_val));
00434 
00435 
00436 
00437         pstate->cfg_gph_id ^= VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00438 
00439 
00440 
00441         switch (pstate->cfg_device_state) {
00442 
00443         case VL53L1_DEVICESTATE_SW_STANDBY:
00444             pstate->cfg_zone_id = 1;
00445             if (pstate->cfg_zone_id >
00446                 pdev->zone_cfg.active_zones) {
00447                 pstate->cfg_zone_id = 0;
00448                 pstate->cfg_timing_status ^= 0x01;
00449             }
00450             pstate->cfg_stream_count = 1;
00451 
00452             if (pdev->gen_cfg.global_config__stream_divider == 0) {
00453                 pstate->cfg_internal_stream_count = 1;
00454                 pstate->cfg_internal_stream_count_val = 0;
00455             } else {
00456                 pstate->cfg_internal_stream_count = 0;
00457                 pstate->cfg_internal_stream_count_val = 1;
00458             }
00459             pstate->cfg_device_state =
00460                     VL53L1_DEVICESTATE_RANGING_DSS_AUTO;
00461             break;
00462 
00463         case VL53L1_DEVICESTATE_RANGING_DSS_AUTO:
00464             pstate->cfg_zone_id++;
00465             if (pstate->cfg_zone_id >
00466                 pdev->zone_cfg.active_zones) {
00467 
00468                 pstate->cfg_zone_id = 0;
00469                 pstate->cfg_timing_status ^= 0x01;
00470 
00471 
00472 
00473 
00474                 if (pdev->zone_cfg.active_zones > 0) {
00475                     pstate->cfg_device_state =
00476                     VL53L1_DEVICESTATE_RANGING_DSS_MANUAL;
00477                 }
00478             }
00479             break;
00480 
00481         case VL53L1_DEVICESTATE_RANGING_DSS_MANUAL:
00482             pstate->cfg_zone_id++;
00483             if (pstate->cfg_zone_id >
00484                 pdev->zone_cfg.active_zones) {
00485                 pstate->cfg_zone_id = 0;
00486                 pstate->cfg_timing_status ^= 0x01;
00487             }
00488             break;
00489 
00490         default:
00491             pstate->cfg_device_state =
00492                     VL53L1_DEVICESTATE_SW_STANDBY;
00493             pstate->cfg_stream_count = 0;
00494             pstate->cfg_internal_stream_count = 0;
00495             pstate->cfg_internal_stream_count_val = 0;
00496             pstate->cfg_gph_id =
00497                     VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00498             pstate->cfg_timing_status = 0;
00499             pstate->cfg_zone_id       = 0;
00500             break;
00501         }
00502     }
00503 
00504 
00505     if (pdev->zone_cfg.active_zones == 0) {
00506 
00507         pZ->VL53L1_p_002[prev_cfg_zone_id].expected_stream_count
00508             = prev_cfg_stream_count - 1;
00509 
00510         pZ->VL53L1_p_002[pstate->rd_zone_id].expected_gph_id =
00511             prev_cfg_gph_id ^ VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
00512     } else {
00513         pZ->VL53L1_p_002[prev_cfg_zone_id].expected_stream_count
00514             = prev_cfg_stream_count;
00515         pZ->VL53L1_p_002[prev_cfg_zone_id].expected_gph_id =
00516             prev_cfg_gph_id;
00517     }
00518 
00519 
00520 
00521     LOG_FUNCTION_END(status);
00522 
00523     return status;
00524 }
00525 
00526 
00527 void VL53L1_copy_rtn_good_spads_to_buffer(
00528     VL53L1_nvm_copy_data_t  *pdata,
00529     uint8_t                 *pbuffer)
00530 {
00531 
00532 
00533     *(pbuffer +  0) = pdata->global_config__spad_enables_rtn_0;
00534     *(pbuffer +  1) = pdata->global_config__spad_enables_rtn_1;
00535     *(pbuffer +  2) = pdata->global_config__spad_enables_rtn_2;
00536     *(pbuffer +  3) = pdata->global_config__spad_enables_rtn_3;
00537     *(pbuffer +  4) = pdata->global_config__spad_enables_rtn_4;
00538     *(pbuffer +  5) = pdata->global_config__spad_enables_rtn_5;
00539     *(pbuffer +  6) = pdata->global_config__spad_enables_rtn_6;
00540     *(pbuffer +  7) = pdata->global_config__spad_enables_rtn_7;
00541     *(pbuffer +  8) = pdata->global_config__spad_enables_rtn_8;
00542     *(pbuffer +  9) = pdata->global_config__spad_enables_rtn_9;
00543     *(pbuffer + 10) = pdata->global_config__spad_enables_rtn_10;
00544     *(pbuffer + 11) = pdata->global_config__spad_enables_rtn_11;
00545     *(pbuffer + 12) = pdata->global_config__spad_enables_rtn_12;
00546     *(pbuffer + 13) = pdata->global_config__spad_enables_rtn_13;
00547     *(pbuffer + 14) = pdata->global_config__spad_enables_rtn_14;
00548     *(pbuffer + 15) = pdata->global_config__spad_enables_rtn_15;
00549     *(pbuffer + 16) = pdata->global_config__spad_enables_rtn_16;
00550     *(pbuffer + 17) = pdata->global_config__spad_enables_rtn_17;
00551     *(pbuffer + 18) = pdata->global_config__spad_enables_rtn_18;
00552     *(pbuffer + 19) = pdata->global_config__spad_enables_rtn_19;
00553     *(pbuffer + 20) = pdata->global_config__spad_enables_rtn_20;
00554     *(pbuffer + 21) = pdata->global_config__spad_enables_rtn_21;
00555     *(pbuffer + 22) = pdata->global_config__spad_enables_rtn_22;
00556     *(pbuffer + 23) = pdata->global_config__spad_enables_rtn_23;
00557     *(pbuffer + 24) = pdata->global_config__spad_enables_rtn_24;
00558     *(pbuffer + 25) = pdata->global_config__spad_enables_rtn_25;
00559     *(pbuffer + 26) = pdata->global_config__spad_enables_rtn_26;
00560     *(pbuffer + 27) = pdata->global_config__spad_enables_rtn_27;
00561     *(pbuffer + 28) = pdata->global_config__spad_enables_rtn_28;
00562     *(pbuffer + 29) = pdata->global_config__spad_enables_rtn_29;
00563     *(pbuffer + 30) = pdata->global_config__spad_enables_rtn_30;
00564     *(pbuffer + 31) = pdata->global_config__spad_enables_rtn_31;
00565 }
00566 
00567 
00568 void VL53L1_init_system_results(
00569         VL53L1_system_results_t  *pdata)
00570 {
00571 
00572 
00573     pdata->result__interrupt_status                       = 0xFF;
00574     pdata->result__range_status                           = 0xFF;
00575     pdata->result__report_status                          = 0xFF;
00576     pdata->result__stream_count                           = 0xFF;
00577 
00578     pdata->result__dss_actual_effective_spads_sd0         = 0xFFFF;
00579     pdata->result__peak_signal_count_rate_mcps_sd0        = 0xFFFF;
00580     pdata->result__ambient_count_rate_mcps_sd0            = 0xFFFF;
00581     pdata->result__sigma_sd0                              = 0xFFFF;
00582     pdata->result__phase_sd0                              = 0xFFFF;
00583     pdata->result__final_crosstalk_corrected_range_mm_sd0 = 0xFFFF;
00584     pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 =
00585             0xFFFF;
00586     pdata->result__mm_inner_actual_effective_spads_sd0    = 0xFFFF;
00587     pdata->result__mm_outer_actual_effective_spads_sd0    = 0xFFFF;
00588     pdata->result__avg_signal_count_rate_mcps_sd0         = 0xFFFF;
00589 
00590     pdata->result__dss_actual_effective_spads_sd1         = 0xFFFF;
00591     pdata->result__peak_signal_count_rate_mcps_sd1        = 0xFFFF;
00592     pdata->result__ambient_count_rate_mcps_sd1            = 0xFFFF;
00593     pdata->result__sigma_sd1                              = 0xFFFF;
00594     pdata->result__phase_sd1                              = 0xFFFF;
00595     pdata->result__final_crosstalk_corrected_range_mm_sd1 = 0xFFFF;
00596     pdata->result__spare_0_sd1                            = 0xFFFF;
00597     pdata->result__spare_1_sd1                            = 0xFFFF;
00598     pdata->result__spare_2_sd1                            = 0xFFFF;
00599     pdata->result__spare_3_sd1                            = 0xFF;
00600 
00601 }
00602 
00603 
00604 void V53L1_init_zone_results_structure(
00605     uint8_t                 active_zones,
00606     VL53L1_zone_results_t  *pdata)
00607 {
00608 
00609 
00610 
00611     uint8_t  z = 0;
00612     VL53L1_zone_objects_t *pobjects;
00613 
00614     pdata->max_zones    = VL53L1_MAX_USER_ZONES;
00615     pdata->active_zones = active_zones;
00616 
00617     for (z = 0; z < pdata->max_zones; z++) {
00618         pobjects = &(pdata->VL53L1_p_002[z]);
00619         pobjects->cfg_device_state = VL53L1_DEVICESTATE_SW_STANDBY;
00620         pobjects->rd_device_state  = VL53L1_DEVICESTATE_SW_STANDBY;
00621         pobjects->max_objects      = VL53L1_MAX_RANGE_RESULTS;
00622         pobjects->active_objects   = 0;
00623     }
00624 }
00625 
00626 void V53L1_init_zone_dss_configs(
00627     VL53L1_DEV              Dev)
00628 {
00629 
00630 
00631 
00632     VL53L1_LLDriverResults_t  *pres =
00633             VL53L1DevStructGetLLResultsHandle(Dev);
00634     uint8_t  z = 0;
00635     uint8_t max_zones    = VL53L1_MAX_USER_ZONES;
00636     VL53L1_zone_private_dyn_cfgs_t *pdata = &(pres->zone_dyn_cfgs);
00637 
00638     for (z = 0; z < max_zones; z++) {
00639         pdata->VL53L1_p_002[z].dss_mode =
00640             VL53L1_DSS_CONTROL__MODE_TARGET_RATE;
00641         pdata->VL53L1_p_002[z].dss_requested_effective_spad_count = 0;
00642     }
00643 }
00644 
00645 
00646 void VL53L1_init_histogram_config_structure(
00647     uint8_t   even_bin0,
00648     uint8_t   even_bin1,
00649     uint8_t   even_bin2,
00650     uint8_t   even_bin3,
00651     uint8_t   even_bin4,
00652     uint8_t   even_bin5,
00653     uint8_t   odd_bin0,
00654     uint8_t   odd_bin1,
00655     uint8_t   odd_bin2,
00656     uint8_t   odd_bin3,
00657     uint8_t   odd_bin4,
00658     uint8_t   odd_bin5,
00659     VL53L1_histogram_config_t  *pdata)
00660 {
00661 
00662 
00663     pdata->histogram_config__low_amb_even_bin_0_1  =
00664             (even_bin1 << 4) + even_bin0;
00665     pdata->histogram_config__low_amb_even_bin_2_3  =
00666             (even_bin3 << 4) + even_bin2;
00667     pdata->histogram_config__low_amb_even_bin_4_5  =
00668             (even_bin5 << 4) + even_bin4;
00669 
00670     pdata->histogram_config__low_amb_odd_bin_0_1   =
00671             (odd_bin1 << 4) + odd_bin0;
00672     pdata->histogram_config__low_amb_odd_bin_2_3   =
00673             (odd_bin3 << 4) + odd_bin2;
00674     pdata->histogram_config__low_amb_odd_bin_4_5   =
00675             (odd_bin5 << 4) + odd_bin4;
00676 
00677     pdata->histogram_config__mid_amb_even_bin_0_1  =
00678             pdata->histogram_config__low_amb_even_bin_0_1;
00679     pdata->histogram_config__mid_amb_even_bin_2_3  =
00680             pdata->histogram_config__low_amb_even_bin_2_3;
00681     pdata->histogram_config__mid_amb_even_bin_4_5  =
00682             pdata->histogram_config__low_amb_even_bin_4_5;
00683 
00684     pdata->histogram_config__mid_amb_odd_bin_0_1   =
00685             pdata->histogram_config__low_amb_odd_bin_0_1;
00686     pdata->histogram_config__mid_amb_odd_bin_2     = odd_bin2;
00687     pdata->histogram_config__mid_amb_odd_bin_3_4   =
00688             (odd_bin4 << 4) + odd_bin3;
00689     pdata->histogram_config__mid_amb_odd_bin_5     = odd_bin5;
00690 
00691     pdata->histogram_config__user_bin_offset       = 0x00;
00692 
00693     pdata->histogram_config__high_amb_even_bin_0_1 =
00694             pdata->histogram_config__low_amb_even_bin_0_1;
00695     pdata->histogram_config__high_amb_even_bin_2_3 =
00696             pdata->histogram_config__low_amb_even_bin_2_3;
00697     pdata->histogram_config__high_amb_even_bin_4_5 =
00698             pdata->histogram_config__low_amb_even_bin_4_5;
00699 
00700     pdata->histogram_config__high_amb_odd_bin_0_1  =
00701             pdata->histogram_config__low_amb_odd_bin_0_1;
00702     pdata->histogram_config__high_amb_odd_bin_2_3  =
00703             pdata->histogram_config__low_amb_odd_bin_2_3;
00704     pdata->histogram_config__high_amb_odd_bin_4_5  =
00705             pdata->histogram_config__low_amb_odd_bin_4_5;
00706 
00707 
00708 
00709     pdata->histogram_config__amb_thresh_low        = 0xFFFF;
00710     pdata->histogram_config__amb_thresh_high       = 0xFFFF;
00711 
00712 
00713 
00714     pdata->histogram_config__spad_array_selection  = 0x00;
00715 
00716 }
00717 
00718 void VL53L1_init_histogram_multizone_config_structure(
00719     uint8_t   even_bin0,
00720     uint8_t   even_bin1,
00721     uint8_t   even_bin2,
00722     uint8_t   even_bin3,
00723     uint8_t   even_bin4,
00724     uint8_t   even_bin5,
00725     uint8_t   odd_bin0,
00726     uint8_t   odd_bin1,
00727     uint8_t   odd_bin2,
00728     uint8_t   odd_bin3,
00729     uint8_t   odd_bin4,
00730     uint8_t   odd_bin5,
00731     VL53L1_histogram_config_t  *pdata)
00732 {
00733 
00734 
00735     pdata->histogram_config__low_amb_even_bin_0_1  =
00736             (even_bin1 << 4) + even_bin0;
00737     pdata->histogram_config__low_amb_even_bin_2_3  =
00738             (even_bin3 << 4) + even_bin2;
00739     pdata->histogram_config__low_amb_even_bin_4_5  =
00740             (even_bin5 << 4) + even_bin4;
00741 
00742     pdata->histogram_config__low_amb_odd_bin_0_1   =
00743             pdata->histogram_config__low_amb_even_bin_0_1;
00744     pdata->histogram_config__low_amb_odd_bin_2_3
00745         = pdata->histogram_config__low_amb_even_bin_2_3;
00746     pdata->histogram_config__low_amb_odd_bin_4_5
00747         = pdata->histogram_config__low_amb_even_bin_4_5;
00748 
00749     pdata->histogram_config__mid_amb_even_bin_0_1  =
00750         pdata->histogram_config__low_amb_even_bin_0_1;
00751     pdata->histogram_config__mid_amb_even_bin_2_3
00752         = pdata->histogram_config__low_amb_even_bin_2_3;
00753     pdata->histogram_config__mid_amb_even_bin_4_5
00754         = pdata->histogram_config__low_amb_even_bin_4_5;
00755 
00756     pdata->histogram_config__mid_amb_odd_bin_0_1
00757         = pdata->histogram_config__low_amb_odd_bin_0_1;
00758     pdata->histogram_config__mid_amb_odd_bin_2     = odd_bin2;
00759     pdata->histogram_config__mid_amb_odd_bin_3_4   =
00760             (odd_bin4 << 4) + odd_bin3;
00761     pdata->histogram_config__mid_amb_odd_bin_5     = odd_bin5;
00762 
00763     pdata->histogram_config__user_bin_offset       = 0x00;
00764 
00765     pdata->histogram_config__high_amb_even_bin_0_1 =
00766             (odd_bin1 << 4) + odd_bin0;
00767     pdata->histogram_config__high_amb_even_bin_2_3 =
00768             (odd_bin3 << 4) + odd_bin2;
00769     pdata->histogram_config__high_amb_even_bin_4_5 =
00770             (odd_bin5 << 4) + odd_bin4;
00771 
00772     pdata->histogram_config__high_amb_odd_bin_0_1
00773         = pdata->histogram_config__high_amb_even_bin_0_1;
00774     pdata->histogram_config__high_amb_odd_bin_2_3
00775         = pdata->histogram_config__high_amb_even_bin_2_3;
00776     pdata->histogram_config__high_amb_odd_bin_4_5
00777         = pdata->histogram_config__high_amb_even_bin_4_5;
00778 
00779 
00780 
00781     pdata->histogram_config__amb_thresh_low        = 0xFFFF;
00782     pdata->histogram_config__amb_thresh_high       = 0xFFFF;
00783 
00784 
00785 
00786     pdata->histogram_config__spad_array_selection  = 0x00;
00787 }
00788 
00789 
00790 void VL53L1_init_xtalk_bin_data_struct(
00791     uint32_t                        bin_value,
00792     uint16_t                        VL53L1_p_024,
00793     VL53L1_xtalk_histogram_shape_t *pdata)
00794 {
00795 
00796 
00797 
00798     uint16_t          i = 0;
00799 
00800     pdata->zone_id                   = 0;
00801     pdata->time_stamp                = 0;
00802 
00803     pdata->VL53L1_p_022                 = 0;
00804     pdata->VL53L1_p_023               = VL53L1_XTALK_HISTO_BINS;
00805     pdata->VL53L1_p_024            = (uint8_t)VL53L1_p_024;
00806 
00807     pdata->phasecal_result__reference_phase   = 0;
00808     pdata->phasecal_result__vcsel_start       = 0;
00809     pdata->cal_config__vcsel_start            = 0;
00810 
00811     pdata->vcsel_width                        = 0;
00812     pdata->VL53L1_p_019                = 0;
00813 
00814     pdata->zero_distance_phase                = 0;
00815 
00816     for (i = 0; i < VL53L1_XTALK_HISTO_BINS; i++) {
00817         if (i < VL53L1_p_024)
00818             pdata->bin_data[i] = bin_value;
00819         else
00820             pdata->bin_data[i] = 0;
00821     }
00822 }
00823 
00824 
00825 void VL53L1_i2c_encode_uint16_t(
00826     uint16_t    ip_value,
00827     uint16_t    count,
00828     uint8_t    *pbuffer)
00829 {
00830 
00831 
00832     uint16_t   i    = 0;
00833     uint16_t   VL53L1_p_002 = 0;
00834 
00835     VL53L1_p_002 =  ip_value;
00836 
00837     for (i = 0; i < count; i++) {
00838         pbuffer[count-i-1] = (uint8_t)(VL53L1_p_002 & 0x00FF);
00839         VL53L1_p_002 = VL53L1_p_002 >> 8;
00840     }
00841 }
00842 
00843 uint16_t VL53L1_i2c_decode_uint16_t(
00844     uint16_t    count,
00845     uint8_t    *pbuffer)
00846 {
00847 
00848 
00849     uint16_t   value = 0x00;
00850 
00851     while (count-- > 0)
00852         value = (value << 8) | (uint16_t)*pbuffer++;
00853 
00854     return value;
00855 }
00856 
00857 
00858 void VL53L1_i2c_encode_int16_t(
00859     int16_t     ip_value,
00860     uint16_t    count,
00861     uint8_t    *pbuffer)
00862 {
00863 
00864 
00865     uint16_t   i    = 0;
00866     int16_t    VL53L1_p_002 = 0;
00867 
00868     VL53L1_p_002 =  ip_value;
00869 
00870     for (i = 0; i < count; i++) {
00871         pbuffer[count-i-1] = (uint8_t)(VL53L1_p_002 & 0x00FF);
00872         VL53L1_p_002 = VL53L1_p_002 >> 8;
00873     }
00874 }
00875 
00876 int16_t VL53L1_i2c_decode_int16_t(
00877     uint16_t    count,
00878     uint8_t    *pbuffer)
00879 {
00880 
00881 
00882     int16_t    value = 0x00;
00883 
00884 
00885     if (*pbuffer >= 0x80)
00886         value = 0xFFFF;
00887 
00888     while (count-- > 0)
00889         value = (value << 8) | (int16_t)*pbuffer++;
00890 
00891     return value;
00892 }
00893 
00894 void VL53L1_i2c_encode_uint32_t(
00895     uint32_t    ip_value,
00896     uint16_t    count,
00897     uint8_t    *pbuffer)
00898 {
00899 
00900 
00901     uint16_t   i    = 0;
00902     uint32_t   VL53L1_p_002 = 0;
00903 
00904     VL53L1_p_002 =  ip_value;
00905 
00906     for (i = 0; i < count; i++) {
00907         pbuffer[count-i-1] = (uint8_t)(VL53L1_p_002 & 0x00FF);
00908         VL53L1_p_002 = VL53L1_p_002 >> 8;
00909     }
00910 }
00911 
00912 uint32_t VL53L1_i2c_decode_uint32_t(
00913     uint16_t    count,
00914     uint8_t    *pbuffer)
00915 {
00916 
00917 
00918     uint32_t   value = 0x00;
00919 
00920     while (count-- > 0)
00921         value = (value << 8) | (uint32_t)*pbuffer++;
00922 
00923     return value;
00924 }
00925 
00926 
00927 uint32_t VL53L1_i2c_decode_with_mask(
00928     uint16_t    count,
00929     uint8_t    *pbuffer,
00930     uint32_t    bit_mask,
00931     uint32_t    down_shift,
00932     uint32_t    offset)
00933 {
00934 
00935 
00936     uint32_t   value = 0x00;
00937 
00938 
00939     while (count-- > 0)
00940         value = (value << 8) | (uint32_t)*pbuffer++;
00941 
00942 
00943     value =  value & bit_mask;
00944     if (down_shift > 0)
00945         value = value >> down_shift;
00946 
00947 
00948     value = value + offset;
00949 
00950     return value;
00951 }
00952 
00953 
00954 void VL53L1_i2c_encode_int32_t(
00955     int32_t     ip_value,
00956     uint16_t    count,
00957     uint8_t    *pbuffer)
00958 {
00959 
00960 
00961     uint16_t   i    = 0;
00962     int32_t    VL53L1_p_002 = 0;
00963 
00964     VL53L1_p_002 =  ip_value;
00965 
00966     for (i = 0; i < count; i++) {
00967         pbuffer[count-i-1] = (uint8_t)(VL53L1_p_002 & 0x00FF);
00968         VL53L1_p_002 = VL53L1_p_002 >> 8;
00969     }
00970 }
00971 
00972 int32_t VL53L1_i2c_decode_int32_t(
00973     uint16_t    count,
00974     uint8_t    *pbuffer)
00975 {
00976 
00977 
00978     int32_t    value = 0x00;
00979 
00980 
00981     if (*pbuffer >= 0x80)
00982         value = 0xFFFFFFFF;
00983 
00984     while (count-- > 0)
00985         value = (value << 8) | (int32_t)*pbuffer++;
00986 
00987     return value;
00988 }
00989 
00990 
00991 VL53L1_Error VL53L1_start_test(
00992     VL53L1_DEV    Dev,
00993     uint8_t       test_mode__ctrl)
00994 {
00995 
00996 
00997     VL53L1_Error status = VL53L1_ERROR_NONE;
00998 
00999     LOG_FUNCTION_START("");
01000 
01001     if (status == VL53L1_ERROR_NONE) {
01002         status = VL53L1_WrByte(
01003                     Dev,
01004                     VL53L1_TEST_MODE__CTRL,
01005                     test_mode__ctrl);
01006     }
01007 
01008     LOG_FUNCTION_END(status);
01009 
01010     return status;
01011 }
01012 
01013 
01014 VL53L1_Error VL53L1_set_firmware_enable_register(
01015     VL53L1_DEV    Dev,
01016     uint8_t       value)
01017 {
01018 
01019 
01020     VL53L1_Error status         = VL53L1_ERROR_NONE;
01021     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01022 
01023     pdev->sys_ctrl.firmware__enable = value;
01024 
01025     status = VL53L1_WrByte(
01026                 Dev,
01027                 VL53L1_FIRMWARE__ENABLE,
01028                 pdev->sys_ctrl.firmware__enable);
01029 
01030     return status;
01031 }
01032 
01033 VL53L1_Error VL53L1_enable_firmware(
01034     VL53L1_DEV    Dev)
01035 {
01036 
01037 
01038     VL53L1_Error status       = VL53L1_ERROR_NONE;
01039 
01040     LOG_FUNCTION_START("");
01041 
01042     status = VL53L1_set_firmware_enable_register(Dev, 0x01);
01043 
01044     LOG_FUNCTION_END(status);
01045 
01046     return status;
01047 }
01048 
01049 
01050 VL53L1_Error VL53L1_disable_firmware(
01051     VL53L1_DEV    Dev)
01052 {
01053 
01054 
01055     VL53L1_Error status       = VL53L1_ERROR_NONE;
01056 
01057     LOG_FUNCTION_START("");
01058 
01059     status = VL53L1_set_firmware_enable_register(Dev, 0x00);
01060 
01061     LOG_FUNCTION_END(status);
01062 
01063     return status;
01064 }
01065 
01066 
01067 VL53L1_Error VL53L1_set_powerforce_register(
01068     VL53L1_DEV    Dev,
01069     uint8_t       value)
01070 {
01071 
01072 
01073     VL53L1_Error status       = VL53L1_ERROR_NONE;
01074     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01075 
01076     pdev->sys_ctrl.power_management__go1_power_force = value;
01077 
01078     status = VL53L1_WrByte(
01079             Dev,
01080             VL53L1_POWER_MANAGEMENT__GO1_POWER_FORCE,
01081             pdev->sys_ctrl.power_management__go1_power_force);
01082 
01083     return status;
01084 }
01085 
01086 
01087 VL53L1_Error VL53L1_enable_powerforce(
01088     VL53L1_DEV    Dev)
01089 {
01090 
01091 
01092     VL53L1_Error status       = VL53L1_ERROR_NONE;
01093 
01094     LOG_FUNCTION_START("");
01095 
01096     status = VL53L1_set_powerforce_register(Dev, 0x01);
01097 
01098     LOG_FUNCTION_END(status);
01099 
01100     return status;
01101 }
01102 
01103 
01104 VL53L1_Error VL53L1_disable_powerforce(
01105     VL53L1_DEV    Dev)
01106 {
01107 
01108 
01109     VL53L1_Error status       = VL53L1_ERROR_NONE;
01110 
01111     LOG_FUNCTION_START("");
01112 
01113     status = VL53L1_set_powerforce_register(Dev, 0x00);
01114 
01115     LOG_FUNCTION_END(status);
01116 
01117     return status;
01118 }
01119 
01120 
01121 VL53L1_Error VL53L1_clear_interrupt(
01122     VL53L1_DEV    Dev)
01123 {
01124 
01125 
01126     VL53L1_Error status       = VL53L1_ERROR_NONE;
01127     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01128 
01129     LOG_FUNCTION_START("");
01130 
01131     pdev->sys_ctrl.system__interrupt_clear = VL53L1_CLEAR_RANGE_INT;
01132 
01133     status = VL53L1_WrByte(
01134                 Dev,
01135                 VL53L1_SYSTEM__INTERRUPT_CLEAR,
01136                 pdev->sys_ctrl.system__interrupt_clear);
01137 
01138     LOG_FUNCTION_END(status);
01139 
01140     return status;
01141 }
01142 
01143 
01144 VL53L1_Error VL53L1_force_shadow_stream_count_to_zero(
01145     VL53L1_DEV    Dev)
01146 {
01147 
01148 
01149     VL53L1_Error status       = VL53L1_ERROR_NONE;
01150 
01151     if (status == VL53L1_ERROR_NONE)
01152         status = VL53L1_disable_firmware(Dev);
01153 
01154     if (status == VL53L1_ERROR_NONE) {
01155         status = VL53L1_WrByte(
01156                 Dev,
01157                 VL53L1_SHADOW_RESULT__STREAM_COUNT,
01158                 0x00);
01159     }
01160 
01161     if (status == VL53L1_ERROR_NONE)
01162         status = VL53L1_enable_firmware(Dev);
01163 
01164     return status;
01165 }
01166 
01167 
01168 uint32_t VL53L1_calc_macro_period_us(
01169     uint16_t  fast_osc_frequency,
01170     uint8_t   VL53L1_p_009)
01171 {
01172 
01173 
01174     uint32_t  pll_period_us        = 0;
01175     uint8_t   VL53L1_p_031   = 0;
01176     uint32_t  macro_period_us      = 0;
01177 
01178     LOG_FUNCTION_START("");
01179 
01180 
01181 
01182     pll_period_us = VL53L1_calc_pll_period_us(fast_osc_frequency);
01183 
01184 
01185 
01186     VL53L1_p_031 = VL53L1_decode_vcsel_period(VL53L1_p_009);
01187 
01188 
01189 
01190     macro_period_us =
01191             (uint32_t)VL53L1_MACRO_PERIOD_VCSEL_PERIODS *
01192             pll_period_us;
01193     macro_period_us = macro_period_us >> 6;
01194 
01195     macro_period_us = macro_period_us * (uint32_t)VL53L1_p_031;
01196     macro_period_us = macro_period_us >> 6;
01197 
01198 
01199 
01200     LOG_FUNCTION_END(0);
01201 
01202     return macro_period_us;
01203 }
01204 
01205 
01206 uint16_t VL53L1_calc_range_ignore_threshold(
01207     uint32_t central_rate,
01208     int16_t  x_gradient,
01209     int16_t  y_gradient,
01210     uint8_t  rate_mult)
01211 {
01212 
01213 
01214     int32_t    range_ignore_thresh_int  = 0;
01215     uint16_t   range_ignore_thresh_kcps = 0;
01216     int32_t    central_rate_int         = 0;
01217     int16_t    x_gradient_int           = 0;
01218     int16_t    y_gradient_int           = 0;
01219 
01220     LOG_FUNCTION_START("");
01221 
01222 
01223 
01224     central_rate_int = ((int32_t)central_rate * (1 << 4)) / (1000);
01225 
01226     if (x_gradient < 0)
01227         x_gradient_int = x_gradient * -1;
01228 
01229     if (y_gradient < 0)
01230         y_gradient_int = y_gradient * -1;
01231 
01232 
01233 
01234 
01235 
01236     range_ignore_thresh_int = (8 * x_gradient_int * 4) +
01237             (8 * y_gradient_int * 4);
01238 
01239 
01240 
01241     range_ignore_thresh_int = range_ignore_thresh_int / 1000;
01242 
01243 
01244 
01245     range_ignore_thresh_int = range_ignore_thresh_int + central_rate_int;
01246 
01247 
01248 
01249     range_ignore_thresh_int = (int32_t)rate_mult * range_ignore_thresh_int;
01250 
01251     range_ignore_thresh_int = (range_ignore_thresh_int + (1<<4)) / (1<<5);
01252 
01253 
01254 
01255     if (range_ignore_thresh_int > 0xFFFF)
01256         range_ignore_thresh_kcps = 0xFFFF;
01257     else
01258         range_ignore_thresh_kcps = (uint16_t)range_ignore_thresh_int;
01259 
01260 
01261 
01262     LOG_FUNCTION_END(0);
01263 
01264     return range_ignore_thresh_kcps;
01265 }
01266 
01267 
01268 uint32_t VL53L1_calc_timeout_mclks(
01269     uint32_t timeout_us,
01270     uint32_t macro_period_us)
01271 {
01272 
01273 
01274     uint32_t timeout_mclks   = 0;
01275 
01276     LOG_FUNCTION_START("");
01277 
01278     timeout_mclks   =
01279             ((timeout_us << 12) + (macro_period_us>>1)) /
01280             macro_period_us;
01281 
01282     LOG_FUNCTION_END(0);
01283 
01284     return timeout_mclks;
01285 }
01286 
01287 
01288 uint16_t VL53L1_calc_encoded_timeout(
01289     uint32_t timeout_us,
01290     uint32_t macro_period_us)
01291 {
01292 
01293 
01294     uint32_t timeout_mclks   = 0;
01295     uint16_t timeout_encoded = 0;
01296 
01297     LOG_FUNCTION_START("");
01298 
01299     timeout_mclks   =
01300         VL53L1_calc_timeout_mclks(timeout_us, macro_period_us);
01301 
01302     timeout_encoded =
01303         VL53L1_encode_timeout(timeout_mclks);
01304 
01305 
01306 
01307     LOG_FUNCTION_END(0);
01308 
01309     return timeout_encoded;
01310 }
01311 
01312 
01313 uint32_t VL53L1_calc_timeout_us(
01314     uint32_t timeout_mclks,
01315     uint32_t macro_period_us)
01316 {
01317 
01318 
01319     uint32_t timeout_us     = 0;
01320     uint64_t tmp            = 0;
01321 
01322     LOG_FUNCTION_START("");
01323 
01324     tmp  = (uint64_t)timeout_mclks * (uint64_t)macro_period_us;
01325     tmp += 0x00800;
01326     tmp  = tmp >> 12;
01327 
01328     timeout_us = (uint32_t)tmp;
01329 
01330 
01331 
01332     LOG_FUNCTION_END(0);
01333 
01334     return timeout_us;
01335 }
01336 
01337 uint32_t VL53L1_calc_crosstalk_plane_offset_with_margin(
01338         uint32_t     plane_offset_kcps,
01339         int16_t      margin_offset_kcps)
01340 {
01341     uint32_t plane_offset_with_margin = 0;
01342     int32_t  plane_offset_kcps_temp   = 0;
01343 
01344     LOG_FUNCTION_START("");
01345 
01346     plane_offset_kcps_temp =
01347         (int32_t)plane_offset_kcps +
01348         (int32_t)margin_offset_kcps;
01349 
01350     if (plane_offset_kcps_temp < 0)
01351         plane_offset_kcps_temp = 0;
01352     else
01353         if (plane_offset_kcps_temp > 0x3FFFF)
01354             plane_offset_kcps_temp = 0x3FFFF;
01355 
01356     plane_offset_with_margin = (uint32_t) plane_offset_kcps_temp;
01357 
01358     LOG_FUNCTION_END(0);
01359 
01360     return plane_offset_with_margin;
01361 
01362 }
01363 
01364 uint32_t VL53L1_calc_decoded_timeout_us(
01365     uint16_t timeout_encoded,
01366     uint32_t macro_period_us)
01367 {
01368 
01369 
01370     uint32_t timeout_mclks  = 0;
01371     uint32_t timeout_us     = 0;
01372 
01373     LOG_FUNCTION_START("");
01374 
01375     timeout_mclks =
01376         VL53L1_decode_timeout(timeout_encoded);
01377 
01378     timeout_us    =
01379         VL53L1_calc_timeout_us(timeout_mclks, macro_period_us);
01380 
01381     LOG_FUNCTION_END(0);
01382 
01383     return timeout_us;
01384 }
01385 
01386 
01387 uint16_t VL53L1_encode_timeout(uint32_t timeout_mclks)
01388 {
01389 
01390 
01391     uint16_t encoded_timeout = 0;
01392     uint32_t ls_byte = 0;
01393     uint16_t ms_byte = 0;
01394 
01395     if (timeout_mclks > 0) {
01396         ls_byte = timeout_mclks - 1;
01397 
01398         while ((ls_byte & 0xFFFFFF00) > 0) {
01399             ls_byte = ls_byte >> 1;
01400             ms_byte++;
01401         }
01402 
01403         encoded_timeout = (ms_byte << 8)
01404                 + (uint16_t) (ls_byte & 0x000000FF);
01405     }
01406 
01407     return encoded_timeout;
01408 }
01409 
01410 
01411 uint32_t VL53L1_decode_timeout(uint16_t encoded_timeout)
01412 {
01413 
01414 
01415     uint32_t timeout_macro_clks = 0;
01416 
01417     timeout_macro_clks = ((uint32_t) (encoded_timeout & 0x00FF)
01418             << (uint32_t) ((encoded_timeout & 0xFF00) >> 8)) + 1;
01419 
01420     return timeout_macro_clks;
01421 }
01422 
01423 
01424 VL53L1_Error VL53L1_calc_timeout_register_values(
01425     uint32_t                 phasecal_config_timeout_us,
01426     uint32_t                 mm_config_timeout_us,
01427     uint32_t                 range_config_timeout_us,
01428     uint16_t                 fast_osc_frequency,
01429     VL53L1_general_config_t *pgeneral,
01430     VL53L1_timing_config_t  *ptiming)
01431 {
01432 
01433 
01434     VL53L1_Error status = VL53L1_ERROR_NONE;
01435 
01436     uint32_t macro_period_us    = 0;
01437     uint32_t timeout_mclks      = 0;
01438     uint16_t timeout_encoded    = 0;
01439 
01440     LOG_FUNCTION_START("");
01441 
01442     if (fast_osc_frequency == 0) {
01443         status = VL53L1_ERROR_DIVISION_BY_ZERO;
01444     } else {
01445 
01446         macro_period_us =
01447                 VL53L1_calc_macro_period_us(
01448                     fast_osc_frequency,
01449                     ptiming->range_config__vcsel_period_a);
01450 
01451 
01452         timeout_mclks =
01453             VL53L1_calc_timeout_mclks(
01454                 phasecal_config_timeout_us,
01455                 macro_period_us);
01456 
01457 
01458         if (timeout_mclks > 0xFF)
01459             timeout_mclks = 0xFF;
01460 
01461         pgeneral->phasecal_config__timeout_macrop =
01462                 (uint8_t)timeout_mclks;
01463 
01464 
01465         timeout_encoded =
01466             VL53L1_calc_encoded_timeout(
01467                 mm_config_timeout_us,
01468                 macro_period_us);
01469 
01470         ptiming->mm_config__timeout_macrop_a_hi =
01471                 (uint8_t)((timeout_encoded & 0xFF00) >> 8);
01472         ptiming->mm_config__timeout_macrop_a_lo =
01473                 (uint8_t) (timeout_encoded & 0x00FF);
01474 
01475 
01476         timeout_encoded =
01477             VL53L1_calc_encoded_timeout(
01478                 range_config_timeout_us,
01479                 macro_period_us);
01480 
01481         ptiming->range_config__timeout_macrop_a_hi =
01482                 (uint8_t)((timeout_encoded & 0xFF00) >> 8);
01483         ptiming->range_config__timeout_macrop_a_lo =
01484                 (uint8_t) (timeout_encoded & 0x00FF);
01485 
01486 
01487         macro_period_us =
01488                 VL53L1_calc_macro_period_us(
01489                     fast_osc_frequency,
01490                     ptiming->range_config__vcsel_period_b);
01491 
01492 
01493         timeout_encoded =
01494                 VL53L1_calc_encoded_timeout(
01495                     mm_config_timeout_us,
01496                     macro_period_us);
01497 
01498         ptiming->mm_config__timeout_macrop_b_hi =
01499                 (uint8_t)((timeout_encoded & 0xFF00) >> 8);
01500         ptiming->mm_config__timeout_macrop_b_lo =
01501                 (uint8_t) (timeout_encoded & 0x00FF);
01502 
01503 
01504         timeout_encoded = VL53L1_calc_encoded_timeout(
01505                             range_config_timeout_us,
01506                             macro_period_us);
01507 
01508         ptiming->range_config__timeout_macrop_b_hi =
01509                 (uint8_t)((timeout_encoded & 0xFF00) >> 8);
01510         ptiming->range_config__timeout_macrop_b_lo =
01511                 (uint8_t) (timeout_encoded & 0x00FF);
01512     }
01513 
01514     LOG_FUNCTION_END(0);
01515 
01516     return status;
01517 
01518 }
01519 
01520 
01521 uint8_t VL53L1_encode_vcsel_period(uint8_t VL53L1_p_031)
01522 {
01523 
01524 
01525     uint8_t vcsel_period_reg = 0;
01526 
01527     vcsel_period_reg = (VL53L1_p_031 >> 1) - 1;
01528 
01529     return vcsel_period_reg;
01530 }
01531 
01532 
01533 uint32_t VL53L1_decode_unsigned_integer(
01534     uint8_t  *pbuffer,
01535     uint8_t   no_of_bytes)
01536 {
01537 
01538 
01539     uint8_t   i = 0;
01540     uint32_t  decoded_value = 0;
01541 
01542     for (i = 0; i < no_of_bytes; i++)
01543         decoded_value = (decoded_value << 8) + (uint32_t)pbuffer[i];
01544 
01545     return decoded_value;
01546 }
01547 
01548 
01549 void VL53L1_encode_unsigned_integer(
01550     uint32_t  ip_value,
01551     uint8_t   no_of_bytes,
01552     uint8_t  *pbuffer)
01553 {
01554 
01555 
01556     uint8_t   i    = 0;
01557     uint32_t  VL53L1_p_002 = 0;
01558 
01559     VL53L1_p_002 = ip_value;
01560     for (i = 0; i < no_of_bytes; i++) {
01561         pbuffer[no_of_bytes-i-1] = VL53L1_p_002 & 0x00FF;
01562         VL53L1_p_002 = VL53L1_p_002 >> 8;
01563     }
01564 }
01565 
01566 
01567 VL53L1_Error  VL53L1_hist_copy_and_scale_ambient_info(
01568     VL53L1_zone_hist_info_t       *pidata,
01569     VL53L1_histogram_bin_data_t   *podata)
01570 {
01571 
01572 
01573     VL53L1_Error status = VL53L1_ERROR_NONE;
01574 
01575     int64_t  evts              = 0;
01576     int64_t  tmpi              = 0;
01577     int64_t  tmpo              = 0;
01578 
01579     LOG_FUNCTION_START("");
01580 
01581 
01582     if (pidata->result__dss_actual_effective_spads == 0) {
01583         status = VL53L1_ERROR_DIVISION_BY_ZERO;
01584     } else {
01585         if (pidata->number_of_ambient_bins >  0 &&
01586             podata->number_of_ambient_bins == 0) {
01587 
01588 
01589 
01590             tmpo    = 1 + (int64_t)podata->total_periods_elapsed;
01591             tmpo   *=
01592             (int64_t)podata->result__dss_actual_effective_spads;
01593 
01594             tmpi    = 1 + (int64_t)pidata->total_periods_elapsed;
01595             tmpi   *=
01596             (int64_t)pidata->result__dss_actual_effective_spads;
01597 
01598             evts  = tmpo *
01599                 (int64_t)pidata->ambient_events_sum;
01600             evts += (tmpi/2);
01601 
01602 
01603             if (tmpi != 0)
01604                 evts = do_division_s(evts, tmpi);
01605 
01606             podata->ambient_events_sum = (int32_t)evts;
01607 
01608 
01609 
01610             podata->VL53L1_p_004 =
01611                     podata->ambient_events_sum;
01612             podata->VL53L1_p_004 +=
01613                 ((int32_t)pidata->number_of_ambient_bins / 2);
01614             podata->VL53L1_p_004 /=
01615                 (int32_t)pidata->number_of_ambient_bins;
01616         }
01617     }
01618 
01619     LOG_FUNCTION_END(0);
01620 
01621     return status;
01622 }
01623 
01624 
01625 void  VL53L1_hist_get_bin_sequence_config(
01626     VL53L1_DEV                     Dev,
01627     VL53L1_histogram_bin_data_t   *pdata)
01628 {
01629 
01630 
01631     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01632 
01633     int32_t amb_thresh_low   = 0;
01634     int32_t amb_thresh_high  = 0;
01635 
01636     uint8_t i = 0;
01637 
01638     LOG_FUNCTION_START("");
01639 
01640 
01641 
01642     amb_thresh_low  = 1024 *
01643         (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_low;
01644     amb_thresh_high = 1024 *
01645         (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_high;
01646 
01647 
01648 
01649     if ((pdev->ll_state.rd_stream_count & 0x01) == 0) {
01650 
01651         pdata->bin_seq[5] =
01652         pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 >> 4;
01653         pdata->bin_seq[4] =
01654         pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 & 0x0F;
01655         pdata->bin_seq[3] =
01656         pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 >> 4;
01657         pdata->bin_seq[2] =
01658         pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 & 0x0F;
01659         pdata->bin_seq[1] =
01660         pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 >> 4;
01661         pdata->bin_seq[0] =
01662         pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 & 0x0F;
01663 
01664         if (pdata->ambient_events_sum > amb_thresh_high) {
01665             pdata->bin_seq[5] =
01666             pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5
01667             >> 4;
01668             pdata->bin_seq[4] =
01669             pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5
01670             & 0x0F;
01671             pdata->bin_seq[3] =
01672             pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3
01673             >> 4;
01674             pdata->bin_seq[2] =
01675             pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3
01676             & 0x0F;
01677             pdata->bin_seq[1] =
01678             pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1
01679             >> 4;
01680             pdata->bin_seq[0] =
01681             pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1
01682             & 0x0F;
01683         }
01684 
01685         if (pdata->ambient_events_sum < amb_thresh_low) {
01686             pdata->bin_seq[5] =
01687             pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5
01688             >> 4;
01689             pdata->bin_seq[4] =
01690             pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5
01691             & 0x0F;
01692             pdata->bin_seq[3] =
01693             pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3
01694             >> 4;
01695             pdata->bin_seq[2] =
01696             pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3
01697             & 0x0F;
01698             pdata->bin_seq[1] =
01699             pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1
01700             >> 4;
01701             pdata->bin_seq[0] =
01702             pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1
01703             & 0x0F;
01704         }
01705 
01706     } else {
01707         pdata->bin_seq[5] =
01708             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_5
01709             & 0x0F;
01710         pdata->bin_seq[4] =
01711             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4
01712             & 0x0F;
01713         pdata->bin_seq[3] =
01714             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4
01715             >> 4;
01716         pdata->bin_seq[2] =
01717             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_2 &
01718             0x0F;
01719         pdata->bin_seq[1] =
01720             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1
01721             >> 4;
01722         pdata->bin_seq[0] =
01723             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1
01724             & 0x0F;
01725 
01726         if (pdata->ambient_events_sum > amb_thresh_high) {
01727             pdata->bin_seq[5] =
01728             pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5
01729             >> 4;
01730             pdata->bin_seq[4] =
01731             pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5
01732             & 0x0F;
01733             pdata->bin_seq[3] =
01734             pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3
01735             >> 4;
01736             pdata->bin_seq[2] =
01737             pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3
01738             & 0x0F;
01739             pdata->bin_seq[1] =
01740             pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1
01741             >> 4;
01742             pdata->bin_seq[0] =
01743             pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1
01744             & 0x0F;
01745         }
01746 
01747         if (pdata->ambient_events_sum < amb_thresh_low) {
01748             pdata->bin_seq[5] =
01749             pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5
01750             >> 4;
01751             pdata->bin_seq[4] =
01752             pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5
01753             & 0x0F;
01754             pdata->bin_seq[3] =
01755             pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3
01756             >> 4;
01757             pdata->bin_seq[2] =
01758             pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3
01759             & 0x0F;
01760             pdata->bin_seq[1] =
01761             pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1
01762             >> 4;
01763             pdata->bin_seq[0] =
01764             pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1
01765             & 0x0F;
01766         }
01767     }
01768 
01769 
01770 
01771     for (i = 0; i < VL53L1_MAX_BIN_SEQUENCE_LENGTH; i++)
01772         pdata->bin_rep[i] = 1;
01773 
01774     LOG_FUNCTION_END(0);
01775 
01776 }
01777 
01778 
01779 VL53L1_Error  VL53L1_hist_phase_consistency_check(
01780     VL53L1_DEV                   Dev,
01781     VL53L1_zone_hist_info_t     *phist_prev,
01782     VL53L1_zone_objects_t       *prange_prev,
01783     VL53L1_range_results_t      *prange_curr)
01784 {
01785 
01786 
01787 
01788     VL53L1_Error  status = VL53L1_ERROR_NONE;
01789     VL53L1_LLDriverData_t *pdev =
01790         VL53L1DevStructGetLLDriverHandle(Dev);
01791 
01792     uint8_t   lc = 0;
01793     uint8_t   p = 0;
01794 
01795     uint16_t  phase_delta      = 0;
01796     uint16_t  phase_tolerance  = 0;
01797 
01798     int32_t   events_delta     = 0;
01799     int32_t   events_tolerance = 0;
01800 
01801 
01802     uint8_t event_sigma;
01803     uint16_t event_min_spad_count;
01804     uint16_t min_max_tolerance;
01805     uint8_t pht;
01806 
01807     VL53L1_DeviceError  range_status = 0;
01808 
01809     LOG_FUNCTION_START("");
01810 
01811     event_sigma =
01812         pdev->histpostprocess.algo__consistency_check__event_sigma;
01813     event_min_spad_count =
01814     pdev->histpostprocess.algo__consistency_check__event_min_spad_count;
01815     min_max_tolerance =
01816     pdev->histpostprocess.algo__consistency_check__min_max_tolerance;
01817 
01818 
01819     pht = pdev->histpostprocess.algo__consistency_check__phase_tolerance;
01820     phase_tolerance = (uint16_t)pht;
01821     phase_tolerance = phase_tolerance << 8;
01822 
01823 
01824 
01825     if (prange_prev->rd_device_state !=
01826             VL53L1_DEVICESTATE_RANGING_GATHER_DATA &&
01827         prange_prev->rd_device_state !=
01828                 VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA)
01829         return status;
01830 
01831 
01832 
01833     if (phase_tolerance == 0)
01834         return status;
01835 
01836     for (lc = 0; lc < prange_curr->active_results; lc++) {
01837 
01838         if (!((prange_curr->VL53L1_p_002[lc].range_status ==
01839             VL53L1_DEVICEERROR_RANGECOMPLETE) ||
01840             (prange_curr->VL53L1_p_002[lc].range_status ==
01841             VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK)))
01842             continue;
01843 
01844 
01845 
01846 
01847 
01848 
01849         if (prange_prev->active_objects == 0)
01850             prange_curr->VL53L1_p_002[lc].range_status =
01851             VL53L1_DEVICEERROR_PREV_RANGE_NO_TARGETS;
01852         else
01853             prange_curr->VL53L1_p_002[lc].range_status =
01854                 VL53L1_DEVICEERROR_PHASECONSISTENCY;
01855 
01856 
01857 
01858 
01859 
01860         for (p = 0; p < prange_prev->active_objects; p++) {
01861 
01862             if (prange_curr->VL53L1_p_002[lc].VL53L1_p_014 >
01863                 prange_prev->VL53L1_p_002[p].VL53L1_p_014) {
01864                 phase_delta =
01865                 prange_curr->VL53L1_p_002[lc].VL53L1_p_014 -
01866                 prange_prev->VL53L1_p_002[p].VL53L1_p_014;
01867             } else {
01868                 phase_delta =
01869                 prange_prev->VL53L1_p_002[p].VL53L1_p_014 -
01870                 prange_curr->VL53L1_p_002[lc].VL53L1_p_014;
01871             }
01872 
01873             if (phase_delta < phase_tolerance) {
01874 
01875 
01876 
01877 
01878 
01879                 if (status == VL53L1_ERROR_NONE)
01880                     status =
01881                     VL53L1_hist_events_consistency_check(
01882                     event_sigma,
01883                     event_min_spad_count,
01884                     phist_prev,
01885                     &(prange_prev->VL53L1_p_002[p]),
01886                     &(prange_curr->VL53L1_p_002[lc]),
01887                     &events_tolerance,
01888                     &events_delta,
01889                     &range_status);
01890 
01891 
01892 
01893 
01894                 if (status == VL53L1_ERROR_NONE &&
01895                     range_status ==
01896                     VL53L1_DEVICEERROR_RANGECOMPLETE)
01897                     status =
01898                     VL53L1_hist_merged_pulse_check(
01899                     min_max_tolerance,
01900                     &(prange_curr->VL53L1_p_002[lc]),
01901                     &range_status);
01902 
01903                 prange_curr->VL53L1_p_002[lc].range_status =
01904                         range_status;
01905             }
01906         }
01907 
01908     }
01909 
01910     LOG_FUNCTION_END(status);
01911 
01912     return status;
01913 }
01914 
01915 
01916 
01917 VL53L1_Error  VL53L1_hist_events_consistency_check(
01918     uint8_t                      event_sigma,
01919     uint16_t                     min_effective_spad_count,
01920     VL53L1_zone_hist_info_t     *phist_prev,
01921     VL53L1_object_data_t        *prange_prev,
01922     VL53L1_range_data_t         *prange_curr,
01923     int32_t                     *pevents_tolerance,
01924     int32_t                     *pevents_delta,
01925     VL53L1_DeviceError          *prange_status)
01926 {
01927 
01928 
01929 
01930     VL53L1_Error  status = VL53L1_ERROR_NONE;
01931 
01932     int64_t   tmpp                   = 0;
01933     int64_t   tmpc                   = 0;
01934     int64_t   events_scaler          = 0;
01935     int64_t   events_scaler_sq       = 0;
01936     int64_t   c_signal_events        = 0;
01937     int64_t   c_sig_noise_sq         = 0;
01938     int64_t   c_amb_noise_sq         = 0;
01939     int64_t   p_amb_noise_sq         = 0;
01940 
01941     int32_t   p_signal_events        = 0;
01942     uint32_t  noise_sq_sum           = 0;
01943 
01944 
01945 
01946     if (event_sigma == 0) {
01947         *prange_status = VL53L1_DEVICEERROR_RANGECOMPLETE;
01948         return status;
01949     }
01950 
01951 
01952 
01953     tmpp  = 1 + (int64_t)phist_prev->total_periods_elapsed;
01954     tmpp *= (int64_t)phist_prev->result__dss_actual_effective_spads;
01955 
01956 
01957 
01958     tmpc  = 1 + (int64_t)prange_curr->total_periods_elapsed;
01959     tmpc *= (int64_t)prange_curr->VL53L1_p_006;
01960 
01961 
01962 
01963     events_scaler  = tmpp * 4096;
01964     events_scaler += (tmpc/2);
01965     if (tmpc != 0)
01966         events_scaler = do_division_s(events_scaler, tmpc);
01967 
01968     events_scaler_sq  = events_scaler * events_scaler;
01969     events_scaler_sq += 2048;
01970     events_scaler_sq /= 4096;
01971 
01972 
01973 
01974     c_signal_events  = (int64_t)prange_curr->VL53L1_p_021;
01975     c_signal_events -= (int64_t)prange_curr->VL53L1_p_020;
01976     c_signal_events *= (int64_t)events_scaler;
01977     c_signal_events += 2048;
01978     c_signal_events /= 4096;
01979 
01980     c_sig_noise_sq  = (int64_t)events_scaler_sq;
01981     c_sig_noise_sq *= (int64_t)prange_curr->VL53L1_p_021;
01982     c_sig_noise_sq += 2048;
01983     c_sig_noise_sq /= 4096;
01984 
01985     c_amb_noise_sq  = (int64_t)events_scaler_sq;
01986     c_amb_noise_sq *= (int64_t)prange_curr->VL53L1_p_020;
01987     c_amb_noise_sq += 2048;
01988     c_amb_noise_sq /= 4096;
01989 
01990 
01991     c_amb_noise_sq += 2;
01992     c_amb_noise_sq /= 4;
01993 
01994 
01995 
01996     p_amb_noise_sq  =
01997         (int64_t)prange_prev->VL53L1_p_020;
01998 
01999 
02000     p_amb_noise_sq += 2;
02001     p_amb_noise_sq /= 4;
02002 
02003     noise_sq_sum =
02004         (uint32_t)prange_prev->VL53L1_p_021 +
02005         (uint32_t)c_sig_noise_sq +
02006         (uint32_t)p_amb_noise_sq +
02007         (uint32_t)c_amb_noise_sq;
02008 
02009     *pevents_tolerance =
02010         (int32_t)VL53L1_isqrt(noise_sq_sum * 16);
02011 
02012     *pevents_tolerance *= (int32_t)event_sigma;
02013     *pevents_tolerance += 32;
02014     *pevents_tolerance /= 64;
02015 
02016     p_signal_events  = (int32_t)prange_prev->VL53L1_p_021;
02017     p_signal_events -= (int32_t)prange_prev->VL53L1_p_020;
02018 
02019     if ((int32_t)c_signal_events > p_signal_events)
02020         *pevents_delta =
02021             (int32_t)c_signal_events - p_signal_events;
02022     else
02023         *pevents_delta =
02024             p_signal_events - (int32_t)c_signal_events;
02025 
02026     if (*pevents_delta > *pevents_tolerance &&
02027         prange_curr->VL53L1_p_006 > min_effective_spad_count)
02028         *prange_status = VL53L1_DEVICEERROR_EVENTCONSISTENCY;
02029     else
02030         *prange_status = VL53L1_DEVICEERROR_RANGECOMPLETE;
02031 
02032 
02033 
02034 
02035 
02036     return status;
02037 }
02038 
02039 
02040 
02041 
02042 VL53L1_Error  VL53L1_hist_merged_pulse_check(
02043     int16_t                      min_max_tolerance_mm,
02044     VL53L1_range_data_t         *pdata,
02045     VL53L1_DeviceError          *prange_status)
02046 {
02047 
02048 
02049     VL53L1_Error  status   = VL53L1_ERROR_NONE;
02050     int16_t       delta_mm = 0;
02051 
02052     if (pdata->max_range_mm > pdata->min_range_mm)
02053         delta_mm =
02054             pdata->max_range_mm - pdata->min_range_mm;
02055     else
02056         delta_mm =
02057             pdata->min_range_mm - pdata->max_range_mm;
02058 
02059     if (min_max_tolerance_mm > 0 &&
02060         delta_mm > min_max_tolerance_mm)
02061         *prange_status = VL53L1_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE;
02062     else
02063         *prange_status = VL53L1_DEVICEERROR_RANGECOMPLETE;
02064 
02065     return status;
02066 }
02067 
02068 
02069 
02070 
02071 VL53L1_Error  VL53L1_hist_xmonitor_consistency_check(
02072     VL53L1_DEV                   Dev,
02073     VL53L1_zone_hist_info_t     *phist_prev,
02074     VL53L1_zone_objects_t       *prange_prev,
02075     VL53L1_range_data_t         *prange_curr)
02076 {
02077 
02078 
02079     VL53L1_Error  status = VL53L1_ERROR_NONE;
02080     VL53L1_LLDriverData_t *pdev =
02081         VL53L1DevStructGetLLDriverHandle(Dev);
02082 
02083     int32_t   events_delta     = 0;
02084     int32_t   events_tolerance = 0;
02085     uint8_t event_sigma;
02086     uint16_t min_spad_count;
02087 
02088     event_sigma = pdev->histpostprocess.algo__crosstalk_detect_event_sigma;
02089     min_spad_count =
02090     pdev->histpostprocess.algo__consistency_check__event_min_spad_count;
02091 
02092     if (prange_curr->range_status == VL53L1_DEVICEERROR_RANGECOMPLETE ||
02093         prange_curr->range_status ==
02094             VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK ||
02095         prange_curr->range_status ==
02096                 VL53L1_DEVICEERROR_EVENTCONSISTENCY) {
02097 
02098         if (prange_prev->xmonitor.range_status ==
02099                 VL53L1_DEVICEERROR_RANGECOMPLETE ||
02100             prange_prev->xmonitor.range_status ==
02101             VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK ||
02102             prange_prev->xmonitor.range_status ==
02103                 VL53L1_DEVICEERROR_EVENTCONSISTENCY) {
02104 
02105             prange_curr->range_status =
02106                     VL53L1_DEVICEERROR_RANGECOMPLETE;
02107 
02108             status =
02109                 VL53L1_hist_events_consistency_check(
02110                     event_sigma,
02111                     min_spad_count,
02112                     phist_prev,
02113                     &(prange_prev->xmonitor),
02114                     prange_curr,
02115                     &events_tolerance,
02116                     &events_delta,
02117                     &(prange_curr->range_status));
02118 
02119         }
02120     }
02121 
02122     return status;
02123 }
02124 
02125 
02126 
02127 
02128 VL53L1_Error  VL53L1_hist_wrap_dmax(
02129     VL53L1_hist_post_process_config_t  *phistpostprocess,
02130     VL53L1_histogram_bin_data_t        *pcurrent,
02131     int16_t                            *pwrap_dmax_mm)
02132 {
02133 
02134 
02135 
02136     VL53L1_Error  status = VL53L1_ERROR_NONE;
02137 
02138     uint32_t  pll_period_mm        = 0;
02139     uint32_t  wrap_dmax_phase      = 0;
02140     uint32_t  range_mm             = 0;
02141 
02142     LOG_FUNCTION_START("");
02143 
02144     *pwrap_dmax_mm = 0;
02145 
02146 
02147     if (pcurrent->VL53L1_p_019 != 0) {
02148 
02149 
02150 
02151         pll_period_mm =
02152             VL53L1_calc_pll_period_mm(
02153                 pcurrent->VL53L1_p_019);
02154 
02155 
02156 
02157         wrap_dmax_phase =
02158             (uint32_t)phistpostprocess->valid_phase_high << 8;
02159 
02160 
02161 
02162         range_mm = wrap_dmax_phase * pll_period_mm;
02163         range_mm = (range_mm + (1<<14)) >> 15;
02164 
02165         *pwrap_dmax_mm = (int16_t)range_mm;
02166     }
02167 
02168     LOG_FUNCTION_END(status);
02169 
02170     return status;
02171 }
02172 
02173 
02174 void VL53L1_hist_combine_mm1_mm2_offsets(
02175     int16_t                               mm1_offset_mm,
02176     int16_t                               mm2_offset_mm,
02177     uint8_t                               encoded_mm_roi_centre,
02178     uint8_t                               encoded_mm_roi_size,
02179     uint8_t                               encoded_zone_centre,
02180     uint8_t                               encoded_zone_size,
02181     VL53L1_additional_offset_cal_data_t  *pcal_data,
02182     uint8_t                              *pgood_spads,
02183     uint16_t                              aperture_attenuation,
02184     int16_t                               *prange_offset_mm)
02185 {
02186 
02187 
02188 
02189     uint16_t max_mm_inner_effective_spads = 0;
02190     uint16_t max_mm_outer_effective_spads = 0;
02191     uint16_t mm_inner_effective_spads     = 0;
02192     uint16_t mm_outer_effective_spads     = 0;
02193 
02194     uint32_t scaled_mm1_peak_rate_mcps    = 0;
02195     uint32_t scaled_mm2_peak_rate_mcps    = 0;
02196 
02197     int32_t tmp0 = 0;
02198     int32_t tmp1 = 0;
02199 
02200 
02201 
02202     VL53L1_calc_mm_effective_spads(
02203         encoded_mm_roi_centre,
02204         encoded_mm_roi_size,
02205         0xC7,
02206         0xFF,
02207         pgood_spads,
02208         aperture_attenuation,
02209         &max_mm_inner_effective_spads,
02210         &max_mm_outer_effective_spads);
02211 
02212     if ((max_mm_inner_effective_spads == 0) ||
02213         (max_mm_outer_effective_spads == 0))
02214         goto FAIL;
02215 
02216 
02217 
02218     VL53L1_calc_mm_effective_spads(
02219         encoded_mm_roi_centre,
02220         encoded_mm_roi_size,
02221         encoded_zone_centre,
02222         encoded_zone_size,
02223         pgood_spads,
02224         aperture_attenuation,
02225         &mm_inner_effective_spads,
02226         &mm_outer_effective_spads);
02227 
02228 
02229 
02230     scaled_mm1_peak_rate_mcps  =
02231     (uint32_t)pcal_data->result__mm_inner_peak_signal_count_rtn_mcps;
02232     scaled_mm1_peak_rate_mcps *= (uint32_t)mm_inner_effective_spads;
02233     scaled_mm1_peak_rate_mcps /= (uint32_t)max_mm_inner_effective_spads;
02234 
02235     scaled_mm2_peak_rate_mcps  =
02236     (uint32_t)pcal_data->result__mm_outer_peak_signal_count_rtn_mcps;
02237     scaled_mm2_peak_rate_mcps *= (uint32_t)mm_outer_effective_spads;
02238     scaled_mm2_peak_rate_mcps /= (uint32_t)max_mm_outer_effective_spads;
02239 
02240 
02241 
02242     tmp0  = ((int32_t)mm1_offset_mm * (int32_t)scaled_mm1_peak_rate_mcps);
02243     tmp0 += ((int32_t)mm2_offset_mm * (int32_t)scaled_mm2_peak_rate_mcps);
02244 
02245     tmp1 =  (int32_t)scaled_mm1_peak_rate_mcps +
02246             (int32_t)scaled_mm2_peak_rate_mcps;
02247 
02248 
02249 
02250     if (tmp1 != 0)
02251         tmp0 = (tmp0 * 4) / tmp1;
02252 FAIL:
02253     *prange_offset_mm = (int16_t)tmp0;
02254 
02255 }
02256 
02257 
02258 VL53L1_Error VL53L1_hist_xtalk_extract_calc_window(
02259     int16_t                             target_distance_mm,
02260     uint16_t                            target_width_oversize,
02261     VL53L1_histogram_bin_data_t        *phist_bins,
02262     VL53L1_hist_xtalk_extract_data_t   *pxtalk_data)
02263 {
02264 
02265 
02266     VL53L1_Error  status = VL53L1_ERROR_NONE;
02267 
02268     LOG_FUNCTION_START("");
02269 
02270 
02271     pxtalk_data->pll_period_mm =
02272         VL53L1_calc_pll_period_mm(phist_bins->VL53L1_p_019);
02273 
02274 
02275     pxtalk_data->xtalk_width_phase =
02276         (int32_t)phist_bins->vcsel_width * 128;
02277     pxtalk_data->target_width_phase =
02278         pxtalk_data->xtalk_width_phase +
02279         (int32_t)target_width_oversize * 128;
02280 
02281 
02282 
02283     pxtalk_data->xtalk_start_phase =
02284         (int32_t)phist_bins->zero_distance_phase -
02285         (pxtalk_data->xtalk_width_phase / 2);
02286     pxtalk_data->xtalk_end_phase  =
02287         (int32_t)pxtalk_data->xtalk_start_phase +
02288         pxtalk_data->xtalk_width_phase;
02289 
02290     if (pxtalk_data->xtalk_start_phase < 0)
02291         pxtalk_data->xtalk_start_phase = 0;
02292 
02293 
02294 
02295 
02296     pxtalk_data->VL53L1_p_015 =
02297         (uint8_t)(pxtalk_data->xtalk_start_phase / 2048);
02298 
02299 
02300     pxtalk_data->VL53L1_p_016 =
02301         (uint8_t)((pxtalk_data->xtalk_end_phase + 2047) / 2048);
02302 
02303 
02304 
02305     pxtalk_data->target_start_phase  =
02306             (int32_t)target_distance_mm * 2048 * 16;
02307     pxtalk_data->target_start_phase +=
02308             ((int32_t)pxtalk_data->pll_period_mm / 2);
02309     pxtalk_data->target_start_phase /= (int32_t)pxtalk_data->pll_period_mm;
02310     pxtalk_data->target_start_phase +=
02311             (int32_t)phist_bins->zero_distance_phase;
02312 
02313 
02314 
02315     pxtalk_data->target_start_phase -=
02316             (pxtalk_data->target_width_phase / 2);
02317     pxtalk_data->target_end_phase  =
02318         (int32_t)pxtalk_data->target_start_phase +
02319         pxtalk_data->target_width_phase;
02320 
02321     if (pxtalk_data->target_start_phase < 0)
02322         pxtalk_data->target_start_phase = 0;
02323 
02324 
02325     pxtalk_data->target_start =
02326         (uint8_t)(pxtalk_data->target_start_phase / 2048);
02327 
02328 
02329     if (pxtalk_data->VL53L1_p_016 > (pxtalk_data->target_start-1))
02330         pxtalk_data->VL53L1_p_016 = pxtalk_data->target_start-1;
02331 
02332 
02333     pxtalk_data->effective_width =
02334             (2048 * ((int32_t)pxtalk_data->VL53L1_p_016+1));
02335     pxtalk_data->effective_width -= pxtalk_data->xtalk_start_phase;
02336 
02337 
02338     if (pxtalk_data->effective_width > pxtalk_data->xtalk_width_phase)
02339         pxtalk_data->effective_width = pxtalk_data->xtalk_width_phase;
02340 
02341     if (pxtalk_data->effective_width < 1)
02342         pxtalk_data->effective_width = 1;
02343 
02344 
02345     pxtalk_data->event_scaler  =  pxtalk_data->xtalk_width_phase * 1000;
02346     pxtalk_data->event_scaler +=  (pxtalk_data->effective_width / 2);
02347     pxtalk_data->event_scaler /=  pxtalk_data->effective_width;
02348 
02349 
02350     if (pxtalk_data->event_scaler < 1000)
02351         pxtalk_data->event_scaler = 1000;
02352 
02353     if (pxtalk_data->event_scaler > 4000)
02354         pxtalk_data->event_scaler = 4000;
02355 
02356 
02357     pxtalk_data->event_scaler_sum += pxtalk_data->event_scaler;
02358 
02359 
02360     pxtalk_data->peak_duration_us_sum +=
02361         (uint32_t)phist_bins->peak_duration_us;
02362 
02363 
02364     pxtalk_data->effective_spad_count_sum +=
02365         (uint32_t)phist_bins->result__dss_actual_effective_spads;
02366 
02367 
02368     pxtalk_data->zero_distance_phase_sum +=
02369         (uint32_t)phist_bins->zero_distance_phase;
02370 
02371     LOG_FUNCTION_END(status);
02372 
02373     return status;
02374 }
02375 
02376 
02377 VL53L1_Error VL53L1_hist_xtalk_extract_calc_event_sums(
02378     VL53L1_histogram_bin_data_t        *phist_bins,
02379     VL53L1_hist_xtalk_extract_data_t   *pxtalk_data)
02380 {
02381 
02382 
02383 
02384     VL53L1_Error  status = VL53L1_ERROR_NONE;
02385 
02386     uint8_t   lb = 0;
02387     uint8_t   i = 0;
02388 
02389     LOG_FUNCTION_START("");
02390 
02391 
02392 
02393     for (lb  = pxtalk_data->VL53L1_p_015;
02394          lb <= pxtalk_data->VL53L1_p_016;
02395          lb++) {
02396 
02397 
02398         i = (lb + phist_bins->number_of_ambient_bins +
02399             phist_bins->VL53L1_p_024) %
02400                     phist_bins->VL53L1_p_024;
02401 
02402 
02403         pxtalk_data->signal_events_sum += phist_bins->bin_data[i];
02404         pxtalk_data->signal_events_sum -=
02405                 phist_bins->VL53L1_p_004;
02406     }
02407 
02408 
02409 
02410     for (lb  = 0; lb < VL53L1_XTALK_HISTO_BINS  &&
02411             lb < phist_bins->VL53L1_p_024; lb++) {
02412 
02413 
02414         i = (lb + phist_bins->number_of_ambient_bins +
02415             phist_bins->VL53L1_p_024) %
02416                     phist_bins->VL53L1_p_024;
02417 
02418 
02419         pxtalk_data->bin_data_sums[lb] += phist_bins->bin_data[i];
02420         pxtalk_data->bin_data_sums[lb] -=
02421                 phist_bins->VL53L1_p_004;
02422     }
02423 
02424     pxtalk_data->sample_count += 1;
02425 
02426     LOG_FUNCTION_END(status);
02427 
02428     return status;
02429 }
02430 
02431 
02432 VL53L1_Error VL53L1_hist_xtalk_extract_calc_rate_per_spad(
02433     VL53L1_hist_xtalk_extract_data_t   *pxtalk_data)
02434 {
02435 
02436 
02437 
02438     VL53L1_Error  status = VL53L1_ERROR_NONE;
02439 
02440     uint64_t tmp64_0        = 0;
02441     uint64_t tmp64_1        = 0;
02442     uint64_t xtalk_per_spad = 0;
02443 
02444     LOG_FUNCTION_START("");
02445 
02446 
02447 
02448 
02449 
02450 
02451     if (pxtalk_data->signal_events_sum > 0) {
02452         tmp64_0 =
02453             ((uint64_t)pxtalk_data->signal_events_sum *
02454              (uint64_t)pxtalk_data->sample_count *
02455              (uint64_t)pxtalk_data->event_scaler_avg * 256U) << 9U;
02456         tmp64_1 =
02457             (uint64_t)pxtalk_data->effective_spad_count_sum *
02458             (uint64_t)pxtalk_data->peak_duration_us_sum;
02459 
02460 
02461 
02462         if (tmp64_1 > 0U) {
02463 
02464             tmp64_0 = tmp64_0 + (tmp64_1 >> 1U);
02465             xtalk_per_spad = do_division_u(tmp64_0, tmp64_1);
02466         } else {
02467             xtalk_per_spad = (uint64_t)tmp64_0;
02468         }
02469 
02470     } else {
02471         status = VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
02472     }
02473 
02474     pxtalk_data->xtalk_rate_kcps_per_spad = (uint32_t)xtalk_per_spad;
02475 
02476     LOG_FUNCTION_END(status);
02477 
02478     return status;
02479 }
02480 
02481 
02482 VL53L1_Error VL53L1_hist_xtalk_extract_calc_shape(
02483     VL53L1_hist_xtalk_extract_data_t  *pxtalk_data,
02484     VL53L1_xtalk_histogram_shape_t    *pxtalk_shape)
02485 {
02486 
02487 
02488     VL53L1_Error  status = VL53L1_ERROR_NONE;
02489 
02490     int32_t  lb = 0;
02491     uint64_t total_events    = 0U;
02492     uint64_t tmp64_0         = 0U;
02493     int32_t  remaining_area  = 1024;
02494 
02495     LOG_FUNCTION_START("");
02496 
02497 
02498 
02499     pxtalk_shape->VL53L1_p_022      = 0;
02500     pxtalk_shape->VL53L1_p_023    = VL53L1_XTALK_HISTO_BINS;
02501     pxtalk_shape->VL53L1_p_024 = VL53L1_XTALK_HISTO_BINS;
02502 
02503     pxtalk_shape->zero_distance_phase =
02504         (uint16_t)pxtalk_data->zero_distance_phase_avg;
02505     pxtalk_shape->phasecal_result__reference_phase =
02506         (uint16_t)pxtalk_data->zero_distance_phase_avg + (3*2048);
02507 
02508 
02509 
02510     if (pxtalk_data->signal_events_sum > 0)
02511         total_events =
02512             (uint64_t)pxtalk_data->signal_events_sum *
02513             (uint64_t)pxtalk_data->event_scaler_avg;
02514     else
02515         total_events = 1;
02516     if (total_events == 0)
02517         total_events = 1;
02518 
02519 
02520     remaining_area  = 1024;
02521     pxtalk_data->max_shape_value = 0;
02522 
02523     for (lb = 0; lb < VL53L1_XTALK_HISTO_BINS; lb++) {
02524 
02525         if ((lb < (int32_t)pxtalk_data->VL53L1_p_015 ||
02526              lb > (int32_t)pxtalk_data->VL53L1_p_016)  ||
02527                 pxtalk_data->bin_data_sums[lb] < 0) {
02528 
02529 
02530             if (remaining_area > 0 && remaining_area < 1024) {
02531                 if (remaining_area >
02532                     pxtalk_data->max_shape_value) {
02533                     pxtalk_shape->bin_data[lb] =
02534                     (uint32_t)pxtalk_data->max_shape_value;
02535                     remaining_area -=
02536                         pxtalk_data->max_shape_value;
02537                 } else {
02538                     pxtalk_shape->bin_data[lb] =
02539                         (uint32_t)remaining_area;
02540                     remaining_area = 0;
02541                 }
02542             } else {
02543                 pxtalk_shape->bin_data[lb] = 0;
02544             }
02545 
02546         } else {
02547 
02548             tmp64_0 =
02549                 (uint64_t)pxtalk_data->bin_data_sums[lb]
02550                             * 1024U * 1000U;
02551             tmp64_0 += (total_events >> 1);
02552             tmp64_0 = do_division_u(tmp64_0, total_events);
02553             if (tmp64_0 > 0xFFFFU)
02554                 tmp64_0 = 0xFFFFU;
02555 
02556             pxtalk_shape->bin_data[lb] = (uint32_t)tmp64_0;
02557 
02558 
02559             if ((int32_t)pxtalk_shape->bin_data[lb] >
02560                 pxtalk_data->max_shape_value)
02561                 pxtalk_data->max_shape_value =
02562                     (int32_t)pxtalk_shape->bin_data[lb];
02563 
02564             remaining_area -= (int32_t)pxtalk_shape->bin_data[lb];
02565         }
02566     }
02567 
02568     LOG_FUNCTION_END(status);
02569 
02570     return status;
02571 }
02572 
02573 
02574 VL53L1_Error VL53L1_hist_xtalk_shape_model(
02575     uint16_t                         events_per_bin,
02576     uint16_t                         pulse_centre,
02577     uint16_t                         pulse_width,
02578     VL53L1_xtalk_histogram_shape_t  *pxtalk_shape)
02579 {
02580 
02581 
02582     VL53L1_Error  status = VL53L1_ERROR_NONE;
02583 
02584     uint32_t phase_start  = 0;
02585     uint32_t phase_stop   = 0;
02586     uint32_t phase_bin    = 0;
02587 
02588     uint32_t bin_start    = 0;
02589     uint32_t bin_stop     = 0;
02590 
02591     uint32_t  lb           = 0;
02592     uint16_t  VL53L1_p_008      = 0;
02593 
02594     LOG_FUNCTION_START("");
02595 
02596 
02597 
02598     pxtalk_shape->VL53L1_p_022      = 0;
02599     pxtalk_shape->VL53L1_p_023    = VL53L1_XTALK_HISTO_BINS;
02600     pxtalk_shape->VL53L1_p_024 = VL53L1_XTALK_HISTO_BINS;
02601 
02602     pxtalk_shape->zero_distance_phase              = pulse_centre;
02603     pxtalk_shape->phasecal_result__reference_phase =
02604             pulse_centre + (3*2048);
02605 
02606 
02607     if (pulse_centre > (pulse_width >> 1))
02608         phase_start = (uint32_t)pulse_centre -
02609             ((uint32_t)pulse_width >> 1);
02610     else
02611         phase_start = 0;
02612 
02613     phase_stop = (uint32_t)pulse_centre  +
02614             ((uint32_t)pulse_width >> 1);
02615 
02616 
02617     bin_start = (phase_start / 2048);
02618     bin_stop  = (phase_stop  / 2048);
02619 
02620     for (lb = 0; lb < VL53L1_XTALK_HISTO_BINS; lb++) {
02621         VL53L1_p_008 = 0;
02622 
02623 
02624         if (lb == bin_start && lb == bin_stop) {
02625             VL53L1_p_008 =
02626             VL53L1_hist_xtalk_shape_model_interp(
02627                 events_per_bin,
02628                 phase_stop - phase_start);
02629 
02630         } else if (lb > bin_start && lb < bin_stop) {
02631 
02632 
02633             VL53L1_p_008 = events_per_bin;
02634 
02635         } else if (lb == bin_start) {
02636 
02637 
02638             phase_bin = (lb + 1) * 2048;
02639             VL53L1_p_008 =
02640             VL53L1_hist_xtalk_shape_model_interp(
02641                 events_per_bin,
02642                 (phase_bin - phase_start));
02643 
02644         } else if (lb == bin_stop) {
02645 
02646 
02647             phase_bin = lb * 2048;
02648             VL53L1_p_008 =
02649             VL53L1_hist_xtalk_shape_model_interp(
02650                 events_per_bin,
02651                 (phase_stop - phase_bin));
02652         }
02653 
02654         pxtalk_shape->bin_data[lb] = VL53L1_p_008;
02655     }
02656 
02657     LOG_FUNCTION_END(status);
02658 
02659     return status;
02660 }
02661 
02662 
02663 uint16_t VL53L1_hist_xtalk_shape_model_interp(
02664     uint16_t      events_per_bin,
02665     uint32_t      phase_delta)
02666 {
02667 
02668 
02669     uint32_t  VL53L1_p_008  = 0;
02670 
02671     LOG_FUNCTION_START("");
02672 
02673 
02674     VL53L1_p_008  = (uint32_t)events_per_bin * phase_delta;
02675     VL53L1_p_008 +=  1024;
02676     VL53L1_p_008 /=  2048;
02677 
02678 
02679     if (VL53L1_p_008 > 0xFFFFU)
02680         VL53L1_p_008 = 0xFFFFU;
02681 
02682     LOG_FUNCTION_END(0);
02683 
02684     return (uint16_t)VL53L1_p_008;
02685 }
02686 
02687 
02688 void VL53L1_spad_number_to_byte_bit_index(
02689     uint8_t  spad_number,
02690     uint8_t *pbyte_index,
02691     uint8_t *pbit_index,
02692     uint8_t *pbit_mask)
02693 {
02694 
02695 
02696 
02697     *pbyte_index  = spad_number >> 3;
02698     *pbit_index   = spad_number & 0x07;
02699     *pbit_mask    = 0x01 << *pbit_index;
02700 
02701 }
02702 
02703 
02704 void VL53L1_encode_row_col(
02705     uint8_t  row,
02706     uint8_t  col,
02707     uint8_t *pspad_number)
02708 {
02709 
02710 
02711     if (row > 7)
02712         *pspad_number = 128 + (col << 3) + (15-row);
02713     else
02714         *pspad_number = ((15-col) << 3) + row;
02715 
02716 }
02717 
02718 
02719 void VL53L1_decode_zone_size(
02720     uint8_t  encoded_xy_size,
02721     uint8_t  *pwidth,
02722     uint8_t  *pheight)
02723 {
02724 
02725 
02726 
02727     *pheight = encoded_xy_size >> 4;
02728     *pwidth  = encoded_xy_size & 0x0F;
02729 
02730 }
02731 
02732 
02733 void VL53L1_encode_zone_size(
02734     uint8_t  width,
02735     uint8_t  height,
02736     uint8_t *pencoded_xy_size)
02737 {
02738 
02739 
02740     *pencoded_xy_size = (height << 4) + width;
02741 
02742 }
02743 
02744 
02745 void VL53L1_decode_zone_limits(
02746     uint8_t   encoded_xy_centre,
02747     uint8_t   encoded_xy_size,
02748     int16_t  *px_ll,
02749     int16_t  *py_ll,
02750     int16_t  *px_ur,
02751     int16_t  *py_ur)
02752 {
02753 
02754 
02755 
02756     uint8_t x_centre = 0;
02757     uint8_t y_centre = 0;
02758     uint8_t width    = 0;
02759     uint8_t height   = 0;
02760 
02761 
02762 
02763     VL53L1_decode_row_col(
02764         encoded_xy_centre,
02765         &y_centre,
02766         &x_centre);
02767 
02768     VL53L1_decode_zone_size(
02769         encoded_xy_size,
02770         &width,
02771         &height);
02772 
02773 
02774 
02775     *px_ll = (int16_t)x_centre - ((int16_t)width + 1) / 2;
02776     if (*px_ll < 0)
02777         *px_ll = 0;
02778 
02779     *px_ur = *px_ll + (int16_t)width;
02780     if (*px_ur > (VL53L1_SPAD_ARRAY_WIDTH-1))
02781         *px_ur = VL53L1_SPAD_ARRAY_WIDTH-1;
02782 
02783     *py_ll = (int16_t)y_centre - ((int16_t)height + 1) / 2;
02784     if (*py_ll < 0)
02785         *py_ll = 0;
02786 
02787     *py_ur = *py_ll + (int16_t)height;
02788     if (*py_ur > (VL53L1_SPAD_ARRAY_HEIGHT-1))
02789         *py_ur = VL53L1_SPAD_ARRAY_HEIGHT-1;
02790 }
02791 
02792 
02793 uint8_t VL53L1_is_aperture_location(
02794     uint8_t row,
02795     uint8_t col)
02796 {
02797 
02798 
02799     uint8_t is_aperture = 0;
02800     uint8_t mod_row     = row % 4;
02801     uint8_t mod_col     = col % 4;
02802 
02803     if (mod_row == 0 && mod_col == 2)
02804         is_aperture = 1;
02805 
02806     if (mod_row == 2 && mod_col == 0)
02807         is_aperture = 1;
02808 
02809     return is_aperture;
02810 }
02811 
02812 
02813 void VL53L1_calc_max_effective_spads(
02814     uint8_t     encoded_zone_centre,
02815     uint8_t     encoded_zone_size,
02816     uint8_t    *pgood_spads,
02817     uint16_t    aperture_attenuation,
02818     uint16_t   *pmax_effective_spads)
02819 {
02820 
02821 
02822 
02823     int16_t   x         = 0;
02824     int16_t   y         = 0;
02825 
02826     int16_t   zone_x_ll = 0;
02827     int16_t   zone_y_ll = 0;
02828     int16_t   zone_x_ur = 0;
02829     int16_t   zone_y_ur = 0;
02830 
02831     uint8_t   spad_number = 0;
02832     uint8_t   byte_index  = 0;
02833     uint8_t   bit_index   = 0;
02834     uint8_t   bit_mask    = 0;
02835 
02836     uint8_t   is_aperture = 0;
02837 
02838 
02839 
02840     VL53L1_decode_zone_limits(
02841         encoded_zone_centre,
02842         encoded_zone_size,
02843         &zone_x_ll,
02844         &zone_y_ll,
02845         &zone_x_ur,
02846         &zone_y_ur);
02847 
02848 
02849 
02850     *pmax_effective_spads = 0;
02851 
02852     for (y = zone_y_ll; y <= zone_y_ur; y++) {
02853         for (x = zone_x_ll; x <= zone_x_ur; x++) {
02854 
02855 
02856 
02857             VL53L1_encode_row_col(
02858                 (uint8_t)y,
02859                 (uint8_t)x,
02860                 &spad_number);
02861 
02862 
02863 
02864             VL53L1_spad_number_to_byte_bit_index(
02865                 spad_number,
02866                 &byte_index,
02867                 &bit_index,
02868                 &bit_mask);
02869 
02870 
02871 
02872             if ((pgood_spads[byte_index] & bit_mask) > 0) {
02873 
02874 
02875                 is_aperture = VL53L1_is_aperture_location(
02876                     (uint8_t)y,
02877                     (uint8_t)x);
02878 
02879                 if (is_aperture > 0)
02880                     *pmax_effective_spads +=
02881                             aperture_attenuation;
02882                 else
02883                     *pmax_effective_spads += 0x0100;
02884 
02885             }
02886         }
02887     }
02888 }
02889 
02890 
02891 void VL53L1_calc_mm_effective_spads(
02892     uint8_t     encoded_mm_roi_centre,
02893     uint8_t     encoded_mm_roi_size,
02894     uint8_t     encoded_zone_centre,
02895     uint8_t     encoded_zone_size,
02896     uint8_t    *pgood_spads,
02897     uint16_t    aperture_attenuation,
02898     uint16_t   *pmm_inner_effective_spads,
02899     uint16_t   *pmm_outer_effective_spads)
02900 {
02901 
02902 
02903 
02904     int16_t   x         = 0;
02905     int16_t   y         = 0;
02906 
02907     int16_t   mm_x_ll   = 0;
02908     int16_t   mm_y_ll   = 0;
02909     int16_t   mm_x_ur   = 0;
02910     int16_t   mm_y_ur   = 0;
02911 
02912     int16_t   zone_x_ll = 0;
02913     int16_t   zone_y_ll = 0;
02914     int16_t   zone_x_ur = 0;
02915     int16_t   zone_y_ur = 0;
02916 
02917     uint8_t   spad_number = 0;
02918     uint8_t   byte_index  = 0;
02919     uint8_t   bit_index   = 0;
02920     uint8_t   bit_mask    = 0;
02921 
02922     uint8_t   is_aperture = 0;
02923     uint16_t  spad_attenuation = 0;
02924 
02925 
02926 
02927     VL53L1_decode_zone_limits(
02928         encoded_mm_roi_centre,
02929         encoded_mm_roi_size,
02930         &mm_x_ll,
02931         &mm_y_ll,
02932         &mm_x_ur,
02933         &mm_y_ur);
02934 
02935     VL53L1_decode_zone_limits(
02936         encoded_zone_centre,
02937         encoded_zone_size,
02938         &zone_x_ll,
02939         &zone_y_ll,
02940         &zone_x_ur,
02941         &zone_y_ur);
02942 
02943 
02944 
02945     *pmm_inner_effective_spads = 0;
02946     *pmm_outer_effective_spads = 0;
02947 
02948     for (y = zone_y_ll; y <= zone_y_ur; y++) {
02949         for (x = zone_x_ll; x <= zone_x_ur; x++) {
02950 
02951 
02952 
02953             VL53L1_encode_row_col(
02954                 (uint8_t)y,
02955                 (uint8_t)x,
02956                 &spad_number);
02957 
02958 
02959 
02960             VL53L1_spad_number_to_byte_bit_index(
02961                 spad_number,
02962                 &byte_index,
02963                 &bit_index,
02964                 &bit_mask);
02965 
02966 
02967 
02968             if ((pgood_spads[byte_index] & bit_mask) > 0) {
02969 
02970 
02971                 is_aperture = VL53L1_is_aperture_location(
02972                     (uint8_t)y,
02973                     (uint8_t)x);
02974 
02975                 if (is_aperture > 0)
02976                     spad_attenuation = aperture_attenuation;
02977                 else
02978                     spad_attenuation = 0x0100;
02979 
02980 
02981 
02982                 if (x >= mm_x_ll && x <= mm_x_ur &&
02983                     y >= mm_y_ll && y <= mm_y_ur)
02984                     *pmm_inner_effective_spads +=
02985                         spad_attenuation;
02986                 else
02987                     *pmm_outer_effective_spads +=
02988                         spad_attenuation;
02989             }
02990         }
02991     }
02992 }
02993 
02994 
02995 void VL53L1_hist_copy_results_to_sys_and_core(
02996     VL53L1_histogram_bin_data_t      *pbins,
02997     VL53L1_range_results_t           *phist,
02998     VL53L1_system_results_t          *psys,
02999     VL53L1_core_results_t            *pcore)
03000 {
03001 
03002 
03003     uint8_t  i = 0;
03004 
03005     VL53L1_range_data_t  *pdata;
03006 
03007     LOG_FUNCTION_START("");
03008 
03009 
03010 
03011     VL53L1_init_system_results(psys);
03012 
03013 
03014 
03015     psys->result__interrupt_status = pbins->result__interrupt_status;
03016     psys->result__range_status     = phist->active_results;
03017     psys->result__report_status    = pbins->result__report_status;
03018     psys->result__stream_count     = pbins->result__stream_count;
03019 
03020     pdata = &(phist->VL53L1_p_002[0]);
03021 
03022     for (i = 0; i < phist->active_results; i++) {
03023 
03024         switch (i) {
03025         case 0:
03026             psys->result__dss_actual_effective_spads_sd0 =
03027                     pdata->VL53L1_p_006;
03028             psys->result__peak_signal_count_rate_mcps_sd0 =
03029                     pdata->peak_signal_count_rate_mcps;
03030             psys->result__avg_signal_count_rate_mcps_sd0 =
03031                     pdata->avg_signal_count_rate_mcps;
03032             psys->result__ambient_count_rate_mcps_sd0 =
03033                     pdata->ambient_count_rate_mcps;
03034 
03035             psys->result__sigma_sd0 = pdata->VL53L1_p_005;
03036             psys->result__phase_sd0 = pdata->VL53L1_p_014;
03037 
03038             psys->result__final_crosstalk_corrected_range_mm_sd0 =
03039                     (uint16_t)pdata->median_range_mm;
03040 
03041             psys->result__phase_sd1  = pdata->zero_distance_phase;
03042 
03043             pcore->result_core__ranging_total_events_sd0 =
03044                     pdata->VL53L1_p_021;
03045             pcore->result_core__signal_total_events_sd0 =
03046                     pdata->VL53L1_p_013;
03047             pcore->result_core__total_periods_elapsed_sd0 =
03048                     pdata->total_periods_elapsed;
03049             pcore->result_core__ambient_window_events_sd0 =
03050                     pdata->VL53L1_p_020;
03051 
03052             break;
03053         case 1:
03054             psys->result__dss_actual_effective_spads_sd1 =
03055                 pdata->VL53L1_p_006;
03056             psys->result__peak_signal_count_rate_mcps_sd1 =
03057                 pdata->peak_signal_count_rate_mcps;
03058             psys->result__ambient_count_rate_mcps_sd1 =
03059                 pdata->ambient_count_rate_mcps;
03060 
03061             psys->result__sigma_sd1 = pdata->VL53L1_p_005;
03062             psys->result__phase_sd1 = pdata->VL53L1_p_014;
03063 
03064             psys->result__final_crosstalk_corrected_range_mm_sd1 =
03065                 (uint16_t)pdata->median_range_mm;
03066 
03067             pcore->result_core__ranging_total_events_sd1 =
03068                 pdata->VL53L1_p_021;
03069             pcore->result_core__signal_total_events_sd1 =
03070                 pdata->VL53L1_p_013;
03071             pcore->result_core__total_periods_elapsed_sd1 =
03072                 pdata->total_periods_elapsed;
03073             pcore->result_core__ambient_window_events_sd1 =
03074                 pdata->VL53L1_p_020;
03075             break;
03076         }
03077 
03078         pdata++;
03079     }
03080 
03081     LOG_FUNCTION_END(0);
03082 
03083 }
03084 
03085 
03086 VL53L1_Error VL53L1_sum_histogram_data(
03087         VL53L1_histogram_bin_data_t *phist_input,
03088         VL53L1_histogram_bin_data_t *phist_output)
03089 {
03090 
03091 
03092     VL53L1_Error status = VL53L1_ERROR_NONE;
03093 
03094     uint8_t i = 0;
03095     uint8_t smallest_bin_num = 0;
03096 
03097     LOG_FUNCTION_START("");
03098 
03099 
03100 
03101     if (status == VL53L1_ERROR_NONE) {
03102         if (phist_output->VL53L1_p_024 >=
03103                 phist_input->VL53L1_p_024)
03104             smallest_bin_num = phist_input->VL53L1_p_024;
03105         else
03106             smallest_bin_num = phist_output->VL53L1_p_024;
03107     }
03108 
03109 
03110 
03111 
03112 
03113     if (status == VL53L1_ERROR_NONE)
03114         for (i = 0; i < smallest_bin_num; i++)
03115 
03116             phist_output->bin_data[i] += phist_input->bin_data[i];
03117 
03118     if (status == VL53L1_ERROR_NONE)
03119         phist_output->VL53L1_p_004 +=
03120             phist_input->VL53L1_p_004;
03121 
03122 
03123     LOG_FUNCTION_END(status);
03124 
03125     return status;
03126 }
03127 
03128 
03129 VL53L1_Error VL53L1_avg_histogram_data(
03130             uint8_t no_of_samples,
03131             VL53L1_histogram_bin_data_t *phist_sum,
03132             VL53L1_histogram_bin_data_t *phist_avg)
03133 {
03134 
03135 
03136     VL53L1_Error status = VL53L1_ERROR_NONE;
03137 
03138     uint8_t i = 0;
03139 
03140     LOG_FUNCTION_START("");
03141 
03142 
03143 
03144 
03145 
03146     if (status == VL53L1_ERROR_NONE) {
03147         for (i = 0; i < phist_sum->VL53L1_p_024; i++) {
03148 
03149 
03150 
03151             if (no_of_samples > 0)
03152                 phist_avg->bin_data[i] =
03153                     phist_sum->bin_data[i] /
03154                     (int32_t)no_of_samples;
03155             else
03156                 phist_avg->bin_data[i] = phist_sum->bin_data[i];
03157         }
03158     }
03159 
03160     if (status == VL53L1_ERROR_NONE) {
03161         if (no_of_samples > 0)
03162             phist_avg->VL53L1_p_004 =
03163                 phist_sum->VL53L1_p_004 /
03164                     (int32_t)no_of_samples;
03165         else
03166             phist_avg->VL53L1_p_004 =
03167                     phist_sum->VL53L1_p_004;
03168     }
03169 
03170     LOG_FUNCTION_END(status);
03171 
03172     return status;
03173 }
03174 
03175 
03176 VL53L1_Error VL53L1_save_cfg_data(
03177     VL53L1_DEV  Dev)
03178 {
03179 
03180 
03181     VL53L1_Error status = VL53L1_ERROR_NONE;
03182 
03183     VL53L1_LLDriverData_t  *pdev =
03184             VL53L1DevStructGetLLDriverHandle(Dev);
03185     VL53L1_LLDriverResults_t  *pres =
03186             VL53L1DevStructGetLLResultsHandle(Dev);
03187 
03188     VL53L1_zone_private_dyn_cfg_t *pzone_dyn_cfg;
03189     VL53L1_dynamic_config_t       *pdynamic = &(pdev->dyn_cfg);
03190 
03191     LOG_FUNCTION_START("");
03192 
03193     pzone_dyn_cfg =
03194         &(pres->zone_dyn_cfgs.VL53L1_p_002[pdev->ll_state.cfg_zone_id]);
03195 
03196     pzone_dyn_cfg->expected_stream_count =
03197             pdev->ll_state.cfg_stream_count;
03198 
03199     pzone_dyn_cfg->expected_gph_id =
03200             pdev->ll_state.cfg_gph_id;
03201 
03202     pzone_dyn_cfg->roi_config__user_roi_centre_spad =
03203         pdynamic->roi_config__user_roi_centre_spad;
03204 
03205     pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size =
03206         pdynamic->roi_config__user_roi_requested_global_xy_size;
03207 
03208     LOG_FUNCTION_END(status);
03209 
03210     return status;
03211 }
03212 
03213 
03214 VL53L1_Error VL53L1_dynamic_zone_update(
03215     VL53L1_DEV  Dev,
03216     VL53L1_range_results_t *presults)
03217 {
03218 
03219 
03220     VL53L1_Error status = VL53L1_ERROR_NONE;
03221 
03222     VL53L1_LLDriverData_t  *pdev =
03223             VL53L1DevStructGetLLDriverHandle(Dev);
03224     VL53L1_LLDriverResults_t  *pres =
03225             VL53L1DevStructGetLLResultsHandle(Dev);
03226     VL53L1_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
03227 
03228     uint8_t   zone_id = pdev->ll_state.rd_zone_id;
03229     uint8_t   i;
03230     uint16_t  max_total_rate_per_spads;
03231     uint16_t  target_rate =
03232         pdev->stat_cfg.dss_config__target_total_rate_mcps;
03233     uint32_t  temp = 0xFFFF;
03234 #ifdef VL53L1_LOG_ENABLE
03235     uint16_t eff_spad_cnt =
03236         pZ->VL53L1_p_002[zone_id].dss_requested_effective_spad_count;
03237 #endif
03238 
03239     LOG_FUNCTION_START("");
03240 
03241     pZ->VL53L1_p_002[zone_id].dss_requested_effective_spad_count = 0;
03242 
03243     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03244         "    DYNZONEUPDATE: peak signal count rate mcps:");
03245 
03246     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03247         "%u actual effective spads: %u\n",
03248         presults->VL53L1_p_002[0].peak_signal_count_rate_mcps,
03249         presults->VL53L1_p_002[0].VL53L1_p_006);
03250 
03251     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03252         "    DYNZONEUPDATE: active results: %u\n",
03253         presults->active_results);
03254 
03255     max_total_rate_per_spads =
03256         presults->VL53L1_p_002[0].total_rate_per_spad_mcps;
03257 
03258     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03259         "    DYNZONEUPDATE: max total rate per spad at start: %u\n",
03260         max_total_rate_per_spads);
03261 
03262     for (i = 1; i < presults->active_results; i++) {
03263         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03264         "    DYNZONEUPDATE: zone total rate per spad: zone_id: %u,",
03265         i);
03266 
03267         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03268         "total rate per spad: %u\n",
03269         presults->VL53L1_p_002[i].total_rate_per_spad_mcps);
03270 
03271         if (presults->VL53L1_p_002[i].total_rate_per_spad_mcps >
03272             max_total_rate_per_spads)
03273             max_total_rate_per_spads =
03274             presults->VL53L1_p_002[i].total_rate_per_spad_mcps;
03275 
03276     }
03277 
03278     if (max_total_rate_per_spads == 0) {
03279 
03280         temp = 0xFFFF;
03281     } else {
03282 
03283         temp = target_rate << 14;
03284         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03285             "    DYNZONEUPDATE: 1: temp: %u\n",
03286             temp);
03287 
03288 
03289         temp = temp / max_total_rate_per_spads;
03290 
03291         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03292             "    DYNZONEUPDATE: 2: temp: %u\n",
03293             temp);
03294 
03295 
03296         if (temp > 0xFFFF)
03297             temp = 0xFFFF;
03298 
03299         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03300             "    DYNZONEUPDATE: 3: temp: %u\n",
03301             temp);
03302     }
03303 
03304     pZ->VL53L1_p_002[zone_id].dss_requested_effective_spad_count =
03305             (uint16_t)temp;
03306 
03307     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03308         "    DYNZONEUPDATE: zone_id: %u, target_rate: %u,",
03309         zone_id,
03310         target_rate);
03311 
03312     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03313         "max_total_rate_per_spads: %u, requested_spads: %u\n",
03314         max_total_rate_per_spads,
03315         eff_spad_cnt);
03316 
03317     LOG_FUNCTION_END(status);
03318 
03319     return status;
03320 }
03321 
03322 VL53L1_Error VL53L1_multizone_hist_bins_update(
03323     VL53L1_DEV  Dev)
03324 {
03325 
03326 
03327     VL53L1_Error status = VL53L1_ERROR_NONE;
03328 
03329     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03330     VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
03331     VL53L1_zone_config_t *pzone_cfg = &(pdev->zone_cfg);
03332     VL53L1_histogram_config_t *phist_cfg = &(pdev->hist_cfg);
03333     VL53L1_histogram_config_t *pmulti_hist =
03334             &(pzone_cfg->multizone_hist_cfg);
03335 
03336     uint8_t   next_range_is_odd_timing = (pstate->cfg_stream_count) % 2;
03337 
03338     LOG_FUNCTION_START("");
03339 
03340 
03341     if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
03342         VL53L1_ZONECONFIG_BINCONFIG__LOWAMB) {
03343         if (!next_range_is_odd_timing) {
03344             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03345             "   HISTBINCONFIGUPDATE: Setting LOWAMB EVEN timing\n");
03346             phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03347             pmulti_hist->histogram_config__low_amb_even_bin_0_1;
03348             phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03349             pmulti_hist->histogram_config__low_amb_even_bin_2_3;
03350             phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03351             pmulti_hist->histogram_config__low_amb_even_bin_4_5;
03352         }
03353 
03354         if (next_range_is_odd_timing) {
03355             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03356             "    HISTBINCONFIGUPDATE: Setting LOWAMB ODD timing\n");
03357             phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03358             pmulti_hist->histogram_config__low_amb_even_bin_0_1;
03359             phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03360             pmulti_hist->histogram_config__low_amb_even_bin_2_3;
03361             phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03362             pmulti_hist->histogram_config__low_amb_even_bin_4_5;
03363         }
03364     } else if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
03365         VL53L1_ZONECONFIG_BINCONFIG__MIDAMB) {
03366         trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03367             "    HISTBINCONFIGUPDATE: Setting MIDAMB timing\n");
03368         if (!next_range_is_odd_timing) {
03369             trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03370             "   HISTBINCONFIGUPDATE: Setting MIDAMB EVEN timing\n");
03371             phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03372             pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
03373             phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03374             pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
03375             phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03376             pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
03377         }
03378 
03379         if (next_range_is_odd_timing) {
03380             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03381             "    HISTBINCONFIGUPDATE: Setting MIDAMB ODD timing\n");
03382             phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03383             pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
03384             phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03385             pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
03386             phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03387             pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
03388         }
03389     } else if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
03390             VL53L1_ZONECONFIG_BINCONFIG__HIGHAMB) {
03391         if (!next_range_is_odd_timing) {
03392             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03393             "    HISTBINCONFIGUPDATE: Setting HIGHAMB EVEN timing\n"
03394                     );
03395             phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03396             pmulti_hist->histogram_config__high_amb_even_bin_0_1;
03397             phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03398             pmulti_hist->histogram_config__high_amb_even_bin_2_3;
03399             phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03400             pmulti_hist->histogram_config__high_amb_even_bin_4_5;
03401         }
03402 
03403         if (next_range_is_odd_timing) {
03404             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03405             "   HISTBINCONFIGUPDATE: Setting HIGHAMB ODD timing\n");
03406             phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03407             pmulti_hist->histogram_config__high_amb_even_bin_0_1;
03408             phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03409             pmulti_hist->histogram_config__high_amb_even_bin_2_3;
03410             phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03411             pmulti_hist->histogram_config__high_amb_even_bin_4_5;
03412         }
03413     }
03414 
03415 
03416 
03417     if (status == VL53L1_ERROR_NONE) {
03418         VL53L1_copy_hist_bins_to_static_cfg(
03419             phist_cfg,
03420             &(pdev->stat_cfg),
03421             &(pdev->tim_cfg));
03422     }
03423 
03424     LOG_FUNCTION_END(status);
03425 
03426     return status;
03427 }
03428 
03429 
03430 
03431 VL53L1_Error VL53L1_update_internal_stream_counters(
03432     VL53L1_DEV  Dev,
03433     uint8_t     external_stream_count,
03434     uint8_t    *pinternal_stream_count,
03435     uint8_t    *pinternal_stream_count_val)
03436 {
03437 
03438     VL53L1_Error status = VL53L1_ERROR_NONE;
03439     uint8_t stream_divider;
03440 
03441     VL53L1_LLDriverData_t  *pdev =
03442             VL53L1DevStructGetLLDriverHandle(Dev);
03443 
03444     LOG_FUNCTION_START("");
03445 
03446     stream_divider = pdev->gen_cfg.global_config__stream_divider;
03447 
03448     if (stream_divider == 0) {
03449 
03450 
03451         *pinternal_stream_count = external_stream_count;
03452 
03453     } else if (*pinternal_stream_count_val == (stream_divider-1)) {
03454 
03455 
03456         if (*pinternal_stream_count == 0xFF)
03457             *pinternal_stream_count = 0x80;
03458         else
03459             *pinternal_stream_count = *pinternal_stream_count + 1;
03460 
03461 
03462         *pinternal_stream_count_val = 0;
03463 
03464     } else {
03465 
03466 
03467         *pinternal_stream_count_val = *pinternal_stream_count_val + 1;
03468     }
03469 
03470     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03471         "UPDINTSTREAMCOUNT   internal_steam_count:  %d,",
03472         *pinternal_stream_count);
03473 
03474     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03475         "internal_stream_count_val: %d, divider: %d\n",
03476         *pinternal_stream_count_val,
03477         stream_divider);
03478 
03479     LOG_FUNCTION_END(status);
03480 
03481     return status;
03482 }
03483 
03484 
03485 
03486 VL53L1_Error VL53L1_set_histogram_multizone_initial_bin_config(
03487     VL53L1_zone_config_t        *pzone_cfg,
03488     VL53L1_histogram_config_t   *phist_cfg,
03489     VL53L1_histogram_config_t   *pmulti_hist)
03490 {
03491     VL53L1_Error  status = VL53L1_ERROR_NONE;
03492 
03493     LOG_FUNCTION_START("");
03494 
03495 
03496     if (pzone_cfg->bin_config[0] ==
03497             VL53L1_ZONECONFIG_BINCONFIG__LOWAMB) {
03498         phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03499             pmulti_hist->histogram_config__low_amb_even_bin_0_1;
03500         phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03501             pmulti_hist->histogram_config__low_amb_even_bin_2_3;
03502         phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03503             pmulti_hist->histogram_config__low_amb_even_bin_4_5;
03504 
03505         phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03506             pmulti_hist->histogram_config__low_amb_even_bin_0_1;
03507         phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03508             pmulti_hist->histogram_config__low_amb_even_bin_2_3;
03509         phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03510             pmulti_hist->histogram_config__low_amb_even_bin_4_5;
03511     } else if (pzone_cfg->bin_config[0] ==
03512             VL53L1_ZONECONFIG_BINCONFIG__MIDAMB) {
03513         phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03514             pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
03515         phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03516             pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
03517         phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03518             pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
03519 
03520         phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03521             pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
03522         phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03523             pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
03524         phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03525             pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
03526     } else if (pzone_cfg->bin_config[0] ==
03527             VL53L1_ZONECONFIG_BINCONFIG__HIGHAMB) {
03528         phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03529             pmulti_hist->histogram_config__high_amb_even_bin_0_1;
03530         phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03531             pmulti_hist->histogram_config__high_amb_even_bin_2_3;
03532         phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03533             pmulti_hist->histogram_config__high_amb_even_bin_4_5;
03534         phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03535             pmulti_hist->histogram_config__high_amb_even_bin_0_1;
03536         phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03537             pmulti_hist->histogram_config__high_amb_even_bin_2_3;
03538         phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03539             pmulti_hist->histogram_config__high_amb_even_bin_4_5;
03540     }
03541 
03542     LOG_FUNCTION_END(status);
03543     return status;
03544 }
03545 
03546 
03547 
03548 uint8_t VL53L1_encode_GPIO_interrupt_config(
03549     VL53L1_GPIO_interrupt_config_t  *pintconf)
03550 {
03551     uint8_t system__interrupt_config;
03552 
03553     system__interrupt_config = pintconf->intr_mode_distance;
03554     system__interrupt_config |= ((pintconf->intr_mode_rate) << 2);
03555     system__interrupt_config |= ((pintconf->intr_new_measure_ready) << 5);
03556     system__interrupt_config |= ((pintconf->intr_no_target) << 6);
03557     system__interrupt_config |= ((pintconf->intr_combined_mode) << 7);
03558 
03559     return system__interrupt_config;
03560 }
03561 
03562 
03563 
03564 VL53L1_GPIO_interrupt_config_t VL53L1_decode_GPIO_interrupt_config(
03565     uint8_t     system__interrupt_config)
03566 {
03567     VL53L1_GPIO_interrupt_config_t  intconf;
03568 
03569     intconf.intr_mode_distance = system__interrupt_config & 0x03;
03570     intconf.intr_mode_rate = (system__interrupt_config >> 2) & 0x03;
03571     intconf.intr_new_measure_ready = (system__interrupt_config >> 5) & 0x01;
03572     intconf.intr_no_target = (system__interrupt_config >> 6) & 0x01;
03573     intconf.intr_combined_mode = (system__interrupt_config >> 7) & 0x01;
03574 
03575 
03576     intconf.threshold_rate_low = 0;
03577     intconf.threshold_rate_high = 0;
03578     intconf.threshold_distance_low = 0;
03579     intconf.threshold_distance_high = 0;
03580 
03581     return intconf;
03582 }
03583 
03584 
03585 
03586 VL53L1_Error VL53L1_set_GPIO_distance_threshold(
03587     VL53L1_DEV                      Dev,
03588     uint16_t            threshold_high,
03589     uint16_t            threshold_low)
03590 {
03591     VL53L1_Error  status = VL53L1_ERROR_NONE;
03592 
03593     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03594 
03595     LOG_FUNCTION_START("");
03596 
03597     pdev->dyn_cfg.system__thresh_high = threshold_high;
03598     pdev->dyn_cfg.system__thresh_low = threshold_low;
03599 
03600     LOG_FUNCTION_END(status);
03601     return status;
03602 }
03603 
03604 
03605 
03606 VL53L1_Error VL53L1_set_GPIO_rate_threshold(
03607     VL53L1_DEV                      Dev,
03608     uint16_t            threshold_high,
03609     uint16_t            threshold_low)
03610 {
03611     VL53L1_Error  status = VL53L1_ERROR_NONE;
03612 
03613     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03614 
03615     LOG_FUNCTION_START("");
03616 
03617     pdev->gen_cfg.system__thresh_rate_high = threshold_high;
03618     pdev->gen_cfg.system__thresh_rate_low = threshold_low;
03619 
03620     LOG_FUNCTION_END(status);
03621     return status;
03622 }
03623 
03624 
03625 
03626 VL53L1_Error VL53L1_set_GPIO_thresholds_from_struct(
03627     VL53L1_DEV                      Dev,
03628     VL53L1_GPIO_interrupt_config_t *pintconf)
03629 {
03630     VL53L1_Error  status = VL53L1_ERROR_NONE;
03631 
03632     LOG_FUNCTION_START("");
03633 
03634     status = VL53L1_set_GPIO_distance_threshold(
03635             Dev,
03636             pintconf->threshold_distance_high,
03637             pintconf->threshold_distance_low);
03638 
03639     if (status == VL53L1_ERROR_NONE) {
03640         status =
03641             VL53L1_set_GPIO_rate_threshold(
03642                 Dev,
03643                 pintconf->threshold_rate_high,
03644                 pintconf->threshold_rate_low);
03645     }
03646 
03647     LOG_FUNCTION_END(status);
03648     return status;
03649 }
03650 
03651 
03652 VL53L1_Error VL53L1_set_ref_spad_char_config(
03653     VL53L1_DEV    Dev,
03654     uint8_t       vcsel_period_a,
03655     uint32_t      phasecal_timeout_us,
03656     uint16_t      total_rate_target_mcps,
03657     uint16_t      max_count_rate_rtn_limit_mcps,
03658     uint16_t      min_count_rate_rtn_limit_mcps,
03659     uint16_t      fast_osc_frequency)
03660 {
03661 
03662 
03663     VL53L1_Error status = VL53L1_ERROR_NONE;
03664     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03665 
03666     uint8_t buffer[2];
03667 
03668     uint32_t macro_period_us = 0;
03669     uint32_t timeout_mclks   = 0;
03670 
03671     LOG_FUNCTION_START("");
03672 
03673 
03674     macro_period_us =
03675         VL53L1_calc_macro_period_us(
03676             fast_osc_frequency,
03677             vcsel_period_a);
03678 
03679 
03680 
03681     timeout_mclks = phasecal_timeout_us << 12;
03682     timeout_mclks = timeout_mclks + (macro_period_us>>1);
03683     timeout_mclks = timeout_mclks / macro_period_us;
03684 
03685     if (timeout_mclks > 0xFF)
03686         pdev->gen_cfg.phasecal_config__timeout_macrop = 0xFF;
03687     else
03688         pdev->gen_cfg.phasecal_config__timeout_macrop =
03689                 (uint8_t)timeout_mclks;
03690 
03691     pdev->tim_cfg.range_config__vcsel_period_a = vcsel_period_a;
03692 
03693 
03694 
03695     if (status == VL53L1_ERROR_NONE)
03696         status =
03697             VL53L1_WrByte(
03698                 Dev,
03699                 VL53L1_PHASECAL_CONFIG__TIMEOUT_MACROP,
03700                 pdev->gen_cfg.phasecal_config__timeout_macrop);
03701 
03702     if (status == VL53L1_ERROR_NONE)
03703         status =
03704             VL53L1_WrByte(
03705                 Dev,
03706                 VL53L1_RANGE_CONFIG__VCSEL_PERIOD_A,
03707                 pdev->tim_cfg.range_config__vcsel_period_a);
03708 
03709 
03710 
03711     buffer[0] = pdev->tim_cfg.range_config__vcsel_period_a;
03712     buffer[1] = pdev->tim_cfg.range_config__vcsel_period_a;
03713 
03714     if (status == VL53L1_ERROR_NONE)
03715         status =
03716             VL53L1_WriteMulti(
03717                 Dev,
03718                 VL53L1_SD_CONFIG__WOI_SD0,
03719                 buffer,
03720                 2);
03721 
03722 
03723 
03724     pdev->customer.ref_spad_char__total_rate_target_mcps =
03725             total_rate_target_mcps;
03726 
03727     if (status == VL53L1_ERROR_NONE)
03728         status =
03729             VL53L1_WrWord(
03730                 Dev,
03731                 VL53L1_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS,
03732                 total_rate_target_mcps);
03733 
03734     if (status == VL53L1_ERROR_NONE)
03735         status =
03736             VL53L1_WrWord(
03737                 Dev,
03738                 VL53L1_RANGE_CONFIG__SIGMA_THRESH,
03739                 max_count_rate_rtn_limit_mcps);
03740 
03741     if (status == VL53L1_ERROR_NONE)
03742         status =
03743             VL53L1_WrWord(
03744             Dev,
03745             VL53L1_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS,
03746             min_count_rate_rtn_limit_mcps);
03747 
03748     LOG_FUNCTION_END(status);
03749 
03750     return status;
03751 }
03752 
03753 
03754 VL53L1_Error VL53L1_set_ssc_config(
03755     VL53L1_DEV            Dev,
03756     VL53L1_ssc_config_t  *pssc_cfg,
03757     uint16_t              fast_osc_frequency)
03758 {
03759 
03760 
03761     VL53L1_Error status = VL53L1_ERROR_NONE;
03762     uint8_t buffer[5];
03763 
03764     uint32_t macro_period_us = 0;
03765     uint16_t timeout_encoded = 0;
03766 
03767     LOG_FUNCTION_START("");
03768 
03769 
03770     macro_period_us =
03771         VL53L1_calc_macro_period_us(
03772             fast_osc_frequency,
03773             pssc_cfg->VL53L1_p_009);
03774 
03775 
03776     timeout_encoded =
03777         VL53L1_calc_encoded_timeout(
03778             pssc_cfg->timeout_us,
03779             macro_period_us);
03780 
03781 
03782 
03783     if (status == VL53L1_ERROR_NONE)
03784         status =
03785             VL53L1_WrByte(
03786                 Dev,
03787                 VL53L1_CAL_CONFIG__VCSEL_START,
03788                 pssc_cfg->vcsel_start);
03789 
03790     if (status == VL53L1_ERROR_NONE)
03791         status =
03792             VL53L1_WrByte(
03793                 Dev,
03794                 VL53L1_GLOBAL_CONFIG__VCSEL_WIDTH,
03795                 pssc_cfg->vcsel_width);
03796 
03797 
03798 
03799     buffer[0] = (uint8_t)((timeout_encoded &  0x0000FF00) >> 8);
03800     buffer[1] = (uint8_t) (timeout_encoded &  0x000000FF);
03801     buffer[2] = pssc_cfg->VL53L1_p_009;
03802     buffer[3] = (uint8_t)((pssc_cfg->rate_limit_mcps &  0x0000FF00) >> 8);
03803     buffer[4] = (uint8_t) (pssc_cfg->rate_limit_mcps &  0x000000FF);
03804 
03805     if (status == VL53L1_ERROR_NONE)
03806         status =
03807             VL53L1_WriteMulti(
03808                 Dev,
03809                 VL53L1_RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
03810                 buffer,
03811                 5);
03812 
03813 
03814 
03815     buffer[0] = pssc_cfg->VL53L1_p_009;
03816     buffer[1] = pssc_cfg->VL53L1_p_009;
03817 
03818     if (status == VL53L1_ERROR_NONE)
03819         status =
03820             VL53L1_WriteMulti(
03821                 Dev,
03822                 VL53L1_SD_CONFIG__WOI_SD0,
03823                 buffer,
03824                 2);
03825 
03826 
03827     if (status == VL53L1_ERROR_NONE)
03828         status =
03829             VL53L1_WrByte(
03830                 Dev,
03831                 VL53L1_NVM_BIST__CTRL,
03832                 pssc_cfg->array_select);
03833 
03834     LOG_FUNCTION_END(status);
03835 
03836     return status;
03837 }
03838 
03839 
03840 VL53L1_Error VL53L1_get_spad_rate_data(
03841     VL53L1_DEV                Dev,
03842     VL53L1_spad_rate_data_t  *pspad_rates)
03843 {
03844 
03845 
03846 
03847     VL53L1_Error status = VL53L1_ERROR_NONE;
03848     int               i = 0;
03849 
03850     uint8_t  VL53L1_p_002[512];
03851     uint8_t *pdata = &VL53L1_p_002[0];
03852 
03853     LOG_FUNCTION_START("");
03854 
03855 
03856 
03857     if (status == VL53L1_ERROR_NONE)
03858         status = VL53L1_disable_firmware(Dev);
03859 
03860 
03861 
03862     if (status == VL53L1_ERROR_NONE)
03863         status =
03864             VL53L1_ReadMulti(
03865                 Dev,
03866                 VL53L1_PRIVATE__PATCH_BASE_ADDR_RSLV,
03867                 pdata,
03868                 512);
03869 
03870 
03871     pdata = &VL53L1_p_002[0];
03872     for (i = 0; i < VL53L1_NO_OF_SPAD_ENABLES; i++) {
03873         pspad_rates->rate_data[i] =
03874             (uint16_t)VL53L1_decode_unsigned_integer(pdata, 2);
03875         pdata += 2;
03876     }
03877 
03878 
03879 
03880     pspad_rates->VL53L1_p_023     = VL53L1_NO_OF_SPAD_ENABLES;
03881     pspad_rates->no_of_values    = VL53L1_NO_OF_SPAD_ENABLES;
03882     pspad_rates->fractional_bits = 15;
03883 
03884 
03885 
03886     if (status == VL53L1_ERROR_NONE)
03887         status = VL53L1_enable_firmware(Dev);
03888 
03889     LOG_FUNCTION_END(status);
03890 
03891     return status;
03892 }
03893 
03894 
03895 
03896 VL53L1_Error VL53L1_dynamic_xtalk_correction_calc_required_samples(
03897     VL53L1_DEV                          Dev
03898     )
03899 {
03900 
03901 
03902 
03903     VL53L1_Error  status = VL53L1_ERROR_NONE;
03904 
03905     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03906     VL53L1_LLDriverResults_t *pres = VL53L1DevStructGetLLResultsHandle(Dev);
03907     VL53L1_smudge_corrector_config_t *pconfig =
03908                 &(pdev->smudge_correct_config);
03909     VL53L1_smudge_corrector_internals_t *pint =
03910                 &(pdev->smudge_corrector_internals);
03911 
03912     VL53L1_range_results_t *presults = &(pres->range_results);
03913     VL53L1_range_data_t *pxmonitor = &(presults->xmonitor);
03914 
03915     uint32_t peak_duration_us = pxmonitor->peak_duration_us;
03916 
03917     uint64_t temp64a;
03918     uint64_t temp64z;
03919 
03920     LOG_FUNCTION_START("");
03921 
03922     if (peak_duration_us == 0)
03923         peak_duration_us = 1000;
03924 
03925     temp64a = pxmonitor->VL53L1_p_021 +
03926         pxmonitor->VL53L1_p_020;
03927     temp64a = do_division_u((temp64a * 1000), peak_duration_us);
03928     temp64a = do_division_u((temp64a * 1000), peak_duration_us);
03929 
03930     temp64z = pconfig->noise_margin * pxmonitor->VL53L1_p_006;
03931     if (temp64z == 0)
03932         temp64z = 1;
03933     temp64a = temp64a * 1000 * 256;
03934     temp64a = do_division_u(temp64a, temp64z);
03935     temp64a = temp64a * 1000 * 256;
03936     temp64a = do_division_u(temp64a, temp64z);
03937 
03938     pint->required_samples = (uint32_t)temp64a;
03939 
03940 
03941     if (pint->required_samples < 2)
03942         pint->required_samples = 2;
03943 
03944     LOG_FUNCTION_END(status);
03945 
03946     return status;
03947 }
03948 
03949 VL53L1_Error VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
03950     VL53L1_DEV              Dev,
03951     uint32_t                xtalk_offset_out,
03952     VL53L1_smudge_corrector_config_t    *pconfig,
03953     VL53L1_smudge_corrector_data_t      *pout,
03954     uint8_t                 add_smudge,
03955     uint8_t                 soft_update
03956     )
03957 {
03958 
03959 
03960 
03961     VL53L1_Error  status = VL53L1_ERROR_NONE;
03962     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03963 
03964     int16_t  x_gradient_scaler;
03965     int16_t  y_gradient_scaler;
03966     uint32_t orig_xtalk_offset;
03967     int16_t  orig_x_gradient;
03968     int16_t  orig_y_gradient;
03969     uint8_t histo_merge_nb;
03970     uint8_t i;
03971     int32_t  itemp32;
03972     uint32_t SmudgeFactor;
03973     VL53L1_xtalk_config_t  *pX = &(pdev->xtalk_cfg);
03974     VL53L1_xtalk_calibration_results_t  *pC = &(pdev->xtalk_cal);
03975     uint32_t *pcpo;
03976     uint32_t max, nXtalk, cXtalk;
03977     uint8_t merge_enabled;
03978 
03979 
03980     LOG_FUNCTION_START("");
03981 
03982     merge_enabled = (pdev->tuning_parms.tp_hist_merge == 1) &&
03983         (VL53L1DevDataGet(Dev, CurrentParameters.PresetMode) ==
03984          VL53L1_PRESETMODE_RANGING);
03985 
03986 
03987     if (add_smudge == 1) {
03988         pout->algo__crosstalk_compensation_plane_offset_kcps =
03989             (uint32_t)xtalk_offset_out +
03990             (uint32_t)pconfig->smudge_margin;
03991     } else {
03992         pout->algo__crosstalk_compensation_plane_offset_kcps =
03993             (uint32_t)xtalk_offset_out;
03994     }
03995 
03996 
03997     orig_xtalk_offset =
03998     pX->nvm_default__crosstalk_compensation_plane_offset_kcps;
03999 
04000     orig_x_gradient =
04001         pX->nvm_default__crosstalk_compensation_x_plane_gradient_kcps;
04002 
04003     orig_y_gradient =
04004         pX->nvm_default__crosstalk_compensation_y_plane_gradient_kcps;
04005 
04006     if (((pconfig->user_scaler_set == 0) ||
04007         (pconfig->scaler_calc_method == 1)) &&
04008         (pC->algo__crosstalk_compensation_plane_offset_kcps != 0)) {
04009 
04010         VL53L1_compute_histo_merge_nb(Dev, &histo_merge_nb);
04011         if (histo_merge_nb == 0)
04012             histo_merge_nb = 1;
04013         if (!merge_enabled)
04014             orig_xtalk_offset =
04015             pC->algo__crosstalk_compensation_plane_offset_kcps;
04016         else
04017             orig_xtalk_offset =
04018             pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb-1];
04019 
04020         orig_x_gradient =
04021             pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
04022 
04023         orig_y_gradient =
04024             pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
04025     }
04026 
04027 
04028     if ((pconfig->user_scaler_set == 0) && (orig_x_gradient == 0))
04029         pout->gradient_zero_flag |= 0x01;
04030 
04031     if ((pconfig->user_scaler_set == 0) && (orig_y_gradient == 0))
04032         pout->gradient_zero_flag |= 0x02;
04033 
04034 
04035 
04036     if (orig_xtalk_offset == 0)
04037         orig_xtalk_offset = 1;
04038 
04039 
04040 
04041     if (pconfig->user_scaler_set == 1) {
04042         x_gradient_scaler = pconfig->x_gradient_scaler;
04043         y_gradient_scaler = pconfig->y_gradient_scaler;
04044     } else {
04045 
04046         x_gradient_scaler = (int16_t)do_division_s(
04047                 (((int32_t)orig_x_gradient) << 6),
04048                 orig_xtalk_offset);
04049         pconfig->x_gradient_scaler = x_gradient_scaler;
04050         y_gradient_scaler = (int16_t)do_division_s(
04051                 (((int32_t)orig_y_gradient) << 6),
04052                 orig_xtalk_offset);
04053         pconfig->y_gradient_scaler = y_gradient_scaler;
04054     }
04055 
04056 
04057 
04058     if (pconfig->scaler_calc_method == 0) {
04059 
04060 
04061         itemp32 = (int32_t)(
04062             pout->algo__crosstalk_compensation_plane_offset_kcps *
04063                 x_gradient_scaler);
04064         itemp32 = itemp32 >> 6;
04065         if (itemp32 > 0xFFFF)
04066             itemp32 = 0xFFFF;
04067 
04068         pout->algo__crosstalk_compensation_x_plane_gradient_kcps =
04069             (int16_t)itemp32;
04070 
04071         itemp32 = (int32_t)(
04072             pout->algo__crosstalk_compensation_plane_offset_kcps *
04073                 y_gradient_scaler);
04074         itemp32 = itemp32 >> 6;
04075         if (itemp32 > 0xFFFF)
04076             itemp32 = 0xFFFF;
04077 
04078         pout->algo__crosstalk_compensation_y_plane_gradient_kcps =
04079             (int16_t)itemp32;
04080     } else if (pconfig->scaler_calc_method == 1) {
04081 
04082 
04083         itemp32 = (int32_t)(orig_xtalk_offset -
04084             pout->algo__crosstalk_compensation_plane_offset_kcps);
04085         itemp32 = (int32_t)(do_division_s(itemp32, 16));
04086         itemp32 = itemp32 << 2;
04087         itemp32 = itemp32 + (int32_t)(orig_x_gradient);
04088         if (itemp32 > 0xFFFF)
04089             itemp32 = 0xFFFF;
04090 
04091         pout->algo__crosstalk_compensation_x_plane_gradient_kcps =
04092             (int16_t)itemp32;
04093 
04094         itemp32 = (int32_t)(orig_xtalk_offset -
04095             pout->algo__crosstalk_compensation_plane_offset_kcps);
04096         itemp32 = (int32_t)(do_division_s(itemp32, 80));
04097         itemp32 = itemp32 << 2;
04098         itemp32 = itemp32 + (int32_t)(orig_y_gradient);
04099         if (itemp32 > 0xFFFF)
04100             itemp32 = 0xFFFF;
04101 
04102         pout->algo__crosstalk_compensation_y_plane_gradient_kcps =
04103             (int16_t)itemp32;
04104     }
04105 
04106 
04107     if (pconfig->smudge_corr_apply_enabled == 1 &&
04108             (soft_update != 1)) {
04109         pout->new_xtalk_applied_flag = 1;
04110         nXtalk = pout->algo__crosstalk_compensation_plane_offset_kcps;
04111 
04112         VL53L1_compute_histo_merge_nb(Dev, &histo_merge_nb);
04113         max = pdev->tuning_parms.tp_hist_merge_max_size;
04114         pcpo = &(pC->algo__xtalk_cpo_HistoMerge_kcps[0]);
04115         if ((histo_merge_nb > 0) && merge_enabled && (nXtalk != 0)) {
04116             cXtalk =
04117             pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb-1];
04118             SmudgeFactor = cXtalk * 1000 / nXtalk;
04119             if (SmudgeFactor >= pconfig->max_smudge_factor)
04120                 pout->new_xtalk_applied_flag = 0;
04121             else if (SmudgeFactor > 0)
04122                 for (i = 0; i < max; i++) {
04123                 *pcpo *= 1000;
04124                 *pcpo /= SmudgeFactor;
04125                 pcpo++;
04126                 }
04127         }
04128         if (pout->new_xtalk_applied_flag) {
04129 
04130         pX->algo__crosstalk_compensation_plane_offset_kcps =
04131         pout->algo__crosstalk_compensation_plane_offset_kcps;
04132         pX->algo__crosstalk_compensation_x_plane_gradient_kcps =
04133         pout->algo__crosstalk_compensation_x_plane_gradient_kcps;
04134         pX->algo__crosstalk_compensation_y_plane_gradient_kcps =
04135         pout->algo__crosstalk_compensation_y_plane_gradient_kcps;
04136 
04137         if (pconfig->smudge_corr_single_apply == 1) {
04138 
04139             pconfig->smudge_corr_apply_enabled = 0;
04140             pconfig->smudge_corr_single_apply = 0;
04141         }
04142         }
04143     }
04144 
04145 
04146     if (soft_update != 1)
04147         pout->smudge_corr_valid = 1;
04148 
04149     LOG_FUNCTION_END(status);
04150 
04151     return status;
04152 }
04153 
04154 #define CONT_CONTINUE   0
04155 #define CONT_NEXT_LOOP  1
04156 #define CONT_RESET  2
04157 VL53L1_Error VL53L1_dynamic_xtalk_correction_corrector(
04158     VL53L1_DEV                          Dev
04159     )
04160 {
04161 
04162 
04163 
04164     VL53L1_Error  status = VL53L1_ERROR_NONE;
04165 
04166     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04167     VL53L1_LLDriverResults_t *pres = VL53L1DevStructGetLLResultsHandle(Dev);
04168     VL53L1_smudge_corrector_config_t *pconfig =
04169                 &(pdev->smudge_correct_config);
04170     VL53L1_smudge_corrector_internals_t *pint =
04171                 &(pdev->smudge_corrector_internals);
04172     VL53L1_smudge_corrector_data_t *pout =
04173             &(pres->range_results.smudge_corrector_data);
04174     VL53L1_range_results_t  *pR = &(pres->range_results);
04175     VL53L1_xtalk_config_t  *pX = &(pdev->xtalk_cfg);
04176 
04177     uint8_t run_smudge_detection = 0;
04178     uint8_t merging_complete = 0;
04179     uint8_t run_nodetect = 0;
04180     uint8_t ambient_check = 0;
04181     int32_t itemp32 = 0;
04182     uint64_t utemp64 = 0;
04183     uint8_t continue_processing = CONT_CONTINUE;
04184     uint32_t xtalk_offset_out = 0;
04185     uint32_t xtalk_offset_in = 0;
04186     uint32_t current_xtalk = 0;
04187     uint32_t smudge_margin_adjusted = 0;
04188     uint8_t i = 0;
04189     uint8_t nodetect_index = 0;
04190     uint16_t    amr;
04191     uint32_t    cco;
04192     uint8_t histo_merge_nb;
04193     uint8_t merge_enabled;
04194 
04195 
04196     LOG_FUNCTION_START("");
04197 
04198     merge_enabled = (pdev->tuning_parms.tp_hist_merge == 1) &&
04199         (VL53L1DevDataGet(Dev, CurrentParameters.PresetMode) ==
04200          VL53L1_PRESETMODE_RANGING);
04201 
04202     VL53L1_compute_histo_merge_nb(Dev, &histo_merge_nb);
04203     if ((histo_merge_nb == 0) || (!merge_enabled))
04204         histo_merge_nb = 1;
04205 
04206 
04207     VL53L1_dynamic_xtalk_correction_output_init(pres);
04208 
04209 
04210     ambient_check = (pconfig->smudge_corr_ambient_threshold == 0) ||
04211         ((pconfig->smudge_corr_ambient_threshold * histo_merge_nb) >
04212         ((uint32_t)pR->xmonitor.ambient_count_rate_mcps));
04213 
04214 
04215     merging_complete = ((!merge_enabled) ||
04216     (histo_merge_nb == pdev->tuning_parms.tp_hist_merge_max_size));
04217 
04218     run_smudge_detection =
04219         (pconfig->smudge_corr_enabled == 1) &&
04220         ambient_check &&
04221         (pR->xmonitor.range_status
04222             == VL53L1_DEVICEERROR_RANGECOMPLETE) &&
04223         merging_complete;
04224 
04225 
04226     if ((pR->xmonitor.range_status
04227         != VL53L1_DEVICEERROR_RANGECOMPLETE) &&
04228             (pconfig->smudge_corr_enabled == 1)) {
04229 
04230         run_nodetect = 2;
04231         for (i = 0; i < pR->active_results; i++) {
04232             if (pR->VL53L1_p_002[i].range_status ==
04233                 VL53L1_DEVICEERROR_RANGECOMPLETE) {
04234                 if (pR->VL53L1_p_002[i].median_range_mm
04235                         <=
04236                     pconfig->nodetect_min_range_mm) {
04237                     run_nodetect = 0;
04238                 } else {
04239                     if (run_nodetect == 2) {
04240                         run_nodetect = 1;
04241                         nodetect_index = i;
04242                     }
04243                 }
04244             }
04245         }
04246 
04247         if (run_nodetect == 2)
04248 
04249             run_nodetect = 0;
04250 
04251         amr =
04252         pR->VL53L1_p_002[nodetect_index].ambient_count_rate_mcps;
04253 
04254         if (run_nodetect == 1) {
04255 
04256 
04257 
04258 
04259             utemp64 = 1000 * ((uint64_t)amr);
04260 
04261 
04262             utemp64 = utemp64 << 9;
04263 
04264 
04265             if (utemp64 < pconfig->nodetect_ambient_threshold)
04266                 run_nodetect = 1;
04267             else
04268                 run_nodetect = 0;
04269 
04270         }
04271     }
04272 
04273 
04274     if (run_smudge_detection) {
04275 
04276         pint->nodetect_counter = 0;
04277 
04278 
04279         VL53L1_dynamic_xtalk_correction_calc_required_samples(Dev);
04280 
04281 
04282         xtalk_offset_in =
04283             pR->xmonitor.VL53L1_p_012;
04284 
04285 
04286         cco = pX->algo__crosstalk_compensation_plane_offset_kcps;
04287         current_xtalk = ((uint32_t)cco) << 2;
04288 
04289 
04290         smudge_margin_adjusted =
04291                 ((uint32_t)(pconfig->smudge_margin)) << 2;
04292 
04293 
04294         itemp32 = xtalk_offset_in - current_xtalk +
04295             smudge_margin_adjusted;
04296 
04297         if (itemp32 < 0)
04298             itemp32 = itemp32 * (-1);
04299 
04300 
04301         if (itemp32 > ((int32_t)pconfig->single_xtalk_delta)) {
04302             if ((int32_t)xtalk_offset_in >
04303                 ((int32_t)current_xtalk -
04304                     (int32_t)smudge_margin_adjusted)) {
04305                 pout->single_xtalk_delta_flag = 1;
04306             } else {
04307                 pout->single_xtalk_delta_flag = 2;
04308             }
04309         }
04310 
04311 
04312         pint->current_samples = pint->current_samples + 1;
04313 
04314 
04315         if (pint->current_samples > pconfig->sample_limit) {
04316             pout->sample_limit_exceeded_flag = 1;
04317             continue_processing = CONT_RESET;
04318         } else {
04319             pint->accumulator = pint->accumulator +
04320                 xtalk_offset_in;
04321         }
04322 
04323         if (pint->current_samples < pint->required_samples)
04324             continue_processing = CONT_NEXT_LOOP;
04325 
04326 
04327         xtalk_offset_out =
04328         (uint32_t)(do_division_u(pint->accumulator,
04329             pint->current_samples));
04330 
04331 
04332         itemp32 = xtalk_offset_out - current_xtalk +
04333             smudge_margin_adjusted;
04334 
04335         if (itemp32 < 0)
04336             itemp32 = itemp32 * (-1);
04337 
04338         if (continue_processing == CONT_CONTINUE &&
04339             (itemp32 >= ((int32_t)(pconfig->averaged_xtalk_delta)))
04340             ) {
04341             if ((int32_t)xtalk_offset_out >
04342                 ((int32_t)current_xtalk -
04343                     (int32_t)smudge_margin_adjusted))
04344                 pout->averaged_xtalk_delta_flag = 1;
04345             else
04346                 pout->averaged_xtalk_delta_flag = 2;
04347         }
04348 
04349         if (continue_processing == CONT_CONTINUE &&
04350             (itemp32 < ((int32_t)(pconfig->averaged_xtalk_delta)))
04351             )
04352 
04353             continue_processing = CONT_RESET;
04354 
04355 
04356 
04357         pout->smudge_corr_clipped = 0;
04358         if ((continue_processing == CONT_CONTINUE) &&
04359             (pconfig->smudge_corr_clip_limit != 0)) {
04360             if (xtalk_offset_out >
04361             (pconfig->smudge_corr_clip_limit * histo_merge_nb)) {
04362                 pout->smudge_corr_clipped = 1;
04363                 continue_processing = CONT_RESET;
04364             }
04365         }
04366 
04367 
04368 
04369         if (pconfig->user_xtalk_offset_limit_hi &&
04370             (xtalk_offset_out >
04371                 pconfig->user_xtalk_offset_limit))
04372             xtalk_offset_out =
04373                 pconfig->user_xtalk_offset_limit;
04374 
04375 
04376 
04377         if ((pconfig->user_xtalk_offset_limit_hi == 0) &&
04378             (xtalk_offset_out <
04379                 pconfig->user_xtalk_offset_limit))
04380             xtalk_offset_out =
04381                 pconfig->user_xtalk_offset_limit;
04382 
04383 
04384 
04385         xtalk_offset_out = xtalk_offset_out >> 2;
04386         if (xtalk_offset_out > 0x3FFFF)
04387             xtalk_offset_out = 0x3FFFF;
04388 
04389 
04390         if (continue_processing == CONT_CONTINUE) {
04391 
04392             VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
04393                 Dev,
04394                 xtalk_offset_out,
04395                 pconfig,
04396                 pout,
04397                 1,
04398                 0
04399                 );
04400 
04401 
04402             continue_processing = CONT_RESET;
04403         } else {
04404 
04405             VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
04406                 Dev,
04407                 xtalk_offset_out,
04408                 pconfig,
04409                 pout,
04410                 1,
04411                 1
04412                 );
04413         }
04414 
04415 
04416         if (continue_processing == CONT_RESET) {
04417             pint->accumulator = 0;
04418             pint->current_samples = 0;
04419             pint->nodetect_counter = 0;
04420         }
04421 
04422     }
04423 
04424     continue_processing = CONT_CONTINUE;
04425     if (run_nodetect == 1) {
04426 
04427         pint->nodetect_counter += 1;
04428 
04429 
04430         if (pint->nodetect_counter < pconfig->nodetect_sample_limit)
04431             continue_processing = CONT_NEXT_LOOP;
04432 
04433 
04434         xtalk_offset_out = (uint32_t)(pconfig->nodetect_xtalk_offset);
04435 
04436         if (continue_processing == CONT_CONTINUE) {
04437 
04438             VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
04439                 Dev,
04440                 xtalk_offset_out,
04441                 pconfig,
04442                 pout,
04443                 0,
04444                 0
04445                 );
04446 
04447 
04448             pout->smudge_corr_valid = 2;
04449 
04450 
04451             continue_processing = CONT_RESET;
04452         } else {
04453 
04454             VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
04455                 Dev,
04456                 xtalk_offset_out,
04457                 pconfig,
04458                 pout,
04459                 0,
04460                 1
04461                 );
04462         }
04463 
04464 
04465         if (continue_processing == CONT_RESET) {
04466             pint->accumulator = 0;
04467             pint->current_samples = 0;
04468             pint->nodetect_counter = 0;
04469         }
04470     }
04471 
04472     LOG_FUNCTION_END(status);
04473 
04474     return status;
04475 }
04476 
04477 VL53L1_Error VL53L1_dynamic_xtalk_correction_data_init(
04478     VL53L1_DEV                          Dev
04479     )
04480 {
04481 
04482 
04483 
04484 
04485     VL53L1_Error  status = VL53L1_ERROR_NONE;
04486 
04487     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04488     VL53L1_LLDriverResults_t *pres = VL53L1DevStructGetLLResultsHandle(Dev);
04489 
04490     LOG_FUNCTION_START("");
04491 
04492 
04493 
04494     pdev->smudge_correct_config.smudge_corr_enabled       = 1;
04495     pdev->smudge_correct_config.smudge_corr_apply_enabled = 1;
04496     pdev->smudge_correct_config.smudge_corr_single_apply  =
04497         VL53L1_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY_DEFAULT;
04498 
04499     pdev->smudge_correct_config.smudge_margin =
04500         VL53L1_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN_DEFAULT;
04501     pdev->smudge_correct_config.noise_margin =
04502         VL53L1_TUNINGPARM_DYNXTALK_NOISE_MARGIN_DEFAULT;
04503     pdev->smudge_correct_config.user_xtalk_offset_limit =
04504         VL53L1_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_DEFAULT;
04505     pdev->smudge_correct_config.user_xtalk_offset_limit_hi =
04506         VL53L1_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI_DEFAULT;
04507     pdev->smudge_correct_config.sample_limit =
04508         VL53L1_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT_DEFAULT;
04509     pdev->smudge_correct_config.single_xtalk_delta =
04510         VL53L1_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA_DEFAULT;
04511     pdev->smudge_correct_config.averaged_xtalk_delta =
04512         VL53L1_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA_DEFAULT;
04513     pdev->smudge_correct_config.smudge_corr_clip_limit =
04514         VL53L1_TUNINGPARM_DYNXTALK_CLIP_LIMIT_DEFAULT;
04515     pdev->smudge_correct_config.smudge_corr_ambient_threshold =
04516         VL53L1_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD_DEFAULT;
04517     pdev->smudge_correct_config.scaler_calc_method =
04518         0;
04519     pdev->smudge_correct_config.x_gradient_scaler =
04520         VL53L1_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER_DEFAULT;
04521     pdev->smudge_correct_config.y_gradient_scaler =
04522         VL53L1_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER_DEFAULT;
04523     pdev->smudge_correct_config.user_scaler_set =
04524         VL53L1_TUNINGPARM_DYNXTALK_USER_SCALER_SET_DEFAULT;
04525     pdev->smudge_correct_config.nodetect_ambient_threshold =
04526         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS_DEFAULT;
04527     pdev->smudge_correct_config.nodetect_sample_limit =
04528         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT_DEFAULT;
04529     pdev->smudge_correct_config.nodetect_xtalk_offset =
04530         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS_DEFAULT;
04531     pdev->smudge_correct_config.nodetect_min_range_mm =
04532         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM_DEFAULT;
04533     pdev->smudge_correct_config.max_smudge_factor =
04534         VL53L1_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR_DEFAULT;
04535 
04536 
04537     pdev->smudge_corrector_internals.current_samples = 0;
04538     pdev->smudge_corrector_internals.required_samples = 0;
04539     pdev->smudge_corrector_internals.accumulator = 0;
04540     pdev->smudge_corrector_internals.nodetect_counter = 0;
04541 
04542 
04543     VL53L1_dynamic_xtalk_correction_output_init(pres);
04544 
04545     LOG_FUNCTION_END(status);
04546 
04547     return status;
04548 }
04549 
04550 VL53L1_Error VL53L1_dynamic_xtalk_correction_output_init(
04551     VL53L1_LLDriverResults_t *pres
04552     )
04553 {
04554 
04555 
04556 
04557 
04558     VL53L1_Error  status = VL53L1_ERROR_NONE;
04559 
04560     VL53L1_smudge_corrector_data_t *pdata;
04561 
04562     LOG_FUNCTION_START("");
04563 
04564 
04565     pdata = &(pres->range_results.smudge_corrector_data);
04566 
04567     pdata->smudge_corr_valid = 0;
04568     pdata->smudge_corr_clipped = 0;
04569     pdata->single_xtalk_delta_flag = 0;
04570     pdata->averaged_xtalk_delta_flag = 0;
04571     pdata->sample_limit_exceeded_flag = 0;
04572     pdata->gradient_zero_flag = 0;
04573     pdata->new_xtalk_applied_flag = 0;
04574 
04575     pdata->algo__crosstalk_compensation_plane_offset_kcps = 0;
04576     pdata->algo__crosstalk_compensation_x_plane_gradient_kcps = 0;
04577     pdata->algo__crosstalk_compensation_y_plane_gradient_kcps = 0;
04578 
04579     LOG_FUNCTION_END(status);
04580 
04581     return status;
04582 }
04583 
04584 
04585 VL53L1_Error VL53L1_xtalk_cal_data_init(
04586     VL53L1_DEV                          Dev
04587     )
04588 {
04589 
04590 
04591 
04592 
04593     VL53L1_Error  status = VL53L1_ERROR_NONE;
04594 
04595     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04596 
04597     LOG_FUNCTION_START("");
04598 
04599 
04600 
04601     pdev->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps = 0;
04602     pdev->xtalk_cal.algo__crosstalk_compensation_x_plane_gradient_kcps = 0;
04603     pdev->xtalk_cal.algo__crosstalk_compensation_y_plane_gradient_kcps = 0;
04604     memset(&pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0], 0,
04605         sizeof(pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps));
04606 
04607     LOG_FUNCTION_END(status);
04608 
04609     return status;
04610 }
04611 
04612 
04613 
04614 
04615 
04616 
04617 VL53L1_Error VL53L1_low_power_auto_data_init(
04618     VL53L1_DEV                          Dev
04619     )
04620 {
04621 
04622 
04623 
04624 
04625     VL53L1_Error  status = VL53L1_ERROR_NONE;
04626 
04627     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04628 
04629     LOG_FUNCTION_START("");
04630 
04631     pdev->low_power_auto_data.vhv_loop_bound =
04632         VL53L1_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND_DEFAULT;
04633     pdev->low_power_auto_data.is_low_power_auto_mode = 0;
04634     pdev->low_power_auto_data.low_power_auto_range_count = 0;
04635     pdev->low_power_auto_data.saved_interrupt_config = 0;
04636     pdev->low_power_auto_data.saved_vhv_init = 0;
04637     pdev->low_power_auto_data.saved_vhv_timeout = 0;
04638     pdev->low_power_auto_data.first_run_phasecal_result = 0;
04639     pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
04640     pdev->low_power_auto_data.dss__required_spads = 0;
04641 
04642     LOG_FUNCTION_END(status);
04643 
04644     return status;
04645 }
04646 
04647 VL53L1_Error VL53L1_low_power_auto_data_stop_range(
04648     VL53L1_DEV                          Dev
04649     )
04650 {
04651 
04652 
04653 
04654 
04655     VL53L1_Error  status = VL53L1_ERROR_NONE;
04656 
04657     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04658 
04659     LOG_FUNCTION_START("");
04660 
04661 
04662 
04663     pdev->low_power_auto_data.low_power_auto_range_count = 0xFF;
04664 
04665     pdev->low_power_auto_data.first_run_phasecal_result = 0;
04666     pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
04667     pdev->low_power_auto_data.dss__required_spads = 0;
04668 
04669 
04670     if (pdev->low_power_auto_data.saved_vhv_init != 0)
04671         pdev->stat_nvm.vhv_config__init =
04672             pdev->low_power_auto_data.saved_vhv_init;
04673     if (pdev->low_power_auto_data.saved_vhv_timeout != 0)
04674         pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
04675             pdev->low_power_auto_data.saved_vhv_timeout;
04676 
04677 
04678     pdev->gen_cfg.phasecal_config__override = 0x00;
04679 
04680     LOG_FUNCTION_END(status);
04681 
04682     return status;
04683 }
04684 
04685 VL53L1_Error VL53L1_config_low_power_auto_mode(
04686     VL53L1_general_config_t   *pgeneral,
04687     VL53L1_dynamic_config_t   *pdynamic,
04688     VL53L1_low_power_auto_data_t *plpadata
04689     )
04690 {
04691 
04692 
04693 
04694 
04695     VL53L1_Error  status = VL53L1_ERROR_NONE;
04696 
04697     LOG_FUNCTION_START("");
04698 
04699 
04700     plpadata->is_low_power_auto_mode = 1;
04701 
04702 
04703     plpadata->low_power_auto_range_count = 0;
04704 
04705 
04706     pdynamic->system__sequence_config =
04707             VL53L1_SEQUENCE_VHV_EN |
04708             VL53L1_SEQUENCE_PHASECAL_EN |
04709             VL53L1_SEQUENCE_DSS1_EN |
04710 
04711 
04712 
04713             VL53L1_SEQUENCE_RANGE_EN;
04714 
04715 
04716     pgeneral->dss_config__manual_effective_spads_select = 200 << 8;
04717     pgeneral->dss_config__roi_mode_control =
04718         VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
04719 
04720     LOG_FUNCTION_END(status);
04721 
04722     return status;
04723 }
04724 
04725 VL53L1_Error VL53L1_low_power_auto_setup_manual_calibration(
04726     VL53L1_DEV        Dev)
04727 {
04728 
04729 
04730 
04731     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04732 
04733 
04734     VL53L1_Error  status = VL53L1_ERROR_NONE;
04735 
04736     LOG_FUNCTION_START("");
04737 
04738 
04739     pdev->low_power_auto_data.saved_vhv_init =
04740         pdev->stat_nvm.vhv_config__init;
04741     pdev->low_power_auto_data.saved_vhv_timeout =
04742         pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound;
04743 
04744 
04745     pdev->stat_nvm.vhv_config__init &= 0x7F;
04746 
04747     pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
04748         (pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound & 0x03) +
04749         (pdev->low_power_auto_data.vhv_loop_bound << 2);
04750 
04751     pdev->gen_cfg.phasecal_config__override = 0x01;
04752     pdev->low_power_auto_data.first_run_phasecal_result =
04753         pdev->dbg_results.phasecal_result__vcsel_start;
04754     pdev->gen_cfg.cal_config__vcsel_start =
04755         pdev->low_power_auto_data.first_run_phasecal_result;
04756 
04757     LOG_FUNCTION_END(status);
04758 
04759     return status;
04760 }
04761 
04762 VL53L1_Error VL53L1_low_power_auto_update_DSS(
04763     VL53L1_DEV        Dev)
04764 {
04765 
04766 
04767 
04768     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04769 
04770     VL53L1_system_results_t *pS = &(pdev->sys_results);
04771 
04772 
04773     VL53L1_Error  status = VL53L1_ERROR_NONE;
04774 
04775     uint32_t utemp32a;
04776 
04777     LOG_FUNCTION_START("");
04778 
04779 
04780 
04781 
04782     utemp32a =
04783         pS->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0
04784          + pS->result__ambient_count_rate_mcps_sd0;
04785 
04786 
04787     if (utemp32a > 0xFFFF)
04788         utemp32a = 0xFFFF;
04789 
04790 
04791 
04792     utemp32a = utemp32a << 16;
04793 
04794 
04795     if (pdev->sys_results.result__dss_actual_effective_spads_sd0 == 0)
04796         status = VL53L1_ERROR_DIVISION_BY_ZERO;
04797     else {
04798 
04799         utemp32a = utemp32a /
04800         pdev->sys_results.result__dss_actual_effective_spads_sd0;
04801 
04802         pdev->low_power_auto_data.dss__total_rate_per_spad_mcps =
04803             utemp32a;
04804 
04805 
04806         utemp32a = pdev->stat_cfg.dss_config__target_total_rate_mcps <<
04807             16;
04808 
04809 
04810         if (pdev->low_power_auto_data.dss__total_rate_per_spad_mcps
04811                 == 0)
04812             status = VL53L1_ERROR_DIVISION_BY_ZERO;
04813         else {
04814 
04815             utemp32a = utemp32a /
04816             pdev->low_power_auto_data.dss__total_rate_per_spad_mcps;
04817 
04818 
04819             if (utemp32a > 0xFFFF)
04820                 utemp32a = 0xFFFF;
04821 
04822 
04823             pdev->low_power_auto_data.dss__required_spads =
04824                 (uint16_t)utemp32a;
04825 
04826 
04827             pdev->gen_cfg.dss_config__manual_effective_spads_select
04828             = pdev->low_power_auto_data.dss__required_spads;
04829             pdev->gen_cfg.dss_config__roi_mode_control =
04830             VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
04831         }
04832 
04833     }
04834 
04835     if (status == VL53L1_ERROR_DIVISION_BY_ZERO) {
04836 
04837 
04838 
04839         pdev->low_power_auto_data.dss__required_spads = 0x8000;
04840 
04841 
04842         pdev->gen_cfg.dss_config__manual_effective_spads_select =
04843             pdev->low_power_auto_data.dss__required_spads;
04844         pdev->gen_cfg.dss_config__roi_mode_control =
04845             VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
04846 
04847 
04848         status = VL53L1_ERROR_NONE;
04849     }
04850 
04851     LOG_FUNCTION_END(status);
04852 
04853     return status;
04854 }
04855 
04856 
04857 
04858 
04859 VL53L1_Error VL53L1_compute_histo_merge_nb(
04860     VL53L1_DEV        Dev,  uint8_t *histo_merge_nb)
04861 {
04862     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04863     VL53L1_Error  status = VL53L1_ERROR_NONE;
04864     uint8_t i, timing;
04865     uint8_t sum = 0;
04866 
04867     timing = (pdev->hist_data.bin_seq[0] == 7 ? 1 : 0);
04868     for (i = 0; i < VL53L1_BIN_REC_SIZE; i++)
04869         if (pdev->multi_bins_rec[i][timing][7] > 0)
04870             sum++;
04871     *histo_merge_nb = sum;
04872 
04873     return status;
04874 }
04875 
04876