ST Expansion SW Team / VL53L1

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   X_NUCLEO_53L1CB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53l1_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     timeout_mclks   =
01226             ((timeout_us << 12) + (macro_period_us>>1)) /
01227             macro_period_us;
01228 
01229     LOG_FUNCTION_END(0);
01230 
01231     return timeout_mclks;
01232 }
01233 
01234 
01235 uint16_t VL53L1_calc_encoded_timeout(
01236     uint32_t timeout_us,
01237     uint32_t macro_period_us)
01238 {
01239 
01240 
01241     uint32_t timeout_mclks   = 0;
01242     uint16_t timeout_encoded = 0;
01243 
01244     LOG_FUNCTION_START("");
01245 
01246     timeout_mclks   =
01247         VL53L1_calc_timeout_mclks(timeout_us, macro_period_us);
01248 
01249     timeout_encoded =
01250         VL53L1_encode_timeout(timeout_mclks);
01251 
01252 
01253 
01254     LOG_FUNCTION_END(0);
01255 
01256     return timeout_encoded;
01257 }
01258 
01259 
01260 uint32_t VL53L1_calc_timeout_us(
01261     uint32_t timeout_mclks,
01262     uint32_t macro_period_us)
01263 {
01264 
01265 
01266     uint32_t timeout_us     = 0;
01267     uint64_t tmp            = 0;
01268 
01269     LOG_FUNCTION_START("");
01270 
01271     tmp  = (uint64_t)timeout_mclks * (uint64_t)macro_period_us;
01272     tmp += 0x00800;
01273     tmp  = tmp >> 12;
01274 
01275     timeout_us = (uint32_t)tmp;
01276 
01277 
01278 
01279     LOG_FUNCTION_END(0);
01280 
01281     return timeout_us;
01282 }
01283 
01284 uint32_t VL53L1_calc_crosstalk_plane_offset_with_margin(
01285         uint32_t     plane_offset_kcps,
01286         int16_t      margin_offset_kcps)
01287 {
01288     uint32_t plane_offset_with_margin = 0;
01289     int32_t  plane_offset_kcps_temp   = 0;
01290 
01291     LOG_FUNCTION_START("");
01292 
01293     plane_offset_kcps_temp =
01294         (int32_t)plane_offset_kcps +
01295         (int32_t)margin_offset_kcps;
01296 
01297     if (plane_offset_kcps_temp < 0)
01298         plane_offset_kcps_temp = 0;
01299     else
01300         if (plane_offset_kcps_temp > 0x3FFFF)
01301             plane_offset_kcps_temp = 0x3FFFF;
01302 
01303     plane_offset_with_margin = (uint32_t) plane_offset_kcps_temp;
01304 
01305     LOG_FUNCTION_END(0);
01306 
01307     return plane_offset_with_margin;
01308 
01309 }
01310 
01311 uint32_t VL53L1_calc_decoded_timeout_us(
01312     uint16_t timeout_encoded,
01313     uint32_t macro_period_us)
01314 {
01315 
01316 
01317     uint32_t timeout_mclks  = 0;
01318     uint32_t timeout_us     = 0;
01319 
01320     LOG_FUNCTION_START("");
01321 
01322     timeout_mclks =
01323         VL53L1_decode_timeout(timeout_encoded);
01324 
01325     timeout_us    =
01326         VL53L1_calc_timeout_us(timeout_mclks, macro_period_us);
01327 
01328     LOG_FUNCTION_END(0);
01329 
01330     return timeout_us;
01331 }
01332 
01333 
01334 uint16_t VL53L1_encode_timeout(uint32_t timeout_mclks)
01335 {
01336 
01337 
01338     uint16_t encoded_timeout = 0;
01339     uint32_t ls_byte = 0;
01340     uint16_t ms_byte = 0;
01341 
01342     if (timeout_mclks > 0) {
01343         ls_byte = timeout_mclks - 1;
01344 
01345         while ((ls_byte & 0xFFFFFF00) > 0) {
01346             ls_byte = ls_byte >> 1;
01347             ms_byte++;
01348         }
01349 
01350         encoded_timeout = (ms_byte << 8)
01351                 + (uint16_t) (ls_byte & 0x000000FF);
01352     }
01353 
01354     return encoded_timeout;
01355 }
01356 
01357 
01358 uint32_t VL53L1_decode_timeout(uint16_t encoded_timeout)
01359 {
01360 
01361 
01362     uint32_t timeout_macro_clks = 0;
01363 
01364     timeout_macro_clks = ((uint32_t) (encoded_timeout & 0x00FF)
01365             << (uint32_t) ((encoded_timeout & 0xFF00) >> 8)) + 1;
01366 
01367     return timeout_macro_clks;
01368 }
01369 
01370 
01371 VL53L1_Error VL53L1_calc_timeout_register_values(
01372     uint32_t                 phasecal_config_timeout_us,
01373     uint32_t                 mm_config_timeout_us,
01374     uint32_t                 range_config_timeout_us,
01375     uint16_t                 fast_osc_frequency,
01376     VL53L1_general_config_t *pgeneral,
01377     VL53L1_timing_config_t  *ptiming)
01378 {
01379 
01380 
01381     VL53L1_Error status = VL53L1_ERROR_NONE;
01382 
01383     uint32_t macro_period_us    = 0;
01384     uint32_t timeout_mclks      = 0;
01385     uint16_t timeout_encoded    = 0;
01386 
01387     LOG_FUNCTION_START("");
01388 
01389     if (fast_osc_frequency == 0) {
01390         status = VL53L1_ERROR_DIVISION_BY_ZERO;
01391     } else {
01392 
01393         macro_period_us =
01394                 VL53L1_calc_macro_period_us(
01395                     fast_osc_frequency,
01396                     ptiming->range_config__vcsel_period_a);
01397 
01398 
01399         timeout_mclks =
01400             VL53L1_calc_timeout_mclks(
01401                 phasecal_config_timeout_us,
01402                 macro_period_us);
01403 
01404 
01405         if (timeout_mclks > 0xFF)
01406             timeout_mclks = 0xFF;
01407 
01408         pgeneral->phasecal_config__timeout_macrop =
01409                 (uint8_t)timeout_mclks;
01410 
01411 
01412         timeout_encoded =
01413             VL53L1_calc_encoded_timeout(
01414                 mm_config_timeout_us,
01415                 macro_period_us);
01416 
01417         ptiming->mm_config__timeout_macrop_a_hi =
01418                 (uint8_t)((timeout_encoded & 0xFF00) >> 8);
01419         ptiming->mm_config__timeout_macrop_a_lo =
01420                 (uint8_t) (timeout_encoded & 0x00FF);
01421 
01422 
01423         timeout_encoded =
01424             VL53L1_calc_encoded_timeout(
01425                 range_config_timeout_us,
01426                 macro_period_us);
01427 
01428         ptiming->range_config__timeout_macrop_a_hi =
01429                 (uint8_t)((timeout_encoded & 0xFF00) >> 8);
01430         ptiming->range_config__timeout_macrop_a_lo =
01431                 (uint8_t) (timeout_encoded & 0x00FF);
01432 
01433 
01434         macro_period_us =
01435                 VL53L1_calc_macro_period_us(
01436                     fast_osc_frequency,
01437                     ptiming->range_config__vcsel_period_b);
01438 
01439 
01440         timeout_encoded =
01441                 VL53L1_calc_encoded_timeout(
01442                     mm_config_timeout_us,
01443                     macro_period_us);
01444 
01445         ptiming->mm_config__timeout_macrop_b_hi =
01446                 (uint8_t)((timeout_encoded & 0xFF00) >> 8);
01447         ptiming->mm_config__timeout_macrop_b_lo =
01448                 (uint8_t) (timeout_encoded & 0x00FF);
01449 
01450 
01451         timeout_encoded = VL53L1_calc_encoded_timeout(
01452                             range_config_timeout_us,
01453                             macro_period_us);
01454 
01455         ptiming->range_config__timeout_macrop_b_hi =
01456                 (uint8_t)((timeout_encoded & 0xFF00) >> 8);
01457         ptiming->range_config__timeout_macrop_b_lo =
01458                 (uint8_t) (timeout_encoded & 0x00FF);
01459     }
01460 
01461     LOG_FUNCTION_END(0);
01462 
01463     return status;
01464 
01465 }
01466 
01467 
01468 uint8_t VL53L1_encode_vcsel_period(uint8_t VL53L1_p_031)
01469 {
01470 
01471 
01472     uint8_t vcsel_period_reg = 0;
01473 
01474     vcsel_period_reg = (VL53L1_p_031 >> 1) - 1;
01475 
01476     return vcsel_period_reg;
01477 }
01478 
01479 
01480 uint32_t VL53L1_decode_unsigned_integer(
01481     uint8_t  *pbuffer,
01482     uint8_t   no_of_bytes)
01483 {
01484 
01485 
01486     uint8_t   i = 0;
01487     uint32_t  decoded_value = 0;
01488 
01489     for (i = 0; i < no_of_bytes; i++)
01490         decoded_value = (decoded_value << 8) + (uint32_t)pbuffer[i];
01491 
01492     return decoded_value;
01493 }
01494 
01495 
01496 void VL53L1_encode_unsigned_integer(
01497     uint32_t  ip_value,
01498     uint8_t   no_of_bytes,
01499     uint8_t  *pbuffer)
01500 {
01501 
01502 
01503     uint8_t   i    = 0;
01504     uint32_t  VL53L1_p_002 = 0;
01505 
01506     VL53L1_p_002 = ip_value;
01507     for (i = 0; i < no_of_bytes; i++) {
01508         pbuffer[no_of_bytes-i-1] = VL53L1_p_002 & 0x00FF;
01509         VL53L1_p_002 = VL53L1_p_002 >> 8;
01510     }
01511 }
01512 
01513 
01514 VL53L1_Error  VL53L1_hist_copy_and_scale_ambient_info(
01515     VL53L1_zone_hist_info_t       *pidata,
01516     VL53L1_histogram_bin_data_t   *podata)
01517 {
01518 
01519 
01520     VL53L1_Error status = VL53L1_ERROR_NONE;
01521 
01522     int64_t  evts              = 0;
01523     int64_t  tmpi              = 0;
01524     int64_t  tmpo              = 0;
01525 
01526     LOG_FUNCTION_START("");
01527 
01528 
01529     if (pidata->result__dss_actual_effective_spads == 0) {
01530         status = VL53L1_ERROR_DIVISION_BY_ZERO;
01531     } else {
01532         if (pidata->number_of_ambient_bins >  0 &&
01533             podata->number_of_ambient_bins == 0) {
01534 
01535 
01536 
01537             tmpo    = 1 + (int64_t)podata->total_periods_elapsed;
01538             tmpo   *=
01539             (int64_t)podata->result__dss_actual_effective_spads;
01540 
01541             tmpi    = 1 + (int64_t)pidata->total_periods_elapsed;
01542             tmpi   *=
01543             (int64_t)pidata->result__dss_actual_effective_spads;
01544 
01545             evts  = tmpo *
01546                 (int64_t)pidata->ambient_events_sum;
01547             evts += (tmpi/2);
01548 
01549 
01550             if (tmpi != 0)
01551                 evts = do_division_s(evts, tmpi);
01552 
01553             podata->ambient_events_sum = (int32_t)evts;
01554 
01555 
01556 
01557             podata->VL53L1_p_004 =
01558                     podata->ambient_events_sum;
01559             podata->VL53L1_p_004 +=
01560                 ((int32_t)pidata->number_of_ambient_bins / 2);
01561             podata->VL53L1_p_004 /=
01562                 (int32_t)pidata->number_of_ambient_bins;
01563         }
01564     }
01565 
01566     LOG_FUNCTION_END(0);
01567 
01568     return status;
01569 }
01570 
01571 
01572 void  VL53L1_hist_get_bin_sequence_config(
01573     VL53L1_DEV                     Dev,
01574     VL53L1_histogram_bin_data_t   *pdata)
01575 {
01576 
01577 
01578     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
01579 
01580     int32_t amb_thresh_low   = 0;
01581     int32_t amb_thresh_high  = 0;
01582 
01583     uint8_t i = 0;
01584 
01585     LOG_FUNCTION_START("");
01586 
01587 
01588 
01589     amb_thresh_low  = 1024 *
01590         (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_low;
01591     amb_thresh_high = 1024 *
01592         (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_high;
01593 
01594 
01595 
01596     if ((pdev->ll_state.rd_stream_count & 0x01) == 0) {
01597 
01598         pdata->bin_seq[5] =
01599         pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 >> 4;
01600         pdata->bin_seq[4] =
01601         pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 & 0x0F;
01602         pdata->bin_seq[3] =
01603         pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 >> 4;
01604         pdata->bin_seq[2] =
01605         pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 & 0x0F;
01606         pdata->bin_seq[1] =
01607         pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 >> 4;
01608         pdata->bin_seq[0] =
01609         pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 & 0x0F;
01610 
01611         if (pdata->ambient_events_sum > amb_thresh_high) {
01612             pdata->bin_seq[5] =
01613             pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5
01614             >> 4;
01615             pdata->bin_seq[4] =
01616             pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5
01617             & 0x0F;
01618             pdata->bin_seq[3] =
01619             pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3
01620             >> 4;
01621             pdata->bin_seq[2] =
01622             pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3
01623             & 0x0F;
01624             pdata->bin_seq[1] =
01625             pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1
01626             >> 4;
01627             pdata->bin_seq[0] =
01628             pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1
01629             & 0x0F;
01630         }
01631 
01632         if (pdata->ambient_events_sum < amb_thresh_low) {
01633             pdata->bin_seq[5] =
01634             pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5
01635             >> 4;
01636             pdata->bin_seq[4] =
01637             pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5
01638             & 0x0F;
01639             pdata->bin_seq[3] =
01640             pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3
01641             >> 4;
01642             pdata->bin_seq[2] =
01643             pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3
01644             & 0x0F;
01645             pdata->bin_seq[1] =
01646             pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1
01647             >> 4;
01648             pdata->bin_seq[0] =
01649             pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1
01650             & 0x0F;
01651         }
01652 
01653     } else {
01654         pdata->bin_seq[5] =
01655             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_5
01656             & 0x0F;
01657         pdata->bin_seq[4] =
01658             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4
01659             & 0x0F;
01660         pdata->bin_seq[3] =
01661             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4
01662             >> 4;
01663         pdata->bin_seq[2] =
01664             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_2 &
01665             0x0F;
01666         pdata->bin_seq[1] =
01667             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1
01668             >> 4;
01669         pdata->bin_seq[0] =
01670             pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1
01671             & 0x0F;
01672 
01673         if (pdata->ambient_events_sum > amb_thresh_high) {
01674             pdata->bin_seq[5] =
01675             pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5
01676             >> 4;
01677             pdata->bin_seq[4] =
01678             pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5
01679             & 0x0F;
01680             pdata->bin_seq[3] =
01681             pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3
01682             >> 4;
01683             pdata->bin_seq[2] =
01684             pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3
01685             & 0x0F;
01686             pdata->bin_seq[1] =
01687             pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1
01688             >> 4;
01689             pdata->bin_seq[0] =
01690             pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1
01691             & 0x0F;
01692         }
01693 
01694         if (pdata->ambient_events_sum < amb_thresh_low) {
01695             pdata->bin_seq[5] =
01696             pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5
01697             >> 4;
01698             pdata->bin_seq[4] =
01699             pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5
01700             & 0x0F;
01701             pdata->bin_seq[3] =
01702             pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3
01703             >> 4;
01704             pdata->bin_seq[2] =
01705             pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3
01706             & 0x0F;
01707             pdata->bin_seq[1] =
01708             pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1
01709             >> 4;
01710             pdata->bin_seq[0] =
01711             pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1
01712             & 0x0F;
01713         }
01714     }
01715 
01716 
01717 
01718     for (i = 0; i < VL53L1_MAX_BIN_SEQUENCE_LENGTH; i++)
01719         pdata->bin_rep[i] = 1;
01720 
01721     LOG_FUNCTION_END(0);
01722 
01723 }
01724 
01725 
01726 VL53L1_Error  VL53L1_hist_phase_consistency_check(
01727     VL53L1_DEV                   Dev,
01728     VL53L1_zone_hist_info_t     *phist_prev,
01729     VL53L1_zone_objects_t       *prange_prev,
01730     VL53L1_range_results_t      *prange_curr)
01731 {
01732 
01733 
01734 
01735     VL53L1_Error  status = VL53L1_ERROR_NONE;
01736     VL53L1_LLDriverData_t *pdev =
01737         VL53L1DevStructGetLLDriverHandle(Dev);
01738 
01739     uint8_t   lc = 0;
01740     uint8_t   p = 0;
01741 
01742     uint16_t  phase_delta      = 0;
01743     uint16_t  phase_tolerance  = 0;
01744 
01745     int32_t   events_delta     = 0;
01746     int32_t   events_tolerance = 0;
01747 
01748 
01749     uint8_t event_sigma;
01750     uint16_t event_min_spad_count;
01751     uint16_t min_max_tolerance;
01752     uint8_t pht;
01753 
01754     VL53L1_DeviceError  range_status = 0;
01755 
01756     LOG_FUNCTION_START("");
01757 
01758     event_sigma =
01759         pdev->histpostprocess.algo__consistency_check__event_sigma;
01760     event_min_spad_count =
01761     pdev->histpostprocess.algo__consistency_check__event_min_spad_count;
01762     min_max_tolerance =
01763     pdev->histpostprocess.algo__consistency_check__min_max_tolerance;
01764 
01765 
01766     pht = pdev->histpostprocess.algo__consistency_check__phase_tolerance;
01767     phase_tolerance = (uint16_t)pht;
01768     phase_tolerance = phase_tolerance << 8;
01769 
01770 
01771 
01772     if (prange_prev->rd_device_state !=
01773             VL53L1_DEVICESTATE_RANGING_GATHER_DATA &&
01774         prange_prev->rd_device_state !=
01775                 VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA)
01776         return status;
01777 
01778 
01779 
01780     if (phase_tolerance == 0)
01781         return status;
01782 
01783     for (lc = 0; lc < prange_curr->active_results; lc++) {
01784 
01785         if (!((prange_curr->VL53L1_p_002[lc].range_status ==
01786             VL53L1_DEVICEERROR_RANGECOMPLETE) ||
01787             (prange_curr->VL53L1_p_002[lc].range_status ==
01788             VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK)))
01789             continue;
01790 
01791 
01792 
01793 
01794 
01795 
01796         if (prange_prev->active_objects == 0)
01797             prange_curr->VL53L1_p_002[lc].range_status =
01798             VL53L1_DEVICEERROR_PREV_RANGE_NO_TARGETS;
01799         else
01800             prange_curr->VL53L1_p_002[lc].range_status =
01801                 VL53L1_DEVICEERROR_PHASECONSISTENCY;
01802 
01803 
01804 
01805 
01806 
01807         for (p = 0; p < prange_prev->active_objects; p++) {
01808 
01809             if (prange_curr->VL53L1_p_002[lc].VL53L1_p_014 >
01810                 prange_prev->VL53L1_p_002[p].VL53L1_p_014) {
01811                 phase_delta =
01812                 prange_curr->VL53L1_p_002[lc].VL53L1_p_014 -
01813                 prange_prev->VL53L1_p_002[p].VL53L1_p_014;
01814             } else {
01815                 phase_delta =
01816                 prange_prev->VL53L1_p_002[p].VL53L1_p_014 -
01817                 prange_curr->VL53L1_p_002[lc].VL53L1_p_014;
01818             }
01819 
01820             if (phase_delta < phase_tolerance) {
01821 
01822 
01823 
01824 
01825 
01826                 if (status == VL53L1_ERROR_NONE)
01827                     status =
01828                     VL53L1_hist_events_consistency_check(
01829                     event_sigma,
01830                     event_min_spad_count,
01831                     phist_prev,
01832                     &(prange_prev->VL53L1_p_002[p]),
01833                     &(prange_curr->VL53L1_p_002[lc]),
01834                     &events_tolerance,
01835                     &events_delta,
01836                     &range_status);
01837 
01838 
01839 
01840 
01841                 if (status == VL53L1_ERROR_NONE &&
01842                     range_status ==
01843                     VL53L1_DEVICEERROR_RANGECOMPLETE)
01844                     status =
01845                     VL53L1_hist_merged_pulse_check(
01846                     min_max_tolerance,
01847                     &(prange_curr->VL53L1_p_002[lc]),
01848                     &range_status);
01849 
01850                 prange_curr->VL53L1_p_002[lc].range_status =
01851                         range_status;
01852             }
01853         }
01854 
01855     }
01856 
01857     LOG_FUNCTION_END(status);
01858 
01859     return status;
01860 }
01861 
01862 
01863 
01864 VL53L1_Error  VL53L1_hist_events_consistency_check(
01865     uint8_t                      event_sigma,
01866     uint16_t                     min_effective_spad_count,
01867     VL53L1_zone_hist_info_t     *phist_prev,
01868     VL53L1_object_data_t        *prange_prev,
01869     VL53L1_range_data_t         *prange_curr,
01870     int32_t                     *pevents_tolerance,
01871     int32_t                     *pevents_delta,
01872     VL53L1_DeviceError          *prange_status)
01873 {
01874 
01875 
01876 
01877     VL53L1_Error  status = VL53L1_ERROR_NONE;
01878 
01879     int64_t   tmpp                   = 0;
01880     int64_t   tmpc                   = 0;
01881     int64_t   events_scaler          = 0;
01882     int64_t   events_scaler_sq       = 0;
01883     int64_t   c_signal_events        = 0;
01884     int64_t   c_sig_noise_sq         = 0;
01885     int64_t   c_amb_noise_sq         = 0;
01886     int64_t   p_amb_noise_sq         = 0;
01887 
01888     int32_t   p_signal_events        = 0;
01889     uint32_t  noise_sq_sum           = 0;
01890 
01891 
01892 
01893     if (event_sigma == 0) {
01894         *prange_status = VL53L1_DEVICEERROR_RANGECOMPLETE;
01895         return status;
01896     }
01897 
01898 
01899 
01900     tmpp  = 1 + (int64_t)phist_prev->total_periods_elapsed;
01901     tmpp *= (int64_t)phist_prev->result__dss_actual_effective_spads;
01902 
01903 
01904 
01905     tmpc  = 1 + (int64_t)prange_curr->total_periods_elapsed;
01906     tmpc *= (int64_t)prange_curr->VL53L1_p_006;
01907 
01908 
01909 
01910     events_scaler  = tmpp * 4096;
01911     events_scaler += (tmpc/2);
01912     if (tmpc != 0)
01913         events_scaler = do_division_s(events_scaler, tmpc);
01914 
01915     events_scaler_sq  = events_scaler * events_scaler;
01916     events_scaler_sq += 2048;
01917     events_scaler_sq /= 4096;
01918 
01919 
01920 
01921     c_signal_events  = (int64_t)prange_curr->VL53L1_p_021;
01922     c_signal_events -= (int64_t)prange_curr->VL53L1_p_020;
01923     c_signal_events *= (int64_t)events_scaler;
01924     c_signal_events += 2048;
01925     c_signal_events /= 4096;
01926 
01927     c_sig_noise_sq  = (int64_t)events_scaler_sq;
01928     c_sig_noise_sq *= (int64_t)prange_curr->VL53L1_p_021;
01929     c_sig_noise_sq += 2048;
01930     c_sig_noise_sq /= 4096;
01931 
01932     c_amb_noise_sq  = (int64_t)events_scaler_sq;
01933     c_amb_noise_sq *= (int64_t)prange_curr->VL53L1_p_020;
01934     c_amb_noise_sq += 2048;
01935     c_amb_noise_sq /= 4096;
01936 
01937 
01938     c_amb_noise_sq += 2;
01939     c_amb_noise_sq /= 4;
01940 
01941 
01942 
01943     p_amb_noise_sq  =
01944         (int64_t)prange_prev->VL53L1_p_020;
01945 
01946 
01947     p_amb_noise_sq += 2;
01948     p_amb_noise_sq /= 4;
01949 
01950     noise_sq_sum =
01951         (uint32_t)prange_prev->VL53L1_p_021 +
01952         (uint32_t)c_sig_noise_sq +
01953         (uint32_t)p_amb_noise_sq +
01954         (uint32_t)c_amb_noise_sq;
01955 
01956     *pevents_tolerance =
01957         (int32_t)VL53L1_isqrt(noise_sq_sum * 16);
01958 
01959     *pevents_tolerance *= (int32_t)event_sigma;
01960     *pevents_tolerance += 32;
01961     *pevents_tolerance /= 64;
01962 
01963     p_signal_events  = (int32_t)prange_prev->VL53L1_p_021;
01964     p_signal_events -= (int32_t)prange_prev->VL53L1_p_020;
01965 
01966     if ((int32_t)c_signal_events > p_signal_events)
01967         *pevents_delta =
01968             (int32_t)c_signal_events - p_signal_events;
01969     else
01970         *pevents_delta =
01971             p_signal_events - (int32_t)c_signal_events;
01972 
01973     if (*pevents_delta > *pevents_tolerance &&
01974         prange_curr->VL53L1_p_006 > min_effective_spad_count)
01975         *prange_status = VL53L1_DEVICEERROR_EVENTCONSISTENCY;
01976     else
01977         *prange_status = VL53L1_DEVICEERROR_RANGECOMPLETE;
01978 
01979 
01980 
01981 
01982 
01983     return status;
01984 }
01985 
01986 
01987 
01988 
01989 VL53L1_Error  VL53L1_hist_merged_pulse_check(
01990     int16_t                      min_max_tolerance_mm,
01991     VL53L1_range_data_t         *pdata,
01992     VL53L1_DeviceError          *prange_status)
01993 {
01994 
01995 
01996     VL53L1_Error  status   = VL53L1_ERROR_NONE;
01997     int16_t       delta_mm = 0;
01998 
01999     if (pdata->max_range_mm > pdata->min_range_mm)
02000         delta_mm =
02001             pdata->max_range_mm - pdata->min_range_mm;
02002     else
02003         delta_mm =
02004             pdata->min_range_mm - pdata->max_range_mm;
02005 
02006     if (min_max_tolerance_mm > 0 &&
02007         delta_mm > min_max_tolerance_mm)
02008         *prange_status = VL53L1_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE;
02009     else
02010         *prange_status = VL53L1_DEVICEERROR_RANGECOMPLETE;
02011 
02012     return status;
02013 }
02014 
02015 
02016 
02017 
02018 VL53L1_Error  VL53L1_hist_xmonitor_consistency_check(
02019     VL53L1_DEV                   Dev,
02020     VL53L1_zone_hist_info_t     *phist_prev,
02021     VL53L1_zone_objects_t       *prange_prev,
02022     VL53L1_range_data_t         *prange_curr)
02023 {
02024 
02025 
02026     VL53L1_Error  status = VL53L1_ERROR_NONE;
02027     VL53L1_LLDriverData_t *pdev =
02028         VL53L1DevStructGetLLDriverHandle(Dev);
02029 
02030     int32_t   events_delta     = 0;
02031     int32_t   events_tolerance = 0;
02032     uint8_t event_sigma;
02033     uint16_t min_spad_count;
02034 
02035     event_sigma = pdev->histpostprocess.algo__crosstalk_detect_event_sigma;
02036     min_spad_count =
02037     pdev->histpostprocess.algo__consistency_check__event_min_spad_count;
02038 
02039     if (prange_curr->range_status == VL53L1_DEVICEERROR_RANGECOMPLETE ||
02040         prange_curr->range_status ==
02041             VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK ||
02042         prange_curr->range_status ==
02043                 VL53L1_DEVICEERROR_EVENTCONSISTENCY) {
02044 
02045         if (prange_prev->xmonitor.range_status ==
02046                 VL53L1_DEVICEERROR_RANGECOMPLETE ||
02047             prange_prev->xmonitor.range_status ==
02048             VL53L1_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK ||
02049             prange_prev->xmonitor.range_status ==
02050                 VL53L1_DEVICEERROR_EVENTCONSISTENCY) {
02051 
02052             prange_curr->range_status =
02053                     VL53L1_DEVICEERROR_RANGECOMPLETE;
02054 
02055             status =
02056                 VL53L1_hist_events_consistency_check(
02057                     event_sigma,
02058                     min_spad_count,
02059                     phist_prev,
02060                     &(prange_prev->xmonitor),
02061                     prange_curr,
02062                     &events_tolerance,
02063                     &events_delta,
02064                     &(prange_curr->range_status));
02065 
02066         }
02067     }
02068 
02069     return status;
02070 }
02071 
02072 
02073 
02074 
02075 VL53L1_Error  VL53L1_hist_wrap_dmax(
02076     VL53L1_hist_post_process_config_t  *phistpostprocess,
02077     VL53L1_histogram_bin_data_t        *pcurrent,
02078     int16_t                            *pwrap_dmax_mm)
02079 {
02080 
02081 
02082 
02083     VL53L1_Error  status = VL53L1_ERROR_NONE;
02084 
02085     uint32_t  pll_period_mm        = 0;
02086     uint32_t  wrap_dmax_phase      = 0;
02087     uint32_t  range_mm             = 0;
02088 
02089     LOG_FUNCTION_START("");
02090 
02091     *pwrap_dmax_mm = 0;
02092 
02093 
02094     if (pcurrent->VL53L1_p_019 != 0) {
02095 
02096 
02097 
02098         pll_period_mm =
02099             VL53L1_calc_pll_period_mm(
02100                 pcurrent->VL53L1_p_019);
02101 
02102 
02103 
02104         wrap_dmax_phase =
02105             (uint32_t)phistpostprocess->valid_phase_high << 8;
02106 
02107 
02108 
02109         range_mm = wrap_dmax_phase * pll_period_mm;
02110         range_mm = (range_mm + (1<<14)) >> 15;
02111 
02112         *pwrap_dmax_mm = (int16_t)range_mm;
02113     }
02114 
02115     LOG_FUNCTION_END(status);
02116 
02117     return status;
02118 }
02119 
02120 
02121 void VL53L1_hist_combine_mm1_mm2_offsets(
02122     int16_t                               mm1_offset_mm,
02123     int16_t                               mm2_offset_mm,
02124     uint8_t                               encoded_mm_roi_centre,
02125     uint8_t                               encoded_mm_roi_size,
02126     uint8_t                               encoded_zone_centre,
02127     uint8_t                               encoded_zone_size,
02128     VL53L1_additional_offset_cal_data_t  *pcal_data,
02129     uint8_t                              *pgood_spads,
02130     uint16_t                              aperture_attenuation,
02131     int16_t                               *prange_offset_mm)
02132 {
02133 
02134 
02135 
02136     uint16_t max_mm_inner_effective_spads = 0;
02137     uint16_t max_mm_outer_effective_spads = 0;
02138     uint16_t mm_inner_effective_spads     = 0;
02139     uint16_t mm_outer_effective_spads     = 0;
02140 
02141     uint32_t scaled_mm1_peak_rate_mcps    = 0;
02142     uint32_t scaled_mm2_peak_rate_mcps    = 0;
02143 
02144     int32_t tmp0 = 0;
02145     int32_t tmp1 = 0;
02146 
02147 
02148 
02149     VL53L1_calc_mm_effective_spads(
02150         encoded_mm_roi_centre,
02151         encoded_mm_roi_size,
02152         0xC7,
02153         0xFF,
02154         pgood_spads,
02155         aperture_attenuation,
02156         &max_mm_inner_effective_spads,
02157         &max_mm_outer_effective_spads);
02158 
02159     if ((max_mm_inner_effective_spads == 0) ||
02160         (max_mm_outer_effective_spads == 0))
02161         goto FAIL;
02162 
02163 
02164 
02165     VL53L1_calc_mm_effective_spads(
02166         encoded_mm_roi_centre,
02167         encoded_mm_roi_size,
02168         encoded_zone_centre,
02169         encoded_zone_size,
02170         pgood_spads,
02171         aperture_attenuation,
02172         &mm_inner_effective_spads,
02173         &mm_outer_effective_spads);
02174 
02175 
02176 
02177     scaled_mm1_peak_rate_mcps  =
02178     (uint32_t)pcal_data->result__mm_inner_peak_signal_count_rtn_mcps;
02179     scaled_mm1_peak_rate_mcps *= (uint32_t)mm_inner_effective_spads;
02180     scaled_mm1_peak_rate_mcps /= (uint32_t)max_mm_inner_effective_spads;
02181 
02182     scaled_mm2_peak_rate_mcps  =
02183     (uint32_t)pcal_data->result__mm_outer_peak_signal_count_rtn_mcps;
02184     scaled_mm2_peak_rate_mcps *= (uint32_t)mm_outer_effective_spads;
02185     scaled_mm2_peak_rate_mcps /= (uint32_t)max_mm_outer_effective_spads;
02186 
02187 
02188 
02189     tmp0  = ((int32_t)mm1_offset_mm * (int32_t)scaled_mm1_peak_rate_mcps);
02190     tmp0 += ((int32_t)mm2_offset_mm * (int32_t)scaled_mm2_peak_rate_mcps);
02191 
02192     tmp1 =  (int32_t)scaled_mm1_peak_rate_mcps +
02193             (int32_t)scaled_mm2_peak_rate_mcps;
02194 
02195 
02196 
02197     if (tmp1 != 0)
02198         tmp0 = (tmp0 * 4) / tmp1;
02199 FAIL:
02200     *prange_offset_mm = (int16_t)tmp0;
02201 
02202 }
02203 
02204 
02205 VL53L1_Error VL53L1_hist_xtalk_extract_calc_window(
02206     int16_t                             target_distance_mm,
02207     uint16_t                            target_width_oversize,
02208     VL53L1_histogram_bin_data_t        *phist_bins,
02209     VL53L1_hist_xtalk_extract_data_t   *pxtalk_data)
02210 {
02211 
02212 
02213     VL53L1_Error  status = VL53L1_ERROR_NONE;
02214 
02215     LOG_FUNCTION_START("");
02216 
02217 
02218     pxtalk_data->pll_period_mm =
02219         VL53L1_calc_pll_period_mm(phist_bins->VL53L1_p_019);
02220 
02221 
02222     pxtalk_data->xtalk_width_phase =
02223         (int32_t)phist_bins->vcsel_width * 128;
02224     pxtalk_data->target_width_phase =
02225         pxtalk_data->xtalk_width_phase +
02226         (int32_t)target_width_oversize * 128;
02227 
02228 
02229 
02230     pxtalk_data->xtalk_start_phase =
02231         (int32_t)phist_bins->zero_distance_phase -
02232         (pxtalk_data->xtalk_width_phase / 2);
02233     pxtalk_data->xtalk_end_phase  =
02234         (int32_t)pxtalk_data->xtalk_start_phase +
02235         pxtalk_data->xtalk_width_phase;
02236 
02237     if (pxtalk_data->xtalk_start_phase < 0)
02238         pxtalk_data->xtalk_start_phase = 0;
02239 
02240 
02241 
02242 
02243     pxtalk_data->VL53L1_p_015 =
02244         (uint8_t)(pxtalk_data->xtalk_start_phase / 2048);
02245 
02246 
02247     pxtalk_data->VL53L1_p_016 =
02248         (uint8_t)((pxtalk_data->xtalk_end_phase + 2047) / 2048);
02249 
02250 
02251 
02252     pxtalk_data->target_start_phase  =
02253             (int32_t)target_distance_mm * 2048 * 16;
02254     pxtalk_data->target_start_phase +=
02255             ((int32_t)pxtalk_data->pll_period_mm / 2);
02256     pxtalk_data->target_start_phase /= (int32_t)pxtalk_data->pll_period_mm;
02257     pxtalk_data->target_start_phase +=
02258             (int32_t)phist_bins->zero_distance_phase;
02259 
02260 
02261 
02262     pxtalk_data->target_start_phase -=
02263             (pxtalk_data->target_width_phase / 2);
02264     pxtalk_data->target_end_phase  =
02265         (int32_t)pxtalk_data->target_start_phase +
02266         pxtalk_data->target_width_phase;
02267 
02268     if (pxtalk_data->target_start_phase < 0)
02269         pxtalk_data->target_start_phase = 0;
02270 
02271 
02272     pxtalk_data->target_start =
02273         (uint8_t)(pxtalk_data->target_start_phase / 2048);
02274 
02275 
02276     if (pxtalk_data->VL53L1_p_016 > (pxtalk_data->target_start-1))
02277         pxtalk_data->VL53L1_p_016 = pxtalk_data->target_start-1;
02278 
02279 
02280     pxtalk_data->effective_width =
02281             (2048 * ((int32_t)pxtalk_data->VL53L1_p_016+1));
02282     pxtalk_data->effective_width -= pxtalk_data->xtalk_start_phase;
02283 
02284 
02285     if (pxtalk_data->effective_width > pxtalk_data->xtalk_width_phase)
02286         pxtalk_data->effective_width = pxtalk_data->xtalk_width_phase;
02287 
02288     if (pxtalk_data->effective_width < 1)
02289         pxtalk_data->effective_width = 1;
02290 
02291 
02292     pxtalk_data->event_scaler  =  pxtalk_data->xtalk_width_phase * 1000;
02293     pxtalk_data->event_scaler +=  (pxtalk_data->effective_width / 2);
02294     pxtalk_data->event_scaler /=  pxtalk_data->effective_width;
02295 
02296 
02297     if (pxtalk_data->event_scaler < 1000)
02298         pxtalk_data->event_scaler = 1000;
02299 
02300     if (pxtalk_data->event_scaler > 4000)
02301         pxtalk_data->event_scaler = 4000;
02302 
02303 
02304     pxtalk_data->event_scaler_sum += pxtalk_data->event_scaler;
02305 
02306 
02307     pxtalk_data->peak_duration_us_sum +=
02308         (uint32_t)phist_bins->peak_duration_us;
02309 
02310 
02311     pxtalk_data->effective_spad_count_sum +=
02312         (uint32_t)phist_bins->result__dss_actual_effective_spads;
02313 
02314 
02315     pxtalk_data->zero_distance_phase_sum +=
02316         (uint32_t)phist_bins->zero_distance_phase;
02317 
02318     LOG_FUNCTION_END(status);
02319 
02320     return status;
02321 }
02322 
02323 
02324 VL53L1_Error VL53L1_hist_xtalk_extract_calc_event_sums(
02325     VL53L1_histogram_bin_data_t        *phist_bins,
02326     VL53L1_hist_xtalk_extract_data_t   *pxtalk_data)
02327 {
02328 
02329 
02330 
02331     VL53L1_Error  status = VL53L1_ERROR_NONE;
02332 
02333     uint8_t   lb = 0;
02334     uint8_t   i = 0;
02335 
02336     LOG_FUNCTION_START("");
02337 
02338 
02339 
02340     for (lb  = pxtalk_data->VL53L1_p_015;
02341          lb <= pxtalk_data->VL53L1_p_016;
02342          lb++) {
02343 
02344 
02345         i = (lb + phist_bins->number_of_ambient_bins +
02346             phist_bins->VL53L1_p_024) %
02347                     phist_bins->VL53L1_p_024;
02348 
02349 
02350         pxtalk_data->signal_events_sum += phist_bins->bin_data[i];
02351         pxtalk_data->signal_events_sum -=
02352                 phist_bins->VL53L1_p_004;
02353     }
02354 
02355 
02356 
02357     for (lb  = 0; lb < VL53L1_XTALK_HISTO_BINS  &&
02358             lb < phist_bins->VL53L1_p_024; lb++) {
02359 
02360 
02361         i = (lb + phist_bins->number_of_ambient_bins +
02362             phist_bins->VL53L1_p_024) %
02363                     phist_bins->VL53L1_p_024;
02364 
02365 
02366         pxtalk_data->bin_data_sums[lb] += phist_bins->bin_data[i];
02367         pxtalk_data->bin_data_sums[lb] -=
02368                 phist_bins->VL53L1_p_004;
02369     }
02370 
02371     pxtalk_data->sample_count += 1;
02372 
02373     LOG_FUNCTION_END(status);
02374 
02375     return status;
02376 }
02377 
02378 
02379 VL53L1_Error VL53L1_hist_xtalk_extract_calc_rate_per_spad(
02380     VL53L1_hist_xtalk_extract_data_t   *pxtalk_data)
02381 {
02382 
02383 
02384 
02385     VL53L1_Error  status = VL53L1_ERROR_NONE;
02386 
02387     uint64_t tmp64_0        = 0;
02388     uint64_t tmp64_1        = 0;
02389     uint64_t xtalk_per_spad = 0;
02390 
02391     LOG_FUNCTION_START("");
02392 
02393 
02394 
02395 
02396 
02397 
02398     if (pxtalk_data->signal_events_sum > 0) {
02399         tmp64_0 =
02400             ((uint64_t)pxtalk_data->signal_events_sum *
02401              (uint64_t)pxtalk_data->sample_count *
02402              (uint64_t)pxtalk_data->event_scaler_avg * 256U) << 9U;
02403         tmp64_1 =
02404             (uint64_t)pxtalk_data->effective_spad_count_sum *
02405             (uint64_t)pxtalk_data->peak_duration_us_sum;
02406 
02407 
02408 
02409         if (tmp64_1 > 0U) {
02410 
02411             tmp64_0 = tmp64_0 + (tmp64_1 >> 1U);
02412             xtalk_per_spad = do_division_u(tmp64_0, tmp64_1);
02413         } else {
02414             xtalk_per_spad = (uint64_t)tmp64_0;
02415         }
02416 
02417     } else {
02418         status = VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
02419     }
02420 
02421     pxtalk_data->xtalk_rate_kcps_per_spad = (uint32_t)xtalk_per_spad;
02422 
02423     LOG_FUNCTION_END(status);
02424 
02425     return status;
02426 }
02427 
02428 
02429 VL53L1_Error VL53L1_hist_xtalk_extract_calc_shape(
02430     VL53L1_hist_xtalk_extract_data_t  *pxtalk_data,
02431     VL53L1_xtalk_histogram_shape_t    *pxtalk_shape)
02432 {
02433 
02434 
02435     VL53L1_Error  status = VL53L1_ERROR_NONE;
02436 
02437     int32_t  lb = 0;
02438     uint64_t total_events    = 0U;
02439     uint64_t tmp64_0         = 0U;
02440     int32_t  remaining_area  = 1024;
02441 
02442     LOG_FUNCTION_START("");
02443 
02444 
02445 
02446     pxtalk_shape->VL53L1_p_022      = 0;
02447     pxtalk_shape->VL53L1_p_023    = VL53L1_XTALK_HISTO_BINS;
02448     pxtalk_shape->VL53L1_p_024 = VL53L1_XTALK_HISTO_BINS;
02449 
02450     pxtalk_shape->zero_distance_phase =
02451         (uint16_t)pxtalk_data->zero_distance_phase_avg;
02452     pxtalk_shape->phasecal_result__reference_phase =
02453         (uint16_t)pxtalk_data->zero_distance_phase_avg + (3*2048);
02454 
02455 
02456 
02457     if (pxtalk_data->signal_events_sum > 0)
02458         total_events =
02459             (uint64_t)pxtalk_data->signal_events_sum *
02460             (uint64_t)pxtalk_data->event_scaler_avg;
02461     else
02462         total_events = 1;
02463     if (total_events == 0)
02464         total_events = 1;
02465 
02466 
02467     remaining_area  = 1024;
02468     pxtalk_data->max_shape_value = 0;
02469 
02470     for (lb = 0; lb < VL53L1_XTALK_HISTO_BINS; lb++) {
02471 
02472         if ((lb < (int32_t)pxtalk_data->VL53L1_p_015 ||
02473              lb > (int32_t)pxtalk_data->VL53L1_p_016)  ||
02474                 pxtalk_data->bin_data_sums[lb] < 0) {
02475 
02476 
02477             if (remaining_area > 0 && remaining_area < 1024) {
02478                 if (remaining_area >
02479                     pxtalk_data->max_shape_value) {
02480                     pxtalk_shape->bin_data[lb] =
02481                     (uint32_t)pxtalk_data->max_shape_value;
02482                     remaining_area -=
02483                         pxtalk_data->max_shape_value;
02484                 } else {
02485                     pxtalk_shape->bin_data[lb] =
02486                         (uint32_t)remaining_area;
02487                     remaining_area = 0;
02488                 }
02489             } else {
02490                 pxtalk_shape->bin_data[lb] = 0;
02491             }
02492 
02493         } else {
02494 
02495             tmp64_0 =
02496                 (uint64_t)pxtalk_data->bin_data_sums[lb]
02497                             * 1024U * 1000U;
02498             tmp64_0 += (total_events >> 1);
02499             tmp64_0 = do_division_u(tmp64_0, total_events);
02500             if (tmp64_0 > 0xFFFFU)
02501                 tmp64_0 = 0xFFFFU;
02502 
02503             pxtalk_shape->bin_data[lb] = (uint32_t)tmp64_0;
02504 
02505 
02506             if ((int32_t)pxtalk_shape->bin_data[lb] >
02507                 pxtalk_data->max_shape_value)
02508                 pxtalk_data->max_shape_value =
02509                     (int32_t)pxtalk_shape->bin_data[lb];
02510 
02511             remaining_area -= (int32_t)pxtalk_shape->bin_data[lb];
02512         }
02513     }
02514 
02515     LOG_FUNCTION_END(status);
02516 
02517     return status;
02518 }
02519 
02520 
02521 VL53L1_Error VL53L1_hist_xtalk_shape_model(
02522     uint16_t                         events_per_bin,
02523     uint16_t                         pulse_centre,
02524     uint16_t                         pulse_width,
02525     VL53L1_xtalk_histogram_shape_t  *pxtalk_shape)
02526 {
02527 
02528 
02529     VL53L1_Error  status = VL53L1_ERROR_NONE;
02530 
02531     uint32_t phase_start  = 0;
02532     uint32_t phase_stop   = 0;
02533     uint32_t phase_bin    = 0;
02534 
02535     uint32_t bin_start    = 0;
02536     uint32_t bin_stop     = 0;
02537 
02538     uint32_t  lb           = 0;
02539     uint16_t  VL53L1_p_008      = 0;
02540 
02541     LOG_FUNCTION_START("");
02542 
02543 
02544 
02545     pxtalk_shape->VL53L1_p_022      = 0;
02546     pxtalk_shape->VL53L1_p_023    = VL53L1_XTALK_HISTO_BINS;
02547     pxtalk_shape->VL53L1_p_024 = VL53L1_XTALK_HISTO_BINS;
02548 
02549     pxtalk_shape->zero_distance_phase              = pulse_centre;
02550     pxtalk_shape->phasecal_result__reference_phase =
02551             pulse_centre + (3*2048);
02552 
02553 
02554     if (pulse_centre > (pulse_width >> 1))
02555         phase_start = (uint32_t)pulse_centre -
02556             ((uint32_t)pulse_width >> 1);
02557     else
02558         phase_start = 0;
02559 
02560     phase_stop = (uint32_t)pulse_centre  +
02561             ((uint32_t)pulse_width >> 1);
02562 
02563 
02564     bin_start = (phase_start / 2048);
02565     bin_stop  = (phase_stop  / 2048);
02566 
02567     for (lb = 0; lb < VL53L1_XTALK_HISTO_BINS; lb++) {
02568         VL53L1_p_008 = 0;
02569 
02570 
02571         if (lb == bin_start && lb == bin_stop) {
02572             VL53L1_p_008 =
02573             VL53L1_hist_xtalk_shape_model_interp(
02574                 events_per_bin,
02575                 phase_stop - phase_start);
02576 
02577         } else if (lb > bin_start && lb < bin_stop) {
02578 
02579 
02580             VL53L1_p_008 = events_per_bin;
02581 
02582         } else if (lb == bin_start) {
02583 
02584 
02585             phase_bin = (lb + 1) * 2048;
02586             VL53L1_p_008 =
02587             VL53L1_hist_xtalk_shape_model_interp(
02588                 events_per_bin,
02589                 (phase_bin - phase_start));
02590 
02591         } else if (lb == bin_stop) {
02592 
02593 
02594             phase_bin = lb * 2048;
02595             VL53L1_p_008 =
02596             VL53L1_hist_xtalk_shape_model_interp(
02597                 events_per_bin,
02598                 (phase_stop - phase_bin));
02599         }
02600 
02601         pxtalk_shape->bin_data[lb] = VL53L1_p_008;
02602     }
02603 
02604     LOG_FUNCTION_END(status);
02605 
02606     return status;
02607 }
02608 
02609 
02610 uint16_t VL53L1_hist_xtalk_shape_model_interp(
02611     uint16_t      events_per_bin,
02612     uint32_t      phase_delta)
02613 {
02614 
02615 
02616     uint32_t  VL53L1_p_008  = 0;
02617 
02618     LOG_FUNCTION_START("");
02619 
02620 
02621     VL53L1_p_008  = (uint32_t)events_per_bin * phase_delta;
02622     VL53L1_p_008 +=  1024;
02623     VL53L1_p_008 /=  2048;
02624 
02625 
02626     if (VL53L1_p_008 > 0xFFFFU)
02627         VL53L1_p_008 = 0xFFFFU;
02628 
02629     LOG_FUNCTION_END(0);
02630 
02631     return (uint16_t)VL53L1_p_008;
02632 }
02633 
02634 
02635 void VL53L1_spad_number_to_byte_bit_index(
02636     uint8_t  spad_number,
02637     uint8_t *pbyte_index,
02638     uint8_t *pbit_index,
02639     uint8_t *pbit_mask)
02640 {
02641 
02642 
02643 
02644     *pbyte_index  = spad_number >> 3;
02645     *pbit_index   = spad_number & 0x07;
02646     *pbit_mask    = 0x01 << *pbit_index;
02647 
02648 }
02649 
02650 
02651 void VL53L1_encode_row_col(
02652     uint8_t  row,
02653     uint8_t  col,
02654     uint8_t *pspad_number)
02655 {
02656 
02657 
02658     if (row > 7)
02659         *pspad_number = 128 + (col << 3) + (15-row);
02660     else
02661         *pspad_number = ((15-col) << 3) + row;
02662 
02663 }
02664 
02665 
02666 void VL53L1_decode_zone_size(
02667     uint8_t  encoded_xy_size,
02668     uint8_t  *pwidth,
02669     uint8_t  *pheight)
02670 {
02671 
02672 
02673 
02674     *pheight = encoded_xy_size >> 4;
02675     *pwidth  = encoded_xy_size & 0x0F;
02676 
02677 }
02678 
02679 
02680 void VL53L1_encode_zone_size(
02681     uint8_t  width,
02682     uint8_t  height,
02683     uint8_t *pencoded_xy_size)
02684 {
02685 
02686 
02687     *pencoded_xy_size = (height << 4) + width;
02688 
02689 }
02690 
02691 
02692 void VL53L1_decode_zone_limits(
02693     uint8_t   encoded_xy_centre,
02694     uint8_t   encoded_xy_size,
02695     int16_t  *px_ll,
02696     int16_t  *py_ll,
02697     int16_t  *px_ur,
02698     int16_t  *py_ur)
02699 {
02700 
02701 
02702 
02703     uint8_t x_centre = 0;
02704     uint8_t y_centre = 0;
02705     uint8_t width    = 0;
02706     uint8_t height   = 0;
02707 
02708 
02709 
02710     VL53L1_decode_row_col(
02711         encoded_xy_centre,
02712         &y_centre,
02713         &x_centre);
02714 
02715     VL53L1_decode_zone_size(
02716         encoded_xy_size,
02717         &width,
02718         &height);
02719 
02720 
02721 
02722     *px_ll = (int16_t)x_centre - ((int16_t)width + 1) / 2;
02723     if (*px_ll < 0)
02724         *px_ll = 0;
02725 
02726     *px_ur = *px_ll + (int16_t)width;
02727     if (*px_ur > (VL53L1_SPAD_ARRAY_WIDTH-1))
02728         *px_ur = VL53L1_SPAD_ARRAY_WIDTH-1;
02729 
02730     *py_ll = (int16_t)y_centre - ((int16_t)height + 1) / 2;
02731     if (*py_ll < 0)
02732         *py_ll = 0;
02733 
02734     *py_ur = *py_ll + (int16_t)height;
02735     if (*py_ur > (VL53L1_SPAD_ARRAY_HEIGHT-1))
02736         *py_ur = VL53L1_SPAD_ARRAY_HEIGHT-1;
02737 }
02738 
02739 
02740 uint8_t VL53L1_is_aperture_location(
02741     uint8_t row,
02742     uint8_t col)
02743 {
02744 
02745 
02746     uint8_t is_aperture = 0;
02747     uint8_t mod_row     = row % 4;
02748     uint8_t mod_col     = col % 4;
02749 
02750     if (mod_row == 0 && mod_col == 2)
02751         is_aperture = 1;
02752 
02753     if (mod_row == 2 && mod_col == 0)
02754         is_aperture = 1;
02755 
02756     return is_aperture;
02757 }
02758 
02759 
02760 void VL53L1_calc_max_effective_spads(
02761     uint8_t     encoded_zone_centre,
02762     uint8_t     encoded_zone_size,
02763     uint8_t    *pgood_spads,
02764     uint16_t    aperture_attenuation,
02765     uint16_t   *pmax_effective_spads)
02766 {
02767 
02768 
02769 
02770     int16_t   x         = 0;
02771     int16_t   y         = 0;
02772 
02773     int16_t   zone_x_ll = 0;
02774     int16_t   zone_y_ll = 0;
02775     int16_t   zone_x_ur = 0;
02776     int16_t   zone_y_ur = 0;
02777 
02778     uint8_t   spad_number = 0;
02779     uint8_t   byte_index  = 0;
02780     uint8_t   bit_index   = 0;
02781     uint8_t   bit_mask    = 0;
02782 
02783     uint8_t   is_aperture = 0;
02784 
02785 
02786 
02787     VL53L1_decode_zone_limits(
02788         encoded_zone_centre,
02789         encoded_zone_size,
02790         &zone_x_ll,
02791         &zone_y_ll,
02792         &zone_x_ur,
02793         &zone_y_ur);
02794 
02795 
02796 
02797     *pmax_effective_spads = 0;
02798 
02799     for (y = zone_y_ll; y <= zone_y_ur; y++) {
02800         for (x = zone_x_ll; x <= zone_x_ur; x++) {
02801 
02802 
02803 
02804             VL53L1_encode_row_col(
02805                 (uint8_t)y,
02806                 (uint8_t)x,
02807                 &spad_number);
02808 
02809 
02810 
02811             VL53L1_spad_number_to_byte_bit_index(
02812                 spad_number,
02813                 &byte_index,
02814                 &bit_index,
02815                 &bit_mask);
02816 
02817 
02818 
02819             if ((pgood_spads[byte_index] & bit_mask) > 0) {
02820 
02821 
02822                 is_aperture = VL53L1_is_aperture_location(
02823                     (uint8_t)y,
02824                     (uint8_t)x);
02825 
02826                 if (is_aperture > 0)
02827                     *pmax_effective_spads +=
02828                             aperture_attenuation;
02829                 else
02830                     *pmax_effective_spads += 0x0100;
02831 
02832             }
02833         }
02834     }
02835 }
02836 
02837 
02838 void VL53L1_calc_mm_effective_spads(
02839     uint8_t     encoded_mm_roi_centre,
02840     uint8_t     encoded_mm_roi_size,
02841     uint8_t     encoded_zone_centre,
02842     uint8_t     encoded_zone_size,
02843     uint8_t    *pgood_spads,
02844     uint16_t    aperture_attenuation,
02845     uint16_t   *pmm_inner_effective_spads,
02846     uint16_t   *pmm_outer_effective_spads)
02847 {
02848 
02849 
02850 
02851     int16_t   x         = 0;
02852     int16_t   y         = 0;
02853 
02854     int16_t   mm_x_ll   = 0;
02855     int16_t   mm_y_ll   = 0;
02856     int16_t   mm_x_ur   = 0;
02857     int16_t   mm_y_ur   = 0;
02858 
02859     int16_t   zone_x_ll = 0;
02860     int16_t   zone_y_ll = 0;
02861     int16_t   zone_x_ur = 0;
02862     int16_t   zone_y_ur = 0;
02863 
02864     uint8_t   spad_number = 0;
02865     uint8_t   byte_index  = 0;
02866     uint8_t   bit_index   = 0;
02867     uint8_t   bit_mask    = 0;
02868 
02869     uint8_t   is_aperture = 0;
02870     uint16_t  spad_attenuation = 0;
02871 
02872 
02873 
02874     VL53L1_decode_zone_limits(
02875         encoded_mm_roi_centre,
02876         encoded_mm_roi_size,
02877         &mm_x_ll,
02878         &mm_y_ll,
02879         &mm_x_ur,
02880         &mm_y_ur);
02881 
02882     VL53L1_decode_zone_limits(
02883         encoded_zone_centre,
02884         encoded_zone_size,
02885         &zone_x_ll,
02886         &zone_y_ll,
02887         &zone_x_ur,
02888         &zone_y_ur);
02889 
02890 
02891 
02892     *pmm_inner_effective_spads = 0;
02893     *pmm_outer_effective_spads = 0;
02894 
02895     for (y = zone_y_ll; y <= zone_y_ur; y++) {
02896         for (x = zone_x_ll; x <= zone_x_ur; x++) {
02897 
02898 
02899 
02900             VL53L1_encode_row_col(
02901                 (uint8_t)y,
02902                 (uint8_t)x,
02903                 &spad_number);
02904 
02905 
02906 
02907             VL53L1_spad_number_to_byte_bit_index(
02908                 spad_number,
02909                 &byte_index,
02910                 &bit_index,
02911                 &bit_mask);
02912 
02913 
02914 
02915             if ((pgood_spads[byte_index] & bit_mask) > 0) {
02916 
02917 
02918                 is_aperture = VL53L1_is_aperture_location(
02919                     (uint8_t)y,
02920                     (uint8_t)x);
02921 
02922                 if (is_aperture > 0)
02923                     spad_attenuation = aperture_attenuation;
02924                 else
02925                     spad_attenuation = 0x0100;
02926 
02927 
02928 
02929                 if (x >= mm_x_ll && x <= mm_x_ur &&
02930                     y >= mm_y_ll && y <= mm_y_ur)
02931                     *pmm_inner_effective_spads +=
02932                         spad_attenuation;
02933                 else
02934                     *pmm_outer_effective_spads +=
02935                         spad_attenuation;
02936             }
02937         }
02938     }
02939 }
02940 
02941 
02942 void VL53L1_hist_copy_results_to_sys_and_core(
02943     VL53L1_histogram_bin_data_t      *pbins,
02944     VL53L1_range_results_t           *phist,
02945     VL53L1_system_results_t          *psys,
02946     VL53L1_core_results_t            *pcore)
02947 {
02948 
02949 
02950     uint8_t  i = 0;
02951 
02952     VL53L1_range_data_t  *pdata;
02953 
02954     LOG_FUNCTION_START("");
02955 
02956 
02957 
02958     VL53L1_init_system_results(psys);
02959 
02960 
02961 
02962     psys->result__interrupt_status = pbins->result__interrupt_status;
02963     psys->result__range_status     = phist->active_results;
02964     psys->result__report_status    = pbins->result__report_status;
02965     psys->result__stream_count     = pbins->result__stream_count;
02966 
02967     pdata = &(phist->VL53L1_p_002[0]);
02968 
02969     for (i = 0; i < phist->active_results; i++) {
02970 
02971         switch (i) {
02972         case 0:
02973             psys->result__dss_actual_effective_spads_sd0 =
02974                     pdata->VL53L1_p_006;
02975             psys->result__peak_signal_count_rate_mcps_sd0 =
02976                     pdata->peak_signal_count_rate_mcps;
02977             psys->result__avg_signal_count_rate_mcps_sd0 =
02978                     pdata->avg_signal_count_rate_mcps;
02979             psys->result__ambient_count_rate_mcps_sd0 =
02980                     pdata->ambient_count_rate_mcps;
02981 
02982             psys->result__sigma_sd0 = pdata->VL53L1_p_005;
02983             psys->result__phase_sd0 = pdata->VL53L1_p_014;
02984 
02985             psys->result__final_crosstalk_corrected_range_mm_sd0 =
02986                     (uint16_t)pdata->median_range_mm;
02987 
02988             psys->result__phase_sd1  = pdata->zero_distance_phase;
02989 
02990             pcore->result_core__ranging_total_events_sd0 =
02991                     pdata->VL53L1_p_021;
02992             pcore->result_core__signal_total_events_sd0 =
02993                     pdata->VL53L1_p_013;
02994             pcore->result_core__total_periods_elapsed_sd0 =
02995                     pdata->total_periods_elapsed;
02996             pcore->result_core__ambient_window_events_sd0 =
02997                     pdata->VL53L1_p_020;
02998 
02999             break;
03000         case 1:
03001             psys->result__dss_actual_effective_spads_sd1 =
03002                 pdata->VL53L1_p_006;
03003             psys->result__peak_signal_count_rate_mcps_sd1 =
03004                 pdata->peak_signal_count_rate_mcps;
03005             psys->result__ambient_count_rate_mcps_sd1 =
03006                 pdata->ambient_count_rate_mcps;
03007 
03008             psys->result__sigma_sd1 = pdata->VL53L1_p_005;
03009             psys->result__phase_sd1 = pdata->VL53L1_p_014;
03010 
03011             psys->result__final_crosstalk_corrected_range_mm_sd1 =
03012                 (uint16_t)pdata->median_range_mm;
03013 
03014             pcore->result_core__ranging_total_events_sd1 =
03015                 pdata->VL53L1_p_021;
03016             pcore->result_core__signal_total_events_sd1 =
03017                 pdata->VL53L1_p_013;
03018             pcore->result_core__total_periods_elapsed_sd1 =
03019                 pdata->total_periods_elapsed;
03020             pcore->result_core__ambient_window_events_sd1 =
03021                 pdata->VL53L1_p_020;
03022             break;
03023         }
03024 
03025         pdata++;
03026     }
03027 
03028     LOG_FUNCTION_END(0);
03029 
03030 }
03031 
03032 
03033 VL53L1_Error VL53L1_sum_histogram_data(
03034         VL53L1_histogram_bin_data_t *phist_input,
03035         VL53L1_histogram_bin_data_t *phist_output)
03036 {
03037 
03038 
03039     VL53L1_Error status = VL53L1_ERROR_NONE;
03040 
03041     uint8_t i = 0;
03042     uint8_t smallest_bin_num = 0;
03043 
03044     LOG_FUNCTION_START("");
03045 
03046 
03047 
03048     if (status == VL53L1_ERROR_NONE) {
03049         if (phist_output->VL53L1_p_024 >=
03050                 phist_input->VL53L1_p_024)
03051             smallest_bin_num = phist_input->VL53L1_p_024;
03052         else
03053             smallest_bin_num = phist_output->VL53L1_p_024;
03054     }
03055 
03056 
03057 
03058 
03059 
03060     if (status == VL53L1_ERROR_NONE)
03061         for (i = 0; i < smallest_bin_num; i++)
03062 
03063             phist_output->bin_data[i] += phist_input->bin_data[i];
03064 
03065     if (status == VL53L1_ERROR_NONE)
03066         phist_output->VL53L1_p_004 +=
03067             phist_input->VL53L1_p_004;
03068 
03069 
03070     LOG_FUNCTION_END(status);
03071 
03072     return status;
03073 }
03074 
03075 
03076 VL53L1_Error VL53L1_avg_histogram_data(
03077             uint8_t no_of_samples,
03078             VL53L1_histogram_bin_data_t *phist_sum,
03079             VL53L1_histogram_bin_data_t *phist_avg)
03080 {
03081 
03082 
03083     VL53L1_Error status = VL53L1_ERROR_NONE;
03084 
03085     uint8_t i = 0;
03086 
03087     LOG_FUNCTION_START("");
03088 
03089 
03090 
03091 
03092 
03093     if (status == VL53L1_ERROR_NONE) {
03094         for (i = 0; i < phist_sum->VL53L1_p_024; i++) {
03095 
03096 
03097 
03098             if (no_of_samples > 0)
03099                 phist_avg->bin_data[i] =
03100                     phist_sum->bin_data[i] /
03101                     (int32_t)no_of_samples;
03102             else
03103                 phist_avg->bin_data[i] = phist_sum->bin_data[i];
03104         }
03105     }
03106 
03107     if (status == VL53L1_ERROR_NONE) {
03108         if (no_of_samples > 0)
03109             phist_avg->VL53L1_p_004 =
03110                 phist_sum->VL53L1_p_004 /
03111                     (int32_t)no_of_samples;
03112         else
03113             phist_avg->VL53L1_p_004 =
03114                     phist_sum->VL53L1_p_004;
03115     }
03116 
03117     LOG_FUNCTION_END(status);
03118 
03119     return status;
03120 }
03121 
03122 
03123 VL53L1_Error VL53L1_save_cfg_data(
03124     VL53L1_DEV  Dev)
03125 {
03126 
03127 
03128     VL53L1_Error status = VL53L1_ERROR_NONE;
03129 
03130     VL53L1_LLDriverData_t  *pdev =
03131             VL53L1DevStructGetLLDriverHandle(Dev);
03132     VL53L1_LLDriverResults_t  *pres =
03133             VL53L1DevStructGetLLResultsHandle(Dev);
03134 
03135     VL53L1_zone_private_dyn_cfg_t *pzone_dyn_cfg;
03136     VL53L1_dynamic_config_t       *pdynamic = &(pdev->dyn_cfg);
03137 
03138     LOG_FUNCTION_START("");
03139 
03140     pzone_dyn_cfg =
03141         &(pres->zone_dyn_cfgs.VL53L1_p_002[pdev->ll_state.cfg_zone_id]);
03142 
03143     pzone_dyn_cfg->expected_stream_count =
03144             pdev->ll_state.cfg_stream_count;
03145 
03146     pzone_dyn_cfg->expected_gph_id =
03147             pdev->ll_state.cfg_gph_id;
03148 
03149     pzone_dyn_cfg->roi_config__user_roi_centre_spad =
03150         pdynamic->roi_config__user_roi_centre_spad;
03151 
03152     pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size =
03153         pdynamic->roi_config__user_roi_requested_global_xy_size;
03154 
03155     LOG_FUNCTION_END(status);
03156 
03157     return status;
03158 }
03159 
03160 
03161 VL53L1_Error VL53L1_dynamic_zone_update(
03162     VL53L1_DEV  Dev,
03163     VL53L1_range_results_t *presults)
03164 {
03165 
03166 
03167     VL53L1_Error status = VL53L1_ERROR_NONE;
03168 
03169     VL53L1_LLDriverData_t  *pdev =
03170             VL53L1DevStructGetLLDriverHandle(Dev);
03171     VL53L1_LLDriverResults_t  *pres =
03172             VL53L1DevStructGetLLResultsHandle(Dev);
03173     VL53L1_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
03174 
03175     uint8_t   zone_id = pdev->ll_state.rd_zone_id;
03176     uint8_t   i;
03177     uint16_t  max_total_rate_per_spads;
03178     uint16_t  target_rate =
03179         pdev->stat_cfg.dss_config__target_total_rate_mcps;
03180     uint32_t  temp = 0xFFFF;
03181 #ifdef VL53L1_LOG_ENABLE
03182     uint16_t eff_spad_cnt =
03183         pZ->VL53L1_p_002[zone_id].dss_requested_effective_spad_count;
03184 #endif
03185 
03186     LOG_FUNCTION_START("");
03187 
03188     pZ->VL53L1_p_002[zone_id].dss_requested_effective_spad_count = 0;
03189 
03190     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03191         "    DYNZONEUPDATE: peak signal count rate mcps:");
03192 
03193     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03194         "%u actual effective spads: %u\n",
03195         presults->VL53L1_p_002[0].peak_signal_count_rate_mcps,
03196         presults->VL53L1_p_002[0].VL53L1_p_006);
03197 
03198     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03199         "    DYNZONEUPDATE: active results: %u\n",
03200         presults->active_results);
03201 
03202     max_total_rate_per_spads =
03203         presults->VL53L1_p_002[0].total_rate_per_spad_mcps;
03204 
03205     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03206         "    DYNZONEUPDATE: max total rate per spad at start: %u\n",
03207         max_total_rate_per_spads);
03208 
03209     for (i = 1; i < presults->active_results; i++) {
03210         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03211         "    DYNZONEUPDATE: zone total rate per spad: zone_id: %u,",
03212         i);
03213 
03214         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03215         "total rate per spad: %u\n",
03216         presults->VL53L1_p_002[i].total_rate_per_spad_mcps);
03217 
03218         if (presults->VL53L1_p_002[i].total_rate_per_spad_mcps >
03219             max_total_rate_per_spads)
03220             max_total_rate_per_spads =
03221             presults->VL53L1_p_002[i].total_rate_per_spad_mcps;
03222 
03223     }
03224 
03225     if (max_total_rate_per_spads == 0) {
03226 
03227         temp = 0xFFFF;
03228     } else {
03229 
03230         temp = target_rate << 14;
03231         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03232             "    DYNZONEUPDATE: 1: temp: %u\n",
03233             temp);
03234 
03235 
03236         temp = temp / max_total_rate_per_spads;
03237 
03238         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03239             "    DYNZONEUPDATE: 2: temp: %u\n",
03240             temp);
03241 
03242 
03243         if (temp > 0xFFFF)
03244             temp = 0xFFFF;
03245 
03246         trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03247             "    DYNZONEUPDATE: 3: temp: %u\n",
03248             temp);
03249     }
03250 
03251     pZ->VL53L1_p_002[zone_id].dss_requested_effective_spad_count =
03252             (uint16_t)temp;
03253 
03254     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03255         "    DYNZONEUPDATE: zone_id: %u, target_rate: %u,",
03256         zone_id,
03257         target_rate);
03258 
03259     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03260         "max_total_rate_per_spads: %u, requested_spads: %u\n",
03261         max_total_rate_per_spads,
03262         eff_spad_cnt);
03263 
03264     LOG_FUNCTION_END(status);
03265 
03266     return status;
03267 }
03268 
03269 VL53L1_Error VL53L1_multizone_hist_bins_update(
03270     VL53L1_DEV  Dev)
03271 {
03272 
03273 
03274     VL53L1_Error status = VL53L1_ERROR_NONE;
03275 
03276     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03277     VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
03278     VL53L1_zone_config_t *pzone_cfg = &(pdev->zone_cfg);
03279     VL53L1_histogram_config_t *phist_cfg = &(pdev->hist_cfg);
03280     VL53L1_histogram_config_t *pmulti_hist =
03281             &(pzone_cfg->multizone_hist_cfg);
03282 
03283     uint8_t   next_range_is_odd_timing = (pstate->cfg_stream_count) % 2;
03284 
03285     LOG_FUNCTION_START("");
03286 
03287 
03288     if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
03289         VL53L1_ZONECONFIG_BINCONFIG__LOWAMB) {
03290         if (!next_range_is_odd_timing) {
03291             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03292             "   HISTBINCONFIGUPDATE: Setting LOWAMB EVEN timing\n");
03293             phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03294             pmulti_hist->histogram_config__low_amb_even_bin_0_1;
03295             phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03296             pmulti_hist->histogram_config__low_amb_even_bin_2_3;
03297             phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03298             pmulti_hist->histogram_config__low_amb_even_bin_4_5;
03299         }
03300 
03301         if (next_range_is_odd_timing) {
03302             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03303             "    HISTBINCONFIGUPDATE: Setting LOWAMB ODD timing\n");
03304             phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03305             pmulti_hist->histogram_config__low_amb_even_bin_0_1;
03306             phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03307             pmulti_hist->histogram_config__low_amb_even_bin_2_3;
03308             phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03309             pmulti_hist->histogram_config__low_amb_even_bin_4_5;
03310         }
03311     } else if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
03312         VL53L1_ZONECONFIG_BINCONFIG__MIDAMB) {
03313         trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03314             "    HISTBINCONFIGUPDATE: Setting MIDAMB timing\n");
03315         if (!next_range_is_odd_timing) {
03316             trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03317             "   HISTBINCONFIGUPDATE: Setting MIDAMB EVEN timing\n");
03318             phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03319             pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
03320             phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03321             pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
03322             phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03323             pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
03324         }
03325 
03326         if (next_range_is_odd_timing) {
03327             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03328             "    HISTBINCONFIGUPDATE: Setting MIDAMB ODD timing\n");
03329             phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03330             pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
03331             phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03332             pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
03333             phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03334             pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
03335         }
03336     } else if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
03337             VL53L1_ZONECONFIG_BINCONFIG__HIGHAMB) {
03338         if (!next_range_is_odd_timing) {
03339             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03340             "    HISTBINCONFIGUPDATE: Setting HIGHAMB EVEN timing\n"
03341                     );
03342             phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03343             pmulti_hist->histogram_config__high_amb_even_bin_0_1;
03344             phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03345             pmulti_hist->histogram_config__high_amb_even_bin_2_3;
03346             phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03347             pmulti_hist->histogram_config__high_amb_even_bin_4_5;
03348         }
03349 
03350         if (next_range_is_odd_timing) {
03351             trace_print (VL53L1_TRACE_LEVEL_DEBUG,
03352             "   HISTBINCONFIGUPDATE: Setting HIGHAMB ODD timing\n");
03353             phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03354             pmulti_hist->histogram_config__high_amb_even_bin_0_1;
03355             phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03356             pmulti_hist->histogram_config__high_amb_even_bin_2_3;
03357             phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03358             pmulti_hist->histogram_config__high_amb_even_bin_4_5;
03359         }
03360     }
03361 
03362 
03363 
03364     if (status == VL53L1_ERROR_NONE) {
03365         VL53L1_copy_hist_bins_to_static_cfg(
03366             phist_cfg,
03367             &(pdev->stat_cfg),
03368             &(pdev->tim_cfg));
03369     }
03370 
03371     LOG_FUNCTION_END(status);
03372 
03373     return status;
03374 }
03375 
03376 
03377 
03378 VL53L1_Error VL53L1_update_internal_stream_counters(
03379     VL53L1_DEV  Dev,
03380     uint8_t     external_stream_count,
03381     uint8_t    *pinternal_stream_count,
03382     uint8_t    *pinternal_stream_count_val)
03383 {
03384 
03385     VL53L1_Error status = VL53L1_ERROR_NONE;
03386     uint8_t stream_divider;
03387 
03388     VL53L1_LLDriverData_t  *pdev =
03389             VL53L1DevStructGetLLDriverHandle(Dev);
03390 
03391     LOG_FUNCTION_START("");
03392 
03393     stream_divider = pdev->gen_cfg.global_config__stream_divider;
03394 
03395     if (stream_divider == 0) {
03396 
03397 
03398         *pinternal_stream_count = external_stream_count;
03399 
03400     } else if (*pinternal_stream_count_val == (stream_divider-1)) {
03401 
03402 
03403         if (*pinternal_stream_count == 0xFF)
03404             *pinternal_stream_count = 0x80;
03405         else
03406             *pinternal_stream_count = *pinternal_stream_count + 1;
03407 
03408 
03409         *pinternal_stream_count_val = 0;
03410 
03411     } else {
03412 
03413 
03414         *pinternal_stream_count_val = *pinternal_stream_count_val + 1;
03415     }
03416 
03417     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03418         "UPDINTSTREAMCOUNT   internal_steam_count:  %d,",
03419         *pinternal_stream_count);
03420 
03421     trace_print(VL53L1_TRACE_LEVEL_DEBUG,
03422         "internal_stream_count_val: %d, divider: %d\n",
03423         *pinternal_stream_count_val,
03424         stream_divider);
03425 
03426     LOG_FUNCTION_END(status);
03427 
03428     return status;
03429 }
03430 
03431 
03432 
03433 VL53L1_Error VL53L1_set_histogram_multizone_initial_bin_config(
03434     VL53L1_zone_config_t        *pzone_cfg,
03435     VL53L1_histogram_config_t   *phist_cfg,
03436     VL53L1_histogram_config_t   *pmulti_hist)
03437 {
03438     VL53L1_Error  status = VL53L1_ERROR_NONE;
03439 
03440     LOG_FUNCTION_START("");
03441 
03442 
03443     if (pzone_cfg->bin_config[0] ==
03444             VL53L1_ZONECONFIG_BINCONFIG__LOWAMB) {
03445         phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03446             pmulti_hist->histogram_config__low_amb_even_bin_0_1;
03447         phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03448             pmulti_hist->histogram_config__low_amb_even_bin_2_3;
03449         phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03450             pmulti_hist->histogram_config__low_amb_even_bin_4_5;
03451 
03452         phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03453             pmulti_hist->histogram_config__low_amb_even_bin_0_1;
03454         phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03455             pmulti_hist->histogram_config__low_amb_even_bin_2_3;
03456         phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03457             pmulti_hist->histogram_config__low_amb_even_bin_4_5;
03458     } else if (pzone_cfg->bin_config[0] ==
03459             VL53L1_ZONECONFIG_BINCONFIG__MIDAMB) {
03460         phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03461             pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
03462         phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03463             pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
03464         phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03465             pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
03466 
03467         phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03468             pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
03469         phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03470             pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
03471         phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03472             pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
03473     } else if (pzone_cfg->bin_config[0] ==
03474             VL53L1_ZONECONFIG_BINCONFIG__HIGHAMB) {
03475         phist_cfg->histogram_config__low_amb_even_bin_0_1  =
03476             pmulti_hist->histogram_config__high_amb_even_bin_0_1;
03477         phist_cfg->histogram_config__low_amb_even_bin_2_3  =
03478             pmulti_hist->histogram_config__high_amb_even_bin_2_3;
03479         phist_cfg->histogram_config__low_amb_even_bin_4_5  =
03480             pmulti_hist->histogram_config__high_amb_even_bin_4_5;
03481         phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
03482             pmulti_hist->histogram_config__high_amb_even_bin_0_1;
03483         phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
03484             pmulti_hist->histogram_config__high_amb_even_bin_2_3;
03485         phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
03486             pmulti_hist->histogram_config__high_amb_even_bin_4_5;
03487     }
03488 
03489     LOG_FUNCTION_END(status);
03490     return status;
03491 }
03492 
03493 
03494 
03495 uint8_t VL53L1_encode_GPIO_interrupt_config(
03496     VL53L1_GPIO_interrupt_config_t  *pintconf)
03497 {
03498     uint8_t system__interrupt_config;
03499 
03500     system__interrupt_config = pintconf->intr_mode_distance;
03501     system__interrupt_config |= ((pintconf->intr_mode_rate) << 2);
03502     system__interrupt_config |= ((pintconf->intr_new_measure_ready) << 5);
03503     system__interrupt_config |= ((pintconf->intr_no_target) << 6);
03504     system__interrupt_config |= ((pintconf->intr_combined_mode) << 7);
03505 
03506     return system__interrupt_config;
03507 }
03508 
03509 
03510 
03511 VL53L1_GPIO_interrupt_config_t VL53L1_decode_GPIO_interrupt_config(
03512     uint8_t     system__interrupt_config)
03513 {
03514     VL53L1_GPIO_interrupt_config_t  intconf;
03515 
03516     intconf.intr_mode_distance = system__interrupt_config & 0x03;
03517     intconf.intr_mode_rate = (system__interrupt_config >> 2) & 0x03;
03518     intconf.intr_new_measure_ready = (system__interrupt_config >> 5) & 0x01;
03519     intconf.intr_no_target = (system__interrupt_config >> 6) & 0x01;
03520     intconf.intr_combined_mode = (system__interrupt_config >> 7) & 0x01;
03521 
03522 
03523     intconf.threshold_rate_low = 0;
03524     intconf.threshold_rate_high = 0;
03525     intconf.threshold_distance_low = 0;
03526     intconf.threshold_distance_high = 0;
03527 
03528     return intconf;
03529 }
03530 
03531 
03532 
03533 VL53L1_Error VL53L1_set_GPIO_distance_threshold(
03534     VL53L1_DEV                      Dev,
03535     uint16_t            threshold_high,
03536     uint16_t            threshold_low)
03537 {
03538     VL53L1_Error  status = VL53L1_ERROR_NONE;
03539 
03540     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03541 
03542     LOG_FUNCTION_START("");
03543 
03544     pdev->dyn_cfg.system__thresh_high = threshold_high;
03545     pdev->dyn_cfg.system__thresh_low = threshold_low;
03546 
03547     LOG_FUNCTION_END(status);
03548     return status;
03549 }
03550 
03551 
03552 
03553 VL53L1_Error VL53L1_set_GPIO_rate_threshold(
03554     VL53L1_DEV                      Dev,
03555     uint16_t            threshold_high,
03556     uint16_t            threshold_low)
03557 {
03558     VL53L1_Error  status = VL53L1_ERROR_NONE;
03559 
03560     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03561 
03562     LOG_FUNCTION_START("");
03563 
03564     pdev->gen_cfg.system__thresh_rate_high = threshold_high;
03565     pdev->gen_cfg.system__thresh_rate_low = threshold_low;
03566 
03567     LOG_FUNCTION_END(status);
03568     return status;
03569 }
03570 
03571 
03572 
03573 VL53L1_Error VL53L1_set_GPIO_thresholds_from_struct(
03574     VL53L1_DEV                      Dev,
03575     VL53L1_GPIO_interrupt_config_t *pintconf)
03576 {
03577     VL53L1_Error  status = VL53L1_ERROR_NONE;
03578 
03579     LOG_FUNCTION_START("");
03580 
03581     status = VL53L1_set_GPIO_distance_threshold(
03582             Dev,
03583             pintconf->threshold_distance_high,
03584             pintconf->threshold_distance_low);
03585 
03586     if (status == VL53L1_ERROR_NONE) {
03587         status =
03588             VL53L1_set_GPIO_rate_threshold(
03589                 Dev,
03590                 pintconf->threshold_rate_high,
03591                 pintconf->threshold_rate_low);
03592     }
03593 
03594     LOG_FUNCTION_END(status);
03595     return status;
03596 }
03597 
03598 
03599 VL53L1_Error VL53L1_set_ref_spad_char_config(
03600     VL53L1_DEV    Dev,
03601     uint8_t       vcsel_period_a,
03602     uint32_t      phasecal_timeout_us,
03603     uint16_t      total_rate_target_mcps,
03604     uint16_t      max_count_rate_rtn_limit_mcps,
03605     uint16_t      min_count_rate_rtn_limit_mcps,
03606     uint16_t      fast_osc_frequency)
03607 {
03608 
03609 
03610     VL53L1_Error status = VL53L1_ERROR_NONE;
03611     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03612 
03613     uint8_t buffer[2];
03614 
03615     uint32_t macro_period_us = 0;
03616     uint32_t timeout_mclks   = 0;
03617 
03618     LOG_FUNCTION_START("");
03619 
03620 
03621     macro_period_us =
03622         VL53L1_calc_macro_period_us(
03623             fast_osc_frequency,
03624             vcsel_period_a);
03625 
03626 
03627 
03628     timeout_mclks = phasecal_timeout_us << 12;
03629     timeout_mclks = timeout_mclks + (macro_period_us>>1);
03630     timeout_mclks = timeout_mclks / macro_period_us;
03631 
03632     if (timeout_mclks > 0xFF)
03633         pdev->gen_cfg.phasecal_config__timeout_macrop = 0xFF;
03634     else
03635         pdev->gen_cfg.phasecal_config__timeout_macrop =
03636                 (uint8_t)timeout_mclks;
03637 
03638     pdev->tim_cfg.range_config__vcsel_period_a = vcsel_period_a;
03639 
03640 
03641 
03642     if (status == VL53L1_ERROR_NONE)
03643         status =
03644             VL53L1_WrByte(
03645                 Dev,
03646                 VL53L1_PHASECAL_CONFIG__TIMEOUT_MACROP,
03647                 pdev->gen_cfg.phasecal_config__timeout_macrop);
03648 
03649     if (status == VL53L1_ERROR_NONE)
03650         status =
03651             VL53L1_WrByte(
03652                 Dev,
03653                 VL53L1_RANGE_CONFIG__VCSEL_PERIOD_A,
03654                 pdev->tim_cfg.range_config__vcsel_period_a);
03655 
03656 
03657 
03658     buffer[0] = pdev->tim_cfg.range_config__vcsel_period_a;
03659     buffer[1] = pdev->tim_cfg.range_config__vcsel_period_a;
03660 
03661     if (status == VL53L1_ERROR_NONE)
03662         status =
03663             VL53L1_WriteMulti(
03664                 Dev,
03665                 VL53L1_SD_CONFIG__WOI_SD0,
03666                 buffer,
03667                 2);
03668 
03669 
03670 
03671     pdev->customer.ref_spad_char__total_rate_target_mcps =
03672             total_rate_target_mcps;
03673 
03674     if (status == VL53L1_ERROR_NONE)
03675         status =
03676             VL53L1_WrWord(
03677                 Dev,
03678                 VL53L1_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS,
03679                 total_rate_target_mcps);
03680 
03681     if (status == VL53L1_ERROR_NONE)
03682         status =
03683             VL53L1_WrWord(
03684                 Dev,
03685                 VL53L1_RANGE_CONFIG__SIGMA_THRESH,
03686                 max_count_rate_rtn_limit_mcps);
03687 
03688     if (status == VL53L1_ERROR_NONE)
03689         status =
03690             VL53L1_WrWord(
03691             Dev,
03692             VL53L1_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS,
03693             min_count_rate_rtn_limit_mcps);
03694 
03695     LOG_FUNCTION_END(status);
03696 
03697     return status;
03698 }
03699 
03700 
03701 VL53L1_Error VL53L1_set_ssc_config(
03702     VL53L1_DEV            Dev,
03703     VL53L1_ssc_config_t  *pssc_cfg,
03704     uint16_t              fast_osc_frequency)
03705 {
03706 
03707 
03708     VL53L1_Error status = VL53L1_ERROR_NONE;
03709     uint8_t buffer[5];
03710 
03711     uint32_t macro_period_us = 0;
03712     uint16_t timeout_encoded = 0;
03713 
03714     LOG_FUNCTION_START("");
03715 
03716 
03717     macro_period_us =
03718         VL53L1_calc_macro_period_us(
03719             fast_osc_frequency,
03720             pssc_cfg->VL53L1_p_009);
03721 
03722 
03723     timeout_encoded =
03724         VL53L1_calc_encoded_timeout(
03725             pssc_cfg->timeout_us,
03726             macro_period_us);
03727 
03728 
03729 
03730     if (status == VL53L1_ERROR_NONE)
03731         status =
03732             VL53L1_WrByte(
03733                 Dev,
03734                 VL53L1_CAL_CONFIG__VCSEL_START,
03735                 pssc_cfg->vcsel_start);
03736 
03737     if (status == VL53L1_ERROR_NONE)
03738         status =
03739             VL53L1_WrByte(
03740                 Dev,
03741                 VL53L1_GLOBAL_CONFIG__VCSEL_WIDTH,
03742                 pssc_cfg->vcsel_width);
03743 
03744 
03745 
03746     buffer[0] = (uint8_t)((timeout_encoded &  0x0000FF00) >> 8);
03747     buffer[1] = (uint8_t) (timeout_encoded &  0x000000FF);
03748     buffer[2] = pssc_cfg->VL53L1_p_009;
03749     buffer[3] = (uint8_t)((pssc_cfg->rate_limit_mcps &  0x0000FF00) >> 8);
03750     buffer[4] = (uint8_t) (pssc_cfg->rate_limit_mcps &  0x000000FF);
03751 
03752     if (status == VL53L1_ERROR_NONE)
03753         status =
03754             VL53L1_WriteMulti(
03755                 Dev,
03756                 VL53L1_RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
03757                 buffer,
03758                 5);
03759 
03760 
03761 
03762     buffer[0] = pssc_cfg->VL53L1_p_009;
03763     buffer[1] = pssc_cfg->VL53L1_p_009;
03764 
03765     if (status == VL53L1_ERROR_NONE)
03766         status =
03767             VL53L1_WriteMulti(
03768                 Dev,
03769                 VL53L1_SD_CONFIG__WOI_SD0,
03770                 buffer,
03771                 2);
03772 
03773 
03774     if (status == VL53L1_ERROR_NONE)
03775         status =
03776             VL53L1_WrByte(
03777                 Dev,
03778                 VL53L1_NVM_BIST__CTRL,
03779                 pssc_cfg->array_select);
03780 
03781     LOG_FUNCTION_END(status);
03782 
03783     return status;
03784 }
03785 
03786 
03787 VL53L1_Error VL53L1_get_spad_rate_data(
03788     VL53L1_DEV                Dev,
03789     VL53L1_spad_rate_data_t  *pspad_rates)
03790 {
03791 
03792 
03793 
03794     VL53L1_Error status = VL53L1_ERROR_NONE;
03795     int               i = 0;
03796 
03797     uint8_t  VL53L1_p_002[512];
03798     uint8_t *pdata = &VL53L1_p_002[0];
03799 
03800     LOG_FUNCTION_START("");
03801 
03802 
03803 
03804     if (status == VL53L1_ERROR_NONE)
03805         status = VL53L1_disable_firmware(Dev);
03806 
03807 
03808 
03809     if (status == VL53L1_ERROR_NONE)
03810         status =
03811             VL53L1_ReadMulti(
03812                 Dev,
03813                 VL53L1_PRIVATE__PATCH_BASE_ADDR_RSLV,
03814                 pdata,
03815                 512);
03816 
03817 
03818     pdata = &VL53L1_p_002[0];
03819     for (i = 0; i < VL53L1_NO_OF_SPAD_ENABLES; i++) {
03820         pspad_rates->rate_data[i] =
03821             (uint16_t)VL53L1_decode_unsigned_integer(pdata, 2);
03822         pdata += 2;
03823     }
03824 
03825 
03826 
03827     pspad_rates->VL53L1_p_023     = VL53L1_NO_OF_SPAD_ENABLES;
03828     pspad_rates->no_of_values    = VL53L1_NO_OF_SPAD_ENABLES;
03829     pspad_rates->fractional_bits = 15;
03830 
03831 
03832 
03833     if (status == VL53L1_ERROR_NONE)
03834         status = VL53L1_enable_firmware(Dev);
03835 
03836     LOG_FUNCTION_END(status);
03837 
03838     return status;
03839 }
03840 
03841 
03842 
03843 VL53L1_Error VL53L1_dynamic_xtalk_correction_calc_required_samples(
03844     VL53L1_DEV                          Dev
03845     )
03846 {
03847 
03848 
03849 
03850     VL53L1_Error  status = VL53L1_ERROR_NONE;
03851 
03852     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03853     VL53L1_LLDriverResults_t *pres = VL53L1DevStructGetLLResultsHandle(Dev);
03854     VL53L1_smudge_corrector_config_t *pconfig =
03855                 &(pdev->smudge_correct_config);
03856     VL53L1_smudge_corrector_internals_t *pint =
03857                 &(pdev->smudge_corrector_internals);
03858 
03859     VL53L1_range_results_t *presults = &(pres->range_results);
03860     VL53L1_range_data_t *pxmonitor = &(presults->xmonitor);
03861 
03862     uint32_t peak_duration_us = pxmonitor->peak_duration_us;
03863 
03864     uint64_t temp64a;
03865     uint64_t temp64z;
03866 
03867     LOG_FUNCTION_START("");
03868 
03869     if (peak_duration_us == 0)
03870         peak_duration_us = 1000;
03871 
03872     temp64a = pxmonitor->VL53L1_p_021 +
03873         pxmonitor->VL53L1_p_020;
03874     temp64a = do_division_u((temp64a * 1000), peak_duration_us);
03875     temp64a = do_division_u((temp64a * 1000), peak_duration_us);
03876 
03877     temp64z = pconfig->noise_margin * pxmonitor->VL53L1_p_006;
03878     if (temp64z == 0)
03879         temp64z = 1;
03880     temp64a = temp64a * 1000 * 256;
03881     temp64a = do_division_u(temp64a, temp64z);
03882     temp64a = temp64a * 1000 * 256;
03883     temp64a = do_division_u(temp64a, temp64z);
03884 
03885     pint->required_samples = (uint32_t)temp64a;
03886 
03887 
03888     if (pint->required_samples < 2)
03889         pint->required_samples = 2;
03890 
03891     LOG_FUNCTION_END(status);
03892 
03893     return status;
03894 }
03895 
03896 VL53L1_Error VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
03897     VL53L1_DEV              Dev,
03898     uint32_t                xtalk_offset_out,
03899     VL53L1_smudge_corrector_config_t    *pconfig,
03900     VL53L1_smudge_corrector_data_t      *pout,
03901     uint8_t                 add_smudge,
03902     uint8_t                 soft_update
03903     )
03904 {
03905 
03906 
03907 
03908     VL53L1_Error  status = VL53L1_ERROR_NONE;
03909     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
03910 
03911     int16_t  x_gradient_scaler;
03912     int16_t  y_gradient_scaler;
03913     uint32_t orig_xtalk_offset;
03914     int16_t  orig_x_gradient;
03915     int16_t  orig_y_gradient;
03916     uint8_t histo_merge_nb;
03917     uint8_t i;
03918     int32_t  itemp32;
03919     uint32_t SmudgeFactor;
03920     VL53L1_xtalk_config_t  *pX = &(pdev->xtalk_cfg);
03921     VL53L1_xtalk_calibration_results_t  *pC = &(pdev->xtalk_cal);
03922     uint32_t *pcpo;
03923     uint32_t max, nXtalk, cXtalk;
03924     uint8_t merge_enabled;
03925 
03926 
03927     LOG_FUNCTION_START("");
03928 
03929     merge_enabled = (pdev->tuning_parms.tp_hist_merge == 1) &&
03930         (VL53L1DevDataGet(Dev, CurrentParameters.PresetMode) ==
03931          VL53L1_PRESETMODE_RANGING);
03932 
03933 
03934     if (add_smudge == 1) {
03935         pout->algo__crosstalk_compensation_plane_offset_kcps =
03936             (uint32_t)xtalk_offset_out +
03937             (uint32_t)pconfig->smudge_margin;
03938     } else {
03939         pout->algo__crosstalk_compensation_plane_offset_kcps =
03940             (uint32_t)xtalk_offset_out;
03941     }
03942 
03943 
03944     orig_xtalk_offset =
03945     pX->nvm_default__crosstalk_compensation_plane_offset_kcps;
03946 
03947     orig_x_gradient =
03948         pX->nvm_default__crosstalk_compensation_x_plane_gradient_kcps;
03949 
03950     orig_y_gradient =
03951         pX->nvm_default__crosstalk_compensation_y_plane_gradient_kcps;
03952 
03953     if (((pconfig->user_scaler_set == 0) ||
03954         (pconfig->scaler_calc_method == 1)) &&
03955         (pC->algo__crosstalk_compensation_plane_offset_kcps != 0)) {
03956 
03957         VL53L1_compute_histo_merge_nb(Dev, &histo_merge_nb);
03958         if (histo_merge_nb == 0)
03959             histo_merge_nb = 1;
03960         if (!merge_enabled)
03961             orig_xtalk_offset =
03962             pC->algo__crosstalk_compensation_plane_offset_kcps;
03963         else
03964             orig_xtalk_offset =
03965             pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb-1];
03966 
03967         orig_x_gradient =
03968             pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
03969 
03970         orig_y_gradient =
03971             pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
03972     }
03973 
03974 
03975     if ((pconfig->user_scaler_set == 0) && (orig_x_gradient == 0))
03976         pout->gradient_zero_flag |= 0x01;
03977 
03978     if ((pconfig->user_scaler_set == 0) && (orig_y_gradient == 0))
03979         pout->gradient_zero_flag |= 0x02;
03980 
03981 
03982 
03983     if (orig_xtalk_offset == 0)
03984         orig_xtalk_offset = 1;
03985 
03986 
03987 
03988     if (pconfig->user_scaler_set == 1) {
03989         x_gradient_scaler = pconfig->x_gradient_scaler;
03990         y_gradient_scaler = pconfig->y_gradient_scaler;
03991     } else {
03992 
03993         x_gradient_scaler = (int16_t)do_division_s(
03994                 (((int32_t)orig_x_gradient) << 6),
03995                 orig_xtalk_offset);
03996         pconfig->x_gradient_scaler = x_gradient_scaler;
03997         y_gradient_scaler = (int16_t)do_division_s(
03998                 (((int32_t)orig_y_gradient) << 6),
03999                 orig_xtalk_offset);
04000         pconfig->y_gradient_scaler = y_gradient_scaler;
04001     }
04002 
04003 
04004 
04005     if (pconfig->scaler_calc_method == 0) {
04006 
04007 
04008         itemp32 = (int32_t)(
04009             pout->algo__crosstalk_compensation_plane_offset_kcps *
04010                 x_gradient_scaler);
04011         itemp32 = itemp32 >> 6;
04012         if (itemp32 > 0xFFFF)
04013             itemp32 = 0xFFFF;
04014 
04015         pout->algo__crosstalk_compensation_x_plane_gradient_kcps =
04016             (int16_t)itemp32;
04017 
04018         itemp32 = (int32_t)(
04019             pout->algo__crosstalk_compensation_plane_offset_kcps *
04020                 y_gradient_scaler);
04021         itemp32 = itemp32 >> 6;
04022         if (itemp32 > 0xFFFF)
04023             itemp32 = 0xFFFF;
04024 
04025         pout->algo__crosstalk_compensation_y_plane_gradient_kcps =
04026             (int16_t)itemp32;
04027     } else if (pconfig->scaler_calc_method == 1) {
04028 
04029 
04030         itemp32 = (int32_t)(orig_xtalk_offset -
04031             pout->algo__crosstalk_compensation_plane_offset_kcps);
04032         itemp32 = (int32_t)(do_division_s(itemp32, 16));
04033         itemp32 = itemp32 << 2;
04034         itemp32 = itemp32 + (int32_t)(orig_x_gradient);
04035         if (itemp32 > 0xFFFF)
04036             itemp32 = 0xFFFF;
04037 
04038         pout->algo__crosstalk_compensation_x_plane_gradient_kcps =
04039             (int16_t)itemp32;
04040 
04041         itemp32 = (int32_t)(orig_xtalk_offset -
04042             pout->algo__crosstalk_compensation_plane_offset_kcps);
04043         itemp32 = (int32_t)(do_division_s(itemp32, 80));
04044         itemp32 = itemp32 << 2;
04045         itemp32 = itemp32 + (int32_t)(orig_y_gradient);
04046         if (itemp32 > 0xFFFF)
04047             itemp32 = 0xFFFF;
04048 
04049         pout->algo__crosstalk_compensation_y_plane_gradient_kcps =
04050             (int16_t)itemp32;
04051     }
04052 
04053 
04054     if (pconfig->smudge_corr_apply_enabled == 1 &&
04055             (soft_update != 1)) {
04056         pout->new_xtalk_applied_flag = 1;
04057         nXtalk = pout->algo__crosstalk_compensation_plane_offset_kcps;
04058 
04059         VL53L1_compute_histo_merge_nb(Dev, &histo_merge_nb);
04060         max = pdev->tuning_parms.tp_hist_merge_max_size;
04061         pcpo = &(pC->algo__xtalk_cpo_HistoMerge_kcps[0]);
04062         if ((histo_merge_nb > 0) && merge_enabled && (nXtalk != 0)) {
04063             cXtalk =
04064             pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb-1];
04065             SmudgeFactor = cXtalk * 1000 / nXtalk;
04066             if (SmudgeFactor >= pconfig->max_smudge_factor)
04067                 pout->new_xtalk_applied_flag = 0;
04068             else if (SmudgeFactor > 0)
04069                 for (i = 0; i < max; i++) {
04070                 *pcpo *= 1000;
04071                 *pcpo /= SmudgeFactor;
04072                 pcpo++;
04073                 }
04074         }
04075         if (pout->new_xtalk_applied_flag) {
04076 
04077         pX->algo__crosstalk_compensation_plane_offset_kcps =
04078         pout->algo__crosstalk_compensation_plane_offset_kcps;
04079         pX->algo__crosstalk_compensation_x_plane_gradient_kcps =
04080         pout->algo__crosstalk_compensation_x_plane_gradient_kcps;
04081         pX->algo__crosstalk_compensation_y_plane_gradient_kcps =
04082         pout->algo__crosstalk_compensation_y_plane_gradient_kcps;
04083 
04084         if (pconfig->smudge_corr_single_apply == 1) {
04085 
04086             pconfig->smudge_corr_apply_enabled = 0;
04087             pconfig->smudge_corr_single_apply = 0;
04088         }
04089         }
04090     }
04091 
04092 
04093     if (soft_update != 1)
04094         pout->smudge_corr_valid = 1;
04095 
04096     LOG_FUNCTION_END(status);
04097 
04098     return status;
04099 }
04100 
04101 #define CONT_CONTINUE   0
04102 #define CONT_NEXT_LOOP  1
04103 #define CONT_RESET  2
04104 VL53L1_Error VL53L1_dynamic_xtalk_correction_corrector(
04105     VL53L1_DEV                          Dev
04106     )
04107 {
04108 
04109 
04110 
04111     VL53L1_Error  status = VL53L1_ERROR_NONE;
04112 
04113     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04114     VL53L1_LLDriverResults_t *pres = VL53L1DevStructGetLLResultsHandle(Dev);
04115     VL53L1_smudge_corrector_config_t *pconfig =
04116                 &(pdev->smudge_correct_config);
04117     VL53L1_smudge_corrector_internals_t *pint =
04118                 &(pdev->smudge_corrector_internals);
04119     VL53L1_smudge_corrector_data_t *pout =
04120             &(pres->range_results.smudge_corrector_data);
04121     VL53L1_range_results_t  *pR = &(pres->range_results);
04122     VL53L1_xtalk_config_t  *pX = &(pdev->xtalk_cfg);
04123 
04124     uint8_t run_smudge_detection = 0;
04125     uint8_t merging_complete = 0;
04126     uint8_t run_nodetect = 0;
04127     uint8_t ambient_check = 0;
04128     int32_t itemp32 = 0;
04129     uint64_t utemp64 = 0;
04130     uint8_t continue_processing = CONT_CONTINUE;
04131     uint32_t xtalk_offset_out = 0;
04132     uint32_t xtalk_offset_in = 0;
04133     uint32_t current_xtalk = 0;
04134     uint32_t smudge_margin_adjusted = 0;
04135     uint8_t i = 0;
04136     uint8_t nodetect_index = 0;
04137     uint16_t    amr;
04138     uint32_t    cco;
04139     uint8_t histo_merge_nb;
04140     uint8_t merge_enabled;
04141 
04142 
04143     LOG_FUNCTION_START("");
04144 
04145     merge_enabled = (pdev->tuning_parms.tp_hist_merge == 1) &&
04146         (VL53L1DevDataGet(Dev, CurrentParameters.PresetMode) ==
04147          VL53L1_PRESETMODE_RANGING);
04148 
04149     VL53L1_compute_histo_merge_nb(Dev, &histo_merge_nb);
04150     if ((histo_merge_nb == 0) || (!merge_enabled))
04151         histo_merge_nb = 1;
04152 
04153 
04154     VL53L1_dynamic_xtalk_correction_output_init(pres);
04155 
04156 
04157     ambient_check = (pconfig->smudge_corr_ambient_threshold == 0) ||
04158         ((pconfig->smudge_corr_ambient_threshold * histo_merge_nb) >
04159         ((uint32_t)pR->xmonitor.ambient_count_rate_mcps));
04160 
04161 
04162     merging_complete = ((!merge_enabled) ||
04163     (histo_merge_nb == pdev->tuning_parms.tp_hist_merge_max_size));
04164 
04165     run_smudge_detection =
04166         (pconfig->smudge_corr_enabled == 1) &&
04167         ambient_check &&
04168         (pR->xmonitor.range_status
04169             == VL53L1_DEVICEERROR_RANGECOMPLETE) &&
04170         merging_complete;
04171 
04172 
04173     if ((pR->xmonitor.range_status
04174         != VL53L1_DEVICEERROR_RANGECOMPLETE) &&
04175             (pconfig->smudge_corr_enabled == 1)) {
04176 
04177         run_nodetect = 2;
04178         for (i = 0; i < pR->active_results; i++) {
04179             if (pR->VL53L1_p_002[i].range_status ==
04180                 VL53L1_DEVICEERROR_RANGECOMPLETE) {
04181                 if (pR->VL53L1_p_002[i].median_range_mm
04182                         <=
04183                     pconfig->nodetect_min_range_mm) {
04184                     run_nodetect = 0;
04185                 } else {
04186                     if (run_nodetect == 2) {
04187                         run_nodetect = 1;
04188                         nodetect_index = i;
04189                     }
04190                 }
04191             }
04192         }
04193 
04194         if (run_nodetect == 2)
04195 
04196             run_nodetect = 0;
04197 
04198         amr =
04199         pR->VL53L1_p_002[nodetect_index].ambient_count_rate_mcps;
04200 
04201         if (run_nodetect == 1) {
04202 
04203 
04204 
04205 
04206             utemp64 = 1000 * ((uint64_t)amr);
04207 
04208 
04209             utemp64 = utemp64 << 9;
04210 
04211 
04212             if (utemp64 < pconfig->nodetect_ambient_threshold)
04213                 run_nodetect = 1;
04214             else
04215                 run_nodetect = 0;
04216 
04217         }
04218     }
04219 
04220 
04221     if (run_smudge_detection) {
04222 
04223         pint->nodetect_counter = 0;
04224 
04225 
04226         VL53L1_dynamic_xtalk_correction_calc_required_samples(Dev);
04227 
04228 
04229         xtalk_offset_in =
04230             pR->xmonitor.VL53L1_p_012;
04231 
04232 
04233         cco = pX->algo__crosstalk_compensation_plane_offset_kcps;
04234         current_xtalk = ((uint32_t)cco) << 2;
04235 
04236 
04237         smudge_margin_adjusted =
04238                 ((uint32_t)(pconfig->smudge_margin)) << 2;
04239 
04240 
04241         itemp32 = xtalk_offset_in - current_xtalk +
04242             smudge_margin_adjusted;
04243 
04244         if (itemp32 < 0)
04245             itemp32 = itemp32 * (-1);
04246 
04247 
04248         if (itemp32 > ((int32_t)pconfig->single_xtalk_delta)) {
04249             if ((int32_t)xtalk_offset_in >
04250                 ((int32_t)current_xtalk -
04251                     (int32_t)smudge_margin_adjusted)) {
04252                 pout->single_xtalk_delta_flag = 1;
04253             } else {
04254                 pout->single_xtalk_delta_flag = 2;
04255             }
04256         }
04257 
04258 
04259         pint->current_samples = pint->current_samples + 1;
04260 
04261 
04262         if (pint->current_samples > pconfig->sample_limit) {
04263             pout->sample_limit_exceeded_flag = 1;
04264             continue_processing = CONT_RESET;
04265         } else {
04266             pint->accumulator = pint->accumulator +
04267                 xtalk_offset_in;
04268         }
04269 
04270         if (pint->current_samples < pint->required_samples)
04271             continue_processing = CONT_NEXT_LOOP;
04272 
04273 
04274         xtalk_offset_out =
04275         (uint32_t)(do_division_u(pint->accumulator,
04276             pint->current_samples));
04277 
04278 
04279         itemp32 = xtalk_offset_out - current_xtalk +
04280             smudge_margin_adjusted;
04281 
04282         if (itemp32 < 0)
04283             itemp32 = itemp32 * (-1);
04284 
04285         if (continue_processing == CONT_CONTINUE &&
04286             (itemp32 >= ((int32_t)(pconfig->averaged_xtalk_delta)))
04287             ) {
04288             if ((int32_t)xtalk_offset_out >
04289                 ((int32_t)current_xtalk -
04290                     (int32_t)smudge_margin_adjusted))
04291                 pout->averaged_xtalk_delta_flag = 1;
04292             else
04293                 pout->averaged_xtalk_delta_flag = 2;
04294         }
04295 
04296         if (continue_processing == CONT_CONTINUE &&
04297             (itemp32 < ((int32_t)(pconfig->averaged_xtalk_delta)))
04298             )
04299 
04300             continue_processing = CONT_RESET;
04301 
04302 
04303 
04304         pout->smudge_corr_clipped = 0;
04305         if ((continue_processing == CONT_CONTINUE) &&
04306             (pconfig->smudge_corr_clip_limit != 0)) {
04307             if (xtalk_offset_out >
04308             (pconfig->smudge_corr_clip_limit * histo_merge_nb)) {
04309                 pout->smudge_corr_clipped = 1;
04310                 continue_processing = CONT_RESET;
04311             }
04312         }
04313 
04314 
04315 
04316         if (pconfig->user_xtalk_offset_limit_hi &&
04317             (xtalk_offset_out >
04318                 pconfig->user_xtalk_offset_limit))
04319             xtalk_offset_out =
04320                 pconfig->user_xtalk_offset_limit;
04321 
04322 
04323 
04324         if ((pconfig->user_xtalk_offset_limit_hi == 0) &&
04325             (xtalk_offset_out <
04326                 pconfig->user_xtalk_offset_limit))
04327             xtalk_offset_out =
04328                 pconfig->user_xtalk_offset_limit;
04329 
04330 
04331 
04332         xtalk_offset_out = xtalk_offset_out >> 2;
04333         if (xtalk_offset_out > 0x3FFFF)
04334             xtalk_offset_out = 0x3FFFF;
04335 
04336 
04337         if (continue_processing == CONT_CONTINUE) {
04338 
04339             VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
04340                 Dev,
04341                 xtalk_offset_out,
04342                 pconfig,
04343                 pout,
04344                 1,
04345                 0
04346                 );
04347 
04348 
04349             continue_processing = CONT_RESET;
04350         } else {
04351 
04352             VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
04353                 Dev,
04354                 xtalk_offset_out,
04355                 pconfig,
04356                 pout,
04357                 1,
04358                 1
04359                 );
04360         }
04361 
04362 
04363         if (continue_processing == CONT_RESET) {
04364             pint->accumulator = 0;
04365             pint->current_samples = 0;
04366             pint->nodetect_counter = 0;
04367         }
04368 
04369     }
04370 
04371     continue_processing = CONT_CONTINUE;
04372     if (run_nodetect == 1) {
04373 
04374         pint->nodetect_counter += 1;
04375 
04376 
04377         if (pint->nodetect_counter < pconfig->nodetect_sample_limit)
04378             continue_processing = CONT_NEXT_LOOP;
04379 
04380 
04381         xtalk_offset_out = (uint32_t)(pconfig->nodetect_xtalk_offset);
04382 
04383         if (continue_processing == CONT_CONTINUE) {
04384 
04385             VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
04386                 Dev,
04387                 xtalk_offset_out,
04388                 pconfig,
04389                 pout,
04390                 0,
04391                 0
04392                 );
04393 
04394 
04395             pout->smudge_corr_valid = 2;
04396 
04397 
04398             continue_processing = CONT_RESET;
04399         } else {
04400 
04401             VL53L1_dynamic_xtalk_correction_calc_new_xtalk(
04402                 Dev,
04403                 xtalk_offset_out,
04404                 pconfig,
04405                 pout,
04406                 0,
04407                 1
04408                 );
04409         }
04410 
04411 
04412         if (continue_processing == CONT_RESET) {
04413             pint->accumulator = 0;
04414             pint->current_samples = 0;
04415             pint->nodetect_counter = 0;
04416         }
04417     }
04418 
04419     LOG_FUNCTION_END(status);
04420 
04421     return status;
04422 }
04423 
04424 VL53L1_Error VL53L1_dynamic_xtalk_correction_data_init(
04425     VL53L1_DEV                          Dev
04426     )
04427 {
04428 
04429 
04430 
04431 
04432     VL53L1_Error  status = VL53L1_ERROR_NONE;
04433 
04434     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04435     VL53L1_LLDriverResults_t *pres = VL53L1DevStructGetLLResultsHandle(Dev);
04436 
04437     LOG_FUNCTION_START("");
04438 
04439 
04440 
04441     pdev->smudge_correct_config.smudge_corr_enabled       = 1;
04442     pdev->smudge_correct_config.smudge_corr_apply_enabled = 1;
04443     pdev->smudge_correct_config.smudge_corr_single_apply  =
04444         VL53L1_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY_DEFAULT;
04445 
04446     pdev->smudge_correct_config.smudge_margin =
04447         VL53L1_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN_DEFAULT;
04448     pdev->smudge_correct_config.noise_margin =
04449         VL53L1_TUNINGPARM_DYNXTALK_NOISE_MARGIN_DEFAULT;
04450     pdev->smudge_correct_config.user_xtalk_offset_limit =
04451         VL53L1_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_DEFAULT;
04452     pdev->smudge_correct_config.user_xtalk_offset_limit_hi =
04453         VL53L1_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI_DEFAULT;
04454     pdev->smudge_correct_config.sample_limit =
04455         VL53L1_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT_DEFAULT;
04456     pdev->smudge_correct_config.single_xtalk_delta =
04457         VL53L1_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA_DEFAULT;
04458     pdev->smudge_correct_config.averaged_xtalk_delta =
04459         VL53L1_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA_DEFAULT;
04460     pdev->smudge_correct_config.smudge_corr_clip_limit =
04461         VL53L1_TUNINGPARM_DYNXTALK_CLIP_LIMIT_DEFAULT;
04462     pdev->smudge_correct_config.smudge_corr_ambient_threshold =
04463         VL53L1_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD_DEFAULT;
04464     pdev->smudge_correct_config.scaler_calc_method =
04465         0;
04466     pdev->smudge_correct_config.x_gradient_scaler =
04467         VL53L1_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER_DEFAULT;
04468     pdev->smudge_correct_config.y_gradient_scaler =
04469         VL53L1_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER_DEFAULT;
04470     pdev->smudge_correct_config.user_scaler_set =
04471         VL53L1_TUNINGPARM_DYNXTALK_USER_SCALER_SET_DEFAULT;
04472     pdev->smudge_correct_config.nodetect_ambient_threshold =
04473         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS_DEFAULT;
04474     pdev->smudge_correct_config.nodetect_sample_limit =
04475         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT_DEFAULT;
04476     pdev->smudge_correct_config.nodetect_xtalk_offset =
04477         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS_DEFAULT;
04478     pdev->smudge_correct_config.nodetect_min_range_mm =
04479         VL53L1_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM_DEFAULT;
04480     pdev->smudge_correct_config.max_smudge_factor =
04481         VL53L1_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR_DEFAULT;
04482 
04483 
04484     pdev->smudge_corrector_internals.current_samples = 0;
04485     pdev->smudge_corrector_internals.required_samples = 0;
04486     pdev->smudge_corrector_internals.accumulator = 0;
04487     pdev->smudge_corrector_internals.nodetect_counter = 0;
04488 
04489 
04490     VL53L1_dynamic_xtalk_correction_output_init(pres);
04491 
04492     LOG_FUNCTION_END(status);
04493 
04494     return status;
04495 }
04496 
04497 VL53L1_Error VL53L1_dynamic_xtalk_correction_output_init(
04498     VL53L1_LLDriverResults_t *pres
04499     )
04500 {
04501 
04502 
04503 
04504 
04505     VL53L1_Error  status = VL53L1_ERROR_NONE;
04506 
04507     VL53L1_smudge_corrector_data_t *pdata;
04508 
04509     LOG_FUNCTION_START("");
04510 
04511 
04512     pdata = &(pres->range_results.smudge_corrector_data);
04513 
04514     pdata->smudge_corr_valid = 0;
04515     pdata->smudge_corr_clipped = 0;
04516     pdata->single_xtalk_delta_flag = 0;
04517     pdata->averaged_xtalk_delta_flag = 0;
04518     pdata->sample_limit_exceeded_flag = 0;
04519     pdata->gradient_zero_flag = 0;
04520     pdata->new_xtalk_applied_flag = 0;
04521 
04522     pdata->algo__crosstalk_compensation_plane_offset_kcps = 0;
04523     pdata->algo__crosstalk_compensation_x_plane_gradient_kcps = 0;
04524     pdata->algo__crosstalk_compensation_y_plane_gradient_kcps = 0;
04525 
04526     LOG_FUNCTION_END(status);
04527 
04528     return status;
04529 }
04530 
04531 
04532 VL53L1_Error VL53L1_xtalk_cal_data_init(
04533     VL53L1_DEV                          Dev
04534     )
04535 {
04536 
04537 
04538 
04539 
04540     VL53L1_Error  status = VL53L1_ERROR_NONE;
04541 
04542     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04543 
04544     LOG_FUNCTION_START("");
04545 
04546 
04547 
04548     pdev->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps = 0;
04549     pdev->xtalk_cal.algo__crosstalk_compensation_x_plane_gradient_kcps = 0;
04550     pdev->xtalk_cal.algo__crosstalk_compensation_y_plane_gradient_kcps = 0;
04551     memset(&pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0], 0,
04552         sizeof(pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps));
04553 
04554     LOG_FUNCTION_END(status);
04555 
04556     return status;
04557 }
04558 
04559 
04560 
04561 
04562 
04563 
04564 VL53L1_Error VL53L1_low_power_auto_data_init(
04565     VL53L1_DEV                          Dev
04566     )
04567 {
04568 
04569 
04570 
04571 
04572     VL53L1_Error  status = VL53L1_ERROR_NONE;
04573 
04574     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04575 
04576     LOG_FUNCTION_START("");
04577 
04578     pdev->low_power_auto_data.vhv_loop_bound =
04579         VL53L1_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND_DEFAULT;
04580     pdev->low_power_auto_data.is_low_power_auto_mode = 0;
04581     pdev->low_power_auto_data.low_power_auto_range_count = 0;
04582     pdev->low_power_auto_data.saved_interrupt_config = 0;
04583     pdev->low_power_auto_data.saved_vhv_init = 0;
04584     pdev->low_power_auto_data.saved_vhv_timeout = 0;
04585     pdev->low_power_auto_data.first_run_phasecal_result = 0;
04586     pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
04587     pdev->low_power_auto_data.dss__required_spads = 0;
04588 
04589     LOG_FUNCTION_END(status);
04590 
04591     return status;
04592 }
04593 
04594 VL53L1_Error VL53L1_low_power_auto_data_stop_range(
04595     VL53L1_DEV                          Dev
04596     )
04597 {
04598 
04599 
04600 
04601 
04602     VL53L1_Error  status = VL53L1_ERROR_NONE;
04603 
04604     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04605 
04606     LOG_FUNCTION_START("");
04607 
04608 
04609 
04610     pdev->low_power_auto_data.low_power_auto_range_count = 0xFF;
04611 
04612     pdev->low_power_auto_data.first_run_phasecal_result = 0;
04613     pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
04614     pdev->low_power_auto_data.dss__required_spads = 0;
04615 
04616 
04617     if (pdev->low_power_auto_data.saved_vhv_init != 0)
04618         pdev->stat_nvm.vhv_config__init =
04619             pdev->low_power_auto_data.saved_vhv_init;
04620     if (pdev->low_power_auto_data.saved_vhv_timeout != 0)
04621         pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
04622             pdev->low_power_auto_data.saved_vhv_timeout;
04623 
04624 
04625     pdev->gen_cfg.phasecal_config__override = 0x00;
04626 
04627     LOG_FUNCTION_END(status);
04628 
04629     return status;
04630 }
04631 
04632 VL53L1_Error VL53L1_config_low_power_auto_mode(
04633     VL53L1_general_config_t   *pgeneral,
04634     VL53L1_dynamic_config_t   *pdynamic,
04635     VL53L1_low_power_auto_data_t *plpadata
04636     )
04637 {
04638 
04639 
04640 
04641 
04642     VL53L1_Error  status = VL53L1_ERROR_NONE;
04643 
04644     LOG_FUNCTION_START("");
04645 
04646 
04647     plpadata->is_low_power_auto_mode = 1;
04648 
04649 
04650     plpadata->low_power_auto_range_count = 0;
04651 
04652 
04653     pdynamic->system__sequence_config =
04654             VL53L1_SEQUENCE_VHV_EN |
04655             VL53L1_SEQUENCE_PHASECAL_EN |
04656             VL53L1_SEQUENCE_DSS1_EN |
04657 
04658 
04659 
04660             VL53L1_SEQUENCE_RANGE_EN;
04661 
04662 
04663     pgeneral->dss_config__manual_effective_spads_select = 200 << 8;
04664     pgeneral->dss_config__roi_mode_control =
04665         VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
04666 
04667     LOG_FUNCTION_END(status);
04668 
04669     return status;
04670 }
04671 
04672 VL53L1_Error VL53L1_low_power_auto_setup_manual_calibration(
04673     VL53L1_DEV        Dev)
04674 {
04675 
04676 
04677 
04678     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04679 
04680 
04681     VL53L1_Error  status = VL53L1_ERROR_NONE;
04682 
04683     LOG_FUNCTION_START("");
04684 
04685 
04686     pdev->low_power_auto_data.saved_vhv_init =
04687         pdev->stat_nvm.vhv_config__init;
04688     pdev->low_power_auto_data.saved_vhv_timeout =
04689         pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound;
04690 
04691 
04692     pdev->stat_nvm.vhv_config__init &= 0x7F;
04693 
04694     pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
04695         (pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound & 0x03) +
04696         (pdev->low_power_auto_data.vhv_loop_bound << 2);
04697 
04698     pdev->gen_cfg.phasecal_config__override = 0x01;
04699     pdev->low_power_auto_data.first_run_phasecal_result =
04700         pdev->dbg_results.phasecal_result__vcsel_start;
04701     pdev->gen_cfg.cal_config__vcsel_start =
04702         pdev->low_power_auto_data.first_run_phasecal_result;
04703 
04704     LOG_FUNCTION_END(status);
04705 
04706     return status;
04707 }
04708 
04709 VL53L1_Error VL53L1_low_power_auto_update_DSS(
04710     VL53L1_DEV        Dev)
04711 {
04712 
04713 
04714 
04715     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04716 
04717     VL53L1_system_results_t *pS = &(pdev->sys_results);
04718 
04719 
04720     VL53L1_Error  status = VL53L1_ERROR_NONE;
04721 
04722     uint32_t utemp32a;
04723 
04724     LOG_FUNCTION_START("");
04725 
04726 
04727 
04728 
04729     utemp32a =
04730         pS->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0
04731          + pS->result__ambient_count_rate_mcps_sd0;
04732 
04733 
04734     if (utemp32a > 0xFFFF)
04735         utemp32a = 0xFFFF;
04736 
04737 
04738 
04739     utemp32a = utemp32a << 16;
04740 
04741 
04742     if (pdev->sys_results.result__dss_actual_effective_spads_sd0 == 0)
04743         status = VL53L1_ERROR_DIVISION_BY_ZERO;
04744     else {
04745 
04746         utemp32a = utemp32a /
04747         pdev->sys_results.result__dss_actual_effective_spads_sd0;
04748 
04749         pdev->low_power_auto_data.dss__total_rate_per_spad_mcps =
04750             utemp32a;
04751 
04752 
04753         utemp32a = pdev->stat_cfg.dss_config__target_total_rate_mcps <<
04754             16;
04755 
04756 
04757         if (pdev->low_power_auto_data.dss__total_rate_per_spad_mcps
04758                 == 0)
04759             status = VL53L1_ERROR_DIVISION_BY_ZERO;
04760         else {
04761 
04762             utemp32a = utemp32a /
04763             pdev->low_power_auto_data.dss__total_rate_per_spad_mcps;
04764 
04765 
04766             if (utemp32a > 0xFFFF)
04767                 utemp32a = 0xFFFF;
04768 
04769 
04770             pdev->low_power_auto_data.dss__required_spads =
04771                 (uint16_t)utemp32a;
04772 
04773 
04774             pdev->gen_cfg.dss_config__manual_effective_spads_select
04775             = pdev->low_power_auto_data.dss__required_spads;
04776             pdev->gen_cfg.dss_config__roi_mode_control =
04777             VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
04778         }
04779 
04780     }
04781 
04782     if (status == VL53L1_ERROR_DIVISION_BY_ZERO) {
04783 
04784 
04785 
04786         pdev->low_power_auto_data.dss__required_spads = 0x8000;
04787 
04788 
04789         pdev->gen_cfg.dss_config__manual_effective_spads_select =
04790             pdev->low_power_auto_data.dss__required_spads;
04791         pdev->gen_cfg.dss_config__roi_mode_control =
04792             VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
04793 
04794 
04795         status = VL53L1_ERROR_NONE;
04796     }
04797 
04798     LOG_FUNCTION_END(status);
04799 
04800     return status;
04801 }
04802 
04803 
04804 
04805 
04806 VL53L1_Error VL53L1_compute_histo_merge_nb(
04807     VL53L1_DEV        Dev,  uint8_t *histo_merge_nb)
04808 {
04809     VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
04810     VL53L1_Error  status = VL53L1_ERROR_NONE;
04811     uint8_t i, timing;
04812     uint8_t sum = 0;
04813 
04814     timing = (pdev->hist_data.bin_seq[0] == 7 ? 1 : 0);
04815     for (i = 0; i < VL53L1_BIN_REC_SIZE; i++)
04816         if (pdev->multi_bins_rec[i][timing][7] > 0)
04817             sum++;
04818     *histo_merge_nb = sum;
04819 
04820     return status;
04821 }
04822