ST Expansion SW Team / VL53L1CB

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   VL53L1CB_noshield_1sensor_polls_auton VL53L1CB_noshield_1sensor_interrupt_auton X_NUCLEO_53L1A2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53l1_core.c Source File

vl53l1_core.c

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