John Alexander / VL53L3_Lib

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Dependents:   VL53L3ExpansionBoard

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53lx_class.cpp Source File

vl53lx_class.cpp

00001 /**
00002  ******************************************************************************
00003  * @file    vl53l3x_class.cpp
00004  * @author  IMG
00005  * @version V0.0.1
00006  * @date    14-December-2018
00007  * @brief   Implementation file for the VL53LX driver class
00008  ******************************************************************************
00009  * @attention
00010  *
00011  * <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
00012  *
00013  * Redistribution and use in source and binary forms, with or without modification,
00014  * are permitted provided that the following conditions are met:
00015  *   1. Redistributions of source code must retain the above copyright notice,
00016  *      this list of conditions and the following disclaimer.
00017  *   2. Redistributions in binary form must reproduce the above copyright notice,
00018  *      this list of conditions and the following disclaimer in the documentation
00019  *      and/or other materials provided with the distribution.
00020  *   3. Neither the name of STMicroelectronics nor the names of its contributors
00021  *      may be used to endorse or promote products derived from this software
00022  *      without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00030  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00032  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  ******************************************************************************
00036 */
00037 
00038 /* Includes */
00039 #include <stdlib.h>
00040 
00041 #include "mbed.h"
00042 
00043 #include "pinmap.h"
00044 //#include "Arduino.h"
00045 #include "vl53lx_class.h"
00046 #include "vl53L3_I2c.h"
00047 
00048 #define TEMP_BUF_SIZE 80
00049 
00050 
00051 /* Write and read functions from I2C */
00052 
00053 VL53LX_Error VL53LX::VL53LX_WriteMulti(VL53LX_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count)
00054 {
00055   int  status;
00056 
00057   status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, pdata, (uint16_t)count);
00058   return status;
00059 }
00060 
00061 VL53LX_Error VL53LX::VL53LX_ReadMulti(VL53LX_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count)
00062 {
00063   int status;
00064 
00065   status = VL53LX_I2CRead(Dev->I2cDevAddr, index, pdata, (uint16_t)count);
00066 
00067   return status;
00068 }
00069 
00070 
00071 VL53LX_Error VL53LX::VL53LX_WrByte(VL53LX_DEV Dev, uint16_t index, uint8_t data)
00072 {
00073   int  status;
00074   status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, &data, 1);
00075   return status;
00076 }
00077 
00078 VL53LX_Error VL53LX::VL53LX_WrWord(VL53LX_DEV Dev, uint16_t index, uint16_t data)
00079 {
00080   int  status;
00081   uint8_t buffer[2];
00082 
00083   buffer[0] = data >> 8;
00084   buffer[1] = data & 0x00FF;
00085   status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, (uint8_t *)buffer, 2);
00086   return status;
00087 }
00088 
00089 VL53LX_Error VL53LX::VL53LX_WrDWord(VL53LX_DEV Dev, uint16_t index, uint32_t data)
00090 {
00091   int  status;
00092   uint8_t buffer[4];
00093 
00094   buffer[0] = (data >> 24) & 0xFF;
00095   buffer[1] = (data >> 16) & 0xFF;
00096   buffer[2] = (data >>  8) & 0xFF;
00097   buffer[3] = (data >>  0) & 0xFF;
00098   status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, (uint8_t *)buffer, 4);
00099   return status;
00100 }
00101 
00102 
00103 VL53LX_Error VL53LX::VL53LX_RdByte(VL53LX_DEV Dev, uint16_t index, uint8_t *data)
00104 {
00105   int  status;
00106 
00107   status = VL53LX_I2CRead(Dev->I2cDevAddr, index, data, 1);
00108 
00109   if (status) {
00110     printf("VL53LX_RdByte fail %d %d %d \n",Dev->I2cDevAddr,index,status);
00111     return -1;
00112   }
00113 
00114   return 0;
00115 }
00116 
00117 VL53LX_Error VL53LX::VL53LX_RdWord(VL53LX_DEV Dev, uint16_t index, uint16_t *data)
00118 {
00119   int  status;
00120   uint8_t buffer[2] = {0, 0};
00121 
00122   status = VL53LX_I2CRead(Dev->I2cDevAddr, index, buffer, 2);
00123   if (!status) {
00124     *data = (buffer[0] << 8) + buffer[1];
00125   }
00126   return status;
00127 
00128 }
00129 
00130 VL53LX_Error VL53LX::VL53LX_RdDWord(VL53LX_DEV Dev, uint16_t index, uint32_t *data)
00131 {
00132   int status;
00133   uint8_t buffer[4] = {0, 0, 0, 0};
00134 
00135   status = VL53LX_I2CRead(Dev->I2cDevAddr, index, buffer, 4);
00136   if (!status) {
00137     *data = ((uint32_t)buffer[0] << 24) + ((uint32_t)buffer[1] << 16) + ((uint32_t)buffer[2] << 8) + (uint32_t)buffer[3];
00138   }
00139   return status;
00140 
00141 }
00142 
00143 VL53LX_Error VL53LX::VL53LX_UpdateByte(VL53LX_DEV Dev, uint16_t index, uint8_t AndData, uint8_t OrData)
00144 {
00145   int  status;
00146   uint8_t buffer = 0;
00147 
00148   /* read data direct onto buffer */
00149   status = VL53LX_I2CRead(Dev->I2cDevAddr, index, &buffer, 1);
00150   if (!status) {
00151     buffer = (buffer & AndData) | OrData;
00152     status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, &buffer, (uint16_t)1);
00153   }
00154   return status;
00155 }
00156 /*
00157 
00158 VL53LX_Error VL53LX::VL53LX_I2CWrite(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToWrite) {
00159     int ret;
00160     uint8_t tmp[TEMP_BUF_SIZE];
00161 
00162     if(NumByteToWrite >= TEMP_BUF_SIZE) return -2;
00163 
00164     // First, send device address. Then, send data and STOP condition
00165     tmp[0] = RegisterAddr >> 8;
00166     tmp[1] = RegisterAddr & 0x0FF;
00167     memcpy(tmp+2, pBuffer, NumByteToWrite);
00168 
00169     ret = write(DeviceAddr, (const char*)tmp, NumByteToWrite+2, false);
00170 
00171     if(ret) return -1;
00172     return 0;
00173 }
00174 */
00175 
00176 
00177 VL53LX_Error VL53LX::VL53LX_I2CWrite(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToWrite)
00178 {
00179     
00180    return  dev_i2c->VL53L3_i2c_write(pBuffer,DeviceAddr,RegisterAddr,NumByteToWrite);
00181 }
00182 
00183 
00184 VL53LX_Error VL53LX::VL53LX_I2CRead(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToRead)
00185 {
00186   
00187     return   dev_i2c->VL53L3_i2c_read(pBuffer,DeviceAddr,RegisterAddr,NumByteToRead);
00188 }
00189 
00190 
00191 VL53LX_Error VL53LX::VL53LX_GetTickCount(
00192   uint32_t *ptick_count_ms)
00193 {
00194 
00195   /* Returns current tick count in [ms] */
00196 
00197   VL53LX_Error status  = VL53LX_ERROR_NONE;
00198 
00199   *ptick_count_ms = us_ticker_read() / 1000;
00200  // *ptick_count_ms = 0;
00201 
00202   return status;
00203 }
00204 
00205 
00206 
00207 VL53LX_Error VL53LX::VL53LX_WaitUs(VL53LX_Dev_t *pdev, int32_t wait_num_us)
00208 {
00209   (void)pdev;
00210   //delay(wait_us / 1000);
00211   wait_ms(wait_num_us/1000);
00212   return VL53LX_ERROR_NONE;
00213 }
00214 
00215 
00216 VL53LX_Error VL53LX::VL53LX_WaitMs(VL53LX_Dev_t *pdev, int32_t wait_num_ms)
00217 {
00218   (void)pdev;
00219   wait_ms(wait_num_ms);
00220   return VL53LX_ERROR_NONE;
00221 }
00222 
00223 
00224 VL53LX_Error VL53LX::VL53LX_WaitValueMaskEx(
00225   VL53LX_Dev_t *pdev,
00226   uint32_t      timeout_ms,
00227   uint16_t      index,
00228   uint8_t       value,
00229   uint8_t       mask,
00230   uint32_t      poll_delay_ms)
00231 {
00232 
00233   /*
00234    * Platform implementation of WaitValueMaskEx V2WReg script command
00235    *
00236    * WaitValueMaskEx(
00237    *          duration_ms,
00238    *          index,
00239    *          value,
00240    *          mask,
00241    *          poll_delay_ms);
00242    */
00243 
00244   VL53LX_Error status         = VL53LX_ERROR_NONE;
00245   uint32_t     start_time_ms = 0;
00246   uint32_t     current_time_ms = 0;
00247   uint32_t     polling_time_ms = 0;
00248   uint8_t      byte_value      = 0;
00249   uint8_t      found           = 0;
00250 
00251 
00252 
00253   /* calculate time limit in absolute time */
00254 
00255   VL53LX_GetTickCount(&start_time_ms);
00256 
00257   /* remember current trace functions and temporarily disable
00258    * function logging
00259    */
00260 
00261 
00262   /* wait until value is found, timeout reached on error occurred */
00263 
00264   while ((status == VL53LX_ERROR_NONE) &&
00265          (polling_time_ms < timeout_ms) &&
00266          (found == 0)) {
00267 
00268     if (status == VL53LX_ERROR_NONE)
00269       status = VL53LX_RdByte(
00270                  pdev,
00271                  index,
00272                  &byte_value);
00273 
00274 
00275     if ((byte_value & mask) == value) {
00276       found = 1;
00277     }
00278 
00279     if (status == VL53LX_ERROR_NONE  &&
00280         found == 0 &&
00281         poll_delay_ms > 0)
00282       status = VL53LX_WaitMs(
00283                  pdev,
00284                  poll_delay_ms);
00285 
00286     /* Update polling time (Compare difference rather than absolute to
00287     negate 32bit wrap around issue) */
00288     VL53LX_GetTickCount(&current_time_ms);
00289     polling_time_ms = current_time_ms - start_time_ms;
00290 
00291   }
00292 
00293 
00294   if (found == 0 && status == VL53LX_ERROR_NONE) {
00295     status = VL53LX_ERROR_TIME_OUT;
00296   }
00297 
00298   return status;
00299 }
00300 
00301 
00302 
00303 /* vl53lx_api_core.c */
00304 VL53LX_Error VL53LX::select_offset_per_vcsel(VL53LX_LLDriverData_t *pdev, int16_t *poffset)
00305 {
00306   VL53LX_Error status = VL53LX_ERROR_NONE;
00307   int16_t tA, tB;
00308   uint8_t isc;
00309 
00310   switch (pdev->preset_mode) {
00311     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
00312       tA = pdev->per_vcsel_cal_data.short_a_offset_mm;
00313       tB = pdev->per_vcsel_cal_data.short_b_offset_mm;
00314       break;
00315     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE:
00316       tA = pdev->per_vcsel_cal_data.medium_a_offset_mm;
00317       tB = pdev->per_vcsel_cal_data.medium_b_offset_mm;
00318       break;
00319     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE:
00320       tA = pdev->per_vcsel_cal_data.long_a_offset_mm;
00321       tB = pdev->per_vcsel_cal_data.long_b_offset_mm;
00322       break;
00323     default:
00324       tA = pdev->per_vcsel_cal_data.long_a_offset_mm;
00325       tB = pdev->per_vcsel_cal_data.long_b_offset_mm;
00326       status = VL53LX_ERROR_INVALID_PARAMS;
00327       *poffset = 0;
00328       break;
00329   }
00330 
00331   isc = pdev->ll_state.cfg_internal_stream_count;
00332   if (status == VL53LX_ERROR_NONE) {
00333     *poffset = (isc & 0x01) ? tA : tB;
00334   }
00335 
00336   return status;
00337 }
00338 
00339 
00340 void VL53LX::vl53lx_diff_histo_stddev(VL53LX_LLDriverData_t *pdev, VL53LX_histogram_bin_data_t *pdata, uint8_t timing, uint8_t HighIndex, uint8_t prev_pos, int32_t *pdiff_histo_stddev)
00341 {
00342   uint16_t   bin                      = 0;
00343   int32_t    total_rate_pre = 0;
00344   int32_t    total_rate_cur = 0;
00345   int32_t    PrevBin, CurrBin;
00346 
00347   total_rate_pre = 0;
00348   total_rate_cur = 0;
00349 
00350 
00351   for (bin = timing * 4; bin < HighIndex; bin++) {
00352     total_rate_pre +=
00353       pdev->multi_bins_rec[prev_pos][timing][bin];
00354     total_rate_cur += pdata->bin_data[bin];
00355   }
00356 
00357   if ((total_rate_pre != 0) && (total_rate_cur != 0))
00358     for (bin = timing * 4; bin < HighIndex; bin++) {
00359       PrevBin = pdev->multi_bins_rec[prev_pos][timing][bin];
00360       PrevBin = (PrevBin * 1000) / total_rate_pre;
00361       CurrBin = pdata->bin_data[bin] * 1000 / total_rate_cur;
00362       *pdiff_histo_stddev += (PrevBin - CurrBin) *
00363                              (PrevBin - CurrBin);
00364     }
00365 }
00366 
00367 
00368 void VL53LX::vl53lx_histo_merge(VL53LX_histogram_bin_data_t *pdata)
00369 {
00370   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
00371   uint16_t   bin                      = 0;
00372   uint8_t    i                        = 0;
00373   int32_t    TuningBinRecSize       = 0;
00374   uint8_t    recom_been_reset     = 0;
00375   uint8_t    timing         = 0;
00376   int32_t    rmt  = 0;
00377   int32_t    diff_histo_stddev    = 0;
00378   uint8_t    HighIndex, prev_pos;
00379   uint8_t    BuffSize = VL53LX_HISTOGRAM_BUFFER_SIZE;
00380   uint8_t    pos;
00381 
00382   VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE,
00383                          &TuningBinRecSize);
00384 
00385   VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD,
00386                          &rmt);
00387 
00388 
00389   if (pdev->pos_before_next_recom == 0) {
00390 
00391     timing = 1 - pdata->result__stream_count % 2;
00392 
00393     diff_histo_stddev = 0;
00394     HighIndex = BuffSize - timing * 4;
00395     if (pdev->bin_rec_pos > 0) {
00396       prev_pos = pdev->bin_rec_pos - 1;
00397     } else {
00398       prev_pos = (TuningBinRecSize - 1);
00399     }
00400 
00401     if (pdev->multi_bins_rec[prev_pos][timing][4] > 0)
00402       vl53lx_diff_histo_stddev(pdev, pdata,
00403                                timing, HighIndex, prev_pos,
00404                                &diff_histo_stddev);
00405 
00406     if (diff_histo_stddev >= rmt) {
00407       memset(pdev->multi_bins_rec, 0,
00408              sizeof(pdev->multi_bins_rec));
00409       pdev->bin_rec_pos = 0;
00410 
00411       recom_been_reset = 1;
00412 
00413       if (timing == 0)
00414         pdev->pos_before_next_recom =
00415           VL53LX_FRAME_WAIT_EVENT;
00416       else
00417         pdev->pos_before_next_recom =
00418           VL53LX_FRAME_WAIT_EVENT + 1;
00419     } else {
00420 
00421       pos = pdev->bin_rec_pos;
00422       for (i = 0; i < BuffSize; i++)
00423         pdev->multi_bins_rec[pos][timing][i] =
00424           pdata->bin_data[i];
00425     }
00426 
00427     if (pdev->bin_rec_pos == (TuningBinRecSize - 1) && timing == 1) {
00428       pdev->bin_rec_pos = 0;
00429     } else if (timing == 1) {
00430       pdev->bin_rec_pos++;
00431     }
00432 
00433     if (!((recom_been_reset == 1) && (timing == 0)) &&
00434         (pdev->pos_before_next_recom == 0)) {
00435 
00436       for (bin = 0; bin < BuffSize; bin++) {
00437         pdata->bin_data[bin] = 0;
00438       }
00439 
00440       for (bin = 0; bin < BuffSize; bin++)
00441         for (i = 0; i < TuningBinRecSize; i++)
00442           pdata->bin_data[bin] +=
00443             (pdev->multi_bins_rec[i][timing][bin]);
00444     }
00445   } else {
00446 
00447     pdev->pos_before_next_recom--;
00448     if (pdev->pos_before_next_recom == 255) {
00449       pdev->pos_before_next_recom = 0;
00450     }
00451   }
00452 }
00453 
00454 VL53LX_Error VL53LX::VL53LX_load_patch()
00455 {
00456   VL53LX_Error status = VL53LX_ERROR_NONE;
00457   int32_t patch_tuning = 0;
00458   uint8_t comms_buffer[256];
00459   uint32_t patch_power;
00460 
00461   if (status == VL53LX_ERROR_NONE)
00462     status = VL53LX_WrByte(Dev,
00463                            VL53LX_FIRMWARE__ENABLE, 0x00);
00464 
00465   if (status == VL53LX_ERROR_NONE) {
00466     VL53LX_enable_powerforce();
00467   }
00468 
00469   VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER,
00470                          &patch_tuning);
00471 
00472   switch (patch_tuning) {
00473     case 0:
00474       patch_power = 0x00;
00475       break;
00476     case 1:
00477       patch_power = 0x10;
00478       break;
00479     case 2:
00480       patch_power = 0x20;
00481       break;
00482     case 3:
00483       patch_power = 0x40;
00484       break;
00485     default:
00486       patch_power = 0x00;
00487   }
00488 
00489   if (status == VL53LX_ERROR_NONE) {
00490 
00491     comms_buffer[0] = 0x29;
00492     comms_buffer[1] = 0xC9;
00493     comms_buffer[2] = 0x0E;
00494     comms_buffer[3] = 0x40;
00495     comms_buffer[4] = 0x28;
00496     comms_buffer[5] = patch_power;
00497 
00498     status = VL53LX_WriteMulti(Dev,
00499                                VL53LX_PATCH__OFFSET_0, comms_buffer, 6);
00500   }
00501 
00502   if (status == VL53LX_ERROR_NONE) {
00503     comms_buffer[0] = 0x03;
00504     comms_buffer[1] = 0x6D;
00505     comms_buffer[2] = 0x03;
00506     comms_buffer[3] = 0x6F;
00507     comms_buffer[4] = 0x07;
00508     comms_buffer[5] = 0x29;
00509     status = VL53LX_WriteMulti(Dev,
00510                                VL53LX_PATCH__ADDRESS_0, comms_buffer, 6);
00511   }
00512 
00513   if (status == VL53LX_ERROR_NONE) {
00514     comms_buffer[0] = 0x00;
00515     comms_buffer[1] = 0x07;
00516     status = VL53LX_WriteMulti(Dev, VL53LX_PATCH__JMP_ENABLES, comms_buffer, 2);
00517   }
00518 
00519   if (status == VL53LX_ERROR_NONE) {
00520     comms_buffer[0] = 0x00;
00521     comms_buffer[1] = 0x07;
00522     status = VL53LX_WriteMulti(Dev,
00523                                VL53LX_PATCH__DATA_ENABLES, comms_buffer, 2);
00524   }
00525 
00526   if (status == VL53LX_ERROR_NONE)
00527     status = VL53LX_WrByte(Dev,
00528                            VL53LX_PATCH__CTRL, 0x01);
00529 
00530   if (status == VL53LX_ERROR_NONE)
00531     status = VL53LX_WrByte(Dev,
00532                            VL53LX_FIRMWARE__ENABLE, 0x01);
00533 
00534 
00535   return status;
00536 }
00537 
00538 VL53LX_Error VL53LX:: VL53LX_unload_patch()
00539 {
00540   VL53LX_Error status = VL53LX_ERROR_NONE;
00541 
00542   if (status == VL53LX_ERROR_NONE) {
00543     status = VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x00);
00544   }
00545 
00546   if (status == VL53LX_ERROR_NONE) {
00547     VL53LX_disable_powerforce();
00548   }
00549 
00550   if (status == VL53LX_ERROR_NONE) {
00551     status = VL53LX_WrByte(Dev, VL53LX_PATCH__CTRL, 0x00);
00552   }
00553 
00554   if (status == VL53LX_ERROR_NONE) {
00555     status = VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x01);
00556   }
00557 
00558 
00559 
00560   return status;
00561 }
00562 
00563 VL53LX_Error VL53LX::VL53LX_get_version(VL53LX_ll_version_t *pdata)
00564 {
00565   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
00566 
00567   VL53LX_init_version();
00568 
00569   memcpy(pdata, &(pdev->version), sizeof(VL53LX_ll_version_t));
00570 
00571   return VL53LX_ERROR_NONE;
00572 }
00573 
00574 VL53LX_Error VL53LX::VL53LX_get_device_firmware_version(uint16_t         *pfw_version)
00575 {
00576   VL53LX_Error  status = VL53LX_ERROR_NONE;
00577 
00578 
00579   if (status == VL53LX_ERROR_NONE) {
00580     status = VL53LX_disable_firmware();
00581   }
00582 
00583   if (status == VL53LX_ERROR_NONE)
00584     status = VL53LX_RdWord(
00585                Dev,
00586                VL53LX_MCU_GENERAL_PURPOSE__GP_0,
00587                pfw_version);
00588 
00589   if (status == VL53LX_ERROR_NONE) {
00590     status = VL53LX_enable_firmware();
00591   }
00592 
00593   return status;
00594 }
00595 
00596 
00597 
00598 VL53LX_Error VL53LX::VL53LX_data_init(uint8_t           read_p2p_data)
00599 {
00600   VL53LX_Error status       = VL53LX_ERROR_NONE;
00601   VL53LX_LLDriverData_t    *pdev =
00602     VL53LXDevStructGetLLDriverHandle(Dev);
00603   VL53LX_LLDriverResults_t *pres =
00604     VL53LXDevStructGetLLResultsHandle(Dev);
00605 
00606 
00607 
00608   VL53LX_zone_objects_t    *pobjects;
00609 
00610   uint8_t  i = 0;
00611 
00612   VL53LX_init_ll_driver_state(VL53LX_DEVICESTATE_UNKNOWN);
00613 
00614   pres->range_results.max_results    = VL53LX_MAX_RANGE_RESULTS;
00615   pres->range_results.active_results = 0;
00616   pres->zone_results.max_zones       = VL53LX_MAX_USER_ZONES;
00617   pres->zone_results.active_zones    = 0;
00618 
00619   for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) {
00620     pobjects = &(pres->zone_results.VL53LX_p_003[i]);
00621     pobjects->xmonitor.VL53LX_p_016 = 0;
00622     pobjects->xmonitor.VL53LX_p_017  = 0;
00623     pobjects->xmonitor.VL53LX_p_011          = 0;
00624     pobjects->xmonitor.range_status =
00625       VL53LX_DEVICEERROR_NOUPDATE;
00626   }
00627 
00628 
00629 
00630   pres->zone_hists.max_zones         = VL53LX_MAX_USER_ZONES;
00631   pres->zone_hists.active_zones      = 0;
00632 
00633 
00634 
00635   pres->zone_cal.max_zones           = VL53LX_MAX_USER_ZONES;
00636   pres->zone_cal.active_zones        = 0;
00637   for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) {
00638     pres->zone_cal.VL53LX_p_003[i].no_of_samples   = 0;
00639     pres->zone_cal.VL53LX_p_003[i].effective_spads = 0;
00640     pres->zone_cal.VL53LX_p_003[i].peak_rate_mcps  = 0;
00641     pres->zone_cal.VL53LX_p_003[i].median_range_mm = 0;
00642     pres->zone_cal.VL53LX_p_003[i].range_mm_offset = 0;
00643   }
00644 
00645   pdev->wait_method             = VL53LX_WAIT_METHOD_BLOCKING;
00646   pdev->preset_mode   = VL53LX_DEVICEPRESETMODE_STANDARD_RANGING;
00647   pdev->zone_preset             = VL53LX_DEVICEZONEPRESET_NONE;
00648   pdev->measurement_mode        = VL53LX_DEVICEMEASUREMENTMODE_STOP;
00649 
00650   pdev->offset_calibration_mode =
00651     VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD;
00652   pdev->offset_correction_mode  =
00653     VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS;
00654   pdev->dmax_mode  =
00655     VL53LX_DEVICEDMAXMODE__FMT_CAL_DATA;
00656 
00657   pdev->phasecal_config_timeout_us  =  1000;
00658   pdev->mm_config_timeout_us        =  2000;
00659   pdev->range_config_timeout_us     = 13000;
00660   pdev->inter_measurement_period_ms =   100;
00661   pdev->dss_config__target_total_rate_mcps = 0x0A00;
00662   pdev->debug_mode                  =  0x00;
00663 
00664   pdev->offset_results.max_results    = VL53LX_MAX_OFFSET_RANGE_RESULTS;
00665   pdev->offset_results.active_results = 0;
00666 
00667 
00668 
00669   pdev->gain_cal.standard_ranging_gain_factor =
00670     VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR_DEFAULT;
00671   pdev->gain_cal.histogram_ranging_gain_factor =
00672     VL53LX_TUNINGPARM_HIST_GAIN_FACTOR_DEFAULT;
00673 
00674 
00675   VL53LX_init_version();
00676 
00677 
00678   memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec));
00679   pdev->bin_rec_pos = 0;
00680   pdev->pos_before_next_recom = 0;
00681 
00682 
00683 
00684   if (read_p2p_data > 0 && status == VL53LX_ERROR_NONE) {
00685     status = VL53LX_read_p2p_data();
00686   }
00687 
00688 
00689   if (status == VL53LX_ERROR_NONE)
00690     status = VL53LX_init_refspadchar_config_struct(
00691                &(pdev->refspadchar));
00692 
00693 
00694   if (status == VL53LX_ERROR_NONE)
00695     status = VL53LX_init_ssc_config_struct(
00696                &(pdev->ssc_cfg));
00697 
00698 
00699   if (status == VL53LX_ERROR_NONE)
00700     status = VL53LX_init_xtalk_config_struct(
00701                &(pdev->customer),
00702                &(pdev->xtalk_cfg));
00703 
00704 
00705   if (status == VL53LX_ERROR_NONE)
00706     status = VL53LX_init_xtalk_extract_config_struct(
00707                &(pdev->xtalk_extract_cfg));
00708 
00709 
00710   if (status == VL53LX_ERROR_NONE)
00711     status = VL53LX_init_offset_cal_config_struct(
00712                &(pdev->offsetcal_cfg));
00713 
00714 
00715   if (status == VL53LX_ERROR_NONE)
00716     status = VL53LX_init_zone_cal_config_struct(
00717                &(pdev->zonecal_cfg));
00718 
00719 
00720   if (status == VL53LX_ERROR_NONE)
00721     status = VL53LX_init_hist_post_process_config_struct(
00722                pdev->xtalk_cfg.global_crosstalk_compensation_enable,
00723                &(pdev->histpostprocess));
00724 
00725 
00726   if (status == VL53LX_ERROR_NONE)
00727     status = VL53LX_init_hist_gen3_dmax_config_struct(
00728                &(pdev->dmax_cfg));
00729 
00730 
00731   if (status == VL53LX_ERROR_NONE)
00732     status = VL53LX_init_tuning_parm_storage_struct(
00733                &(pdev->tuning_parms));
00734 
00735 
00736 
00737   if (status == VL53LX_ERROR_NONE)
00738     status = VL53LX_set_preset_mode(
00739                pdev->preset_mode,
00740                pdev->dss_config__target_total_rate_mcps,
00741                pdev->phasecal_config_timeout_us,
00742                pdev->mm_config_timeout_us,
00743                pdev->range_config_timeout_us,
00744                pdev->inter_measurement_period_ms);
00745 
00746 
00747   VL53LX_init_histogram_bin_data_struct(
00748     0,
00749     VL53LX_HISTOGRAM_BUFFER_SIZE,
00750     &(pdev->hist_data));
00751 
00752   VL53LX_init_histogram_bin_data_struct(
00753     0,
00754     VL53LX_HISTOGRAM_BUFFER_SIZE,
00755     &(pdev->hist_xtalk));
00756 
00757 
00758   VL53LX_init_xtalk_bin_data_struct(
00759     0,
00760     VL53LX_XTALK_HISTO_BINS,
00761     &(pdev->xtalk_shapes.xtalk_shape));
00762 
00763 
00764 
00765   VL53LX_xtalk_cal_data_init();
00766 
00767 
00768 
00769   VL53LX_dynamic_xtalk_correction_data_init();
00770 
00771 
00772 
00773   VL53LX_low_power_auto_data_init();
00774   /*
00775   #ifdef VL53LX_LOG_ENABLE
00776 
00777 
00778 
00779     VL53LX_print_static_nvm_managed(
00780       &(pdev->stat_nvm),
00781       "data_init():pdev->lldata.stat_nvm.",
00782       VL53LX_TRACE_MODULE_DATA_INIT);
00783 
00784     VL53LX_print_customer_nvm_managed(
00785       &(pdev->customer),
00786       "data_init():pdev->lldata.customer.",
00787       VL53LX_TRACE_MODULE_DATA_INIT);
00788 
00789     VL53LX_print_nvm_copy_data(
00790       &(pdev->nvm_copy_data),
00791       "data_init():pdev->lldata.nvm_copy_data.",
00792       VL53LX_TRACE_MODULE_DATA_INIT);
00793 
00794     VL53LX_print_dmax_calibration_data(
00795       &(pdev->fmt_dmax_cal),
00796       "data_init():pdev->lldata.fmt_dmax_cal.",
00797       VL53LX_TRACE_MODULE_DATA_INIT);
00798 
00799     VL53LX_print_dmax_calibration_data(
00800       &(pdev->cust_dmax_cal),
00801       "data_init():pdev->lldata.cust_dmax_cal.",
00802       VL53LX_TRACE_MODULE_DATA_INIT);
00803 
00804     VL53LX_print_additional_offset_cal_data(
00805       &(pdev->add_off_cal_data),
00806       "data_init():pdev->lldata.add_off_cal_data.",
00807       VL53LX_TRACE_MODULE_DATA_INIT);
00808 
00809     VL53LX_print_user_zone(
00810       &(pdev->mm_roi),
00811       "data_init():pdev->lldata.mm_roi.",
00812       VL53LX_TRACE_MODULE_DATA_INIT);
00813 
00814     VL53LX_print_optical_centre(
00815       &(pdev->optical_centre),
00816       "data_init():pdev->lldata.optical_centre.",
00817       VL53LX_TRACE_MODULE_DATA_INIT);
00818 
00819     VL53LX_print_cal_peak_rate_map(
00820       &(pdev->cal_peak_rate_map),
00821       "data_init():pdev->lldata.cal_peak_rate_map.",
00822       VL53LX_TRACE_MODULE_DATA_INIT);
00823 
00824   #endif
00825 
00826     LOG_FUNCTION_END(status);
00827   */
00828   return status;
00829 }
00830 
00831 VL53LX_Error VL53LX::VL53LX_read_p2p_data()
00832 {
00833   VL53LX_Error status       = VL53LX_ERROR_NONE;
00834   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
00835   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
00836   VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
00837   VL53LX_additional_offset_cal_data_t *pCD = &(pdev->add_off_cal_data);
00838 
00839   VL53LX_decoded_nvm_fmt_range_data_t fmt_rrd;
00840 
00841   if (status == VL53LX_ERROR_NONE) {
00842     status = VL53LX_get_static_nvm_managed(&(pdev->stat_nvm));
00843   }
00844 
00845   if (status == VL53LX_ERROR_NONE) {
00846     status = VL53LX_get_customer_nvm_managed(&(pdev->customer));
00847   }
00848 
00849   if (status == VL53LX_ERROR_NONE) {
00850 
00851     status = VL53LX_get_nvm_copy_data(&(pdev->nvm_copy_data));
00852 
00853 
00854     if (status == VL53LX_ERROR_NONE)
00855       VL53LX_copy_rtn_good_spads_to_buffer(
00856         &(pdev->nvm_copy_data),
00857         &(pdev->rtn_good_spads[0]));
00858   }
00859 
00860 
00861 
00862   if (status == VL53LX_ERROR_NONE) {
00863     pHP->algo__crosstalk_compensation_plane_offset_kcps =
00864       pN->algo__crosstalk_compensation_plane_offset_kcps;
00865     pHP->algo__crosstalk_compensation_x_plane_gradient_kcps =
00866       pN->algo__crosstalk_compensation_x_plane_gradient_kcps;
00867     pHP->algo__crosstalk_compensation_y_plane_gradient_kcps =
00868       pN->algo__crosstalk_compensation_y_plane_gradient_kcps;
00869   }
00870 
00871 
00872   if (status == VL53LX_ERROR_NONE)
00873     status =
00874       VL53LX_read_nvm_optical_centre(&(pdev->optical_centre));
00875 
00876 
00877 
00878   if (status == VL53LX_ERROR_NONE)
00879     status =
00880       VL53LX_read_nvm_cal_peak_rate_map(&(pdev->cal_peak_rate_map));
00881 
00882 
00883 
00884   if (status == VL53LX_ERROR_NONE) {
00885 
00886     status =
00887       VL53LX_read_nvm_additional_offset_cal_data(&(pdev->add_off_cal_data));
00888 
00889 
00890 
00891     if (pCD->result__mm_inner_peak_signal_count_rtn_mcps == 0 &&
00892         pCD->result__mm_outer_peak_signal_count_rtn_mcps == 0) {
00893 
00894       pCD->result__mm_inner_peak_signal_count_rtn_mcps
00895         = 0x0080;
00896       pCD->result__mm_outer_peak_signal_count_rtn_mcps
00897         = 0x0180;
00898 
00899 
00900 
00901       VL53LX_calc_mm_effective_spads(
00902         pdev->nvm_copy_data.roi_config__mode_roi_centre_spad,
00903         pdev->nvm_copy_data.roi_config__mode_roi_xy_size,
00904         0xC7,
00905         0xFF,
00906         &(pdev->rtn_good_spads[0]),
00907         VL53LX_RTN_SPAD_APERTURE_TRANSMISSION,
00908         &(pCD->result__mm_inner_actual_effective_spads),
00909         &(pCD->result__mm_outer_actual_effective_spads));
00910     }
00911   }
00912 
00913 
00914   if (status == VL53LX_ERROR_NONE) {
00915 
00916     status =
00917       VL53LX_read_nvm_fmt_range_results_data(VL53LX_NVM__FMT__RANGE_RESULTS__140MM_DARK,
00918                                              &fmt_rrd);
00919 
00920     if (status == VL53LX_ERROR_NONE) {
00921       pdev->fmt_dmax_cal.ref__actual_effective_spads =
00922         fmt_rrd.result__actual_effective_rtn_spads;
00923       pdev->fmt_dmax_cal.ref__peak_signal_count_rate_mcps =
00924         fmt_rrd.result__peak_signal_count_rate_rtn_mcps;
00925       pdev->fmt_dmax_cal.ref__distance_mm =
00926         fmt_rrd.measured_distance_mm;
00927 
00928 
00929       if (pdev->cal_peak_rate_map.cal_reflectance_pc != 0) {
00930         pdev->fmt_dmax_cal.ref_reflectance_pc =
00931           pdev->cal_peak_rate_map.cal_reflectance_pc;
00932       } else {
00933         pdev->fmt_dmax_cal.ref_reflectance_pc = 0x0014;
00934       }
00935 
00936 
00937       pdev->fmt_dmax_cal.coverglass_transmission = 0x0100;
00938     }
00939   }
00940 
00941 
00942   if (status == VL53LX_ERROR_NONE)
00943     status =
00944       VL53LX_RdWord(
00945         Dev,
00946         VL53LX_RESULT__OSC_CALIBRATE_VAL,
00947         &(pdev->dbg_results.result__osc_calibrate_val));
00948 
00949 
00950 
00951   if (pdev->stat_nvm.osc_measured__fast_osc__frequency < 0x1000) {
00952 
00953     pdev->stat_nvm.osc_measured__fast_osc__frequency = 0xBCCC;
00954   }
00955 
00956 
00957 
00958   if (status == VL53LX_ERROR_NONE)
00959     status =
00960       VL53LX_get_mode_mitigation_roi(&(pdev->mm_roi));
00961 
00962 
00963 
00964   if (pdev->optical_centre.x_centre == 0 &&
00965       pdev->optical_centre.y_centre == 0) {
00966     pdev->optical_centre.x_centre =
00967       pdev->mm_roi.x_centre << 4;
00968     pdev->optical_centre.y_centre =
00969       pdev->mm_roi.y_centre << 4;
00970   }
00971 
00972 
00973   return status;
00974 }
00975 
00976 
00977 
00978 VL53LX_Error VL53LX::VL53LX_software_reset()
00979 {
00980   VL53LX_Error status       = VL53LX_ERROR_NONE;
00981 
00982   if (status == VL53LX_ERROR_NONE)
00983     status = VL53LX_WrByte(
00984                Dev,
00985                VL53LX_SOFT_RESET,
00986                0x00);
00987 
00988 
00989   if (status == VL53LX_ERROR_NONE)
00990     status =
00991       VL53LX_WaitUs(
00992         Dev,
00993         VL53LX_SOFTWARE_RESET_DURATION_US);
00994 
00995 
00996   if (status == VL53LX_ERROR_NONE)
00997     status = VL53LX_WrByte(
00998                Dev,
00999                VL53LX_SOFT_RESET,
01000                0x01);
01001 
01002 
01003   if (status == VL53LX_ERROR_NONE) {
01004     status = VL53LX_wait_for_boot_completion();
01005   }
01006 
01007   return status;
01008 }
01009 
01010 VL53LX_Error VL53LX::VL53LX_set_part_to_part_data(VL53LX_calibration_data_t            *pcal_data)
01011 {
01012   VL53LX_Error  status = VL53LX_ERROR_NONE;
01013   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01014   VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
01015   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
01016   VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
01017 
01018   uint32_t tempu32;
01019 
01020 
01021   if (pcal_data->struct_version !=
01022       VL53LX_LL_CALIBRATION_DATA_STRUCT_VERSION) {
01023     status = VL53LX_ERROR_INVALID_PARAMS;
01024   }
01025 
01026   if (status == VL53LX_ERROR_NONE) {
01027 
01028 
01029     memcpy(
01030       &(pdev->customer),
01031       &(pcal_data->customer),
01032       sizeof(VL53LX_customer_nvm_managed_t));
01033 
01034 
01035     memcpy(
01036       &(pdev->add_off_cal_data),
01037       &(pcal_data->add_off_cal_data),
01038       sizeof(VL53LX_additional_offset_cal_data_t));
01039 
01040 
01041     memcpy(
01042       &(pdev->fmt_dmax_cal),
01043       &(pcal_data->fmt_dmax_cal),
01044       sizeof(VL53LX_dmax_calibration_data_t));
01045 
01046 
01047     memcpy(
01048       &(pdev->cust_dmax_cal),
01049       &(pcal_data->cust_dmax_cal),
01050       sizeof(VL53LX_dmax_calibration_data_t));
01051 
01052 
01053     memcpy(
01054       &(pdev->xtalk_shapes),
01055       &(pcal_data->xtalkhisto),
01056       sizeof(VL53LX_xtalk_histogram_data_t));
01057 
01058 
01059     memcpy(
01060       &(pdev->gain_cal),
01061       &(pcal_data->gain_cal),
01062       sizeof(VL53LX_gain_calibration_data_t));
01063 
01064 
01065     memcpy(
01066       &(pdev->cal_peak_rate_map),
01067       &(pcal_data->cal_peak_rate_map),
01068       sizeof(VL53LX_cal_peak_rate_map_t));
01069 
01070 
01071     memcpy(
01072       &(pdev->per_vcsel_cal_data),
01073       &(pcal_data->per_vcsel_cal_data),
01074       sizeof(VL53LX_per_vcsel_period_offset_cal_data_t));
01075 
01076 
01077 
01078     pC->algo__crosstalk_compensation_plane_offset_kcps =
01079       pN->algo__crosstalk_compensation_plane_offset_kcps;
01080     pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
01081       pN->algo__crosstalk_compensation_x_plane_gradient_kcps;
01082     pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
01083       pN->algo__crosstalk_compensation_y_plane_gradient_kcps;
01084 
01085     pHP->algo__crosstalk_compensation_plane_offset_kcps =
01086       VL53LX_calc_crosstalk_plane_offset_with_margin(
01087         pC->algo__crosstalk_compensation_plane_offset_kcps,
01088         pC->histogram_mode_crosstalk_margin_kcps);
01089 
01090     pHP->algo__crosstalk_compensation_x_plane_gradient_kcps =
01091       pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
01092     pHP->algo__crosstalk_compensation_y_plane_gradient_kcps =
01093       pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
01094 
01095 
01096 
01097     if (pC->global_crosstalk_compensation_enable == 0x00) {
01098       pN->algo__crosstalk_compensation_plane_offset_kcps =
01099         0x00;
01100       pN->algo__crosstalk_compensation_x_plane_gradient_kcps =
01101         0x00;
01102       pN->algo__crosstalk_compensation_y_plane_gradient_kcps =
01103         0x00;
01104     } else {
01105       tempu32 =
01106         VL53LX_calc_crosstalk_plane_offset_with_margin(
01107           pC->algo__crosstalk_compensation_plane_offset_kcps,
01108           pC->lite_mode_crosstalk_margin_kcps);
01109 
01110 
01111       if (tempu32 > 0xFFFF) {
01112         tempu32 = 0xFFFF;
01113       }
01114 
01115       pN->algo__crosstalk_compensation_plane_offset_kcps =
01116         (uint16_t)tempu32;
01117     }
01118   }
01119 
01120 
01121   return status;
01122 }
01123 
01124 VL53LX_Error VL53LX::VL53LX_get_part_to_part_data(VL53LX_calibration_data_t      *pcal_data)
01125 {
01126   VL53LX_Error  status = VL53LX_ERROR_NONE;
01127   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01128   VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
01129   VL53LX_customer_nvm_managed_t *pCN = &(pcal_data->customer);
01130 
01131   pcal_data->struct_version =
01132     VL53LX_LL_CALIBRATION_DATA_STRUCT_VERSION;
01133 
01134 
01135   memcpy(
01136     &(pcal_data->customer),
01137     &(pdev->customer),
01138     sizeof(VL53LX_customer_nvm_managed_t));
01139 
01140 
01141 
01142 
01143   if (pC->algo__crosstalk_compensation_plane_offset_kcps > 0xFFFF) {
01144     pCN->algo__crosstalk_compensation_plane_offset_kcps =
01145       0xFFFF;
01146   } else {
01147     pCN->algo__crosstalk_compensation_plane_offset_kcps =
01148       (uint16_t)pC->algo__crosstalk_compensation_plane_offset_kcps;
01149   }
01150   pCN->algo__crosstalk_compensation_x_plane_gradient_kcps =
01151     pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
01152   pCN->algo__crosstalk_compensation_y_plane_gradient_kcps =
01153     pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
01154 
01155 
01156   memcpy(
01157     &(pcal_data->fmt_dmax_cal),
01158     &(pdev->fmt_dmax_cal),
01159     sizeof(VL53LX_dmax_calibration_data_t));
01160 
01161 
01162   memcpy(
01163     &(pcal_data->cust_dmax_cal),
01164     &(pdev->cust_dmax_cal),
01165     sizeof(VL53LX_dmax_calibration_data_t));
01166 
01167 
01168   memcpy(
01169     &(pcal_data->add_off_cal_data),
01170     &(pdev->add_off_cal_data),
01171     sizeof(VL53LX_additional_offset_cal_data_t));
01172 
01173 
01174   memcpy(
01175     &(pcal_data->optical_centre),
01176     &(pdev->optical_centre),
01177     sizeof(VL53LX_optical_centre_t));
01178 
01179 
01180   memcpy(
01181     &(pcal_data->xtalkhisto),
01182     &(pdev->xtalk_shapes),
01183     sizeof(VL53LX_xtalk_histogram_data_t));
01184 
01185 
01186   memcpy(
01187     &(pcal_data->gain_cal),
01188     &(pdev->gain_cal),
01189     sizeof(VL53LX_gain_calibration_data_t));
01190 
01191 
01192   memcpy(
01193     &(pcal_data->cal_peak_rate_map),
01194     &(pdev->cal_peak_rate_map),
01195     sizeof(VL53LX_cal_peak_rate_map_t));
01196 
01197 
01198   memcpy(
01199     &(pcal_data->per_vcsel_cal_data),
01200     &(pdev->per_vcsel_cal_data),
01201     sizeof(VL53LX_per_vcsel_period_offset_cal_data_t));
01202 
01203   return status;
01204 }
01205 
01206 VL53LX_Error VL53LX::VL53LX_set_inter_measurement_period_ms(
01207   uint32_t                inter_measurement_period_ms)
01208 {
01209   VL53LX_Error  status = VL53LX_ERROR_NONE;
01210   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01211 
01212   if (pdev->dbg_results.result__osc_calibrate_val == 0) {
01213     status = VL53LX_ERROR_DIVISION_BY_ZERO;
01214   }
01215 
01216   if (status == VL53LX_ERROR_NONE) {
01217     pdev->inter_measurement_period_ms = inter_measurement_period_ms;
01218     pdev->tim_cfg.system__intermeasurement_period =
01219       inter_measurement_period_ms *
01220       (uint32_t)pdev->dbg_results.result__osc_calibrate_val;
01221   }
01222 
01223 
01224   return status;
01225 }
01226 
01227 VL53LX_Error VL53LX::VL53LX_get_inter_measurement_period_ms(uint32_t               *pinter_measurement_period_ms)
01228 {
01229   VL53LX_Error  status = VL53LX_ERROR_NONE;
01230   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01231 
01232   if (pdev->dbg_results.result__osc_calibrate_val == 0) {
01233     status = VL53LX_ERROR_DIVISION_BY_ZERO;
01234   }
01235 
01236   if (status == VL53LX_ERROR_NONE)
01237     *pinter_measurement_period_ms =
01238       pdev->tim_cfg.system__intermeasurement_period /
01239       (uint32_t)pdev->dbg_results.result__osc_calibrate_val;
01240 
01241   return status;
01242 }
01243 
01244 VL53LX_Error VL53LX::VL53LX_set_timeouts_us(
01245   uint32_t            phasecal_config_timeout_us,
01246   uint32_t            mm_config_timeout_us,
01247   uint32_t            range_config_timeout_us)
01248 {
01249   VL53LX_Error  status = VL53LX_ERROR_NONE;
01250   VL53LX_LLDriverData_t *pdev =
01251     VL53LXDevStructGetLLDriverHandle(Dev);
01252 
01253 
01254   if (pdev->stat_nvm.osc_measured__fast_osc__frequency == 0) {
01255     status = VL53LX_ERROR_DIVISION_BY_ZERO;
01256   }
01257 
01258   if (status == VL53LX_ERROR_NONE) {
01259 
01260     pdev->phasecal_config_timeout_us = phasecal_config_timeout_us;
01261     pdev->mm_config_timeout_us       = mm_config_timeout_us;
01262     pdev->range_config_timeout_us    = range_config_timeout_us;
01263 
01264     status =
01265       VL53LX_calc_timeout_register_values(
01266         phasecal_config_timeout_us,
01267         mm_config_timeout_us,
01268         range_config_timeout_us,
01269         pdev->stat_nvm.osc_measured__fast_osc__frequency,
01270         &(pdev->gen_cfg),
01271         &(pdev->tim_cfg));
01272   }
01273 
01274   return status;
01275 }
01276 
01277 VL53LX_Error VL53LX::VL53LX_get_timeouts_us(
01278   uint32_t            *pphasecal_config_timeout_us,
01279   uint32_t            *pmm_config_timeout_us,
01280   uint32_t      *prange_config_timeout_us)
01281 {
01282 
01283 
01284   VL53LX_Error  status = VL53LX_ERROR_NONE;
01285   VL53LX_LLDriverData_t *pdev =
01286     VL53LXDevStructGetLLDriverHandle(Dev);
01287 
01288   uint32_t  macro_period_us = 0;
01289   uint16_t  timeout_encoded = 0;
01290 
01291   if (pdev->stat_nvm.osc_measured__fast_osc__frequency == 0) {
01292     status = VL53LX_ERROR_DIVISION_BY_ZERO;
01293   }
01294 
01295   if (status == VL53LX_ERROR_NONE) {
01296 
01297 
01298     macro_period_us =
01299       VL53LX_calc_macro_period_us(
01300         pdev->stat_nvm.osc_measured__fast_osc__frequency,
01301         pdev->tim_cfg.range_config__vcsel_period_a);
01302 
01303 
01304 
01305     *pphasecal_config_timeout_us =
01306       VL53LX_calc_timeout_us(
01307         (uint32_t)pdev->gen_cfg.phasecal_config__timeout_macrop,
01308         macro_period_us);
01309 
01310 
01311 
01312     timeout_encoded =
01313       (uint16_t)pdev->tim_cfg.mm_config__timeout_macrop_a_hi;
01314     timeout_encoded = (timeout_encoded << 8) +
01315                       (uint16_t)pdev->tim_cfg.mm_config__timeout_macrop_a_lo;
01316 
01317     *pmm_config_timeout_us =
01318       VL53LX_calc_decoded_timeout_us(
01319         timeout_encoded,
01320         macro_period_us);
01321 
01322 
01323 
01324     timeout_encoded =
01325       (uint16_t)pdev->tim_cfg.range_config__timeout_macrop_a_hi;
01326     timeout_encoded = (timeout_encoded << 8) +
01327                       (uint16_t)pdev->tim_cfg.range_config__timeout_macrop_a_lo;
01328 
01329     *prange_config_timeout_us =
01330       VL53LX_calc_decoded_timeout_us(
01331         timeout_encoded,
01332         macro_period_us);
01333 
01334     pdev->phasecal_config_timeout_us = *pphasecal_config_timeout_us;
01335     pdev->mm_config_timeout_us       = *pmm_config_timeout_us;
01336     pdev->range_config_timeout_us    = *prange_config_timeout_us;
01337 
01338   }
01339 
01340   return status;
01341 }
01342 
01343 VL53LX_Error VL53LX::VL53LX_set_calibration_repeat_period(
01344   uint16_t            cal_config__repeat_period)
01345 {
01346   VL53LX_Error  status = VL53LX_ERROR_NONE;
01347   VL53LX_LLDriverData_t *pdev =
01348     VL53LXDevStructGetLLDriverHandle(Dev);
01349 
01350   pdev->gen_cfg.cal_config__repeat_rate = cal_config__repeat_period;
01351 
01352   return status;
01353 
01354 }
01355 
01356 VL53LX_Error VL53LX::VL53LX_get_calibration_repeat_period(
01357   uint16_t           *pcal_config__repeat_period)
01358 {
01359 
01360 
01361   VL53LX_Error  status = VL53LX_ERROR_NONE;
01362   VL53LX_LLDriverData_t *pdev =
01363     VL53LXDevStructGetLLDriverHandle(Dev);
01364 
01365   *pcal_config__repeat_period = pdev->gen_cfg.cal_config__repeat_rate;
01366 
01367   return status;
01368 
01369 }
01370 
01371 VL53LX_Error VL53LX::VL53LX_set_sequence_config_bit(
01372   VL53LX_DeviceSequenceConfig   bit_id,
01373   uint8_t                       value)
01374 {
01375 
01376   VL53LX_Error  status = VL53LX_ERROR_NONE;
01377   VL53LX_LLDriverData_t *pdev =
01378     VL53LXDevStructGetLLDriverHandle(Dev);
01379 
01380   uint8_t  bit_mask        = 0x01;
01381   uint8_t  clr_mask        = 0xFF  - bit_mask;
01382   uint8_t  bit_value       = value & bit_mask;
01383 
01384   if (bit_id <= VL53LX_DEVICESEQUENCECONFIG_RANGE) {
01385 
01386     if (bit_id > 0) {
01387       bit_mask  = 0x01 << bit_id;
01388       bit_value = bit_value << bit_id;
01389       clr_mask  = 0xFF  - bit_mask;
01390     }
01391 
01392     pdev->dyn_cfg.system__sequence_config =
01393       (pdev->dyn_cfg.system__sequence_config & clr_mask) |
01394       bit_value;
01395 
01396   } else {
01397     status = VL53LX_ERROR_INVALID_PARAMS;
01398   }
01399 
01400   return status;
01401 
01402 }
01403 
01404 
01405 VL53LX_Error VL53LX::VL53LX_get_sequence_config_bit(
01406   VL53LX_DeviceSequenceConfig   bit_id,
01407   uint8_t                      *pvalue)
01408 {
01409   VL53LX_Error  status = VL53LX_ERROR_NONE;
01410   VL53LX_LLDriverData_t *pdev =
01411     VL53LXDevStructGetLLDriverHandle(Dev);
01412 
01413   uint8_t  bit_mask        = 0x01;
01414 
01415   if (bit_id <= VL53LX_DEVICESEQUENCECONFIG_RANGE) {
01416 
01417     if (bit_id > 0) {
01418       bit_mask  = 0x01 << bit_id;
01419     }
01420 
01421     *pvalue =
01422       pdev->dyn_cfg.system__sequence_config & bit_mask;
01423 
01424     if (bit_id > 0) {
01425       *pvalue  = *pvalue >> bit_id;
01426     }
01427 
01428   } else {
01429     status = VL53LX_ERROR_INVALID_PARAMS;
01430   }
01431 
01432   return status;
01433 }
01434 
01435 VL53LX_Error VL53LX::VL53LX_set_interrupt_polarity(
01436   VL53LX_DeviceInterruptPolarity  interrupt_polarity)
01437 {
01438   VL53LX_Error  status = VL53LX_ERROR_NONE;
01439   VL53LX_LLDriverData_t *pdev =
01440     VL53LXDevStructGetLLDriverHandle(Dev);
01441 
01442   pdev->stat_cfg.gpio_hv_mux__ctrl =
01443     (pdev->stat_cfg.gpio_hv_mux__ctrl &
01444      VL53LX_DEVICEINTERRUPTPOLARITY_CLEAR_MASK) |
01445     (interrupt_polarity &
01446      VL53LX_DEVICEINTERRUPTPOLARITY_BIT_MASK);
01447 
01448   return status;
01449 
01450 }
01451 
01452 VL53LX_Error VL53LX::VL53LX_set_refspadchar_config_struct(
01453   VL53LX_refspadchar_config_t   *pdata)
01454 {
01455   VL53LX_Error  status = VL53LX_ERROR_NONE;
01456   VL53LX_LLDriverData_t *pdev =
01457     VL53LXDevStructGetLLDriverHandle(Dev);
01458 
01459   pdev->refspadchar.device_test_mode = pdata->device_test_mode;
01460   pdev->refspadchar.VL53LX_p_005     = pdata->VL53LX_p_005;
01461   pdev->refspadchar.timeout_us       = pdata->timeout_us;
01462   pdev->refspadchar.target_count_rate_mcps    =
01463     pdata->target_count_rate_mcps;
01464   pdev->refspadchar.min_count_rate_limit_mcps =
01465     pdata->min_count_rate_limit_mcps;
01466   pdev->refspadchar.max_count_rate_limit_mcps =
01467     pdata->max_count_rate_limit_mcps;
01468 
01469 
01470   return status;
01471 }
01472 
01473 
01474 VL53LX_Error VL53LX::VL53LX_get_refspadchar_config_struct(
01475   VL53LX_refspadchar_config_t   *pdata)
01476 {
01477   VL53LX_Error  status = VL53LX_ERROR_NONE;
01478   VL53LX_LLDriverData_t *pdev =
01479     VL53LXDevStructGetLLDriverHandle(Dev);
01480 
01481   pdata->device_test_mode       = pdev->refspadchar.device_test_mode;
01482   pdata->VL53LX_p_005           = pdev->refspadchar.VL53LX_p_005;
01483   pdata->timeout_us             = pdev->refspadchar.timeout_us;
01484   pdata->target_count_rate_mcps =
01485     pdev->refspadchar.target_count_rate_mcps;
01486   pdata->min_count_rate_limit_mcps =
01487     pdev->refspadchar.min_count_rate_limit_mcps;
01488   pdata->max_count_rate_limit_mcps =
01489     pdev->refspadchar.max_count_rate_limit_mcps;
01490 
01491 
01492   return status;
01493 }
01494 
01495 VL53LX_Error VL53LX::VL53LX_set_range_ignore_threshold(
01496   uint8_t                 range_ignore_thresh_mult,
01497   uint16_t                range_ignore_threshold_mcps)
01498 {
01499 
01500 
01501   VL53LX_Error  status = VL53LX_ERROR_NONE;
01502   VL53LX_LLDriverData_t *pdev =
01503     VL53LXDevStructGetLLDriverHandle(Dev);
01504 
01505   pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps =
01506     range_ignore_threshold_mcps;
01507 
01508   pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult =
01509     range_ignore_thresh_mult;
01510 
01511   return status;
01512 
01513 }
01514 
01515 
01516 VL53LX_Error VL53LX::VL53LX_get_range_ignore_threshold(
01517   uint8_t                *prange_ignore_thresh_mult,
01518   uint16_t               *prange_ignore_threshold_mcps_internal,
01519   uint16_t               *prange_ignore_threshold_mcps_current)
01520 {
01521 
01522 
01523   VL53LX_Error  status = VL53LX_ERROR_NONE;
01524   VL53LX_LLDriverData_t *pdev =
01525     VL53LXDevStructGetLLDriverHandle(Dev);
01526 
01527   *prange_ignore_thresh_mult =
01528     pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult;
01529 
01530   *prange_ignore_threshold_mcps_current =
01531     pdev->stat_cfg.algo__range_ignore_threshold_mcps;
01532 
01533   *prange_ignore_threshold_mcps_internal =
01534     pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps;
01535 
01536   return status;
01537 
01538 }
01539 
01540 VL53LX_Error VL53LX::VL53LX_get_interrupt_polarity(
01541   VL53LX_DeviceInterruptPolarity  *pinterrupt_polarity)
01542 {
01543   VL53LX_Error  status = VL53LX_ERROR_NONE;
01544   VL53LX_LLDriverData_t *pdev =
01545     VL53LXDevStructGetLLDriverHandle(Dev);
01546 
01547   *pinterrupt_polarity =
01548     pdev->stat_cfg.gpio_hv_mux__ctrl &
01549     VL53LX_DEVICEINTERRUPTPOLARITY_BIT_MASK;
01550 
01551   return status;
01552 
01553 }
01554 
01555 VL53LX_Error VL53LX::VL53LX_set_user_zone(
01556   VL53LX_user_zone_t     *puser_zone)
01557 {
01558   VL53LX_Error  status = VL53LX_ERROR_NONE;
01559   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01560 
01561   VL53LX_encode_row_col(
01562     puser_zone->y_centre,
01563     puser_zone->x_centre,
01564     &(pdev->dyn_cfg.roi_config__user_roi_centre_spad));
01565 
01566 
01567   VL53LX_encode_zone_size(
01568     puser_zone->width,
01569     puser_zone->height,
01570     &(pdev->dyn_cfg.roi_config__user_roi_requested_global_xy_size));
01571 
01572 
01573   return status;
01574 }
01575 
01576 VL53LX_Error VL53LX::VL53LX_get_user_zone(
01577   VL53LX_user_zone_t     *puser_zone)
01578 {
01579   VL53LX_Error  status = VL53LX_ERROR_NONE;
01580   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01581 
01582   VL53LX_decode_row_col(
01583     pdev->dyn_cfg.roi_config__user_roi_centre_spad,
01584     &(puser_zone->y_centre),
01585     &(puser_zone->x_centre));
01586 
01587 
01588   VL53LX_decode_zone_size(
01589     pdev->dyn_cfg.roi_config__user_roi_requested_global_xy_size,
01590     &(puser_zone->width),
01591     &(puser_zone->height));
01592 
01593 
01594   return status;
01595 }
01596 VL53LX_Error VL53LX::VL53LX_get_mode_mitigation_roi(
01597   VL53LX_user_zone_t     *pmm_roi)
01598 {
01599 
01600 
01601   VL53LX_Error  status = VL53LX_ERROR_NONE;
01602   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01603 
01604   uint8_t  x       = 0;
01605   uint8_t  y       = 0;
01606   uint8_t  xy_size = 0;
01607 
01608 
01609   VL53LX_decode_row_col(
01610     pdev->nvm_copy_data.roi_config__mode_roi_centre_spad,
01611     &y,
01612     &x);
01613 
01614   pmm_roi->x_centre = x;
01615   pmm_roi->y_centre = y;
01616 
01617 
01618   xy_size = pdev->nvm_copy_data.roi_config__mode_roi_xy_size;
01619 
01620   pmm_roi->height = xy_size >> 4;
01621   pmm_roi->width  = xy_size & 0x0F;
01622 
01623 
01624   return status;
01625 }
01626 VL53LX_Error VL53LX::VL53LX_set_zone_config(
01627   VL53LX_zone_config_t      *pzone_cfg)
01628 {
01629   VL53LX_Error  status = VL53LX_ERROR_NONE;
01630   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01631   memcpy(&(pdev->zone_cfg.user_zones), &(pzone_cfg->user_zones),
01632          sizeof(pdev->zone_cfg.user_zones));
01633 
01634 
01635   pdev->zone_cfg.max_zones    = pzone_cfg->max_zones;
01636   pdev->zone_cfg.active_zones = pzone_cfg->active_zones;
01637 
01638   status = VL53LX_init_zone_config_histogram_bins(&pdev->zone_cfg);
01639 
01640 
01641 
01642   if (pzone_cfg->active_zones == 0) {
01643     pdev->gen_cfg.global_config__stream_divider = 0;
01644   } else if (pzone_cfg->active_zones < VL53LX_MAX_USER_ZONES)
01645     pdev->gen_cfg.global_config__stream_divider =
01646       pzone_cfg->active_zones + 1;
01647   else
01648     pdev->gen_cfg.global_config__stream_divider =
01649       VL53LX_MAX_USER_ZONES + 1;
01650 
01651   return status;
01652 
01653 }
01654 
01655 
01656 
01657 VL53LX_Error VL53LX::VL53LX_get_zone_config(
01658   VL53LX_zone_config_t      *pzone_cfg)
01659 {
01660 
01661 
01662   VL53LX_Error  status = VL53LX_ERROR_NONE;
01663   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01664   memcpy(pzone_cfg, &(pdev->zone_cfg), sizeof(VL53LX_zone_config_t));
01665 
01666   return status;
01667 }
01668 
01669 VL53LX_Error VL53LX::VL53LX_get_preset_mode_timing_cfg(
01670   VL53LX_DevicePresetModes     device_preset_mode,
01671   uint16_t                    *pdss_config__target_total_rate_mcps,
01672   uint32_t                    *pphasecal_config_timeout_us,
01673   uint32_t                    *pmm_config_timeout_us,
01674   uint32_t                    *prange_config_timeout_us)
01675 {
01676   VL53LX_Error  status = VL53LX_ERROR_NONE;
01677   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
01678 
01679   switch (device_preset_mode) {
01680 
01681     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING:
01682     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_SHORT_RANGE:
01683     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_LONG_RANGE:
01684     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL:
01685     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL:
01686     case VL53LX_DEVICEPRESETMODE_OLT:
01687       *pdss_config__target_total_rate_mcps =
01688         pdev->tuning_parms.tp_dss_target_lite_mcps;
01689       *pphasecal_config_timeout_us =
01690         pdev->tuning_parms.tp_phasecal_timeout_lite_us;
01691       *pmm_config_timeout_us =
01692         pdev->tuning_parms.tp_mm_timeout_lite_us;
01693       *prange_config_timeout_us =
01694         pdev->tuning_parms.tp_range_timeout_lite_us;
01695       break;
01696 
01697     case VL53LX_DEVICEPRESETMODE_TIMED_RANGING:
01698     case VL53LX_DEVICEPRESETMODE_TIMED_RANGING_SHORT_RANGE:
01699     case VL53LX_DEVICEPRESETMODE_TIMED_RANGING_LONG_RANGE:
01700     case VL53LX_DEVICEPRESETMODE_SINGLESHOT_RANGING:
01701       *pdss_config__target_total_rate_mcps =
01702         pdev->tuning_parms.tp_dss_target_timed_mcps;
01703       *pphasecal_config_timeout_us =
01704         pdev->tuning_parms.tp_phasecal_timeout_timed_us;
01705       *pmm_config_timeout_us =
01706         pdev->tuning_parms.tp_mm_timeout_timed_us;
01707       *prange_config_timeout_us =
01708         pdev->tuning_parms.tp_range_timeout_timed_us;
01709       break;
01710 
01711     case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_SHORT_RANGE:
01712     case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_MEDIUM_RANGE:
01713     case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_LONG_RANGE:
01714       *pdss_config__target_total_rate_mcps =
01715         pdev->tuning_parms.tp_dss_target_timed_mcps;
01716       *pphasecal_config_timeout_us =
01717         pdev->tuning_parms.tp_phasecal_timeout_timed_us;
01718       *pmm_config_timeout_us =
01719         pdev->tuning_parms.tp_mm_timeout_lpa_us;
01720       *prange_config_timeout_us =
01721         pdev->tuning_parms.tp_range_timeout_lpa_us;
01722       break;
01723 
01724     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING:
01725     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_WITH_MM1:
01726     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_WITH_MM2:
01727     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM1_CAL:
01728     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM2_CAL:
01729     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_REF_ARRAY:
01730     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE:
01731     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE_MM1:
01732     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE_MM2:
01733     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_CHARACTERISATION:
01734       *pdss_config__target_total_rate_mcps =
01735         pdev->tuning_parms.tp_dss_target_histo_mcps;
01736       *pphasecal_config_timeout_us =
01737         pdev->tuning_parms.tp_phasecal_timeout_hist_long_us;
01738       *pmm_config_timeout_us =
01739         pdev->tuning_parms.tp_mm_timeout_histo_us;
01740       *prange_config_timeout_us =
01741         pdev->tuning_parms.tp_range_timeout_histo_us;
01742 
01743       break;
01744 
01745     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE:
01746       *pdss_config__target_total_rate_mcps =
01747         pdev->tuning_parms.tp_dss_target_histo_mz_mcps;
01748       *pphasecal_config_timeout_us =
01749         pdev->tuning_parms.tp_phasecal_timeout_mz_med_us;
01750       *pmm_config_timeout_us =
01751         pdev->tuning_parms.tp_mm_timeout_mz_us;
01752       *prange_config_timeout_us =
01753         pdev->tuning_parms.tp_range_timeout_mz_us;
01754       break;
01755 
01756     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_SHORT_RANGE:
01757       *pdss_config__target_total_rate_mcps =
01758         pdev->tuning_parms.tp_dss_target_histo_mz_mcps;
01759       *pphasecal_config_timeout_us =
01760         pdev->tuning_parms.tp_phasecal_timeout_mz_short_us;
01761       *pmm_config_timeout_us =
01762         pdev->tuning_parms.tp_mm_timeout_mz_us;
01763       *prange_config_timeout_us =
01764         pdev->tuning_parms.tp_range_timeout_mz_us;
01765       break;
01766 
01767     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_LONG_RANGE:
01768       *pdss_config__target_total_rate_mcps =
01769         pdev->tuning_parms.tp_dss_target_histo_mz_mcps;
01770       *pphasecal_config_timeout_us =
01771         pdev->tuning_parms.tp_phasecal_timeout_mz_long_us;
01772       *pmm_config_timeout_us =
01773         pdev->tuning_parms.tp_mm_timeout_mz_us;
01774       *prange_config_timeout_us =
01775         pdev->tuning_parms.tp_range_timeout_mz_us;
01776       break;
01777 
01778     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_SHORT_TIMING:
01779       *pdss_config__target_total_rate_mcps =
01780         pdev->tuning_parms.tp_dss_target_histo_mcps;
01781       *pphasecal_config_timeout_us =
01782         pdev->tuning_parms.tp_phasecal_timeout_hist_short_us;
01783       *pmm_config_timeout_us =
01784         pdev->tuning_parms.tp_mm_timeout_histo_us;
01785       *prange_config_timeout_us =
01786         pdev->tuning_parms.tp_range_timeout_histo_us;
01787       break;
01788 
01789     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE:
01790     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE_MM1:
01791     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE_MM2:
01792       *pdss_config__target_total_rate_mcps =
01793         pdev->tuning_parms.tp_dss_target_histo_mcps;
01794       *pphasecal_config_timeout_us =
01795         pdev->tuning_parms.tp_phasecal_timeout_hist_med_us;
01796       *pmm_config_timeout_us =
01797         pdev->tuning_parms.tp_mm_timeout_histo_us;
01798       *prange_config_timeout_us =
01799         pdev->tuning_parms.tp_range_timeout_histo_us;
01800       break;
01801 
01802 
01803     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
01804     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE_MM1:
01805     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE_MM2:
01806       *pdss_config__target_total_rate_mcps =
01807         pdev->tuning_parms.tp_dss_target_histo_mcps;
01808       *pphasecal_config_timeout_us =
01809         pdev->tuning_parms.tp_phasecal_timeout_hist_short_us;
01810       *pmm_config_timeout_us =
01811         pdev->tuning_parms.tp_mm_timeout_histo_us;
01812       *prange_config_timeout_us =
01813         pdev->tuning_parms.tp_range_timeout_histo_us;
01814       break;
01815 
01816     case VL53LX_DEVICEPRESETMODE_SPECIAL_HISTOGRAM_SHORT_RANGE:
01817       *pdss_config__target_total_rate_mcps =
01818         pdev->tuning_parms.tp_dss_target_very_short_mcps;
01819       *pphasecal_config_timeout_us =
01820         pdev->tuning_parms.tp_phasecal_timeout_hist_short_us;
01821       *pmm_config_timeout_us =
01822         pdev->tuning_parms.tp_mm_timeout_histo_us;
01823       *prange_config_timeout_us =
01824         pdev->tuning_parms.tp_range_timeout_histo_us;
01825       break;
01826 
01827     default:
01828       status = VL53LX_ERROR_INVALID_PARAMS;
01829       break;
01830 
01831   }
01832 
01833   return status;
01834 }
01835 
01836 VL53LX_Error VL53LX::VL53LX_set_preset_mode(
01837   VL53LX_DevicePresetModes     device_preset_mode,
01838   uint16_t                     dss_config__target_total_rate_mcps,
01839   uint32_t                     phasecal_config_timeout_us,
01840   uint32_t                     mm_config_timeout_us,
01841   uint32_t                     range_config_timeout_us,
01842   uint32_t                     inter_measurement_period_ms)
01843 {
01844 
01845 
01846   VL53LX_Error  status = VL53LX_ERROR_NONE;
01847   VL53LX_LLDriverData_t *pdev =
01848     VL53LXDevStructGetLLDriverHandle(Dev);
01849   VL53LX_LLDriverResults_t *pres =
01850     VL53LXDevStructGetLLResultsHandle(Dev);
01851 
01852   VL53LX_hist_post_process_config_t *phistpostprocess =
01853     &(pdev->histpostprocess);
01854 
01855   VL53LX_static_config_t        *pstatic       = &(pdev->stat_cfg);
01856   VL53LX_histogram_config_t     *phistogram    = &(pdev->hist_cfg);
01857   VL53LX_general_config_t       *pgeneral      = &(pdev->gen_cfg);
01858   VL53LX_timing_config_t        *ptiming       = &(pdev->tim_cfg);
01859   VL53LX_dynamic_config_t       *pdynamic      = &(pdev->dyn_cfg);
01860   VL53LX_system_control_t       *psystem       = &(pdev->sys_ctrl);
01861   VL53LX_zone_config_t          *pzone_cfg     = &(pdev->zone_cfg);
01862   VL53LX_tuning_parm_storage_t  *ptuning_parms = &(pdev->tuning_parms);
01863   VL53LX_low_power_auto_data_t  *plpadata      =
01864     &(pdev->low_power_auto_data);
01865 
01866 
01867   pdev->preset_mode                 = device_preset_mode;
01868   pdev->mm_config_timeout_us        = mm_config_timeout_us;
01869   pdev->range_config_timeout_us     = range_config_timeout_us;
01870   pdev->inter_measurement_period_ms = inter_measurement_period_ms;
01871 
01872 
01873 
01874   VL53LX_init_ll_driver_state(VL53LX_DEVICESTATE_SW_STANDBY);
01875 
01876 
01877 
01878   switch (device_preset_mode) {
01879 
01880     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING:
01881       status = VL53LX_preset_mode_standard_ranging(
01882                  pstatic,
01883                  phistogram,
01884                  pgeneral,
01885                  ptiming,
01886                  pdynamic,
01887                  psystem,
01888                  ptuning_parms,
01889                  pzone_cfg);
01890       break;
01891 
01892     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_SHORT_RANGE:
01893       status = VL53LX_preset_mode_standard_ranging_short_range(
01894                  pstatic,
01895                  phistogram,
01896                  pgeneral,
01897                  ptiming,
01898                  pdynamic,
01899                  psystem,
01900                  ptuning_parms,
01901                  pzone_cfg);
01902       break;
01903 
01904     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_LONG_RANGE:
01905       status = VL53LX_preset_mode_standard_ranging_long_range(
01906                  pstatic,
01907                  phistogram,
01908                  pgeneral,
01909                  ptiming,
01910                  pdynamic,
01911                  psystem,
01912                  ptuning_parms,
01913                  pzone_cfg);
01914       break;
01915 
01916     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL:
01917       status = VL53LX_preset_mode_standard_ranging_mm1_cal(
01918                  pstatic,
01919                  phistogram,
01920                  pgeneral,
01921                  ptiming,
01922                  pdynamic,
01923                  psystem,
01924                  ptuning_parms,
01925                  pzone_cfg);
01926       break;
01927 
01928     case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL:
01929       status = VL53LX_preset_mode_standard_ranging_mm2_cal(
01930                  pstatic,
01931                  phistogram,
01932                  pgeneral,
01933                  ptiming,
01934                  pdynamic,
01935                  psystem,
01936                  ptuning_parms,
01937                  pzone_cfg);
01938       break;
01939 
01940     case VL53LX_DEVICEPRESETMODE_TIMED_RANGING:
01941       status = VL53LX_preset_mode_timed_ranging(
01942                  pstatic,
01943                  phistogram,
01944                  pgeneral,
01945                  ptiming,
01946                  pdynamic,
01947                  psystem,
01948                  ptuning_parms,
01949                  pzone_cfg);
01950       break;
01951 
01952     case VL53LX_DEVICEPRESETMODE_TIMED_RANGING_SHORT_RANGE:
01953       status = VL53LX_preset_mode_timed_ranging_short_range(
01954                  pstatic,
01955                  phistogram,
01956                  pgeneral,
01957                  ptiming,
01958                  pdynamic,
01959                  psystem,
01960                  ptuning_parms,
01961                  pzone_cfg);
01962       break;
01963 
01964     case VL53LX_DEVICEPRESETMODE_TIMED_RANGING_LONG_RANGE:
01965       status = VL53LX_preset_mode_timed_ranging_long_range(
01966                  pstatic,
01967                  phistogram,
01968                  pgeneral,
01969                  ptiming,
01970                  pdynamic,
01971                  psystem,
01972                  ptuning_parms,
01973                  pzone_cfg);
01974       break;
01975 
01976     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING:
01977       status = VL53LX_preset_mode_histogram_ranging(
01978                  phistpostprocess,
01979                  pstatic,
01980                  phistogram,
01981                  pgeneral,
01982                  ptiming,
01983                  pdynamic,
01984                  psystem,
01985                  ptuning_parms,
01986                  pzone_cfg);
01987       break;
01988 
01989     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_WITH_MM1:
01990       status = VL53LX_preset_mode_histogram_ranging_with_mm1(
01991                  phistpostprocess,
01992                  pstatic,
01993                  phistogram,
01994                  pgeneral,
01995                  ptiming,
01996                  pdynamic,
01997                  psystem,
01998                  ptuning_parms,
01999                  pzone_cfg);
02000       break;
02001 
02002     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_WITH_MM2:
02003       status = VL53LX_preset_mode_histogram_ranging_with_mm2(
02004                  phistpostprocess,
02005                  pstatic,
02006                  phistogram,
02007                  pgeneral,
02008                  ptiming,
02009                  pdynamic,
02010                  psystem,
02011                  ptuning_parms,
02012                  pzone_cfg);
02013       break;
02014 
02015     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM1_CAL:
02016       status = VL53LX_preset_mode_histogram_ranging_mm1_cal(
02017                  phistpostprocess,
02018                  pstatic,
02019                  phistogram,
02020                  pgeneral,
02021                  ptiming,
02022                  pdynamic,
02023                  psystem,
02024                  ptuning_parms,
02025                  pzone_cfg);
02026       break;
02027 
02028     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM2_CAL:
02029       status = VL53LX_preset_mode_histogram_ranging_mm2_cal(
02030                  phistpostprocess,
02031                  pstatic,
02032                  phistogram,
02033                  pgeneral,
02034                  ptiming,
02035                  pdynamic,
02036                  psystem,
02037                  ptuning_parms,
02038                  pzone_cfg);
02039       break;
02040 
02041     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE:
02042       status = VL53LX_preset_mode_histogram_multizone(
02043                  phistpostprocess,
02044                  pstatic,
02045                  phistogram,
02046                  pgeneral,
02047                  ptiming,
02048                  pdynamic,
02049                  psystem,
02050                  ptuning_parms,
02051                  pzone_cfg);
02052       break;
02053 
02054     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_SHORT_RANGE:
02055       status = VL53LX_preset_mode_histogram_multizone_short_range(
02056                  phistpostprocess,
02057                  pstatic,
02058                  phistogram,
02059                  pgeneral,
02060                  ptiming,
02061                  pdynamic,
02062                  psystem,
02063                  ptuning_parms,
02064                  pzone_cfg);
02065       break;
02066 
02067     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_LONG_RANGE:
02068       status = VL53LX_preset_mode_histogram_multizone_long_range(
02069                  phistpostprocess,
02070                  pstatic,
02071                  phistogram,
02072                  pgeneral,
02073                  ptiming,
02074                  pdynamic,
02075                  psystem,
02076                  ptuning_parms,
02077                  pzone_cfg);
02078       break;
02079 
02080     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_REF_ARRAY:
02081       status = VL53LX_preset_mode_histogram_ranging_ref(
02082                  phistpostprocess,
02083                  pstatic,
02084                  phistogram,
02085                  pgeneral,
02086                  ptiming,
02087                  pdynamic,
02088                  psystem,
02089                  ptuning_parms,
02090                  pzone_cfg);
02091       break;
02092 
02093     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_SHORT_TIMING:
02094       status = VL53LX_preset_mode_histogram_ranging_short_timing(
02095                  phistpostprocess,
02096                  pstatic,
02097                  phistogram,
02098                  pgeneral,
02099                  ptiming,
02100                  pdynamic,
02101                  psystem,
02102                  ptuning_parms,
02103                  pzone_cfg);
02104       break;
02105 
02106     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE:
02107       status = VL53LX_preset_mode_histogram_long_range(
02108                  phistpostprocess,
02109                  pstatic,
02110                  phistogram,
02111                  pgeneral,
02112                  ptiming,
02113                  pdynamic,
02114                  psystem,
02115                  ptuning_parms,
02116                  pzone_cfg);
02117       break;
02118 
02119     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE_MM1:
02120       status = VL53LX_preset_mode_histogram_long_range_mm1(
02121                  phistpostprocess,
02122                  pstatic,
02123                  phistogram,
02124                  pgeneral,
02125                  ptiming,
02126                  pdynamic,
02127                  psystem,
02128                  ptuning_parms,
02129                  pzone_cfg);
02130       break;
02131 
02132     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE_MM2:
02133       status = VL53LX_preset_mode_histogram_long_range_mm2(
02134                  phistpostprocess,
02135                  pstatic,
02136                  phistogram,
02137                  pgeneral,
02138                  ptiming,
02139                  pdynamic,
02140                  psystem,
02141                  ptuning_parms,
02142                  pzone_cfg);
02143       break;
02144 
02145     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE:
02146       status = VL53LX_preset_mode_histogram_medium_range(
02147                  phistpostprocess,
02148                  pstatic,
02149                  phistogram,
02150                  pgeneral,
02151                  ptiming,
02152                  pdynamic,
02153                  psystem,
02154                  ptuning_parms,
02155                  pzone_cfg);
02156       break;
02157 
02158     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE_MM1:
02159       status = VL53LX_preset_mode_histogram_medium_range_mm1(
02160                  phistpostprocess,
02161                  pstatic,
02162                  phistogram,
02163                  pgeneral,
02164                  ptiming,
02165                  pdynamic,
02166                  psystem,
02167                  ptuning_parms,
02168                  pzone_cfg);
02169       break;
02170 
02171     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE_MM2:
02172       status = VL53LX_preset_mode_histogram_medium_range_mm2(
02173                  phistpostprocess,
02174                  pstatic,
02175                  phistogram,
02176                  pgeneral,
02177                  ptiming,
02178                  pdynamic,
02179                  psystem,
02180                  ptuning_parms,
02181                  pzone_cfg);
02182       break;
02183 
02184     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
02185       status = VL53LX_preset_mode_histogram_short_range(
02186                  phistpostprocess,
02187                  pstatic,
02188                  phistogram,
02189                  pgeneral,
02190                  ptiming,
02191                  pdynamic,
02192                  psystem,
02193                  ptuning_parms,
02194                  pzone_cfg);
02195       break;
02196 
02197     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE_MM1:
02198       status = VL53LX_preset_mode_histogram_short_range_mm1(
02199                  phistpostprocess,
02200                  pstatic,
02201                  phistogram,
02202                  pgeneral,
02203                  ptiming,
02204                  pdynamic,
02205                  psystem,
02206                  ptuning_parms,
02207                  pzone_cfg);
02208       break;
02209 
02210     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE_MM2:
02211       status = VL53LX_preset_mode_histogram_short_range_mm2(
02212                  phistpostprocess,
02213                  pstatic,
02214                  phistogram,
02215                  pgeneral,
02216                  ptiming,
02217                  pdynamic,
02218                  psystem,
02219                  ptuning_parms,
02220                  pzone_cfg);
02221       break;
02222 
02223     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_CHARACTERISATION:
02224       status = VL53LX_preset_mode_histogram_characterisation(
02225                  phistpostprocess,
02226                  pstatic,
02227                  phistogram,
02228                  pgeneral,
02229                  ptiming,
02230                  pdynamic,
02231                  psystem,
02232                  ptuning_parms,
02233                  pzone_cfg);
02234       break;
02235 
02236     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_XTALK_PLANAR:
02237       status = VL53LX_preset_mode_histogram_xtalk_planar(
02238                  phistpostprocess,
02239                  pstatic,
02240                  phistogram,
02241                  pgeneral,
02242                  ptiming,
02243                  pdynamic,
02244                  psystem,
02245                  ptuning_parms,
02246                  pzone_cfg);
02247       break;
02248 
02249     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_XTALK_MM1:
02250       status = VL53LX_preset_mode_histogram_xtalk_mm1(
02251                  phistpostprocess,
02252                  pstatic,
02253                  phistogram,
02254                  pgeneral,
02255                  ptiming,
02256                  pdynamic,
02257                  psystem,
02258                  ptuning_parms,
02259                  pzone_cfg);
02260       break;
02261 
02262     case VL53LX_DEVICEPRESETMODE_HISTOGRAM_XTALK_MM2:
02263       status = VL53LX_preset_mode_histogram_xtalk_mm2(
02264                  phistpostprocess,
02265                  pstatic,
02266                  phistogram,
02267                  pgeneral,
02268                  ptiming,
02269                  pdynamic,
02270                  psystem,
02271                  ptuning_parms,
02272                  pzone_cfg);
02273       break;
02274 
02275     case VL53LX_DEVICEPRESETMODE_OLT:
02276       status = VL53LX_preset_mode_olt(
02277                  pstatic,
02278                  phistogram,
02279                  pgeneral,
02280                  ptiming,
02281                  pdynamic,
02282                  psystem,
02283                  ptuning_parms,
02284                  pzone_cfg);
02285       break;
02286 
02287     case VL53LX_DEVICEPRESETMODE_SINGLESHOT_RANGING:
02288       status = VL53LX_preset_mode_singleshot_ranging(
02289                  pstatic,
02290                  phistogram,
02291                  pgeneral,
02292                  ptiming,
02293                  pdynamic,
02294                  psystem,
02295                  ptuning_parms,
02296                  pzone_cfg);
02297       break;
02298 
02299     case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_SHORT_RANGE:
02300       status = VL53LX_preset_mode_low_power_auto_short_ranging(
02301                  pstatic,
02302                  phistogram,
02303                  pgeneral,
02304                  ptiming,
02305                  pdynamic,
02306                  psystem,
02307                  ptuning_parms,
02308                  pzone_cfg,
02309                  plpadata);
02310       break;
02311 
02312     case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_MEDIUM_RANGE:
02313       status = VL53LX_preset_mode_low_power_auto_ranging(
02314                  pstatic,
02315                  phistogram,
02316                  pgeneral,
02317                  ptiming,
02318                  pdynamic,
02319                  psystem,
02320                  ptuning_parms,
02321                  pzone_cfg,
02322                  plpadata);
02323       break;
02324 
02325     case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_LONG_RANGE:
02326       status = VL53LX_preset_mode_low_power_auto_long_ranging(
02327                  pstatic,
02328                  phistogram,
02329                  pgeneral,
02330                  ptiming,
02331                  pdynamic,
02332                  psystem,
02333                  ptuning_parms,
02334                  pzone_cfg,
02335                  plpadata);
02336       break;
02337 
02338 
02339     case VL53LX_DEVICEPRESETMODE_SPECIAL_HISTOGRAM_SHORT_RANGE:
02340       status = VL53LX_preset_mode_special_histogram_short_range(
02341                  phistpostprocess,
02342                  pstatic,
02343                  phistogram,
02344                  pgeneral,
02345                  ptiming,
02346                  pdynamic,
02347                  psystem,
02348                  ptuning_parms,
02349                  pzone_cfg);
02350       break;
02351 
02352     default:
02353       status = VL53LX_ERROR_INVALID_PARAMS;
02354       break;
02355 
02356   }
02357 
02358 
02359 
02360   if (status == VL53LX_ERROR_NONE) {
02361 
02362     pstatic->dss_config__target_total_rate_mcps =
02363       dss_config__target_total_rate_mcps;
02364     pdev->dss_config__target_total_rate_mcps    =
02365       dss_config__target_total_rate_mcps;
02366 
02367   }
02368 
02369 
02370 
02371   if (status == VL53LX_ERROR_NONE)
02372     status =
02373       VL53LX_set_timeouts_us(
02374         phasecal_config_timeout_us,
02375         mm_config_timeout_us,
02376         range_config_timeout_us);
02377 
02378   if (status == VL53LX_ERROR_NONE)
02379     status =
02380       VL53LX_set_inter_measurement_period_ms(inter_measurement_period_ms);
02381 
02382 
02383 
02384   V53L1_init_zone_results_structure(
02385     pdev->zone_cfg.active_zones + 1,
02386     &(pres->zone_results));
02387 
02388   return status;
02389 }
02390 
02391 VL53LX_Error VL53LX::VL53LX_set_zone_preset(
02392   VL53LX_DeviceZonePreset    zone_preset)
02393 {
02394 
02395 
02396   VL53LX_Error status = VL53LX_ERROR_NONE;
02397   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02398 
02399   VL53LX_general_config_t       *pgeneral      = &(pdev->gen_cfg);
02400   VL53LX_zone_config_t          *pzone_cfg     = &(pdev->zone_cfg);
02401 
02402   pdev->zone_preset        = zone_preset;
02403 
02404 
02405 
02406   switch (zone_preset) {
02407 
02408     case VL53LX_DEVICEZONEPRESET_XTALK_PLANAR:
02409       status =
02410         VL53LX_zone_preset_xtalk_planar(
02411           pgeneral,
02412           pzone_cfg);
02413       break;
02414 
02415     case VL53LX_DEVICEZONEPRESET_1X1_SIZE_16X16:
02416       status =
02417         VL53LX_init_zone_config_structure(
02418           8, 1, 1,
02419           8, 1, 1,
02420           15, 15,
02421           pzone_cfg);
02422       break;
02423 
02424     case VL53LX_DEVICEZONEPRESET_1X2_SIZE_16X8:
02425       status =
02426         VL53LX_init_zone_config_structure(
02427           8, 1, 1,
02428           4, 8, 2,
02429           15, 7,
02430           pzone_cfg);
02431       break;
02432 
02433     case VL53LX_DEVICEZONEPRESET_2X1_SIZE_8X16:
02434       status =
02435         VL53LX_init_zone_config_structure(
02436           4, 8, 2,
02437           8, 1, 1,
02438           7, 15,
02439           pzone_cfg);
02440       break;
02441 
02442     case VL53LX_DEVICEZONEPRESET_2X2_SIZE_8X8:
02443       status =
02444         VL53LX_init_zone_config_structure(
02445           4, 8, 2,
02446           4, 8, 2,
02447           7, 7,
02448           pzone_cfg);
02449       break;
02450 
02451     case VL53LX_DEVICEZONEPRESET_3X3_SIZE_5X5:
02452       status =
02453         VL53LX_init_zone_config_structure(
02454           2, 5, 3,
02455           2, 5, 3,
02456           4, 4,
02457           pzone_cfg);
02458       break;
02459 
02460     case VL53LX_DEVICEZONEPRESET_4X4_SIZE_4X4:
02461       status =
02462         VL53LX_init_zone_config_structure(
02463           2, 4, 4,
02464           2, 4, 4,
02465           3, 3,
02466           pzone_cfg);
02467       break;
02468 
02469     case VL53LX_DEVICEZONEPRESET_5X5_SIZE_4X4:
02470       status =
02471         VL53LX_init_zone_config_structure(
02472           2, 3, 5,
02473           2, 3, 5,
02474           3, 3,
02475           pzone_cfg);
02476       break;
02477 
02478     case VL53LX_DEVICEZONEPRESET_11X11_SIZE_5X5:
02479       status =
02480         VL53LX_init_zone_config_structure(
02481           3, 1, 11,
02482           3, 1, 11,
02483           4, 4,
02484           pzone_cfg);
02485       break;
02486 
02487     case VL53LX_DEVICEZONEPRESET_13X13_SIZE_4X4:
02488       status =
02489         VL53LX_init_zone_config_structure(
02490           2, 1, 13,
02491           2, 1, 13,
02492           3, 3,
02493           pzone_cfg);
02494 
02495       break;
02496 
02497     case VL53LX_DEVICEZONEPRESET_1X1_SIZE_4X4_POS_8X8:
02498       status =
02499         VL53LX_init_zone_config_structure(
02500           8, 1, 1,
02501           8, 1, 1,
02502           3, 3,
02503           pzone_cfg);
02504       break;
02505 
02506   }
02507 
02508 
02509 
02510   if (pzone_cfg->active_zones == 0) {
02511     pdev->gen_cfg.global_config__stream_divider = 0;
02512   } else if (pzone_cfg->active_zones < VL53LX_MAX_USER_ZONES)
02513     pdev->gen_cfg.global_config__stream_divider =
02514       pzone_cfg->active_zones + 1;
02515   else
02516     pdev->gen_cfg.global_config__stream_divider =
02517       VL53LX_MAX_USER_ZONES + 1;
02518 
02519   return status;
02520 }
02521 
02522 VL53LX_Error  VL53LX::VL53LX_enable_xtalk_compensation()
02523 {
02524   VL53LX_Error status = VL53LX_ERROR_NONE;
02525   uint32_t tempu32;
02526 
02527   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02528   VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
02529   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
02530   VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
02531 
02532   tempu32 = VL53LX_calc_crosstalk_plane_offset_with_margin(
02533               pC->algo__crosstalk_compensation_plane_offset_kcps,
02534               pC->lite_mode_crosstalk_margin_kcps);
02535   if (tempu32 > 0xFFFF) {
02536     tempu32 = 0xFFFF;
02537   }
02538 
02539   pN->algo__crosstalk_compensation_plane_offset_kcps =
02540     (uint16_t)tempu32;
02541 
02542   pN->algo__crosstalk_compensation_x_plane_gradient_kcps =
02543     pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
02544 
02545   pN->algo__crosstalk_compensation_y_plane_gradient_kcps =
02546     pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
02547 
02548 
02549   pHP->algo__crosstalk_compensation_plane_offset_kcps =
02550     VL53LX_calc_crosstalk_plane_offset_with_margin(
02551       pC->algo__crosstalk_compensation_plane_offset_kcps,
02552       pC->histogram_mode_crosstalk_margin_kcps);
02553 
02554   pHP->algo__crosstalk_compensation_x_plane_gradient_kcps
02555     = pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
02556   pHP->algo__crosstalk_compensation_y_plane_gradient_kcps
02557     = pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
02558 
02559 
02560 
02561   pC->global_crosstalk_compensation_enable = 0x01;
02562 
02563   pHP->algo__crosstalk_compensation_enable =
02564     pC->global_crosstalk_compensation_enable;
02565 
02566 
02567 
02568 
02569   if (status == VL53LX_ERROR_NONE) {
02570     pC->crosstalk_range_ignore_threshold_rate_mcps =
02571       VL53LX_calc_range_ignore_threshold(
02572         pC->algo__crosstalk_compensation_plane_offset_kcps,
02573         pC->algo__crosstalk_compensation_x_plane_gradient_kcps,
02574         pC->algo__crosstalk_compensation_y_plane_gradient_kcps,
02575         pC->crosstalk_range_ignore_threshold_mult);
02576   }
02577 
02578 
02579 
02580   if (status == VL53LX_ERROR_NONE)
02581     status =
02582       VL53LX_set_customer_nvm_managed(&(pdev->customer));
02583 
02584   return status;
02585 
02586 }
02587 
02588 void VL53LX::VL53LX_get_xtalk_compensation_enable(uint8_t       *pcrosstalk_compensation_enable)
02589 {
02590   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02591   *pcrosstalk_compensation_enable =
02592     pdev->xtalk_cfg.global_crosstalk_compensation_enable;
02593 
02594 }
02595 
02596 
02597 VL53LX_Error VL53LX::VL53LX_get_lite_xtalk_margin_kcps(
02598   int16_t                           *pxtalk_margin)
02599 {
02600   VL53LX_Error  status = VL53LX_ERROR_NONE;
02601 
02602   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02603 
02604 
02605   *pxtalk_margin = pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps;
02606 
02607   return status;
02608 
02609 }
02610 VL53LX_Error VL53LX::VL53LX_set_lite_xtalk_margin_kcps(
02611   int16_t                        xtalk_margin)
02612 {
02613   VL53LX_Error  status = VL53LX_ERROR_NONE;
02614 
02615   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02616 
02617   pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps = xtalk_margin;
02618 
02619   return status;
02620 }
02621 
02622 VL53LX_Error VL53LX::VL53LX_get_histogram_xtalk_margin_kcps(
02623   int16_t                           *pxtalk_margin)
02624 {
02625   VL53LX_Error  status = VL53LX_ERROR_NONE;
02626 
02627   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02628 
02629   *pxtalk_margin = pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps;
02630 
02631   return status;
02632 
02633 }
02634 VL53LX_Error VL53LX::VL53LX_set_histogram_xtalk_margin_kcps(
02635   int16_t                        xtalk_margin)
02636 {
02637   VL53LX_Error  status = VL53LX_ERROR_NONE;
02638 
02639   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02640 
02641   pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps = xtalk_margin;
02642 
02643   return status;
02644 }
02645 
02646 VL53LX_Error VL53LX::VL53LX_restore_xtalk_nvm_default()
02647 {
02648   VL53LX_Error  status = VL53LX_ERROR_NONE;
02649 
02650   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02651   VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
02652 
02653   pC->algo__crosstalk_compensation_plane_offset_kcps =
02654     pC->nvm_default__crosstalk_compensation_plane_offset_kcps;
02655   pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
02656     pC->nvm_default__crosstalk_compensation_x_plane_gradient_kcps;
02657   pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
02658     pC->nvm_default__crosstalk_compensation_y_plane_gradient_kcps;
02659 
02660 
02661   return status;
02662 }
02663 
02664 VL53LX_Error  VL53LX::VL53LX_disable_xtalk_compensation()
02665 {
02666   VL53LX_Error status = VL53LX_ERROR_NONE;
02667 
02668   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02669   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
02670   VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
02671 
02672   pN->algo__crosstalk_compensation_plane_offset_kcps =
02673     0x00;
02674 
02675   pN->algo__crosstalk_compensation_x_plane_gradient_kcps =
02676     0x00;
02677 
02678   pN->algo__crosstalk_compensation_y_plane_gradient_kcps =
02679     0x00;
02680 
02681 
02682 
02683   pdev->xtalk_cfg.global_crosstalk_compensation_enable = 0x00;
02684 
02685   pHP->algo__crosstalk_compensation_enable =
02686     pdev->xtalk_cfg.global_crosstalk_compensation_enable;
02687 
02688 
02689 
02690   if (status == VL53LX_ERROR_NONE) {
02691     pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps =
02692       0x0000;
02693   }
02694 
02695 
02696 
02697   if (status == VL53LX_ERROR_NONE) {
02698     status =
02699       VL53LX_set_customer_nvm_managed(&(pdev->customer));
02700   }
02701 
02702 
02703   return status;
02704 
02705 }
02706 VL53LX_Error VL53LX::VL53LX_get_histogram_phase_consistency(
02707   uint8_t                            *pphase_consistency)
02708 {
02709   VL53LX_Error  status = VL53LX_ERROR_NONE;
02710 
02711   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02712   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
02713 
02714   *pphase_consistency =
02715     pHP->algo__consistency_check__phase_tolerance;
02716 
02717   return status;
02718 
02719 }
02720 
02721 VL53LX_Error VL53LX::VL53LX_set_histogram_phase_consistency(
02722   uint8_t                             phase_consistency)
02723 {
02724 
02725   VL53LX_Error  status = VL53LX_ERROR_NONE;
02726 
02727   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02728 
02729   pdev->histpostprocess.algo__consistency_check__phase_tolerance =
02730     phase_consistency;
02731 
02732   return status;
02733 
02734 }
02735 VL53LX_Error VL53LX::VL53LX_get_histogram_event_consistency(
02736   uint8_t                            *pevent_consistency)
02737 {
02738   VL53LX_Error  status = VL53LX_ERROR_NONE;
02739 
02740   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02741 
02742   *pevent_consistency =
02743     pdev->histpostprocess.algo__consistency_check__event_sigma;
02744 
02745   return status;
02746 }
02747 
02748 VL53LX_Error VL53LX::VL53LX_set_histogram_event_consistency(
02749   uint8_t                             event_consistency)
02750 {
02751   VL53LX_Error  status = VL53LX_ERROR_NONE;
02752 
02753   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02754 
02755   pdev->histpostprocess.algo__consistency_check__event_sigma =
02756     event_consistency;
02757 
02758   return status;
02759 
02760 }
02761 VL53LX_Error VL53LX::VL53LX_get_histogram_ambient_threshold_sigma(
02762   uint8_t                            *pamb_thresh_sigma)
02763 {
02764   VL53LX_Error  status = VL53LX_ERROR_NONE;
02765 
02766   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02767 
02768   *pamb_thresh_sigma =
02769     pdev->histpostprocess.ambient_thresh_sigma1;
02770 
02771   return status;
02772 
02773 }
02774 
02775 VL53LX_Error VL53LX::VL53LX_set_histogram_ambient_threshold_sigma(
02776   uint8_t                             amb_thresh_sigma)
02777 {
02778   VL53LX_Error  status = VL53LX_ERROR_NONE;
02779 
02780   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02781 
02782   pdev->histpostprocess.ambient_thresh_sigma1 =
02783     amb_thresh_sigma;
02784 
02785 
02786   return status;
02787 
02788 }
02789 
02790 VL53LX_Error VL53LX::VL53LX_get_lite_sigma_threshold(
02791   uint16_t                           *plite_sigma)
02792 {
02793   VL53LX_Error  status = VL53LX_ERROR_NONE;
02794 
02795   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02796 
02797   *plite_sigma =
02798     pdev->tim_cfg.range_config__sigma_thresh;
02799 
02800 
02801   return status;
02802 
02803 }
02804 
02805 VL53LX_Error VL53LX::VL53LX_set_lite_sigma_threshold(
02806   uint16_t                           lite_sigma)
02807 {
02808   VL53LX_Error  status = VL53LX_ERROR_NONE;
02809 
02810   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02811 
02812   pdev->tim_cfg.range_config__sigma_thresh = lite_sigma;
02813 
02814   return status;
02815 
02816 }
02817 
02818 VL53LX_Error VL53LX::VL53LX_get_lite_min_count_rate(
02819   uint16_t                           *plite_mincountrate)
02820 {
02821   VL53LX_Error  status = VL53LX_ERROR_NONE;
02822 
02823   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02824   *plite_mincountrate =
02825     pdev->tim_cfg.range_config__min_count_rate_rtn_limit_mcps;
02826 
02827   return status;
02828 
02829 }
02830 
02831 
02832 VL53LX_Error VL53LX::VL53LX_set_lite_min_count_rate(
02833   uint16_t                            lite_mincountrate)
02834 {
02835   VL53LX_Error  status = VL53LX_ERROR_NONE;
02836 
02837   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02838 
02839   pdev->tim_cfg.range_config__min_count_rate_rtn_limit_mcps =
02840     lite_mincountrate;
02841 
02842   return status;
02843 
02844 }
02845 VL53LX_Error VL53LX::VL53LX_get_xtalk_detect_config(
02846   int16_t                            *pmax_valid_range_mm,
02847   int16_t                            *pmin_valid_range_mm,
02848   uint16_t                           *pmax_valid_rate_kcps,
02849   uint16_t                           *pmax_sigma_mm)
02850 {
02851   VL53LX_Error  status = VL53LX_ERROR_NONE;
02852 
02853   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02854 
02855   *pmax_valid_range_mm =
02856     pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm;
02857   *pmin_valid_range_mm =
02858     pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm;
02859   *pmax_valid_rate_kcps =
02860     pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps;
02861   *pmax_sigma_mm =
02862     pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm;
02863 
02864   return status;
02865 
02866 }
02867 
02868 
02869 
02870 VL53LX_Error VL53LX::VL53LX_set_xtalk_detect_config(
02871   int16_t                             max_valid_range_mm,
02872   int16_t                             min_valid_range_mm,
02873   uint16_t                            max_valid_rate_kcps,
02874   uint16_t                            max_sigma_mm)
02875 {
02876   VL53LX_Error  status = VL53LX_ERROR_NONE;
02877 
02878   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02879 
02880   pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm =
02881     max_valid_range_mm;
02882   pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm =
02883     min_valid_range_mm;
02884   pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps =
02885     max_valid_rate_kcps;
02886   pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm =
02887     max_sigma_mm;
02888 
02889   return status;
02890 
02891 }
02892 
02893 VL53LX_Error VL53LX::VL53LX_get_target_order_mode(
02894   VL53LX_HistTargetOrder             *phist_target_order)
02895 {
02896   VL53LX_Error  status = VL53LX_ERROR_NONE;
02897 
02898   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02899 
02900   *phist_target_order =
02901     pdev->histpostprocess.hist_target_order;
02902 
02903   return status;
02904 
02905 }
02906 VL53LX_Error VL53LX::VL53LX_set_target_order_mode(
02907   VL53LX_HistTargetOrder              hist_target_order)
02908 {
02909 
02910   VL53LX_Error  status = VL53LX_ERROR_NONE;
02911 
02912   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02913 
02914 
02915   pdev->histpostprocess.hist_target_order = hist_target_order;
02916 
02917 
02918   return status;
02919 
02920 }
02921 
02922 VL53LX_Error VL53LX::VL53LX_get_dmax_reflectance_values(
02923   VL53LX_dmax_reflectance_array_t    *pdmax_reflectances)
02924 {
02925 
02926   VL53LX_Error  status = VL53LX_ERROR_NONE;
02927 
02928   uint8_t i = 0;
02929 
02930   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02931 
02932 
02933   for (i = 0; i < VL53LX_MAX_AMBIENT_DMAX_VALUES; i++) {
02934     pdmax_reflectances->target_reflectance_for_dmax[i] =
02935       pdev->dmax_cfg.target_reflectance_for_dmax_calc[i];
02936   }
02937 
02938   return status;
02939 
02940 }
02941 VL53LX_Error VL53LX::VL53LX_set_dmax_reflectance_values(
02942   VL53LX_dmax_reflectance_array_t    *pdmax_reflectances)
02943 {
02944 
02945   VL53LX_Error  status = VL53LX_ERROR_NONE;
02946 
02947   uint8_t i = 0;
02948 
02949   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02950 
02951   for (i = 0; i < VL53LX_MAX_AMBIENT_DMAX_VALUES; i++) {
02952     pdev->dmax_cfg.target_reflectance_for_dmax_calc[i] =
02953       pdmax_reflectances->target_reflectance_for_dmax[i];
02954   }
02955 
02956 
02957   return status;
02958 
02959 }
02960 
02961 VL53LX_Error VL53LX::VL53LX_get_vhv_loopbound(
02962   uint8_t                     *pvhv_loopbound)
02963 {
02964   VL53LX_Error  status = VL53LX_ERROR_NONE;
02965 
02966   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02967 
02968   *pvhv_loopbound =
02969     pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound / 4;
02970 
02971   return status;
02972 
02973 }
02974 
02975 VL53LX_Error VL53LX::VL53LX_set_vhv_loopbound(
02976   uint8_t                      vhv_loopbound)
02977 {
02978   VL53LX_Error  status = VL53LX_ERROR_NONE;
02979 
02980   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02981 
02982   pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
02983     (pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound & 0x03) +
02984     (vhv_loopbound * 4);
02985 
02986   return status;
02987 
02988 }
02989 VL53LX_Error VL53LX::VL53LX_get_vhv_config(
02990   uint8_t                     *pvhv_init_en,
02991   uint8_t                     *pvhv_init_value)
02992 {
02993   VL53LX_Error  status = VL53LX_ERROR_NONE;
02994 
02995   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
02996 
02997 
02998   *pvhv_init_en    = (pdev->stat_nvm.vhv_config__init & 0x80) >> 7;
02999   *pvhv_init_value =
03000     (pdev->stat_nvm.vhv_config__init & 0x7F);
03001 
03002   return status;
03003 
03004 }
03005 
03006 
03007 VL53LX_Error VL53LX::VL53LX_set_vhv_config(
03008   uint8_t                      vhv_init_en,
03009   uint8_t                      vhv_init_value)
03010 {
03011 
03012 
03013 
03014   VL53LX_Error  status = VL53LX_ERROR_NONE;
03015 
03016   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
03017 
03018   pdev->stat_nvm.vhv_config__init =
03019     ((vhv_init_en   & 0x01) << 7) +
03020     (vhv_init_value & 0x7F);
03021 
03022 
03023   return status;
03024 
03025 }
03026 
03027 VL53LX_Error VL53LX::VL53LX_init_and_start_range(
03028   uint8_t                        measurement_mode,
03029   VL53LX_DeviceConfigLevel       device_config_level)
03030 {
03031 
03032 
03033   VL53LX_Error status = VL53LX_ERROR_NONE;
03034   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
03035   VL53LX_LLDriverResults_t  *pres =
03036     VL53LXDevStructGetLLResultsHandle(Dev);
03037 
03038   uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE];
03039 
03040   VL53LX_static_nvm_managed_t   *pstatic_nvm   = &(pdev->stat_nvm);
03041   VL53LX_customer_nvm_managed_t *pcustomer_nvm = &(pdev->customer);
03042   VL53LX_static_config_t        *pstatic       = &(pdev->stat_cfg);
03043   VL53LX_general_config_t       *pgeneral      = &(pdev->gen_cfg);
03044   VL53LX_timing_config_t        *ptiming       = &(pdev->tim_cfg);
03045   VL53LX_dynamic_config_t       *pdynamic      = &(pdev->dyn_cfg);
03046   VL53LX_system_control_t       *psystem       = &(pdev->sys_ctrl);
03047 
03048   VL53LX_ll_driver_state_t  *pstate   = &(pdev->ll_state);
03049   VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
03050 
03051   uint8_t  *pbuffer                   = &buffer[0];
03052   uint16_t i                          = 0;
03053   uint16_t i2c_index                  = 0;
03054   uint16_t i2c_buffer_offset_bytes    = 0;
03055   uint16_t i2c_buffer_size_bytes      = 0;
03056 
03057 
03058   pdev->measurement_mode = measurement_mode;
03059 
03060 
03061 
03062   psystem->system__mode_start =
03063     (psystem->system__mode_start &
03064      VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK) |
03065     measurement_mode;
03066 
03067 
03068 
03069   status =
03070     VL53LX_set_user_zone(
03071       &(pdev->zone_cfg.user_zones[pdev->ll_state.cfg_zone_id]));
03072 
03073 
03074   if (pdev->zone_cfg.active_zones > 0) {
03075     status =
03076       VL53LX_set_zone_dss_config(
03077         &(pres->zone_dyn_cfgs.VL53LX_p_003[pdev->ll_state.cfg_zone_id])
03078       );
03079   }
03080 
03081 
03082 
03083 
03084   if (((pdev->sys_ctrl.system__mode_start &
03085         VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) == 0x00) &&
03086       (pdev->xtalk_cfg.global_crosstalk_compensation_enable
03087        == 0x01)) {
03088     pdev->stat_cfg.algo__range_ignore_threshold_mcps =
03089       pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps;
03090   }
03091 
03092 
03093 
03094 
03095 
03096   if (pdev->low_power_auto_data.low_power_auto_range_count == 0xFF) {
03097     pdev->low_power_auto_data.low_power_auto_range_count = 0x0;
03098   }
03099 
03100 
03101   if ((pdev->low_power_auto_data.is_low_power_auto_mode == 1) &&
03102       (pdev->low_power_auto_data.low_power_auto_range_count == 0)) {
03103 
03104     pdev->low_power_auto_data.saved_interrupt_config =
03105       pdev->gen_cfg.system__interrupt_config_gpio;
03106 
03107     pdev->gen_cfg.system__interrupt_config_gpio = 1 << 5;
03108 
03109     if ((pdev->dyn_cfg.system__sequence_config & (
03110            VL53LX_SEQUENCE_MM1_EN | VL53LX_SEQUENCE_MM2_EN)) ==
03111         0x0) {
03112       pN->algo__part_to_part_range_offset_mm =
03113         (pN->mm_config__outer_offset_mm << 2);
03114     } else {
03115       pN->algo__part_to_part_range_offset_mm = 0x0;
03116     }
03117 
03118 
03119     if (device_config_level <
03120         VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS) {
03121       device_config_level =
03122         VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS;
03123     }
03124   }
03125 
03126   if ((pdev->low_power_auto_data.is_low_power_auto_mode == 1) &&
03127       (pdev->low_power_auto_data.low_power_auto_range_count == 1)) {
03128 
03129     pdev->gen_cfg.system__interrupt_config_gpio =
03130       pdev->low_power_auto_data.saved_interrupt_config;
03131 
03132 
03133     device_config_level = VL53LX_DEVICECONFIGLEVEL_FULL;
03134   }
03135 
03136 
03137 
03138 
03139 
03140   if (status == VL53LX_ERROR_NONE) {
03141     status = VL53LX_save_cfg_data();
03142   }
03143 
03144 
03145 
03146   switch (device_config_level) {
03147     case VL53LX_DEVICECONFIGLEVEL_FULL:
03148       i2c_index = VL53LX_STATIC_NVM_MANAGED_I2C_INDEX;
03149       break;
03150     case VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS:
03151       i2c_index = VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX;
03152       break;
03153     case VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS:
03154       i2c_index = VL53LX_STATIC_CONFIG_I2C_INDEX;
03155       break;
03156     case VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS:
03157       i2c_index = VL53LX_GENERAL_CONFIG_I2C_INDEX;
03158       break;
03159     case VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS:
03160       i2c_index = VL53LX_TIMING_CONFIG_I2C_INDEX;
03161       break;
03162     case VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS:
03163       i2c_index = VL53LX_DYNAMIC_CONFIG_I2C_INDEX;
03164       break;
03165     default:
03166       i2c_index = VL53LX_SYSTEM_CONTROL_I2C_INDEX;
03167       break;
03168   }
03169 
03170 
03171 
03172   i2c_buffer_size_bytes =
03173     (VL53LX_SYSTEM_CONTROL_I2C_INDEX +
03174      VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES) -
03175     i2c_index;
03176 
03177 
03178 
03179   pbuffer = &buffer[0];
03180   for (i = 0; i < i2c_buffer_size_bytes; i++) {
03181     *pbuffer++ = 0;
03182   }
03183 
03184 
03185 
03186   if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_FULL &&
03187       status == VL53LX_ERROR_NONE) {
03188 
03189     i2c_buffer_offset_bytes =
03190       VL53LX_STATIC_NVM_MANAGED_I2C_INDEX - i2c_index;
03191 
03192     status =
03193       VL53LX_i2c_encode_static_nvm_managed(
03194         pstatic_nvm,
03195         VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES,
03196         &buffer[i2c_buffer_offset_bytes]);
03197   }
03198 
03199   if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS &&
03200       status == VL53LX_ERROR_NONE) {
03201 
03202     i2c_buffer_offset_bytes =
03203       VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX - i2c_index;
03204 
03205     status =
03206       VL53LX_i2c_encode_customer_nvm_managed(
03207         pcustomer_nvm,
03208         VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES,
03209         &buffer[i2c_buffer_offset_bytes]);
03210   }
03211 
03212   if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS &&
03213       status == VL53LX_ERROR_NONE) {
03214 
03215     i2c_buffer_offset_bytes =
03216       VL53LX_STATIC_CONFIG_I2C_INDEX - i2c_index;
03217 
03218     status =
03219       VL53LX_i2c_encode_static_config(
03220         pstatic,
03221         VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES,
03222         &buffer[i2c_buffer_offset_bytes]);
03223   }
03224 
03225   if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS &&
03226       status == VL53LX_ERROR_NONE) {
03227 
03228     i2c_buffer_offset_bytes =
03229       VL53LX_GENERAL_CONFIG_I2C_INDEX - i2c_index;
03230 
03231     status =
03232       VL53LX_i2c_encode_general_config(
03233         pgeneral,
03234         VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES,
03235         &buffer[i2c_buffer_offset_bytes]);
03236   }
03237 
03238   if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS &&
03239       status == VL53LX_ERROR_NONE) {
03240 
03241     i2c_buffer_offset_bytes =
03242       VL53LX_TIMING_CONFIG_I2C_INDEX - i2c_index;
03243 
03244     status =
03245       VL53LX_i2c_encode_timing_config(
03246         ptiming,
03247         VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES,
03248         &buffer[i2c_buffer_offset_bytes]);
03249   }
03250 
03251   if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS &&
03252       status == VL53LX_ERROR_NONE) {
03253 
03254     i2c_buffer_offset_bytes =
03255       VL53LX_DYNAMIC_CONFIG_I2C_INDEX - i2c_index;
03256 
03257 
03258     if ((psystem->system__mode_start &
03259          VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) ==
03260         VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) {
03261       pdynamic->system__grouped_parameter_hold_0 =
03262         pstate->cfg_gph_id | 0x01;
03263       pdynamic->system__grouped_parameter_hold_1 =
03264         pstate->cfg_gph_id | 0x01;
03265       pdynamic->system__grouped_parameter_hold   =
03266         pstate->cfg_gph_id;
03267     }
03268     status =
03269       VL53LX_i2c_encode_dynamic_config(
03270         pdynamic,
03271         VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES,
03272         &buffer[i2c_buffer_offset_bytes]);
03273   }
03274 
03275   if (status == VL53LX_ERROR_NONE) {
03276 
03277     i2c_buffer_offset_bytes =
03278       VL53LX_SYSTEM_CONTROL_I2C_INDEX - i2c_index;
03279 
03280     status =
03281       VL53LX_i2c_encode_system_control(
03282         psystem,
03283         VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES,
03284         &buffer[i2c_buffer_offset_bytes]);
03285   }
03286 
03287 
03288 
03289   if (status == VL53LX_ERROR_NONE) {
03290     status =
03291       VL53LX_WriteMulti(
03292         Dev,
03293         i2c_index,
03294         buffer,
03295         (uint32_t)i2c_buffer_size_bytes);
03296   }
03297 
03298 
03299   if (status == VL53LX_ERROR_NONE) {
03300     status = VL53LX_update_ll_driver_rd_state();
03301   }
03302 
03303   if (status == VL53LX_ERROR_NONE) {
03304     status = VL53LX_update_ll_driver_cfg_state();
03305   }
03306 
03307 
03308   return status;
03309 }
03310 VL53LX_Error VL53LX::VL53LX_stop_range()
03311 {
03312 
03313 
03314   VL53LX_Error status = VL53LX_ERROR_NONE;
03315 
03316   VL53LX_LLDriverData_t *pdev =
03317     VL53LXDevStructGetLLDriverHandle(Dev);
03318   VL53LX_LLDriverResults_t *pres =
03319     VL53LXDevStructGetLLResultsHandle(Dev);
03320 
03321 
03322 
03323   pdev->sys_ctrl.system__mode_start =
03324     (pdev->sys_ctrl.system__mode_start &
03325      VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK) |
03326     VL53LX_DEVICEMEASUREMENTMODE_ABORT;
03327 
03328   status = VL53LX_set_system_control(
03329              &pdev->sys_ctrl);
03330 
03331 
03332   pdev->sys_ctrl.system__mode_start =
03333     (pdev->sys_ctrl.system__mode_start &
03334      VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK);
03335 
03336 
03337   VL53LX_init_ll_driver_state(
03338     VL53LX_DEVICESTATE_SW_STANDBY);
03339 
03340 
03341   V53L1_init_zone_results_structure(
03342     pdev->zone_cfg.active_zones + 1,
03343     &(pres->zone_results));
03344 
03345 
03346   V53L1_init_zone_dss_configs();
03347 
03348 
03349   if (pdev->low_power_auto_data.is_low_power_auto_mode == 1) {
03350     VL53LX_low_power_auto_data_stop_range();
03351   }
03352 
03353   return status;
03354 }
03355 
03356 VL53LX_Error VL53LX::VL53LX_get_measurement_results(
03357   VL53LX_DeviceResultsLevel      device_results_level)
03358 {
03359 
03360 
03361   VL53LX_Error status = VL53LX_ERROR_NONE;
03362   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
03363 
03364   uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE];
03365 
03366   VL53LX_system_results_t   *psystem_results = &(pdev->sys_results);
03367   VL53LX_core_results_t     *pcore_results   = &(pdev->core_results);
03368   VL53LX_debug_results_t    *pdebug_results  = &(pdev->dbg_results);
03369 
03370   uint16_t i2c_index               = VL53LX_SYSTEM_RESULTS_I2C_INDEX;
03371   uint16_t i2c_buffer_offset_bytes = 0;
03372   uint16_t i2c_buffer_size_bytes   = 0;
03373 
03374   switch (device_results_level) {
03375     case VL53LX_DEVICERESULTSLEVEL_FULL:
03376       i2c_buffer_size_bytes =
03377         (VL53LX_DEBUG_RESULTS_I2C_INDEX +
03378          VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES) -
03379         i2c_index;
03380       break;
03381     case VL53LX_DEVICERESULTSLEVEL_UPTO_CORE:
03382       i2c_buffer_size_bytes =
03383         (VL53LX_CORE_RESULTS_I2C_INDEX +
03384          VL53LX_CORE_RESULTS_I2C_SIZE_BYTES) -
03385         i2c_index;
03386       break;
03387     default:
03388       i2c_buffer_size_bytes =
03389         VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES;
03390       break;
03391   }
03392 
03393 
03394 
03395   if (status == VL53LX_ERROR_NONE)
03396     status =
03397       VL53LX_ReadMulti(
03398         Dev,
03399         i2c_index,
03400         buffer,
03401         (uint32_t)i2c_buffer_size_bytes);
03402 
03403 
03404 
03405   if (device_results_level >= VL53LX_DEVICERESULTSLEVEL_FULL &&
03406       status == VL53LX_ERROR_NONE) {
03407 
03408     i2c_buffer_offset_bytes =
03409       VL53LX_DEBUG_RESULTS_I2C_INDEX - i2c_index;
03410 
03411     status =
03412       VL53LX_i2c_decode_debug_results(
03413         VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES,
03414         &buffer[i2c_buffer_offset_bytes],
03415         pdebug_results);
03416   }
03417 
03418   if (device_results_level >= VL53LX_DEVICERESULTSLEVEL_UPTO_CORE &&
03419       status == VL53LX_ERROR_NONE) {
03420 
03421     i2c_buffer_offset_bytes =
03422       VL53LX_CORE_RESULTS_I2C_INDEX - i2c_index;
03423 
03424     status =
03425       VL53LX_i2c_decode_core_results(
03426         VL53LX_CORE_RESULTS_I2C_SIZE_BYTES,
03427         &buffer[i2c_buffer_offset_bytes],
03428         pcore_results);
03429   }
03430 
03431   if (status == VL53LX_ERROR_NONE) {
03432 
03433     i2c_buffer_offset_bytes = 0;
03434     status =
03435       VL53LX_i2c_decode_system_results(
03436         VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES,
03437         &buffer[i2c_buffer_offset_bytes],
03438         psystem_results);
03439   }
03440 
03441 
03442   return status;
03443 }
03444 
03445 VL53LX_Error VL53LX::VL53LX_get_device_results(
03446   VL53LX_DeviceResultsLevel     device_results_level,
03447   VL53LX_range_results_t       *prange_results)
03448 {
03449 
03450 
03451   VL53LX_Error status = VL53LX_ERROR_NONE;
03452 
03453   VL53LX_LLDriverData_t *pdev =
03454     VL53LXDevStructGetLLDriverHandle(Dev);
03455   VL53LX_LLDriverResults_t *pres =
03456     VL53LXDevStructGetLLResultsHandle(Dev);
03457 
03458   VL53LX_range_results_t   *presults =
03459     &(pres->range_results);
03460   VL53LX_zone_objects_t    *pobjects =
03461     &(pres->zone_results.VL53LX_p_003[0]);
03462   VL53LX_ll_driver_state_t *pstate   =
03463     &(pdev->ll_state);
03464   VL53LX_zone_config_t     *pzone_cfg =
03465     &(pdev->zone_cfg);
03466   VL53LX_zone_hist_info_t  *phist_info =
03467     &(pres->zone_hists.VL53LX_p_003[0]);
03468 
03469   VL53LX_dmax_calibration_data_t   dmax_cal;
03470   VL53LX_dmax_calibration_data_t *pdmax_cal = &dmax_cal;
03471   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
03472   VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
03473   VL53LX_low_power_auto_data_t *pL = &(pdev->low_power_auto_data);
03474   VL53LX_histogram_bin_data_t *pHD = &(pdev->hist_data);
03475   VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
03476   VL53LX_zone_histograms_t *pZH = &(pres->zone_hists);
03477   VL53LX_xtalk_calibration_results_t *pXCR = &(pdev->xtalk_cal);
03478   uint8_t tmp8;
03479   uint8_t zid;
03480   uint8_t i;
03481   uint8_t histo_merge_nb, idx;
03482   VL53LX_range_data_t *pdata;
03483 
03484 
03485   if ((pdev->sys_ctrl.system__mode_start &
03486        VL53LX_DEVICESCHEDULERMODE_HISTOGRAM)
03487       == VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) {
03488 
03489 
03490 
03491     status = VL53LX_get_histogram_bin_data(&(pdev->hist_data));
03492 
03493 
03494 
03495 
03496     if (status == VL53LX_ERROR_NONE &&
03497         pHD->number_of_ambient_bins == 0) {
03498       zid = pdev->ll_state.rd_zone_id;
03499       status = VL53LX_hist_copy_and_scale_ambient_info(
03500                  &(pZH->VL53LX_p_003[zid]),
03501                  &(pdev->hist_data));
03502     }
03503 
03504 
03505     if (status != VL53LX_ERROR_NONE) {
03506       goto UPDATE_DYNAMIC_CONFIG;
03507     }
03508 
03509     VL53LX_compute_histo_merge_nb(&histo_merge_nb);
03510     if (histo_merge_nb == 0) {
03511       histo_merge_nb = 1;
03512     }
03513     idx = histo_merge_nb - 1;
03514     if (pdev->tuning_parms.tp_hist_merge == 1)
03515       pC->algo__crosstalk_compensation_plane_offset_kcps =
03516         pXCR->algo__xtalk_cpo_HistoMerge_kcps[idx];
03517 
03518     pHP->gain_factor =
03519       pdev->gain_cal.histogram_ranging_gain_factor;
03520 
03521     pHP->algo__crosstalk_compensation_plane_offset_kcps =
03522       VL53LX_calc_crosstalk_plane_offset_with_margin(
03523         pC->algo__crosstalk_compensation_plane_offset_kcps,
03524         pC->histogram_mode_crosstalk_margin_kcps);
03525 
03526     pHP->algo__crosstalk_compensation_x_plane_gradient_kcps =
03527       pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
03528     pHP->algo__crosstalk_compensation_y_plane_gradient_kcps =
03529       pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
03530 
03531     pdev->dmax_cfg.ambient_thresh_sigma =
03532       pHP->ambient_thresh_sigma1;
03533     pdev->dmax_cfg.min_ambient_thresh_events =
03534       pHP->min_ambient_thresh_events;
03535     pdev->dmax_cfg.signal_total_events_limit =
03536       pHP->signal_total_events_limit;
03537     pdev->dmax_cfg.dss_config__target_total_rate_mcps =
03538       pdev->stat_cfg.dss_config__target_total_rate_mcps;
03539     pdev->dmax_cfg.dss_config__aperture_attenuation =
03540       pdev->gen_cfg.dss_config__aperture_attenuation;
03541 
03542     pHP->algo__crosstalk_detect_max_valid_range_mm =
03543       pC->algo__crosstalk_detect_max_valid_range_mm;
03544     pHP->algo__crosstalk_detect_min_valid_range_mm =
03545       pC->algo__crosstalk_detect_min_valid_range_mm;
03546     pHP->algo__crosstalk_detect_max_valid_rate_kcps =
03547       pC->algo__crosstalk_detect_max_valid_rate_kcps;
03548     pHP->algo__crosstalk_detect_max_sigma_mm =
03549       pC->algo__crosstalk_detect_max_sigma_mm;
03550 
03551 
03552 
03553     VL53LX_copy_rtn_good_spads_to_buffer(
03554       &(pdev->nvm_copy_data),
03555       &(pdev->rtn_good_spads[0]));
03556 
03557 
03558 
03559     switch (pdev->offset_correction_mode) {
03560 
03561       case VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS:
03562         tmp8 = pdev->gen_cfg.dss_config__aperture_attenuation;
03563 
03564         VL53LX_hist_combine_mm1_mm2_offsets(
03565           pN->mm_config__inner_offset_mm,
03566           pN->mm_config__outer_offset_mm,
03567           pdev->nvm_copy_data.roi_config__mode_roi_centre_spad,
03568           pdev->nvm_copy_data.roi_config__mode_roi_xy_size,
03569           pHD->roi_config__user_roi_centre_spad,
03570           pHD->roi_config__user_roi_requested_global_xy_size,
03571           &(pdev->add_off_cal_data),
03572           &(pdev->rtn_good_spads[0]),
03573           (uint16_t)tmp8,
03574           &(pHP->range_offset_mm));
03575         break;
03576       case VL53LX_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS:
03577         select_offset_per_vcsel(
03578           pdev,
03579           &(pHP->range_offset_mm));
03580         pHP->range_offset_mm *= 4;
03581         break;
03582       default:
03583         pHP->range_offset_mm = 0;
03584         break;
03585 
03586     }
03587 
03588 
03589 
03590     if (status != VL53LX_ERROR_NONE) {
03591       goto UPDATE_DYNAMIC_CONFIG;
03592     }
03593 
03594 
03595     VL53LX_calc_max_effective_spads(
03596       pHD->roi_config__user_roi_centre_spad,
03597       pHD->roi_config__user_roi_requested_global_xy_size,
03598       &(pdev->rtn_good_spads[0]),
03599       (uint16_t)pdev->gen_cfg.dss_config__aperture_attenuation,
03600       &(pdev->dmax_cfg.max_effective_spads));
03601 
03602     status =
03603       VL53LX_get_dmax_calibration_data(
03604         pdev->dmax_mode,
03605         pdmax_cal);
03606 
03607 
03608     if (status != VL53LX_ERROR_NONE) {
03609       goto UPDATE_DYNAMIC_CONFIG;
03610     }
03611 
03612     status = VL53LX_ipp_hist_process_data(
03613                pdmax_cal,
03614                &(pdev->dmax_cfg),
03615                &(pdev->histpostprocess),
03616                &(pdev->hist_data),
03617                &(pdev->xtalk_shapes),
03618                pdev->wArea1,
03619                pdev->wArea2,
03620                &histo_merge_nb,
03621                presults);
03622 
03623     if ((pdev->tuning_parms.tp_hist_merge == 1) &&
03624         (histo_merge_nb > 1))
03625       for (i = 0; i < VL53LX_MAX_RANGE_RESULTS; i++) {
03626         pdata = &(presults->VL53LX_p_003[i]);
03627         pdata->VL53LX_p_016 /= histo_merge_nb;
03628         pdata->VL53LX_p_017 /= histo_merge_nb;
03629         pdata->VL53LX_p_010 /= histo_merge_nb;
03630         pdata->peak_signal_count_rate_mcps /= histo_merge_nb;
03631         pdata->avg_signal_count_rate_mcps /= histo_merge_nb;
03632         pdata->ambient_count_rate_mcps /= histo_merge_nb;
03633         pdata->VL53LX_p_009 /= histo_merge_nb;
03634       }
03635 
03636 
03637     if (status != VL53LX_ERROR_NONE) {
03638       goto UPDATE_DYNAMIC_CONFIG;
03639     }
03640 
03641     status = VL53LX_hist_wrap_dmax(
03642                &(pdev->histpostprocess),
03643                &(pdev->hist_data),
03644                &(presults->wrap_dmax_mm));
03645 
03646 
03647     if (status != VL53LX_ERROR_NONE) {
03648       goto UPDATE_DYNAMIC_CONFIG;
03649     }
03650 
03651     zid = pdev->ll_state.rd_zone_id;
03652     status = VL53LX_hist_phase_consistency_check(
03653                &(pZH->VL53LX_p_003[zid]),
03654                &(pres->zone_results.VL53LX_p_003[zid]),
03655                presults);
03656 
03657 
03658     if (status != VL53LX_ERROR_NONE) {
03659       goto UPDATE_DYNAMIC_CONFIG;
03660     }
03661 
03662     zid = pdev->ll_state.rd_zone_id;
03663     status = VL53LX_hist_xmonitor_consistency_check(
03664                &(pZH->VL53LX_p_003[zid]),
03665                &(pres->zone_results.VL53LX_p_003[zid]),
03666                &(presults->xmonitor));
03667 
03668 
03669     if (status != VL53LX_ERROR_NONE) {
03670       goto UPDATE_DYNAMIC_CONFIG;
03671     }
03672 
03673 
03674     zid = pdev->ll_state.rd_zone_id;
03675     pZH->max_zones    = VL53LX_MAX_USER_ZONES;
03676     pZH->active_zones =
03677       pdev->zone_cfg.active_zones + 1;
03678     pHD->zone_id       = zid;
03679 
03680     if (zid <
03681         pres->zone_results.max_zones) {
03682 
03683       phist_info =
03684         &(pZH->VL53LX_p_003[zid]);
03685 
03686       phist_info->rd_device_state =
03687         pHD->rd_device_state;
03688 
03689       phist_info->number_of_ambient_bins =
03690         pHD->number_of_ambient_bins;
03691 
03692       phist_info->result__dss_actual_effective_spads =
03693         pHD->result__dss_actual_effective_spads;
03694 
03695       phist_info->VL53LX_p_005 =
03696         pHD->VL53LX_p_005;
03697 
03698       phist_info->total_periods_elapsed =
03699         pHD->total_periods_elapsed;
03700 
03701       phist_info->ambient_events_sum =
03702         pHD->ambient_events_sum;
03703     }
03704 
03705 
03706 
03707     if (status != VL53LX_ERROR_NONE) {
03708       goto UPDATE_DYNAMIC_CONFIG;
03709     }
03710 
03711     VL53LX_hist_copy_results_to_sys_and_core(
03712       &(pdev->hist_data),
03713       presults,
03714       &(pdev->sys_results),
03715       &(pdev->core_results));
03716 
03717 
03718 UPDATE_DYNAMIC_CONFIG:
03719     if (pzone_cfg->active_zones > 0) {
03720       if (pstate->rd_device_state !=
03721           VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) {
03722         if (status == VL53LX_ERROR_NONE) {
03723           status = VL53LX_dynamic_zone_update(presults);
03724         }
03725       }
03726 
03727 
03728       for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) {
03729         pzone_cfg->bin_config[i] =
03730           ((pdev->ll_state.cfg_internal_stream_count)
03731            & 0x01) ?
03732           VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB :
03733           VL53LX_ZONECONFIG_BINCONFIG__LOWAMB;
03734       }
03735 
03736       if (status == VL53LX_ERROR_NONE) {
03737         status = VL53LX_multizone_hist_bins_update();
03738       }
03739 
03740     }
03741 
03742 
03743 
03744     if (status == VL53LX_ERROR_NONE) {
03745       status = VL53LX_dynamic_xtalk_correction_corrector();
03746     }
03747     /*
03748     #ifdef VL53LX_LOG_ENABLE
03749         if (status == VL53LX_ERROR_NONE)
03750           VL53LX_print_histogram_bin_data(
03751             &(pdev->hist_data),
03752             "get_device_results():pdev->lldata.hist_data.",
03753             VL53LX_TRACE_MODULE_HISTOGRAM_DATA);
03754     #endif
03755     */
03756   } else {
03757 
03758     if (status == VL53LX_ERROR_NONE)
03759       status = VL53LX_get_measurement_results(
03760                  device_results_level);
03761 
03762     if (status == VL53LX_ERROR_NONE)
03763       VL53LX_copy_sys_and_core_results_to_range_results(
03764         (int32_t)pdev->gain_cal.standard_ranging_gain_factor,
03765         &(pdev->sys_results),
03766         &(pdev->core_results),
03767         presults);
03768 
03769 
03770 
03771     if (pL->is_low_power_auto_mode == 1) {
03772 
03773       if ((status == VL53LX_ERROR_NONE) &&
03774           (pL->low_power_auto_range_count == 0)) {
03775 
03776         status =
03777           VL53LX_low_power_auto_setup_manual_calibration();
03778         pL->low_power_auto_range_count = 1;
03779       } else if ((status == VL53LX_ERROR_NONE) &&
03780                  (pL->low_power_auto_range_count == 1)) {
03781         pL->low_power_auto_range_count = 2;
03782       }
03783 
03784 
03785       if ((pL->low_power_auto_range_count != 0xFF) &&
03786           (status == VL53LX_ERROR_NONE)) {
03787         status = VL53LX_low_power_auto_update_DSS();
03788       }
03789     }
03790 
03791   }
03792 
03793 
03794   presults->cfg_device_state = pdev->ll_state.cfg_device_state;
03795   presults->rd_device_state  = pdev->ll_state.rd_device_state;
03796   presults->zone_id          = pdev->ll_state.rd_zone_id;
03797 
03798   if (status == VL53LX_ERROR_NONE) {
03799 
03800 
03801     pres->zone_results.max_zones    = VL53LX_MAX_USER_ZONES;
03802     pres->zone_results.active_zones = pdev->zone_cfg.active_zones + 1;
03803     zid = pdev->ll_state.rd_zone_id;
03804 
03805     if (zid < pres->zone_results.max_zones) {
03806 
03807       pobjects =
03808         &(pres->zone_results.VL53LX_p_003[zid]);
03809 
03810       pobjects->cfg_device_state  =
03811         presults->cfg_device_state;
03812       pobjects->rd_device_state   = presults->rd_device_state;
03813       pobjects->zone_id           = presults->zone_id;
03814       pobjects->stream_count      = presults->stream_count;
03815 
03816 
03817 
03818       pobjects->xmonitor.VL53LX_p_016 =
03819         presults->xmonitor.VL53LX_p_016;
03820       pobjects->xmonitor.VL53LX_p_017 =
03821         presults->xmonitor.VL53LX_p_017;
03822       pobjects->xmonitor.VL53LX_p_011 =
03823         presults->xmonitor.VL53LX_p_011;
03824       pobjects->xmonitor.range_status =
03825         presults->xmonitor.range_status;
03826 
03827       pobjects->max_objects      = presults->max_results;
03828       pobjects->active_objects   = presults->active_results;
03829 
03830       for (i = 0; i < presults->active_results; i++) {
03831         pobjects->VL53LX_p_003[i].VL53LX_p_016 =
03832           presults->VL53LX_p_003[i].VL53LX_p_016;
03833         pobjects->VL53LX_p_003[i].VL53LX_p_017 =
03834           presults->VL53LX_p_003[i].VL53LX_p_017;
03835         pobjects->VL53LX_p_003[i].VL53LX_p_011 =
03836           presults->VL53LX_p_003[i].VL53LX_p_011;
03837         pobjects->VL53LX_p_003[i].range_status =
03838           presults->VL53LX_p_003[i].range_status;
03839       }
03840 
03841 
03842     }
03843   }
03844 
03845 
03846 
03847   memcpy(
03848     prange_results,
03849     presults,
03850     sizeof(VL53LX_range_results_t));
03851 
03852 
03853 
03854   if (status == VL53LX_ERROR_NONE) {
03855     status = VL53LX_check_ll_driver_rd_state();
03856   }
03857   /*
03858   #ifdef VL53LX_LOG_ENABLE
03859     if (status == VL53LX_ERROR_NONE)
03860       VL53LX_print_range_results(
03861         presults,
03862         "get_device_results():pdev->llresults.range_results.",
03863         VL53LX_TRACE_MODULE_RANGE_RESULTS_DATA);
03864   #endif
03865   */
03866 
03867   return status;
03868 }
03869 
03870 VL53LX_Error VL53LX::VL53LX_clear_interrupt_and_enable_next_range(
03871   uint8_t           measurement_mode)
03872 {
03873   VL53LX_Error status = VL53LX_ERROR_NONE;
03874   if (status == VL53LX_ERROR_NONE)
03875     status = VL53LX_init_and_start_range(
03876                measurement_mode,
03877                VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS);
03878 
03879 
03880   return status;
03881 }
03882 
03883 
03884 VL53LX_Error VL53LX::VL53LX_get_histogram_bin_data(
03885   VL53LX_histogram_bin_data_t *pdata)
03886 {
03887   VL53LX_Error status = VL53LX_ERROR_NONE;
03888   VL53LX_LLDriverData_t *pdev =
03889     VL53LXDevStructGetLLDriverHandle(Dev);
03890   VL53LX_LLDriverResults_t *pres =
03891     VL53LXDevStructGetLLResultsHandle(Dev);
03892 
03893   VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg;
03894 
03895   VL53LX_static_nvm_managed_t   *pstat_nvm = &(pdev->stat_nvm);
03896   VL53LX_static_config_t        *pstat_cfg = &(pdev->stat_cfg);
03897   VL53LX_general_config_t       *pgen_cfg  = &(pdev->gen_cfg);
03898   VL53LX_timing_config_t        *ptim_cfg  = &(pdev->tim_cfg);
03899   VL53LX_range_results_t        *presults  = &(pres->range_results);
03900 
03901   uint8_t    buffer[VL53LX_MAX_I2C_XFER_SIZE];
03902   uint8_t   *pbuffer = &buffer[0];
03903   uint8_t    bin_23_0 = 0x00;
03904   uint16_t   bin                      = 0;
03905   uint16_t   i2c_buffer_offset_bytes  = 0;
03906   uint16_t   encoded_timeout          = 0;
03907 
03908   uint32_t   pll_period_us            = 0;
03909   uint32_t   periods_elapsed_tmp      = 0;
03910 
03911   uint8_t    i                        = 0;
03912 
03913   int32_t    hist_merge       = 0;
03914 
03915 
03916 
03917   if (status == VL53LX_ERROR_NONE)
03918     status = VL53LX_ReadMulti(
03919                Dev,
03920                VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX,
03921                pbuffer,
03922                VL53LX_HISTOGRAM_BIN_DATA_I2C_SIZE_BYTES);
03923 
03924 
03925 
03926   pdata->result__interrupt_status               = *(pbuffer +   0);
03927   pdata->result__range_status                   = *(pbuffer +   1);
03928   pdata->result__report_status                  = *(pbuffer +   2);
03929   pdata->result__stream_count                   = *(pbuffer +   3);
03930   pdata->result__dss_actual_effective_spads =
03931     VL53LX_i2c_decode_uint16_t(2, pbuffer +   4);
03932 
03933 
03934 
03935   i2c_buffer_offset_bytes =
03936     VL53LX_PHASECAL_RESULT__REFERENCE_PHASE -
03937     VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
03938 
03939   pbuffer = &buffer[i2c_buffer_offset_bytes];
03940 
03941   pdata->phasecal_result__reference_phase =
03942     VL53LX_i2c_decode_uint16_t(2, pbuffer);
03943 
03944   i2c_buffer_offset_bytes =
03945     VL53LX_PHASECAL_RESULT__VCSEL_START -
03946     VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
03947 
03948   pdata->phasecal_result__vcsel_start = buffer[i2c_buffer_offset_bytes];
03949 
03950 
03951 
03952   pdev->dbg_results.phasecal_result__reference_phase =
03953     pdata->phasecal_result__reference_phase;
03954   pdev->dbg_results.phasecal_result__vcsel_start =
03955     pdata->phasecal_result__vcsel_start;
03956 
03957 
03958 
03959   i2c_buffer_offset_bytes =
03960     VL53LX_RESULT__HISTOGRAM_BIN_23_0_MSB -
03961     VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
03962 
03963   bin_23_0 = buffer[i2c_buffer_offset_bytes] << 2;
03964 
03965   i2c_buffer_offset_bytes =
03966     VL53LX_RESULT__HISTOGRAM_BIN_23_0_LSB -
03967     VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
03968 
03969   bin_23_0 += buffer[i2c_buffer_offset_bytes];
03970 
03971   i2c_buffer_offset_bytes =
03972     VL53LX_RESULT__HISTOGRAM_BIN_23_0 -
03973     VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
03974 
03975   buffer[i2c_buffer_offset_bytes] = bin_23_0;
03976 
03977 
03978 
03979   i2c_buffer_offset_bytes =
03980     VL53LX_RESULT__HISTOGRAM_BIN_0_2 -
03981     VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
03982 
03983   pbuffer = &buffer[i2c_buffer_offset_bytes];
03984   for (bin = 0; bin < VL53LX_HISTOGRAM_BUFFER_SIZE; bin++) {
03985     pdata->bin_data[bin] =
03986       (int32_t)VL53LX_i2c_decode_uint32_t(3, pbuffer);
03987     pbuffer += 3;
03988   }
03989 
03990 
03991 
03992 
03993   VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE, &hist_merge);
03994 
03995   if (pdata->result__stream_count == 0) {
03996 
03997     memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec));
03998     pdev->bin_rec_pos = 0;
03999     pdev->pos_before_next_recom = 0;
04000   }
04001 
04002   if (hist_merge == 1) {
04003     vl53lx_histo_merge(pdata);
04004   }
04005 
04006 
04007   pdata->zone_id                 = pdev->ll_state.rd_zone_id;
04008   pdata->VL53LX_p_019               = 0;
04009   pdata->VL53LX_p_020             = VL53LX_HISTOGRAM_BUFFER_SIZE;
04010   pdata->VL53LX_p_021          = VL53LX_HISTOGRAM_BUFFER_SIZE;
04011 
04012   pdata->cal_config__vcsel_start = pgen_cfg->cal_config__vcsel_start;
04013 
04014 
04015 
04016   pdata->vcsel_width =
04017     ((uint16_t)pgen_cfg->global_config__vcsel_width) << 4;
04018   pdata->vcsel_width +=
04019     (uint16_t)pstat_cfg->ana_config__vcsel_pulse_width_offset;
04020 
04021 
04022   pdata->VL53LX_p_015 =
04023     pstat_nvm->osc_measured__fast_osc__frequency;
04024 
04025 
04026 
04027   VL53LX_hist_get_bin_sequence_config(pdata);
04028 
04029 
04030 
04031   if (pdev->ll_state.rd_timing_status == 0) {
04032 
04033     encoded_timeout =
04034       (ptim_cfg->range_config__timeout_macrop_a_hi << 8)
04035       + ptim_cfg->range_config__timeout_macrop_a_lo;
04036     pdata->VL53LX_p_005 =  ptim_cfg->range_config__vcsel_period_a;
04037   } else {
04038 
04039     encoded_timeout =
04040       (ptim_cfg->range_config__timeout_macrop_b_hi << 8)
04041       + ptim_cfg->range_config__timeout_macrop_b_lo;
04042     pdata->VL53LX_p_005 = ptim_cfg->range_config__vcsel_period_b;
04043   }
04044 
04045 
04046 
04047   pdata->number_of_ambient_bins  = 0;
04048 
04049   for (i = 0; i < 6; i++) {
04050     if ((pdata->bin_seq[i] & 0x07) == 0x07)
04051       pdata->number_of_ambient_bins  =
04052         pdata->number_of_ambient_bins + 0x04;
04053   }
04054 
04055   pdata->total_periods_elapsed =
04056     VL53LX_decode_timeout(encoded_timeout);
04057 
04058 
04059 
04060 
04061   pll_period_us =
04062     VL53LX_calc_pll_period_us(pdata->VL53LX_p_015);
04063 
04064 
04065 
04066   periods_elapsed_tmp = pdata->total_periods_elapsed + 1;
04067 
04068 
04069 
04070   pdata->peak_duration_us =
04071     VL53LX_duration_maths(
04072       pll_period_us,
04073       (uint32_t)pdata->vcsel_width,
04074       VL53LX_RANGING_WINDOW_VCSEL_PERIODS,
04075       periods_elapsed_tmp);
04076 
04077   pdata->woi_duration_us     = 0;
04078 
04079 
04080 
04081   VL53LX_hist_calc_zero_distance_phase(pdata);
04082 
04083 
04084 
04085   VL53LX_hist_estimate_ambient_from_ambient_bins(pdata);
04086 
04087 
04088 
04089   pdata->cfg_device_state = pdev->ll_state.cfg_device_state;
04090   pdata->rd_device_state  = pdev->ll_state.rd_device_state;
04091 
04092 
04093 
04094   pzone_dyn_cfg = &(pres->zone_dyn_cfgs.VL53LX_p_003[pdata->zone_id]);
04095 
04096   pdata->roi_config__user_roi_centre_spad =
04097     pzone_dyn_cfg->roi_config__user_roi_centre_spad;
04098   pdata->roi_config__user_roi_requested_global_xy_size =
04099     pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size;
04100 
04101 
04102 
04103   presults->device_status = VL53LX_DEVICEERROR_NOUPDATE;
04104 
04105 
04106 
04107   switch (pdata->result__range_status &
04108           VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) {
04109 
04110     case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
04111     case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
04112     case VL53LX_DEVICEERROR_NOVHVVALUEFOUND:
04113     case VL53LX_DEVICEERROR_USERROICLIP:
04114     case VL53LX_DEVICEERROR_MULTCLIPFAIL:
04115 
04116       presults->device_status = (pdata->result__range_status &
04117                                  VL53LX_RANGE_STATUS__RANGE_STATUS_MASK);
04118 
04119       status = VL53LX_ERROR_RANGE_ERROR;
04120 
04121       break;
04122 
04123   }
04124 
04125 
04126   return status;
04127 }
04128 
04129 void VL53LX::VL53LX_copy_sys_and_core_results_to_range_results(
04130   int32_t                           gain_factor,
04131   VL53LX_system_results_t          *psys,
04132   VL53LX_core_results_t            *pcore,
04133   VL53LX_range_results_t           *presults)
04134 {
04135   uint8_t  i = 0;
04136 
04137   VL53LX_range_data_t *pdata;
04138   int32_t range_mm = 0;
04139   uint32_t tmpu32 = 0;
04140   uint16_t rpscr_crosstalk_corrected_mcps_sd0;
04141   uint16_t rmmo_effective_spads_sd0;
04142   uint16_t rmmi_effective_spads_sd0;
04143 
04144 
04145 
04146 
04147   presults->zone_id         = 0;
04148   presults->stream_count    = psys->result__stream_count;
04149   presults->wrap_dmax_mm    = 0;
04150   presults->max_results     = VL53LX_MAX_RANGE_RESULTS;
04151   presults->active_results  = 1;
04152   rpscr_crosstalk_corrected_mcps_sd0 =
04153     psys->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0;
04154   rmmo_effective_spads_sd0 =
04155     psys->result__mm_outer_actual_effective_spads_sd0;
04156   rmmi_effective_spads_sd0 =
04157     psys->result__mm_inner_actual_effective_spads_sd0;
04158 
04159 
04160   for (i = 0; i < VL53LX_MAX_AMBIENT_DMAX_VALUES; i++) {
04161     presults->VL53LX_p_022[i] = 0;
04162   }
04163 
04164   pdata = &(presults->VL53LX_p_003[0]);
04165 
04166   for (i = 0; i < 2; i++) {
04167 
04168     pdata->range_id     = i;
04169     pdata->time_stamp   = 0;
04170 
04171     if ((psys->result__stream_count == 0) &&
04172         ((psys->result__range_status &
04173           VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) ==
04174          VL53LX_DEVICEERROR_RANGECOMPLETE)) {
04175       pdata->range_status =
04176         VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK;
04177     } else {
04178       pdata->range_status =
04179         psys->result__range_status &
04180         VL53LX_RANGE_STATUS__RANGE_STATUS_MASK;
04181     }
04182 
04183     pdata->VL53LX_p_012 = 0;
04184     pdata->VL53LX_p_019    = 0;
04185     pdata->VL53LX_p_023   = 0;
04186     pdata->VL53LX_p_024     = 0;
04187     pdata->VL53LX_p_013   = 0;
04188     pdata->VL53LX_p_025    = 0;
04189 
04190     switch (i) {
04191 
04192       case 0:
04193         if (psys->result__report_status ==
04194             VL53LX_DEVICEREPORTSTATUS_MM1)
04195           pdata->VL53LX_p_004 =
04196             rmmi_effective_spads_sd0;
04197         else if (psys->result__report_status ==
04198                  VL53LX_DEVICEREPORTSTATUS_MM2)
04199           pdata->VL53LX_p_004 =
04200             rmmo_effective_spads_sd0;
04201         else
04202           pdata->VL53LX_p_004 =
04203             psys->result__dss_actual_effective_spads_sd0;
04204 
04205         pdata->peak_signal_count_rate_mcps =
04206           rpscr_crosstalk_corrected_mcps_sd0;
04207         pdata->avg_signal_count_rate_mcps =
04208           psys->result__avg_signal_count_rate_mcps_sd0;
04209         pdata->ambient_count_rate_mcps =
04210           psys->result__ambient_count_rate_mcps_sd0;
04211 
04212 
04213 
04214 
04215         tmpu32 = ((uint32_t)psys->result__sigma_sd0 << 5);
04216         if (tmpu32 > 0xFFFF) {
04217           tmpu32 = 0xFFFF;
04218         }
04219 
04220         pdata->VL53LX_p_002 = (uint16_t)tmpu32;
04221 
04222 
04223 
04224         pdata->VL53LX_p_011 =
04225           psys->result__phase_sd0;
04226 
04227         range_mm = (int32_t)(
04228                      psys->result__final_crosstalk_corrected_range_mm_sd0);
04229 
04230 
04231         range_mm *= gain_factor;
04232         range_mm += 0x0400;
04233         range_mm /= 0x0800;
04234 
04235         pdata->median_range_mm = (int16_t)range_mm;
04236 
04237         pdata->VL53LX_p_017 =
04238           pcore->result_core__ranging_total_events_sd0;
04239         pdata->VL53LX_p_010 =
04240           pcore->result_core__signal_total_events_sd0;
04241         pdata->total_periods_elapsed =
04242           pcore->result_core__total_periods_elapsed_sd0;
04243         pdata->VL53LX_p_016 =
04244           pcore->result_core__ambient_window_events_sd0;
04245 
04246         break;
04247       case 1:
04248 
04249         pdata->VL53LX_p_004 =
04250           psys->result__dss_actual_effective_spads_sd1;
04251         pdata->peak_signal_count_rate_mcps =
04252           psys->result__peak_signal_count_rate_mcps_sd1;
04253         pdata->avg_signal_count_rate_mcps =
04254           0xFFFF;
04255         pdata->ambient_count_rate_mcps =
04256           psys->result__ambient_count_rate_mcps_sd1;
04257 
04258 
04259 
04260 
04261         tmpu32 = ((uint32_t)psys->result__sigma_sd1 << 5);
04262         if (tmpu32 > 0xFFFF) {
04263           tmpu32 = 0xFFFF;
04264         }
04265 
04266         pdata->VL53LX_p_002 = (uint16_t)tmpu32;
04267 
04268 
04269 
04270         pdata->VL53LX_p_011 =
04271           psys->result__phase_sd1;
04272 
04273         range_mm = (int32_t)(
04274                      psys->result__final_crosstalk_corrected_range_mm_sd1);
04275 
04276 
04277         range_mm *= gain_factor;
04278         range_mm += 0x0400;
04279         range_mm /= 0x0800;
04280 
04281         pdata->median_range_mm = (int16_t)range_mm;
04282 
04283         pdata->VL53LX_p_017 =
04284           pcore->result_core__ranging_total_events_sd1;
04285         pdata->VL53LX_p_010 =
04286           pcore->result_core__signal_total_events_sd1;
04287         pdata->total_periods_elapsed  =
04288           pcore->result_core__total_periods_elapsed_sd1;
04289         pdata->VL53LX_p_016 =
04290           pcore->result_core__ambient_window_events_sd1;
04291 
04292         break;
04293     }
04294 
04295 
04296     pdata->VL53LX_p_026    = pdata->VL53LX_p_011;
04297     pdata->VL53LX_p_027    = pdata->VL53LX_p_011;
04298     pdata->min_range_mm = pdata->median_range_mm;
04299     pdata->max_range_mm = pdata->median_range_mm;
04300 
04301     pdata++;
04302   }
04303 
04304 
04305 
04306   presults->device_status = VL53LX_DEVICEERROR_NOUPDATE;
04307 
04308 
04309 
04310   switch (psys->result__range_status &
04311           VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) {
04312 
04313     case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
04314     case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
04315     case VL53LX_DEVICEERROR_NOVHVVALUEFOUND:
04316     case VL53LX_DEVICEERROR_USERROICLIP:
04317     case VL53LX_DEVICEERROR_MULTCLIPFAIL:
04318 
04319       presults->device_status = (psys->result__range_status &
04320                                  VL53LX_RANGE_STATUS__RANGE_STATUS_MASK);
04321 
04322       presults->VL53LX_p_003[0].range_status =
04323         VL53LX_DEVICEERROR_NOUPDATE;
04324       break;
04325 
04326   }
04327 
04328 }
04329 
04330 VL53LX_Error VL53LX::VL53LX_set_zone_dss_config(
04331   VL53LX_zone_private_dyn_cfg_t  *pzone_dyn_cfg)
04332 {
04333   VL53LX_Error  status = VL53LX_ERROR_NONE;
04334 
04335   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04336   VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
04337 
04338   if (pstate->cfg_device_state ==
04339       VL53LX_DEVICESTATE_RANGING_DSS_MANUAL) {
04340     pdev->gen_cfg.dss_config__roi_mode_control =
04341       VL53LX_DSS_CONTROL__MODE_EFFSPADS;
04342     pdev->gen_cfg.dss_config__manual_effective_spads_select =
04343       pzone_dyn_cfg->dss_requested_effective_spad_count;
04344   } else {
04345     pdev->gen_cfg.dss_config__roi_mode_control =
04346       VL53LX_DSS_CONTROL__MODE_TARGET_RATE;
04347   }
04348 
04349   return status;
04350 }
04351 VL53LX_Error VL53LX::VL53LX_calc_ambient_dmax(
04352   uint16_t        target_reflectance,
04353   int16_t         *pambient_dmax_mm)
04354 {
04355   VL53LX_Error  status = VL53LX_ERROR_NONE;
04356 
04357   VL53LX_LLDriverData_t *pdev =
04358     VL53LXDevStructGetLLDriverHandle(Dev);
04359 
04360   VL53LX_dmax_calibration_data_t   dmax_cal;
04361   VL53LX_dmax_calibration_data_t *pdmax_cal = &dmax_cal;
04362 
04363   status =
04364     VL53LX_get_dmax_calibration_data(
04365       pdev->debug_mode,
04366       pdmax_cal);
04367 
04368 
04369 
04370   if (status == VL53LX_ERROR_NONE)
04371     status =
04372       VL53LX_ipp_hist_ambient_dmax(
04373         target_reflectance,
04374         &(pdev->fmt_dmax_cal),
04375         &(pdev->dmax_cfg),
04376         &(pdev->hist_data),
04377         pambient_dmax_mm);
04378 
04379   return status;
04380 }
04381 
04382 
04383 VL53LX_Error VL53LX::VL53LX_set_GPIO_interrupt_config(
04384   VL53LX_GPIO_Interrupt_Mode  intr_mode_distance,
04385   VL53LX_GPIO_Interrupt_Mode  intr_mode_rate,
04386   uint8_t       intr_new_measure_ready,
04387   uint8_t       intr_no_target,
04388   uint8_t       intr_combined_mode,
04389   uint16_t      thresh_distance_high,
04390   uint16_t      thresh_distance_low,
04391   uint16_t      thresh_rate_high,
04392   uint16_t      thresh_rate_low
04393 )
04394 {
04395   VL53LX_Error  status = VL53LX_ERROR_NONE;
04396 
04397   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04398   VL53LX_GPIO_interrupt_config_t *pintconf =
04399     &(pdev->gpio_interrupt_config);
04400 
04401   pintconf->intr_mode_distance = intr_mode_distance;
04402   pintconf->intr_mode_rate = intr_mode_rate;
04403   pintconf->intr_new_measure_ready = intr_new_measure_ready;
04404   pintconf->intr_no_target = intr_no_target;
04405   pintconf->intr_combined_mode = intr_combined_mode;
04406   pintconf->threshold_distance_high = thresh_distance_high;
04407   pintconf->threshold_distance_low = thresh_distance_low;
04408   pintconf->threshold_rate_high = thresh_rate_high;
04409   pintconf->threshold_rate_low = thresh_rate_low;
04410 
04411 
04412   pdev->gen_cfg.system__interrupt_config_gpio =
04413     VL53LX_encode_GPIO_interrupt_config(pintconf);
04414 
04415 
04416 
04417   status = VL53LX_set_GPIO_thresholds_from_struct(
04418              pintconf);
04419 
04420   return status;
04421 }
04422 
04423 VL53LX_Error VL53LX::VL53LX_set_GPIO_interrupt_config_struct(
04424   VL53LX_GPIO_interrupt_config_t  intconf)
04425 {
04426   VL53LX_Error  status = VL53LX_ERROR_NONE;
04427 
04428   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04429   VL53LX_GPIO_interrupt_config_t *pintconf =
04430     &(pdev->gpio_interrupt_config);
04431   memcpy(pintconf, &(intconf), sizeof(VL53LX_GPIO_interrupt_config_t));
04432 
04433 
04434   pdev->gen_cfg.system__interrupt_config_gpio =
04435     VL53LX_encode_GPIO_interrupt_config(pintconf);
04436 
04437 
04438   status = VL53LX_set_GPIO_thresholds_from_struct(
04439              pintconf);
04440 
04441   return status;
04442 }
04443 
04444 
04445 VL53LX_Error VL53LX::VL53LX_get_GPIO_interrupt_config(
04446   VL53LX_GPIO_interrupt_config_t  *pintconf)
04447 {
04448   VL53LX_Error  status = VL53LX_ERROR_NONE;
04449 
04450   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04451 
04452   pdev->gpio_interrupt_config = VL53LX_decode_GPIO_interrupt_config(
04453                                   pdev->gen_cfg.system__interrupt_config_gpio);
04454 
04455 
04456   pdev->gpio_interrupt_config.threshold_distance_high =
04457     pdev->dyn_cfg.system__thresh_high;
04458   pdev->gpio_interrupt_config.threshold_distance_low =
04459     pdev->dyn_cfg.system__thresh_low;
04460 
04461   pdev->gpio_interrupt_config.threshold_rate_high =
04462     pdev->gen_cfg.system__thresh_rate_high;
04463   pdev->gpio_interrupt_config.threshold_rate_low =
04464     pdev->gen_cfg.system__thresh_rate_low;
04465 
04466   if (pintconf == &(pdev->gpio_interrupt_config)) {
04467 
04468   } else {
04469 
04470 
04471     memcpy(pintconf, &(pdev->gpio_interrupt_config),
04472            sizeof(VL53LX_GPIO_interrupt_config_t));
04473   }
04474 
04475   return status;
04476 }
04477 VL53LX_Error VL53LX::VL53LX_set_dmax_mode(
04478   VL53LX_DeviceDmaxMode    dmax_mode)
04479 {
04480   VL53LX_Error  status = VL53LX_ERROR_NONE;
04481 
04482   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04483 
04484   pdev->dmax_mode = dmax_mode;
04485 
04486   return status;
04487 }
04488 VL53LX_Error VL53LX::VL53LX_get_dmax_mode(
04489   VL53LX_DeviceDmaxMode   *pdmax_mode)
04490 {
04491   VL53LX_Error  status = VL53LX_ERROR_NONE;
04492 
04493   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04494 
04495   *pdmax_mode = pdev->dmax_mode;
04496 
04497 
04498   return status;
04499 }
04500 
04501 
04502 VL53LX_Error VL53LX::VL53LX_get_dmax_calibration_data(
04503   VL53LX_DeviceDmaxMode           dmax_mode,
04504   VL53LX_dmax_calibration_data_t *pdmax_cal)
04505 {
04506 
04507 
04508   VL53LX_Error  status = VL53LX_ERROR_NONE;
04509 
04510   VL53LX_LLDriverData_t    *pdev =
04511     VL53LXDevStructGetLLDriverHandle(Dev);
04512 
04513 
04514   switch (dmax_mode) {
04515 
04516     case VL53LX_DEVICEDMAXMODE__CUST_CAL_DATA:
04517       memcpy(
04518         pdmax_cal,
04519         &(pdev->cust_dmax_cal),
04520         sizeof(VL53LX_dmax_calibration_data_t));
04521       break;
04522 
04523     case VL53LX_DEVICEDMAXMODE__FMT_CAL_DATA:
04524       memcpy(
04525         pdmax_cal,
04526         &(pdev->fmt_dmax_cal),
04527         sizeof(VL53LX_dmax_calibration_data_t));
04528       break;
04529 
04530     default:
04531       status = VL53LX_ERROR_INVALID_PARAMS;
04532       break;
04533 
04534   }
04535 
04536   return status;
04537 }
04538 
04539 VL53LX_Error VL53LX::VL53LX_set_hist_dmax_config(
04540   VL53LX_hist_gen3_dmax_config_t *pdmax_cfg)
04541 {
04542 
04543   VL53LX_Error  status = VL53LX_ERROR_NONE;
04544 
04545   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04546 
04547   memcpy(
04548     &(pdev->dmax_cfg),
04549     pdmax_cfg,
04550     sizeof(VL53LX_hist_gen3_dmax_config_t));
04551 
04552 
04553   return status;
04554 }
04555 
04556 
04557 VL53LX_Error VL53LX::VL53LX_get_hist_dmax_config(
04558   VL53LX_hist_gen3_dmax_config_t *pdmax_cfg)
04559 {
04560 
04561   VL53LX_Error  status = VL53LX_ERROR_NONE;
04562 
04563   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04564 
04565 
04566   memcpy(
04567     pdmax_cfg,
04568     &(pdev->dmax_cfg),
04569     sizeof(VL53LX_hist_gen3_dmax_config_t));
04570 
04571 
04572   return status;
04573 }
04574 
04575 
04576 VL53LX_Error VL53LX::VL53LX_set_offset_calibration_mode(
04577   VL53LX_OffsetCalibrationMode   offset_cal_mode)
04578 {
04579 
04580   VL53LX_Error  status = VL53LX_ERROR_NONE;
04581 
04582   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04583 
04584   pdev->offset_calibration_mode = offset_cal_mode;
04585 
04586   return status;
04587 }
04588 
04589 VL53LX_Error VL53LX::VL53LX_get_offset_calibration_mode(
04590   VL53LX_OffsetCalibrationMode  *poffset_cal_mode)
04591 {
04592   VL53LX_Error  status = VL53LX_ERROR_NONE;
04593 
04594   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04595 
04596   *poffset_cal_mode = pdev->offset_calibration_mode;
04597 
04598   return status;
04599 }
04600 
04601 
04602 VL53LX_Error VL53LX::VL53LX_set_offset_correction_mode(
04603   VL53LX_OffsetCorrectionMode    offset_cor_mode)
04604 {
04605   VL53LX_Error  status = VL53LX_ERROR_NONE;
04606 
04607   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04608 
04609   pdev->offset_correction_mode = offset_cor_mode;
04610 
04611 
04612   return status;
04613 }
04614 
04615 
04616 VL53LX_Error VL53LX::VL53LX_get_offset_correction_mode(
04617   VL53LX_OffsetCorrectionMode   *poffset_cor_mode)
04618 {
04619   VL53LX_Error  status = VL53LX_ERROR_NONE;
04620 
04621   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04622 
04623 
04624   *poffset_cor_mode = pdev->offset_correction_mode;
04625 
04626 
04627   return status;
04628 }
04629 
04630 
04631 VL53LX_Error VL53LX::VL53LX_set_zone_calibration_data(
04632   VL53LX_zone_calibration_results_t  *pzone_cal)
04633 {
04634   VL53LX_Error  status = VL53LX_ERROR_NONE;
04635 
04636   VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
04637 
04638 
04639   if (pzone_cal->struct_version !=
04640       VL53LX_LL_ZONE_CALIBRATION_DATA_STRUCT_VERSION) {
04641     status = VL53LX_ERROR_INVALID_PARAMS;
04642   }
04643 
04644 
04645   if (status == VL53LX_ERROR_NONE)
04646 
04647     memcpy(
04648       &(pres->zone_cal),
04649       pzone_cal,
04650       sizeof(VL53LX_zone_calibration_results_t));
04651 
04652 
04653   return status;
04654 }
04655 
04656 VL53LX_Error VL53LX::VL53LX_get_zone_calibration_data(
04657   VL53LX_zone_calibration_results_t  *pzone_cal)
04658 {
04659 
04660   VL53LX_Error  status = VL53LX_ERROR_NONE;
04661 
04662   VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
04663 
04664   memcpy(
04665     pzone_cal,
04666     &(pres->zone_cal),
04667     sizeof(VL53LX_zone_calibration_results_t));
04668 
04669   pzone_cal->struct_version =
04670     VL53LX_LL_ZONE_CALIBRATION_DATA_STRUCT_VERSION;
04671 
04672 
04673   return status;
04674 }
04675 
04676 
04677 VL53LX_Error VL53LX::VL53LX_get_tuning_debug_data(
04678   VL53LX_tuning_parameters_t           *ptun_data)
04679 {
04680 
04681 
04682   VL53LX_Error  status = VL53LX_ERROR_NONE;
04683 
04684   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
04685   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
04686   VL53LX_xtalkextract_config_t *pXC = &(pdev->xtalk_extract_cfg);
04687 
04688 
04689   ptun_data->vl53lx_tuningparm_version =
04690     pdev->tuning_parms.tp_tuning_parm_version;
04691 
04692   ptun_data->vl53lx_tuningparm_key_table_version =
04693     pdev->tuning_parms.tp_tuning_parm_key_table_version;
04694 
04695 
04696   ptun_data->vl53lx_tuningparm_lld_version =
04697     pdev->tuning_parms.tp_tuning_parm_lld_version;
04698 
04699   ptun_data->vl53lx_tuningparm_hist_algo_select =
04700     pHP->hist_algo_select;
04701 
04702   ptun_data->vl53lx_tuningparm_hist_target_order =
04703     pHP->hist_target_order;
04704 
04705   ptun_data->vl53lx_tuningparm_hist_filter_woi_0 =
04706     pHP->filter_woi0;
04707 
04708   ptun_data->vl53lx_tuningparm_hist_filter_woi_1 =
04709     pHP->filter_woi1;
04710 
04711   ptun_data->vl53lx_tuningparm_hist_amb_est_method =
04712     pHP->hist_amb_est_method;
04713 
04714   ptun_data->vl53lx_tuningparm_hist_amb_thresh_sigma_0 =
04715     pHP->ambient_thresh_sigma0;
04716 
04717   ptun_data->vl53lx_tuningparm_hist_amb_thresh_sigma_1 =
04718     pHP->ambient_thresh_sigma1;
04719 
04720   ptun_data->vl53lx_tuningparm_hist_min_amb_thresh_events =
04721     pHP->min_ambient_thresh_events;
04722 
04723   ptun_data->vl53lx_tuningparm_hist_amb_events_scaler =
04724     pHP->ambient_thresh_events_scaler;
04725 
04726   ptun_data->vl53lx_tuningparm_hist_noise_threshold =
04727     pHP->noise_threshold;
04728 
04729   ptun_data->vl53lx_tuningparm_hist_signal_total_events_limit =
04730     pHP->signal_total_events_limit;
04731 
04732   ptun_data->vl53lx_tuningparm_hist_sigma_est_ref_mm =
04733     pHP->sigma_estimator__sigma_ref_mm;
04734 
04735   ptun_data->vl53lx_tuningparm_hist_sigma_thresh_mm =
04736     pHP->sigma_thresh;
04737 
04738   ptun_data->vl53lx_tuningparm_hist_gain_factor =
04739     pdev->gain_cal.histogram_ranging_gain_factor;
04740 
04741   ptun_data->vl53lx_tuningparm_consistency_hist_phase_tolerance =
04742     pHP->algo__consistency_check__phase_tolerance;
04743 
04744   ptun_data->vl53lx_tuningparm_consistency_hist_min_max_tolerance_mm =
04745     pHP->algo__consistency_check__min_max_tolerance;
04746 
04747   ptun_data->vl53lx_tuningparm_consistency_hist_event_sigma =
04748     pHP->algo__consistency_check__event_sigma;
04749 
04750   ptun_data->vl53lx_tuningparm_consistency_hist_event_sigma_min_spad_limit
04751     = pHP->algo__consistency_check__event_min_spad_count;
04752 
04753   ptun_data->vl53lx_tuningparm_initial_phase_rtn_histo_long_range =
04754     pdev->tuning_parms.tp_init_phase_rtn_hist_long;
04755 
04756   ptun_data->vl53lx_tuningparm_initial_phase_rtn_histo_med_range =
04757     pdev->tuning_parms.tp_init_phase_rtn_hist_med;
04758 
04759   ptun_data->vl53lx_tuningparm_initial_phase_rtn_histo_short_range =
04760     pdev->tuning_parms.tp_init_phase_rtn_hist_short;
04761 
04762   ptun_data->vl53lx_tuningparm_initial_phase_ref_histo_long_range =
04763     pdev->tuning_parms.tp_init_phase_ref_hist_long;
04764 
04765   ptun_data->vl53lx_tuningparm_initial_phase_ref_histo_med_range =
04766     pdev->tuning_parms.tp_init_phase_ref_hist_med;
04767 
04768   ptun_data->vl53lx_tuningparm_initial_phase_ref_histo_short_range =
04769     pdev->tuning_parms.tp_init_phase_ref_hist_short;
04770 
04771   ptun_data->vl53lx_tuningparm_xtalk_detect_min_valid_range_mm =
04772     pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm;
04773 
04774   ptun_data->vl53lx_tuningparm_xtalk_detect_max_valid_range_mm =
04775     pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm;
04776 
04777   ptun_data->vl53lx_tuningparm_xtalk_detect_max_sigma_mm =
04778     pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm;
04779 
04780   ptun_data->vl53lx_tuningparm_xtalk_detect_min_max_tolerance =
04781     pHP->algo__crosstalk_detect_min_max_tolerance;
04782 
04783   ptun_data->vl53lx_tuningparm_xtalk_detect_max_valid_rate_kcps =
04784     pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps;
04785 
04786   ptun_data->vl53lx_tuningparm_xtalk_detect_event_sigma =
04787     pHP->algo__crosstalk_detect_event_sigma;
04788 
04789   ptun_data->vl53lx_tuningparm_hist_xtalk_margin_kcps =
04790     pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps;
04791 
04792   ptun_data->vl53lx_tuningparm_consistency_lite_phase_tolerance =
04793     pdev->tuning_parms.tp_consistency_lite_phase_tolerance;
04794 
04795   ptun_data->vl53lx_tuningparm_phasecal_target =
04796     pdev->tuning_parms.tp_phasecal_target;
04797 
04798   ptun_data->vl53lx_tuningparm_lite_cal_repeat_rate =
04799     pdev->tuning_parms.tp_cal_repeat_rate;
04800 
04801   ptun_data->vl53lx_tuningparm_lite_ranging_gain_factor =
04802     pdev->gain_cal.standard_ranging_gain_factor;
04803 
04804   ptun_data->vl53lx_tuningparm_lite_min_clip_mm =
04805     pdev->tuning_parms.tp_lite_min_clip;
04806 
04807   ptun_data->vl53lx_tuningparm_lite_long_sigma_thresh_mm =
04808     pdev->tuning_parms.tp_lite_long_sigma_thresh_mm;
04809 
04810   ptun_data->vl53lx_tuningparm_lite_med_sigma_thresh_mm =
04811     pdev->tuning_parms.tp_lite_med_sigma_thresh_mm;
04812 
04813   ptun_data->vl53lx_tuningparm_lite_short_sigma_thresh_mm =
04814     pdev->tuning_parms.tp_lite_short_sigma_thresh_mm;
04815 
04816   ptun_data->vl53lx_tuningparm_lite_long_min_count_rate_rtn_mcps =
04817     pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps;
04818 
04819   ptun_data->vl53lx_tuningparm_lite_med_min_count_rate_rtn_mcps =
04820     pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps;
04821 
04822   ptun_data->vl53lx_tuningparm_lite_short_min_count_rate_rtn_mcps =
04823     pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps;
04824 
04825   ptun_data->vl53lx_tuningparm_lite_sigma_est_pulse_width =
04826     pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns;
04827 
04828   ptun_data->vl53lx_tuningparm_lite_sigma_est_amb_width_ns =
04829     pdev->tuning_parms.tp_lite_sigma_est_amb_width_ns;
04830 
04831   ptun_data->vl53lx_tuningparm_lite_sigma_ref_mm =
04832     pdev->tuning_parms.tp_lite_sigma_ref_mm;
04833 
04834   ptun_data->vl53lx_tuningparm_lite_rit_mult =
04835     pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult;
04836 
04837   ptun_data->vl53lx_tuningparm_lite_seed_config =
04838     pdev->tuning_parms.tp_lite_seed_cfg;
04839 
04840   ptun_data->vl53lx_tuningparm_lite_quantifier =
04841     pdev->tuning_parms.tp_lite_quantifier;
04842 
04843   ptun_data->vl53lx_tuningparm_lite_first_order_select =
04844     pdev->tuning_parms.tp_lite_first_order_select;
04845 
04846   ptun_data->vl53lx_tuningparm_lite_xtalk_margin_kcps =
04847     pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps;
04848 
04849   ptun_data->vl53lx_tuningparm_initial_phase_rtn_lite_long_range =
04850     pdev->tuning_parms.tp_init_phase_rtn_lite_long;
04851 
04852   ptun_data->vl53lx_tuningparm_initial_phase_rtn_lite_med_range =
04853     pdev->tuning_parms.tp_init_phase_rtn_lite_med;
04854 
04855   ptun_data->vl53lx_tuningparm_initial_phase_rtn_lite_short_range =
04856     pdev->tuning_parms.tp_init_phase_rtn_lite_short;
04857 
04858   ptun_data->vl53lx_tuningparm_initial_phase_ref_lite_long_range =
04859     pdev->tuning_parms.tp_init_phase_ref_lite_long;
04860 
04861   ptun_data->vl53lx_tuningparm_initial_phase_ref_lite_med_range =
04862     pdev->tuning_parms.tp_init_phase_ref_lite_med;
04863 
04864   ptun_data->vl53lx_tuningparm_initial_phase_ref_lite_short_range =
04865     pdev->tuning_parms.tp_init_phase_ref_lite_short;
04866 
04867   ptun_data->vl53lx_tuningparm_timed_seed_config =
04868     pdev->tuning_parms.tp_timed_seed_cfg;
04869 
04870   ptun_data->vl53lx_tuningparm_dmax_cfg_signal_thresh_sigma =
04871     pdev->dmax_cfg.signal_thresh_sigma;
04872 
04873   ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_0 =
04874     pdev->dmax_cfg.target_reflectance_for_dmax_calc[0];
04875 
04876   ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_1 =
04877     pdev->dmax_cfg.target_reflectance_for_dmax_calc[1];
04878 
04879   ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_2 =
04880     pdev->dmax_cfg.target_reflectance_for_dmax_calc[2];
04881 
04882   ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_3 =
04883     pdev->dmax_cfg.target_reflectance_for_dmax_calc[3];
04884 
04885   ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_4 =
04886     pdev->dmax_cfg.target_reflectance_for_dmax_calc[4];
04887 
04888   ptun_data->vl53lx_tuningparm_vhv_loopbound =
04889     pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound;
04890 
04891   ptun_data->vl53lx_tuningparm_refspadchar_device_test_mode =
04892     pdev->refspadchar.device_test_mode;
04893 
04894   ptun_data->vl53lx_tuningparm_refspadchar_vcsel_period =
04895     pdev->refspadchar.VL53LX_p_005;
04896 
04897   ptun_data->vl53lx_tuningparm_refspadchar_phasecal_timeout_us =
04898     pdev->refspadchar.timeout_us;
04899 
04900   ptun_data->vl53lx_tuningparm_refspadchar_target_count_rate_mcps =
04901     pdev->refspadchar.target_count_rate_mcps;
04902 
04903   ptun_data->vl53lx_tuningparm_refspadchar_min_countrate_limit_mcps =
04904     pdev->refspadchar.min_count_rate_limit_mcps;
04905 
04906   ptun_data->vl53lx_tuningparm_refspadchar_max_countrate_limit_mcps =
04907     pdev->refspadchar.max_count_rate_limit_mcps;
04908 
04909   ptun_data->vl53lx_tuningparm_xtalk_extract_num_of_samples =
04910     pXC->num_of_samples;
04911 
04912   ptun_data->vl53lx_tuningparm_xtalk_extract_min_filter_thresh_mm =
04913     pXC->algo__crosstalk_extract_min_valid_range_mm;
04914 
04915   ptun_data->vl53lx_tuningparm_xtalk_extract_max_filter_thresh_mm =
04916     pXC->algo__crosstalk_extract_max_valid_range_mm;
04917 
04918   ptun_data->vl53lx_tuningparm_xtalk_extract_dss_rate_mcps =
04919     pXC->dss_config__target_total_rate_mcps;
04920 
04921   ptun_data->vl53lx_tuningparm_xtalk_extract_phasecal_timeout_us =
04922     pXC->phasecal_config_timeout_us;
04923 
04924   ptun_data->vl53lx_tuningparm_xtalk_extract_max_valid_rate_kcps =
04925     pXC->algo__crosstalk_extract_max_valid_rate_kcps;
04926 
04927   ptun_data->vl53lx_tuningparm_xtalk_extract_sigma_threshold_mm =
04928     pXC->algo__crosstalk_extract_max_sigma_mm;
04929 
04930   ptun_data->vl53lx_tuningparm_xtalk_extract_dss_timeout_us =
04931     pXC->mm_config_timeout_us;
04932 
04933   ptun_data->vl53lx_tuningparm_xtalk_extract_bin_timeout_us =
04934     pXC->range_config_timeout_us;
04935 
04936   ptun_data->vl53lx_tuningparm_offset_cal_dss_rate_mcps =
04937     pdev->offsetcal_cfg.dss_config__target_total_rate_mcps;
04938 
04939   ptun_data->vl53lx_tuningparm_offset_cal_phasecal_timeout_us =
04940     pdev->offsetcal_cfg.phasecal_config_timeout_us;
04941 
04942   ptun_data->vl53lx_tuningparm_offset_cal_mm_timeout_us =
04943     pdev->offsetcal_cfg.mm_config_timeout_us;
04944 
04945   ptun_data->vl53lx_tuningparm_offset_cal_range_timeout_us =
04946     pdev->offsetcal_cfg.range_config_timeout_us;
04947 
04948   ptun_data->vl53lx_tuningparm_offset_cal_pre_samples =
04949     pdev->offsetcal_cfg.pre_num_of_samples;
04950 
04951   ptun_data->vl53lx_tuningparm_offset_cal_mm1_samples =
04952     pdev->offsetcal_cfg.mm1_num_of_samples;
04953 
04954   ptun_data->vl53lx_tuningparm_offset_cal_mm2_samples =
04955     pdev->offsetcal_cfg.mm2_num_of_samples;
04956 
04957   ptun_data->vl53lx_tuningparm_zone_cal_dss_rate_mcps =
04958     pdev->zonecal_cfg.dss_config__target_total_rate_mcps;
04959 
04960   ptun_data->vl53lx_tuningparm_zone_cal_phasecal_timeout_us =
04961     pdev->zonecal_cfg.phasecal_config_timeout_us;
04962 
04963   ptun_data->vl53lx_tuningparm_zone_cal_dss_timeout_us =
04964     pdev->zonecal_cfg.mm_config_timeout_us;
04965 
04966   ptun_data->vl53lx_tuningparm_zone_cal_phasecal_num_samples =
04967     pdev->zonecal_cfg.phasecal_num_of_samples;
04968 
04969   ptun_data->vl53lx_tuningparm_zone_cal_range_timeout_us =
04970     pdev->zonecal_cfg.range_config_timeout_us;
04971 
04972   ptun_data->vl53lx_tuningparm_zone_cal_zone_num_samples =
04973     pdev->zonecal_cfg.zone_num_of_samples;
04974 
04975   ptun_data->vl53lx_tuningparm_spadmap_vcsel_period =
04976     pdev->ssc_cfg.VL53LX_p_005;
04977 
04978   ptun_data->vl53lx_tuningparm_spadmap_vcsel_start =
04979     pdev->ssc_cfg.vcsel_start;
04980 
04981   ptun_data->vl53lx_tuningparm_spadmap_rate_limit_mcps =
04982     pdev->ssc_cfg.rate_limit_mcps;
04983 
04984   ptun_data->vl53lx_tuningparm_lite_dss_config_target_total_rate_mcps =
04985     pdev->tuning_parms.tp_dss_target_lite_mcps;
04986 
04987   ptun_data->vl53lx_tuningparm_ranging_dss_config_target_total_rate_mcps =
04988     pdev->tuning_parms.tp_dss_target_histo_mcps;
04989 
04990   ptun_data->vl53lx_tuningparm_mz_dss_config_target_total_rate_mcps =
04991     pdev->tuning_parms.tp_dss_target_histo_mz_mcps;
04992 
04993   ptun_data->vl53lx_tuningparm_timed_dss_config_target_total_rate_mcps =
04994     pdev->tuning_parms.tp_dss_target_timed_mcps;
04995 
04996   ptun_data->vl53lx_tuningparm_lite_phasecal_config_timeout_us =
04997     pdev->tuning_parms.tp_phasecal_timeout_lite_us;
04998 
04999   ptun_data->vl53lx_tuningparm_ranging_long_phasecal_config_timeout_us =
05000     pdev->tuning_parms.tp_phasecal_timeout_hist_long_us;
05001 
05002   ptun_data->vl53lx_tuningparm_ranging_med_phasecal_config_timeout_us =
05003     pdev->tuning_parms.tp_phasecal_timeout_hist_med_us;
05004 
05005   ptun_data->vl53lx_tuningparm_ranging_short_phasecal_config_timeout_us =
05006     pdev->tuning_parms.tp_phasecal_timeout_hist_short_us;
05007 
05008   ptun_data->vl53lx_tuningparm_mz_long_phasecal_config_timeout_us =
05009     pdev->tuning_parms.tp_phasecal_timeout_mz_long_us;
05010 
05011   ptun_data->vl53lx_tuningparm_mz_med_phasecal_config_timeout_us =
05012     pdev->tuning_parms.tp_phasecal_timeout_mz_med_us;
05013 
05014   ptun_data->vl53lx_tuningparm_mz_short_phasecal_config_timeout_us =
05015     pdev->tuning_parms.tp_phasecal_timeout_mz_short_us;
05016 
05017   ptun_data->vl53lx_tuningparm_timed_phasecal_config_timeout_us =
05018     pdev->tuning_parms.tp_phasecal_timeout_timed_us;
05019 
05020   ptun_data->vl53lx_tuningparm_lite_mm_config_timeout_us =
05021     pdev->tuning_parms.tp_mm_timeout_lite_us;
05022 
05023   ptun_data->vl53lx_tuningparm_ranging_mm_config_timeout_us =
05024     pdev->tuning_parms.tp_mm_timeout_histo_us;
05025 
05026   ptun_data->vl53lx_tuningparm_mz_mm_config_timeout_us =
05027     pdev->tuning_parms.tp_mm_timeout_mz_us;
05028 
05029   ptun_data->vl53lx_tuningparm_timed_mm_config_timeout_us =
05030     pdev->tuning_parms.tp_mm_timeout_timed_us;
05031 
05032   ptun_data->vl53lx_tuningparm_lite_range_config_timeout_us =
05033     pdev->tuning_parms.tp_range_timeout_lite_us;
05034 
05035   ptun_data->vl53lx_tuningparm_ranging_range_config_timeout_us =
05036     pdev->tuning_parms.tp_range_timeout_histo_us;
05037 
05038   ptun_data->vl53lx_tuningparm_mz_range_config_timeout_us =
05039     pdev->tuning_parms.tp_range_timeout_mz_us;
05040 
05041   ptun_data->vl53lx_tuningparm_timed_range_config_timeout_us =
05042     pdev->tuning_parms.tp_range_timeout_timed_us;
05043 
05044   ptun_data->vl53lx_tuningparm_dynxtalk_smudge_margin =
05045     pdev->smudge_correct_config.smudge_margin;
05046 
05047   ptun_data->vl53lx_tuningparm_dynxtalk_noise_margin =
05048     pdev->smudge_correct_config.noise_margin;
05049 
05050   ptun_data->vl53lx_tuningparm_dynxtalk_xtalk_offset_limit =
05051     pdev->smudge_correct_config.user_xtalk_offset_limit;
05052 
05053   ptun_data->vl53lx_tuningparm_dynxtalk_xtalk_offset_limit_hi =
05054     pdev->smudge_correct_config.user_xtalk_offset_limit_hi;
05055 
05056   ptun_data->vl53lx_tuningparm_dynxtalk_sample_limit =
05057     pdev->smudge_correct_config.sample_limit;
05058 
05059   ptun_data->vl53lx_tuningparm_dynxtalk_single_xtalk_delta =
05060     pdev->smudge_correct_config.single_xtalk_delta;
05061 
05062   ptun_data->vl53lx_tuningparm_dynxtalk_averaged_xtalk_delta =
05063     pdev->smudge_correct_config.averaged_xtalk_delta;
05064 
05065   ptun_data->vl53lx_tuningparm_dynxtalk_clip_limit =
05066     pdev->smudge_correct_config.smudge_corr_clip_limit;
05067 
05068   ptun_data->vl53lx_tuningparm_dynxtalk_scaler_calc_method =
05069     pdev->smudge_correct_config.scaler_calc_method;
05070 
05071   ptun_data->vl53lx_tuningparm_dynxtalk_xgradient_scaler =
05072     pdev->smudge_correct_config.x_gradient_scaler;
05073 
05074   ptun_data->vl53lx_tuningparm_dynxtalk_ygradient_scaler =
05075     pdev->smudge_correct_config.y_gradient_scaler;
05076 
05077   ptun_data->vl53lx_tuningparm_dynxtalk_user_scaler_set =
05078     pdev->smudge_correct_config.user_scaler_set;
05079 
05080   ptun_data->vl53lx_tuningparm_dynxtalk_smudge_cor_single_apply =
05081     pdev->smudge_correct_config.smudge_corr_single_apply;
05082 
05083   ptun_data->vl53lx_tuningparm_dynxtalk_xtalk_amb_threshold =
05084     pdev->smudge_correct_config.smudge_corr_ambient_threshold;
05085 
05086   ptun_data->vl53lx_tuningparm_dynxtalk_nodetect_amb_threshold_kcps =
05087     pdev->smudge_correct_config.nodetect_ambient_threshold;
05088 
05089   ptun_data->vl53lx_tuningparm_dynxtalk_nodetect_sample_limit =
05090     pdev->smudge_correct_config.nodetect_sample_limit;
05091 
05092   ptun_data->vl53lx_tuningparm_dynxtalk_nodetect_xtalk_offset_kcps =
05093     pdev->smudge_correct_config.nodetect_xtalk_offset;
05094 
05095   ptun_data->vl53lx_tuningparm_dynxtalk_nodetect_min_range_mm =
05096     pdev->smudge_correct_config.nodetect_min_range_mm;
05097 
05098   ptun_data->vl53lx_tuningparm_lowpowerauto_vhv_loop_bound =
05099     pdev->low_power_auto_data.vhv_loop_bound;
05100 
05101   ptun_data->vl53lx_tuningparm_lowpowerauto_mm_config_timeout_us =
05102     pdev->tuning_parms.tp_mm_timeout_lpa_us;
05103 
05104   ptun_data->vl53lx_tuningparm_lowpowerauto_range_config_timeout_us =
05105     pdev->tuning_parms.tp_range_timeout_lpa_us;
05106 
05107   ptun_data->vl53lx_tuningparm_very_short_dss_rate_mcps =
05108     pdev->tuning_parms.tp_dss_target_very_short_mcps;
05109 
05110   ptun_data->vl53lx_tuningparm_phasecal_patch_power =
05111     pdev->tuning_parms.tp_phasecal_patch_power;
05112 
05113 
05114   return status;
05115 }
05116 
05117 VL53LX_Error VL53LX::VL53LX_get_tuning_parm(
05118   VL53LX_TuningParms             tuning_parm_key,
05119   int32_t                       *ptuning_parm_value)
05120 {
05121 
05122 
05123 
05124   VL53LX_Error  status = VL53LX_ERROR_NONE;
05125 
05126   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
05127   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
05128   VL53LX_xtalkextract_config_t *pXC = &(pdev->xtalk_extract_cfg);
05129 
05130   switch (tuning_parm_key) {
05131 
05132     case VL53LX_TUNINGPARM_VERSION:
05133       *ptuning_parm_value =
05134         (int32_t)pdev->tuning_parms.tp_tuning_parm_version;
05135       break;
05136     case VL53LX_TUNINGPARM_KEY_TABLE_VERSION:
05137       *ptuning_parm_value =
05138         (int32_t)pdev->tuning_parms.tp_tuning_parm_key_table_version;
05139       break;
05140     case VL53LX_TUNINGPARM_LLD_VERSION:
05141       *ptuning_parm_value =
05142         (int32_t)pdev->tuning_parms.tp_tuning_parm_lld_version;
05143       break;
05144     case VL53LX_TUNINGPARM_HIST_ALGO_SELECT:
05145       *ptuning_parm_value =
05146         (int32_t)pHP->hist_algo_select;
05147       break;
05148     case VL53LX_TUNINGPARM_HIST_TARGET_ORDER:
05149       *ptuning_parm_value =
05150         (int32_t)pHP->hist_target_order;
05151       break;
05152     case VL53LX_TUNINGPARM_HIST_FILTER_WOI_0:
05153       *ptuning_parm_value =
05154         (int32_t)pHP->filter_woi0;
05155       break;
05156     case VL53LX_TUNINGPARM_HIST_FILTER_WOI_1:
05157       *ptuning_parm_value =
05158         (int32_t)pHP->filter_woi1;
05159       break;
05160     case VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD:
05161       *ptuning_parm_value =
05162         (int32_t)pHP->hist_amb_est_method;
05163       break;
05164     case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0:
05165       *ptuning_parm_value =
05166         (int32_t)pHP->ambient_thresh_sigma0;
05167       break;
05168     case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1:
05169       *ptuning_parm_value =
05170         (int32_t)pHP->ambient_thresh_sigma1;
05171       break;
05172     case VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS:
05173       *ptuning_parm_value =
05174         (int32_t)pHP->min_ambient_thresh_events;
05175       break;
05176     case VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER:
05177       *ptuning_parm_value =
05178         (int32_t)pHP->ambient_thresh_events_scaler;
05179       break;
05180     case VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD:
05181       *ptuning_parm_value =
05182         (int32_t)pHP->noise_threshold;
05183       break;
05184     case VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT:
05185       *ptuning_parm_value =
05186         (int32_t)pHP->signal_total_events_limit;
05187       break;
05188     case VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM:
05189       *ptuning_parm_value =
05190         (int32_t)pHP->sigma_estimator__sigma_ref_mm;
05191       break;
05192     case VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM:
05193       *ptuning_parm_value =
05194         (int32_t)pHP->sigma_thresh;
05195       break;
05196     case VL53LX_TUNINGPARM_HIST_GAIN_FACTOR:
05197       *ptuning_parm_value =
05198         (int32_t)pdev->gain_cal.histogram_ranging_gain_factor;
05199       break;
05200     case VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE:
05201       *ptuning_parm_value =
05202         (int32_t)pHP->algo__consistency_check__phase_tolerance;
05203       break;
05204     case VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM:
05205       *ptuning_parm_value =
05206         (int32_t)pHP->algo__consistency_check__min_max_tolerance;
05207       break;
05208     case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA:
05209       *ptuning_parm_value =
05210         (int32_t)pHP->algo__consistency_check__event_sigma;
05211       break;
05212     case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT:
05213       *ptuning_parm_value =
05214         (int32_t)pHP->algo__consistency_check__event_min_spad_count;
05215       break;
05216     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE:
05217       *ptuning_parm_value =
05218         (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_long;
05219       break;
05220     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE:
05221       *ptuning_parm_value =
05222         (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_med;
05223       break;
05224     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE:
05225       *ptuning_parm_value =
05226         (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_short;
05227       break;
05228     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE:
05229       *ptuning_parm_value =
05230         (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_long;
05231       break;
05232     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE:
05233       *ptuning_parm_value =
05234         (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_med;
05235       break;
05236     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE:
05237       *ptuning_parm_value =
05238         (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_short;
05239       break;
05240     case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM:
05241       *ptuning_parm_value = (int32_t)(
05242                               pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm);
05243       break;
05244     case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM:
05245       *ptuning_parm_value = (int32_t)(
05246                               pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm);
05247       break;
05248     case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM:
05249       *ptuning_parm_value =
05250         (int32_t)pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm;
05251       break;
05252     case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE:
05253       *ptuning_parm_value =
05254         (int32_t)pHP->algo__crosstalk_detect_min_max_tolerance;
05255       break;
05256     case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS:
05257       *ptuning_parm_value = (int32_t)(
05258                               pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps);
05259       break;
05260     case VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA:
05261       *ptuning_parm_value =
05262         (int32_t)pHP->algo__crosstalk_detect_event_sigma;
05263       break;
05264     case VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS:
05265       *ptuning_parm_value =
05266         (int32_t)pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps;
05267       break;
05268     case VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE:
05269       *ptuning_parm_value =
05270         (int32_t)pdev->tuning_parms.tp_consistency_lite_phase_tolerance;
05271       break;
05272     case VL53LX_TUNINGPARM_PHASECAL_TARGET:
05273       *ptuning_parm_value =
05274         (int32_t)pdev->tuning_parms.tp_phasecal_target;
05275       break;
05276     case VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE:
05277       *ptuning_parm_value =
05278         (int32_t)pdev->tuning_parms.tp_cal_repeat_rate;
05279       break;
05280     case VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR:
05281       *ptuning_parm_value =
05282         (int32_t)pdev->gain_cal.standard_ranging_gain_factor;
05283       break;
05284     case VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM:
05285       *ptuning_parm_value =
05286         (int32_t)pdev->tuning_parms.tp_lite_min_clip;
05287       break;
05288     case VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM:
05289       *ptuning_parm_value =
05290         (int32_t)pdev->tuning_parms.tp_lite_long_sigma_thresh_mm;
05291       break;
05292     case VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM:
05293       *ptuning_parm_value =
05294         (int32_t)pdev->tuning_parms.tp_lite_med_sigma_thresh_mm;
05295       break;
05296     case VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM:
05297       *ptuning_parm_value =
05298         (int32_t)pdev->tuning_parms.tp_lite_short_sigma_thresh_mm;
05299       break;
05300     case VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS:
05301       *ptuning_parm_value = (int32_t)(
05302                               pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps);
05303       break;
05304     case VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS:
05305       *ptuning_parm_value =
05306         (int32_t)pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps;
05307       break;
05308     case VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS:
05309       *ptuning_parm_value = (int32_t)(
05310                               pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps);
05311       break;
05312     case VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH:
05313       *ptuning_parm_value =
05314         (int32_t)pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns;
05315       break;
05316     case VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS:
05317       *ptuning_parm_value =
05318         (int32_t)pdev->tuning_parms.tp_lite_sigma_est_amb_width_ns;
05319       break;
05320     case VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM:
05321       *ptuning_parm_value =
05322         (int32_t)pdev->tuning_parms.tp_lite_sigma_ref_mm;
05323       break;
05324     case VL53LX_TUNINGPARM_LITE_RIT_MULT:
05325       *ptuning_parm_value =
05326         (int32_t)pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult;
05327       break;
05328     case VL53LX_TUNINGPARM_LITE_SEED_CONFIG:
05329       *ptuning_parm_value =
05330         (int32_t)pdev->tuning_parms.tp_lite_seed_cfg;
05331       break;
05332     case VL53LX_TUNINGPARM_LITE_QUANTIFIER:
05333       *ptuning_parm_value =
05334         (int32_t)pdev->tuning_parms.tp_lite_quantifier;
05335       break;
05336     case VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT:
05337       *ptuning_parm_value =
05338         (int32_t)pdev->tuning_parms.tp_lite_first_order_select;
05339       break;
05340     case VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS:
05341       *ptuning_parm_value =
05342         (int32_t)pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps;
05343       break;
05344     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE:
05345       *ptuning_parm_value =
05346         (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_long;
05347       break;
05348     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE:
05349       *ptuning_parm_value =
05350         (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_med;
05351       break;
05352     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE:
05353       *ptuning_parm_value =
05354         (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_short;
05355       break;
05356     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE:
05357       *ptuning_parm_value =
05358         (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_long;
05359       break;
05360     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE:
05361       *ptuning_parm_value =
05362         (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_med;
05363       break;
05364     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE:
05365       *ptuning_parm_value =
05366         (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_short;
05367       break;
05368     case VL53LX_TUNINGPARM_TIMED_SEED_CONFIG:
05369       *ptuning_parm_value =
05370         (int32_t)pdev->tuning_parms.tp_timed_seed_cfg;
05371       break;
05372     case VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA:
05373       *ptuning_parm_value =
05374         (int32_t)pdev->dmax_cfg.signal_thresh_sigma;
05375       break;
05376     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0:
05377       *ptuning_parm_value =
05378         (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[0];
05379       break;
05380     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1:
05381       *ptuning_parm_value =
05382         (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[1];
05383       break;
05384     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2:
05385       *ptuning_parm_value =
05386         (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[2];
05387       break;
05388     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3:
05389       *ptuning_parm_value =
05390         (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[3];
05391       break;
05392     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4:
05393       *ptuning_parm_value =
05394         (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[4];
05395       break;
05396     case VL53LX_TUNINGPARM_VHV_LOOPBOUND:
05397       *ptuning_parm_value =
05398         (int32_t)pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound;
05399       break;
05400     case VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE:
05401       *ptuning_parm_value =
05402         (int32_t)pdev->refspadchar.device_test_mode;
05403       break;
05404     case VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD:
05405       *ptuning_parm_value =
05406         (int32_t)pdev->refspadchar.VL53LX_p_005;
05407       break;
05408     case VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US:
05409       *ptuning_parm_value =
05410         (int32_t)pdev->refspadchar.timeout_us;
05411       break;
05412     case VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS:
05413       *ptuning_parm_value =
05414         (int32_t)pdev->refspadchar.target_count_rate_mcps;
05415       break;
05416     case VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS:
05417       *ptuning_parm_value =
05418         (int32_t)pdev->refspadchar.min_count_rate_limit_mcps;
05419       break;
05420     case VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS:
05421       *ptuning_parm_value =
05422         (int32_t)pdev->refspadchar.max_count_rate_limit_mcps;
05423       break;
05424     case VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES:
05425       *ptuning_parm_value =
05426         (int32_t)pXC->num_of_samples;
05427       break;
05428     case VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM:
05429       *ptuning_parm_value =
05430         (int32_t)pXC->algo__crosstalk_extract_min_valid_range_mm;
05431       break;
05432     case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM:
05433       *ptuning_parm_value =
05434         (int32_t)pXC->algo__crosstalk_extract_max_valid_range_mm;
05435       break;
05436     case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS:
05437       *ptuning_parm_value =
05438         (int32_t)pXC->dss_config__target_total_rate_mcps;
05439       break;
05440     case VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US:
05441       *ptuning_parm_value =
05442         (int32_t)pXC->phasecal_config_timeout_us;
05443       break;
05444     case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS:
05445       *ptuning_parm_value =
05446         (int32_t)pXC->algo__crosstalk_extract_max_valid_rate_kcps;
05447       break;
05448     case VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM:
05449       *ptuning_parm_value =
05450         (int32_t)pXC->algo__crosstalk_extract_max_sigma_mm;
05451       break;
05452     case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US:
05453       *ptuning_parm_value =
05454         (int32_t)pXC->mm_config_timeout_us;
05455       break;
05456     case VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US:
05457       *ptuning_parm_value =
05458         (int32_t)pXC->range_config_timeout_us;
05459       break;
05460     case VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS:
05461       *ptuning_parm_value =
05462         (int32_t)pdev->offsetcal_cfg.dss_config__target_total_rate_mcps;
05463       break;
05464     case VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US:
05465       *ptuning_parm_value =
05466         (int32_t)pdev->offsetcal_cfg.phasecal_config_timeout_us;
05467       break;
05468     case VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US:
05469       *ptuning_parm_value =
05470         (int32_t)pdev->offsetcal_cfg.mm_config_timeout_us;
05471       break;
05472     case VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US:
05473       *ptuning_parm_value =
05474         (int32_t)pdev->offsetcal_cfg.range_config_timeout_us;
05475       break;
05476     case VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES:
05477       *ptuning_parm_value =
05478         (int32_t)pdev->offsetcal_cfg.pre_num_of_samples;
05479       break;
05480     case VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES:
05481       *ptuning_parm_value =
05482         (int32_t)pdev->offsetcal_cfg.mm1_num_of_samples;
05483       break;
05484     case VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES:
05485       *ptuning_parm_value =
05486         (int32_t)pdev->offsetcal_cfg.mm2_num_of_samples;
05487       break;
05488     case VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS:
05489       *ptuning_parm_value =
05490         (int32_t)pdev->zonecal_cfg.dss_config__target_total_rate_mcps;
05491       break;
05492     case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US:
05493       *ptuning_parm_value =
05494         (int32_t)pdev->zonecal_cfg.phasecal_config_timeout_us;
05495       break;
05496     case VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US:
05497       *ptuning_parm_value =
05498         (int32_t)pdev->zonecal_cfg.mm_config_timeout_us;
05499       break;
05500     case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES:
05501       *ptuning_parm_value =
05502         (int32_t)pdev->zonecal_cfg.phasecal_num_of_samples;
05503       break;
05504     case VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US:
05505       *ptuning_parm_value =
05506         (int32_t)pdev->zonecal_cfg.range_config_timeout_us;
05507       break;
05508     case VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES:
05509       *ptuning_parm_value =
05510         (int32_t)pdev->zonecal_cfg.zone_num_of_samples;
05511       break;
05512     case VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD:
05513       *ptuning_parm_value =
05514         (int32_t)pdev->ssc_cfg.VL53LX_p_005;
05515       break;
05516     case VL53LX_TUNINGPARM_SPADMAP_VCSEL_START:
05517       *ptuning_parm_value =
05518         (int32_t)pdev->ssc_cfg.vcsel_start;
05519       break;
05520     case VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS:
05521       *ptuning_parm_value =
05522         (int32_t)pdev->ssc_cfg.rate_limit_mcps;
05523       break;
05524     case VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
05525       *ptuning_parm_value =
05526         (int32_t)pdev->tuning_parms.tp_dss_target_lite_mcps;
05527       break;
05528     case VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
05529       *ptuning_parm_value =
05530         (int32_t)pdev->tuning_parms.tp_dss_target_histo_mcps;
05531       break;
05532     case VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
05533       *ptuning_parm_value =
05534         (int32_t)pdev->tuning_parms.tp_dss_target_histo_mz_mcps;
05535       break;
05536     case VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
05537       *ptuning_parm_value =
05538         (int32_t)pdev->tuning_parms.tp_dss_target_timed_mcps;
05539       break;
05540     case VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US:
05541       *ptuning_parm_value =
05542         (int32_t)pdev->tuning_parms.tp_phasecal_timeout_lite_us;
05543       break;
05544     case VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US:
05545       *ptuning_parm_value =
05546         (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_long_us;
05547       break;
05548     case VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US:
05549       *ptuning_parm_value =
05550         (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_med_us;
05551       break;
05552     case VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US:
05553       *ptuning_parm_value =
05554         (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_short_us;
05555       break;
05556     case VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US:
05557       *ptuning_parm_value =
05558         (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_long_us;
05559       break;
05560     case VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US:
05561       *ptuning_parm_value =
05562         (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_med_us;
05563       break;
05564     case VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US:
05565       *ptuning_parm_value =
05566         (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_short_us;
05567       break;
05568     case VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US:
05569       *ptuning_parm_value =
05570         (int32_t)pdev->tuning_parms.tp_phasecal_timeout_timed_us;
05571       break;
05572     case VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US:
05573       *ptuning_parm_value =
05574         (int32_t)pdev->tuning_parms.tp_mm_timeout_lite_us;
05575       break;
05576     case VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US:
05577       *ptuning_parm_value =
05578         (int32_t)pdev->tuning_parms.tp_mm_timeout_histo_us;
05579       break;
05580     case VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US:
05581       *ptuning_parm_value =
05582         (int32_t)pdev->tuning_parms.tp_mm_timeout_mz_us;
05583       break;
05584     case VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US:
05585       *ptuning_parm_value =
05586         (int32_t)pdev->tuning_parms.tp_mm_timeout_timed_us;
05587       break;
05588     case VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US:
05589       *ptuning_parm_value =
05590         (int32_t)pdev->tuning_parms.tp_range_timeout_lite_us;
05591       break;
05592     case VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US:
05593       *ptuning_parm_value =
05594         (int32_t)pdev->tuning_parms.tp_range_timeout_histo_us;
05595       break;
05596     case VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US:
05597       *ptuning_parm_value =
05598         (int32_t)pdev->tuning_parms.tp_range_timeout_mz_us;
05599       break;
05600     case VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US:
05601       *ptuning_parm_value =
05602         (int32_t)pdev->tuning_parms.tp_range_timeout_timed_us;
05603       break;
05604     case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN:
05605       *ptuning_parm_value =
05606         (int32_t)pdev->smudge_correct_config.smudge_margin;
05607       break;
05608     case VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN:
05609       *ptuning_parm_value =
05610         (int32_t)pdev->smudge_correct_config.noise_margin;
05611       break;
05612     case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT:
05613       *ptuning_parm_value =
05614         (int32_t)pdev->smudge_correct_config.user_xtalk_offset_limit;
05615       break;
05616     case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI:
05617       *ptuning_parm_value =
05618         (int32_t)pdev->smudge_correct_config.user_xtalk_offset_limit_hi;
05619       break;
05620     case VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT:
05621       *ptuning_parm_value =
05622         (int32_t)pdev->smudge_correct_config.sample_limit;
05623       break;
05624     case VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA:
05625       *ptuning_parm_value =
05626         (int32_t)pdev->smudge_correct_config.single_xtalk_delta;
05627       break;
05628     case VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA:
05629       *ptuning_parm_value =
05630         (int32_t)pdev->smudge_correct_config.averaged_xtalk_delta;
05631       break;
05632     case VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT:
05633       *ptuning_parm_value =
05634         (int32_t)pdev->smudge_correct_config.smudge_corr_clip_limit;
05635       break;
05636     case VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD:
05637       *ptuning_parm_value =
05638         (int32_t)pdev->smudge_correct_config.scaler_calc_method;
05639       break;
05640     case VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER:
05641       *ptuning_parm_value =
05642         (int32_t)pdev->smudge_correct_config.x_gradient_scaler;
05643       break;
05644     case VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER:
05645       *ptuning_parm_value =
05646         (int32_t)pdev->smudge_correct_config.y_gradient_scaler;
05647       break;
05648     case VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET:
05649       *ptuning_parm_value =
05650         (int32_t)pdev->smudge_correct_config.user_scaler_set;
05651       break;
05652     case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY:
05653       *ptuning_parm_value =
05654         (int32_t)pdev->smudge_correct_config.smudge_corr_single_apply;
05655       break;
05656     case VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD:
05657       *ptuning_parm_value = (int32_t)(
05658                               pdev->smudge_correct_config.smudge_corr_ambient_threshold);
05659       break;
05660     case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS:
05661       *ptuning_parm_value =
05662         (int32_t)pdev->smudge_correct_config.nodetect_ambient_threshold;
05663       break;
05664     case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT:
05665       *ptuning_parm_value =
05666         (int32_t)pdev->smudge_correct_config.nodetect_sample_limit;
05667       break;
05668     case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS:
05669       *ptuning_parm_value =
05670         (int32_t)pdev->smudge_correct_config.nodetect_xtalk_offset;
05671       break;
05672     case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM:
05673       *ptuning_parm_value =
05674         (int32_t)pdev->smudge_correct_config.nodetect_min_range_mm;
05675       break;
05676     case VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND:
05677       *ptuning_parm_value =
05678         (int32_t)pdev->low_power_auto_data.vhv_loop_bound;
05679       break;
05680     case VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US:
05681       *ptuning_parm_value =
05682         (int32_t)pdev->tuning_parms.tp_mm_timeout_lpa_us;
05683       break;
05684     case VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US:
05685       *ptuning_parm_value =
05686         (int32_t)pdev->tuning_parms.tp_range_timeout_lpa_us;
05687       break;
05688     case VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS:
05689       *ptuning_parm_value =
05690         (int32_t)pdev->tuning_parms.tp_dss_target_very_short_mcps;
05691       break;
05692     case VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER:
05693       *ptuning_parm_value =
05694         (int32_t) pdev->tuning_parms.tp_phasecal_patch_power;
05695       break;
05696     case VL53LX_TUNINGPARM_HIST_MERGE:
05697       *ptuning_parm_value =
05698         (int32_t) pdev->tuning_parms.tp_hist_merge;
05699       break;
05700     case VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD:
05701       *ptuning_parm_value =
05702         (int32_t) pdev->tuning_parms.tp_reset_merge_threshold;
05703       break;
05704     case VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE:
05705       *ptuning_parm_value =
05706         (int32_t) pdev->tuning_parms.tp_hist_merge_max_size;
05707       break;
05708     case VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR:
05709       *ptuning_parm_value =
05710         pdev->smudge_correct_config.max_smudge_factor;
05711       break;
05712 
05713     default:
05714       *ptuning_parm_value = 0x7FFFFFFF;
05715       status = VL53LX_ERROR_INVALID_PARAMS;
05716       break;
05717 
05718   }
05719 
05720 
05721   return status;
05722 }
05723 
05724 
05725 VL53LX_Error VL53LX::VL53LX_set_tuning_parm(
05726   VL53LX_TuningParms    tuning_parm_key,
05727   int32_t               tuning_parm_value)
05728 {
05729 
05730 
05731 
05732   VL53LX_Error  status = VL53LX_ERROR_NONE;
05733 
05734   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
05735   VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
05736   VL53LX_xtalkextract_config_t *pXC = &(pdev->xtalk_extract_cfg);
05737 
05738   switch (tuning_parm_key) {
05739 
05740     case VL53LX_TUNINGPARM_VERSION:
05741       pdev->tuning_parms.tp_tuning_parm_version =
05742         (uint16_t)tuning_parm_value;
05743       break;
05744     case VL53LX_TUNINGPARM_KEY_TABLE_VERSION:
05745       pdev->tuning_parms.tp_tuning_parm_key_table_version =
05746         (uint16_t)tuning_parm_value;
05747 
05748 
05749 
05750       if ((uint16_t)tuning_parm_value
05751           != VL53LX_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT) {
05752         status = VL53LX_ERROR_TUNING_PARM_KEY_MISMATCH;
05753       }
05754 
05755       break;
05756     case VL53LX_TUNINGPARM_LLD_VERSION:
05757       pdev->tuning_parms.tp_tuning_parm_lld_version =
05758         (uint16_t)tuning_parm_value;
05759       break;
05760     case VL53LX_TUNINGPARM_HIST_ALGO_SELECT:
05761       pHP->hist_algo_select =
05762         (VL53LX_HistAlgoSelect)tuning_parm_value;
05763       break;
05764     case VL53LX_TUNINGPARM_HIST_TARGET_ORDER:
05765       pHP->hist_target_order =
05766         (VL53LX_HistTargetOrder)tuning_parm_value;
05767       break;
05768     case VL53LX_TUNINGPARM_HIST_FILTER_WOI_0:
05769       pHP->filter_woi0 =
05770         (uint8_t)tuning_parm_value;
05771       break;
05772     case VL53LX_TUNINGPARM_HIST_FILTER_WOI_1:
05773       pHP->filter_woi1 =
05774         (uint8_t)tuning_parm_value;
05775       break;
05776     case VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD:
05777       pHP->hist_amb_est_method =
05778         (VL53LX_HistAmbEstMethod)tuning_parm_value;
05779       break;
05780     case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0:
05781       pHP->ambient_thresh_sigma0 =
05782         (uint8_t)tuning_parm_value;
05783       break;
05784     case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1:
05785       pHP->ambient_thresh_sigma1 =
05786         (uint8_t)tuning_parm_value;
05787       break;
05788     case VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS:
05789       pHP->min_ambient_thresh_events =
05790         (int32_t)tuning_parm_value;
05791       break;
05792     case VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER:
05793       pHP->ambient_thresh_events_scaler =
05794         (uint16_t)tuning_parm_value;
05795       break;
05796     case VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD:
05797       pHP->noise_threshold =
05798         (uint16_t)tuning_parm_value;
05799       break;
05800     case VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT:
05801       pHP->signal_total_events_limit =
05802         (int32_t)tuning_parm_value;
05803       break;
05804     case VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM:
05805       pHP->sigma_estimator__sigma_ref_mm =
05806         (uint8_t)tuning_parm_value;
05807       break;
05808     case VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM:
05809       pHP->sigma_thresh =
05810         (uint16_t)tuning_parm_value;
05811       break;
05812     case VL53LX_TUNINGPARM_HIST_GAIN_FACTOR:
05813       pdev->gain_cal.histogram_ranging_gain_factor =
05814         (uint16_t)tuning_parm_value;
05815       break;
05816     case VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE:
05817       pHP->algo__consistency_check__phase_tolerance =
05818         (uint8_t)tuning_parm_value;
05819       break;
05820     case VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM:
05821       pHP->algo__consistency_check__min_max_tolerance =
05822         (uint16_t)tuning_parm_value;
05823       break;
05824     case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA:
05825       pHP->algo__consistency_check__event_sigma =
05826         (uint8_t)tuning_parm_value;
05827       break;
05828     case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT:
05829       pHP->algo__consistency_check__event_min_spad_count =
05830         (uint16_t)tuning_parm_value;
05831       break;
05832     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE:
05833       pdev->tuning_parms.tp_init_phase_rtn_hist_long =
05834         (uint8_t)tuning_parm_value;
05835       break;
05836     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE:
05837       pdev->tuning_parms.tp_init_phase_rtn_hist_med =
05838         (uint8_t)tuning_parm_value;
05839       break;
05840     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE:
05841       pdev->tuning_parms.tp_init_phase_rtn_hist_short =
05842         (uint8_t)tuning_parm_value;
05843       break;
05844     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE:
05845       pdev->tuning_parms.tp_init_phase_ref_hist_long =
05846         (uint8_t)tuning_parm_value;
05847       break;
05848     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE:
05849       pdev->tuning_parms.tp_init_phase_ref_hist_med =
05850         (uint8_t)tuning_parm_value;
05851       break;
05852     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE:
05853       pdev->tuning_parms.tp_init_phase_ref_hist_short =
05854         (uint8_t)tuning_parm_value;
05855       break;
05856     case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM:
05857       pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm =
05858         (int16_t)tuning_parm_value;
05859       break;
05860     case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM:
05861       pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm =
05862         (int16_t)tuning_parm_value;
05863       break;
05864     case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM:
05865       pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm =
05866         (uint16_t)tuning_parm_value;
05867       break;
05868     case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE:
05869       pHP->algo__crosstalk_detect_min_max_tolerance =
05870         (uint16_t)tuning_parm_value;
05871       break;
05872     case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS:
05873       pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps =
05874         (uint16_t)tuning_parm_value;
05875       break;
05876     case VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA:
05877       pHP->algo__crosstalk_detect_event_sigma =
05878         (uint8_t)tuning_parm_value;
05879       break;
05880     case VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS:
05881       pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps =
05882         (int16_t)tuning_parm_value;
05883       break;
05884     case VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE:
05885       pdev->tuning_parms.tp_consistency_lite_phase_tolerance =
05886         (uint8_t)tuning_parm_value;
05887       break;
05888     case VL53LX_TUNINGPARM_PHASECAL_TARGET:
05889       pdev->tuning_parms.tp_phasecal_target =
05890         (uint8_t)tuning_parm_value;
05891       break;
05892     case VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE:
05893       pdev->tuning_parms.tp_cal_repeat_rate =
05894         (uint16_t)tuning_parm_value;
05895       break;
05896     case VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR:
05897       pdev->gain_cal.standard_ranging_gain_factor =
05898         (uint16_t)tuning_parm_value;
05899       break;
05900     case VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM:
05901       pdev->tuning_parms.tp_lite_min_clip =
05902         (uint8_t)tuning_parm_value;
05903       break;
05904     case VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM:
05905       pdev->tuning_parms.tp_lite_long_sigma_thresh_mm =
05906         (uint16_t)tuning_parm_value;
05907       break;
05908     case VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM:
05909       pdev->tuning_parms.tp_lite_med_sigma_thresh_mm =
05910         (uint16_t)tuning_parm_value;
05911       break;
05912     case VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM:
05913       pdev->tuning_parms.tp_lite_short_sigma_thresh_mm =
05914         (uint16_t)tuning_parm_value;
05915       break;
05916     case VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS:
05917       pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps =
05918         (uint16_t)tuning_parm_value;
05919       break;
05920     case VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS:
05921       pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps =
05922         (uint16_t)tuning_parm_value;
05923       break;
05924     case VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS:
05925       pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps =
05926         (uint16_t)tuning_parm_value;
05927       break;
05928     case VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH:
05929       pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns =
05930         (uint8_t)tuning_parm_value;
05931       break;
05932     case VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS:
05933       pdev->tuning_parms.tp_lite_sigma_est_amb_width_ns =
05934         (uint8_t)tuning_parm_value;
05935       break;
05936     case VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM:
05937       pdev->tuning_parms.tp_lite_sigma_ref_mm =
05938         (uint8_t)tuning_parm_value;
05939       break;
05940     case VL53LX_TUNINGPARM_LITE_RIT_MULT:
05941       pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult =
05942         (uint8_t)tuning_parm_value;
05943       break;
05944     case VL53LX_TUNINGPARM_LITE_SEED_CONFIG:
05945       pdev->tuning_parms.tp_lite_seed_cfg =
05946         (uint8_t)tuning_parm_value;
05947       break;
05948     case VL53LX_TUNINGPARM_LITE_QUANTIFIER:
05949       pdev->tuning_parms.tp_lite_quantifier =
05950         (uint8_t)tuning_parm_value;
05951       break;
05952     case VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT:
05953       pdev->tuning_parms.tp_lite_first_order_select =
05954         (uint8_t)tuning_parm_value;
05955       break;
05956     case VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS:
05957       pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps =
05958         (int16_t)tuning_parm_value;
05959       break;
05960     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE:
05961       pdev->tuning_parms.tp_init_phase_rtn_lite_long =
05962         (uint8_t)tuning_parm_value;
05963       break;
05964     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE:
05965       pdev->tuning_parms.tp_init_phase_rtn_lite_med =
05966         (uint8_t)tuning_parm_value;
05967       break;
05968     case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE:
05969       pdev->tuning_parms.tp_init_phase_rtn_lite_short =
05970         (uint8_t)tuning_parm_value;
05971       break;
05972     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE:
05973       pdev->tuning_parms.tp_init_phase_ref_lite_long =
05974         (uint8_t)tuning_parm_value;
05975       break;
05976     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE:
05977       pdev->tuning_parms.tp_init_phase_ref_lite_med =
05978         (uint8_t)tuning_parm_value;
05979       break;
05980     case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE:
05981       pdev->tuning_parms.tp_init_phase_ref_lite_short =
05982         (uint8_t)tuning_parm_value;
05983       break;
05984     case VL53LX_TUNINGPARM_TIMED_SEED_CONFIG:
05985       pdev->tuning_parms.tp_timed_seed_cfg =
05986         (uint8_t)tuning_parm_value;
05987       break;
05988     case VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA:
05989       pdev->dmax_cfg.signal_thresh_sigma =
05990         (uint8_t)tuning_parm_value;
05991       break;
05992     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0:
05993       pdev->dmax_cfg.target_reflectance_for_dmax_calc[0] =
05994         (uint16_t)tuning_parm_value;
05995       break;
05996     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1:
05997       pdev->dmax_cfg.target_reflectance_for_dmax_calc[1] =
05998         (uint16_t)tuning_parm_value;
05999       break;
06000     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2:
06001       pdev->dmax_cfg.target_reflectance_for_dmax_calc[2] =
06002         (uint16_t)tuning_parm_value;
06003       break;
06004     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3:
06005       pdev->dmax_cfg.target_reflectance_for_dmax_calc[3] =
06006         (uint16_t)tuning_parm_value;
06007       break;
06008     case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4:
06009       pdev->dmax_cfg.target_reflectance_for_dmax_calc[4] =
06010         (uint16_t)tuning_parm_value;
06011       break;
06012     case VL53LX_TUNINGPARM_VHV_LOOPBOUND:
06013       pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
06014         (uint8_t)tuning_parm_value;
06015       break;
06016     case VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE:
06017       pdev->refspadchar.device_test_mode =
06018         (uint8_t)tuning_parm_value;
06019       break;
06020     case VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD:
06021       pdev->refspadchar.VL53LX_p_005 =
06022         (uint8_t)tuning_parm_value;
06023       break;
06024     case VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US:
06025       pdev->refspadchar.timeout_us =
06026         (uint32_t)tuning_parm_value;
06027       break;
06028     case VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS:
06029       pdev->refspadchar.target_count_rate_mcps =
06030         (uint16_t)tuning_parm_value;
06031       break;
06032     case VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS:
06033       pdev->refspadchar.min_count_rate_limit_mcps =
06034         (uint16_t)tuning_parm_value;
06035       break;
06036     case VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS:
06037       pdev->refspadchar.max_count_rate_limit_mcps =
06038         (uint16_t)tuning_parm_value;
06039       break;
06040     case VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES:
06041       pXC->num_of_samples =
06042         (uint8_t)tuning_parm_value;
06043       break;
06044     case VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM:
06045       pXC->algo__crosstalk_extract_min_valid_range_mm =
06046         (int16_t)tuning_parm_value;
06047       break;
06048     case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM:
06049       pXC->algo__crosstalk_extract_max_valid_range_mm =
06050         (int16_t)tuning_parm_value;
06051       break;
06052     case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS:
06053       pXC->dss_config__target_total_rate_mcps =
06054         (uint16_t)tuning_parm_value;
06055       break;
06056     case VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US:
06057       pXC->phasecal_config_timeout_us =
06058         (uint32_t)tuning_parm_value;
06059       break;
06060     case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS:
06061       pXC->algo__crosstalk_extract_max_valid_rate_kcps =
06062         (uint16_t)tuning_parm_value;
06063       break;
06064     case VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM:
06065       pXC->algo__crosstalk_extract_max_sigma_mm =
06066         (uint16_t)tuning_parm_value;
06067       break;
06068     case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US:
06069       pXC->mm_config_timeout_us =
06070         (uint32_t)tuning_parm_value;
06071       break;
06072     case VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US:
06073       pXC->range_config_timeout_us =
06074         (uint32_t)tuning_parm_value;
06075       break;
06076     case VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS:
06077       pdev->offsetcal_cfg.dss_config__target_total_rate_mcps =
06078         (uint16_t)tuning_parm_value;
06079       break;
06080     case VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US:
06081       pdev->offsetcal_cfg.phasecal_config_timeout_us =
06082         (uint32_t)tuning_parm_value;
06083       break;
06084     case VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US:
06085       pdev->offsetcal_cfg.mm_config_timeout_us =
06086         (uint32_t)tuning_parm_value;
06087       break;
06088     case VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US:
06089       pdev->offsetcal_cfg.range_config_timeout_us =
06090         (uint32_t)tuning_parm_value;
06091       break;
06092     case VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES:
06093       pdev->offsetcal_cfg.pre_num_of_samples =
06094         (uint8_t)tuning_parm_value;
06095       break;
06096     case VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES:
06097       pdev->offsetcal_cfg.mm1_num_of_samples =
06098         (uint8_t)tuning_parm_value;
06099       break;
06100     case VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES:
06101       pdev->offsetcal_cfg.mm2_num_of_samples =
06102         (uint8_t)tuning_parm_value;
06103       break;
06104     case VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS:
06105       pdev->zonecal_cfg.dss_config__target_total_rate_mcps =
06106         (uint16_t)tuning_parm_value;
06107       break;
06108     case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US:
06109       pdev->zonecal_cfg.phasecal_config_timeout_us =
06110         (uint32_t)tuning_parm_value;
06111       break;
06112     case VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US:
06113       pdev->zonecal_cfg.mm_config_timeout_us =
06114         (uint32_t)tuning_parm_value;
06115       break;
06116     case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES:
06117       pdev->zonecal_cfg.phasecal_num_of_samples =
06118         (uint16_t)tuning_parm_value;
06119       break;
06120     case VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US:
06121       pdev->zonecal_cfg.range_config_timeout_us =
06122         (uint32_t)tuning_parm_value;
06123       break;
06124     case VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES:
06125       pdev->zonecal_cfg.zone_num_of_samples =
06126         (uint16_t)tuning_parm_value;
06127       break;
06128     case VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD:
06129       pdev->ssc_cfg.VL53LX_p_005 =
06130         (uint8_t)tuning_parm_value;
06131       break;
06132     case VL53LX_TUNINGPARM_SPADMAP_VCSEL_START:
06133       pdev->ssc_cfg.vcsel_start =
06134         (uint8_t)tuning_parm_value;
06135       break;
06136     case VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS:
06137       pdev->ssc_cfg.rate_limit_mcps =
06138         (uint16_t)tuning_parm_value;
06139       break;
06140     case VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
06141       pdev->tuning_parms.tp_dss_target_lite_mcps =
06142         (uint16_t)tuning_parm_value;
06143       break;
06144     case VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
06145       pdev->tuning_parms.tp_dss_target_histo_mcps =
06146         (uint16_t)tuning_parm_value;
06147       break;
06148     case VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
06149       pdev->tuning_parms.tp_dss_target_histo_mz_mcps =
06150         (uint16_t)tuning_parm_value;
06151       break;
06152     case VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
06153       pdev->tuning_parms.tp_dss_target_timed_mcps =
06154         (uint16_t)tuning_parm_value;
06155       break;
06156     case VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US:
06157       pdev->tuning_parms.tp_phasecal_timeout_lite_us =
06158         (uint32_t)tuning_parm_value;
06159       break;
06160     case VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US:
06161       pdev->tuning_parms.tp_phasecal_timeout_hist_long_us =
06162         (uint32_t)tuning_parm_value;
06163       break;
06164     case VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US:
06165       pdev->tuning_parms.tp_phasecal_timeout_hist_med_us =
06166         (uint32_t)tuning_parm_value;
06167       break;
06168     case VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US:
06169       pdev->tuning_parms.tp_phasecal_timeout_hist_short_us =
06170         (uint32_t)tuning_parm_value;
06171       break;
06172     case VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US:
06173       pdev->tuning_parms.tp_phasecal_timeout_mz_long_us =
06174         (uint32_t)tuning_parm_value;
06175       break;
06176     case VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US:
06177       pdev->tuning_parms.tp_phasecal_timeout_mz_med_us =
06178         (uint32_t)tuning_parm_value;
06179       break;
06180     case VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US:
06181       pdev->tuning_parms.tp_phasecal_timeout_mz_short_us =
06182         (uint32_t)tuning_parm_value;
06183       break;
06184     case VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US:
06185       pdev->tuning_parms.tp_phasecal_timeout_timed_us =
06186         (uint32_t)tuning_parm_value;
06187       break;
06188     case VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US:
06189       pdev->tuning_parms.tp_mm_timeout_lite_us =
06190         (uint32_t)tuning_parm_value;
06191       break;
06192     case VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US:
06193       pdev->tuning_parms.tp_mm_timeout_histo_us =
06194         (uint32_t)tuning_parm_value;
06195       break;
06196     case VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US:
06197       pdev->tuning_parms.tp_mm_timeout_mz_us =
06198         (uint32_t)tuning_parm_value;
06199       break;
06200     case VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US:
06201       pdev->tuning_parms.tp_mm_timeout_timed_us =
06202         (uint32_t)tuning_parm_value;
06203       break;
06204     case VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US:
06205       pdev->tuning_parms.tp_range_timeout_lite_us =
06206         (uint32_t)tuning_parm_value;
06207       break;
06208     case VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US:
06209       pdev->tuning_parms.tp_range_timeout_histo_us =
06210         (uint32_t)tuning_parm_value;
06211       break;
06212     case VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US:
06213       pdev->tuning_parms.tp_range_timeout_mz_us =
06214         (uint32_t)tuning_parm_value;
06215       break;
06216     case VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US:
06217       pdev->tuning_parms.tp_range_timeout_timed_us =
06218         (uint32_t)tuning_parm_value;
06219       break;
06220     case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN:
06221       pdev->smudge_correct_config.smudge_margin =
06222         (uint16_t)tuning_parm_value;
06223       break;
06224     case VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN:
06225       pdev->smudge_correct_config.noise_margin =
06226         (uint32_t)tuning_parm_value;
06227       break;
06228     case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT:
06229       pdev->smudge_correct_config.user_xtalk_offset_limit =
06230         (uint32_t)tuning_parm_value;
06231       break;
06232     case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI:
06233       pdev->smudge_correct_config.user_xtalk_offset_limit_hi =
06234         (uint8_t)tuning_parm_value;
06235       break;
06236     case VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT:
06237       pdev->smudge_correct_config.sample_limit =
06238         (uint32_t)tuning_parm_value;
06239       break;
06240     case VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA:
06241       pdev->smudge_correct_config.single_xtalk_delta =
06242         (uint32_t)tuning_parm_value;
06243       break;
06244     case VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA:
06245       pdev->smudge_correct_config.averaged_xtalk_delta =
06246         (uint32_t)tuning_parm_value;
06247       break;
06248     case VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT:
06249       pdev->smudge_correct_config.smudge_corr_clip_limit =
06250         (uint32_t)tuning_parm_value;
06251       break;
06252     case VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD:
06253       pdev->smudge_correct_config.scaler_calc_method =
06254         (uint8_t)tuning_parm_value;
06255       break;
06256     case VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER:
06257       pdev->smudge_correct_config.x_gradient_scaler =
06258         (int16_t)tuning_parm_value;
06259       break;
06260     case VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER:
06261       pdev->smudge_correct_config.y_gradient_scaler =
06262         (int16_t)tuning_parm_value;
06263       break;
06264     case VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET:
06265       pdev->smudge_correct_config.user_scaler_set =
06266         (uint8_t)tuning_parm_value;
06267       break;
06268 
06269     case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY:
06270       pdev->smudge_correct_config.smudge_corr_single_apply =
06271         (uint8_t)tuning_parm_value;
06272       break;
06273     case VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD:
06274       pdev->smudge_correct_config.smudge_corr_ambient_threshold =
06275         (uint32_t)tuning_parm_value;
06276       break;
06277     case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS:
06278       pdev->smudge_correct_config.nodetect_ambient_threshold =
06279         (uint32_t)tuning_parm_value;
06280       break;
06281     case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT:
06282       pdev->smudge_correct_config.nodetect_sample_limit =
06283         (uint32_t)tuning_parm_value;
06284       break;
06285     case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS:
06286       pdev->smudge_correct_config.nodetect_xtalk_offset =
06287         (uint32_t)tuning_parm_value;
06288       break;
06289     case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM:
06290       pdev->smudge_correct_config.nodetect_min_range_mm =
06291         (uint16_t)tuning_parm_value;
06292       break;
06293     case VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND:
06294       pdev->low_power_auto_data.vhv_loop_bound =
06295         (uint8_t)tuning_parm_value;
06296       break;
06297     case VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US:
06298       pdev->tuning_parms.tp_mm_timeout_lpa_us =
06299         (uint32_t)tuning_parm_value;
06300       break;
06301     case VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US:
06302       pdev->tuning_parms.tp_range_timeout_lpa_us =
06303         (uint32_t)tuning_parm_value;
06304       break;
06305     case VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS:
06306       pdev->tuning_parms.tp_dss_target_very_short_mcps =
06307         (uint16_t)tuning_parm_value;
06308       break;
06309     case VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER:
06310       pdev->tuning_parms.tp_phasecal_patch_power =
06311         (uint16_t) tuning_parm_value;
06312       break;
06313     case VL53LX_TUNINGPARM_HIST_MERGE:
06314       pdev->tuning_parms.tp_hist_merge =
06315         (uint16_t) tuning_parm_value;
06316       break;
06317     case VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD:
06318       pdev->tuning_parms.tp_reset_merge_threshold =
06319         (uint16_t) tuning_parm_value;
06320       break;
06321     case VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE:
06322       pdev->tuning_parms.tp_hist_merge_max_size =
06323         (uint16_t) tuning_parm_value;
06324       break;
06325     case VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR:
06326       pdev->smudge_correct_config.max_smudge_factor =
06327         (uint32_t)tuning_parm_value;
06328       break;
06329 
06330     default:
06331       status = VL53LX_ERROR_INVALID_PARAMS;
06332       break;
06333 
06334   }
06335 
06336   return status;
06337 }
06338 
06339 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_enable()
06340 {
06341 
06342   VL53LX_Error  status = VL53LX_ERROR_NONE;
06343 
06344   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06345 
06346   pdev->smudge_correct_config.smudge_corr_enabled = 1;
06347 
06348   return status;
06349 }
06350 
06351 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_disable()
06352 {
06353   VL53LX_Error  status = VL53LX_ERROR_NONE;
06354 
06355   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06356 
06357   pdev->smudge_correct_config.smudge_corr_enabled = 0;
06358 
06359   return status;
06360 }
06361 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_apply_enable()
06362 {
06363   VL53LX_Error  status = VL53LX_ERROR_NONE;
06364 
06365   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06366 
06367   pdev->smudge_correct_config.smudge_corr_apply_enabled = 1;
06368 
06369   return status;
06370 }
06371 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_apply_disable()
06372 {
06373   VL53LX_Error  status = VL53LX_ERROR_NONE;
06374 
06375   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06376 
06377   pdev->smudge_correct_config.smudge_corr_apply_enabled = 0;
06378 
06379 
06380   return status;
06381 }
06382 
06383 
06384 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_single_apply_enable()
06385 {
06386   VL53LX_Error  status = VL53LX_ERROR_NONE;
06387 
06388   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06389 
06390   pdev->smudge_correct_config.smudge_corr_single_apply = 1;
06391 
06392 
06393   return status;
06394 }
06395 
06396 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_single_apply_disable()
06397 {
06398 
06399   VL53LX_Error  status = VL53LX_ERROR_NONE;
06400 
06401   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06402 
06403 
06404   pdev->smudge_correct_config.smudge_corr_single_apply = 0;
06405 
06406 
06407   return status;
06408 }
06409 
06410 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_set_scalers(
06411   int16_t   x_scaler_in,
06412   int16_t   y_scaler_in,
06413   uint8_t   user_scaler_set_in
06414 )
06415 {
06416 
06417 
06418 
06419   VL53LX_Error  status = VL53LX_ERROR_NONE;
06420 
06421   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06422 
06423 
06424   pdev->smudge_correct_config.x_gradient_scaler = x_scaler_in;
06425   pdev->smudge_correct_config.y_gradient_scaler = y_scaler_in;
06426   pdev->smudge_correct_config.user_scaler_set = user_scaler_set_in;
06427 
06428   return status;
06429 }
06430 
06431 VL53LX_Error VL53LX::VL53LX_get_current_xtalk_settings(
06432   VL53LX_xtalk_calibration_results_t *pxtalk
06433 )
06434 {
06435 
06436 
06437   VL53LX_Error  status = VL53LX_ERROR_NONE;
06438   uint8_t i;
06439 
06440   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06441 
06442   pxtalk->algo__crosstalk_compensation_plane_offset_kcps =
06443     pdev->xtalk_cfg.algo__crosstalk_compensation_plane_offset_kcps;
06444   pxtalk->algo__crosstalk_compensation_x_plane_gradient_kcps =
06445     pdev->xtalk_cfg.algo__crosstalk_compensation_x_plane_gradient_kcps;
06446   pxtalk->algo__crosstalk_compensation_y_plane_gradient_kcps =
06447     pdev->xtalk_cfg.algo__crosstalk_compensation_y_plane_gradient_kcps;
06448   for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
06449     pxtalk->algo__xtalk_cpo_HistoMerge_kcps[i] =
06450       pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[i];
06451 
06452 
06453   return status;
06454 
06455 }
06456 VL53LX_Error VL53LX::VL53LX_set_current_xtalk_settings(
06457   VL53LX_xtalk_calibration_results_t *pxtalk
06458 )
06459 {
06460 
06461   uint8_t i;
06462   VL53LX_Error  status = VL53LX_ERROR_NONE;
06463 
06464   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
06465 
06466   pdev->xtalk_cfg.algo__crosstalk_compensation_plane_offset_kcps =
06467     pxtalk->algo__crosstalk_compensation_plane_offset_kcps;
06468   pdev->xtalk_cfg.algo__crosstalk_compensation_x_plane_gradient_kcps =
06469     pxtalk->algo__crosstalk_compensation_x_plane_gradient_kcps;
06470   pdev->xtalk_cfg.algo__crosstalk_compensation_y_plane_gradient_kcps =
06471     pxtalk->algo__crosstalk_compensation_y_plane_gradient_kcps;
06472   for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
06473     pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[i] =
06474       pxtalk->algo__xtalk_cpo_HistoMerge_kcps[i];
06475 
06476 
06477   return status;
06478 
06479 }
06480 
06481 /* vl53lx_register_funcs.c */
06482 
06483 VL53LX_Error VL53LX::VL53LX_i2c_encode_static_nvm_managed(
06484   VL53LX_static_nvm_managed_t *pdata,
06485   uint16_t                  buf_size,
06486   uint8_t                  *pbuffer)
06487 {
06488 
06489 
06490   VL53LX_Error status = VL53LX_ERROR_NONE;
06491 
06492   if (buf_size < VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES) {
06493     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
06494   }
06495 
06496   *(pbuffer +   0) =
06497     pdata->i2c_slave__device_address & 0x7F;
06498   *(pbuffer +   1) =
06499     pdata->ana_config__vhv_ref_sel_vddpix & 0xF;
06500   *(pbuffer +   2) =
06501     pdata->ana_config__vhv_ref_sel_vquench & 0x7F;
06502   *(pbuffer +   3) =
06503     pdata->ana_config__reg_avdd1v2_sel & 0x3;
06504   *(pbuffer +   4) =
06505     pdata->ana_config__fast_osc__trim & 0x7F;
06506   VL53LX_i2c_encode_uint16_t(
06507     pdata->osc_measured__fast_osc__frequency,
06508     2,
06509     pbuffer +   5);
06510   *(pbuffer +   7) =
06511     pdata->vhv_config__timeout_macrop_loop_bound;
06512   *(pbuffer +   8) =
06513     pdata->vhv_config__count_thresh;
06514   *(pbuffer +   9) =
06515     pdata->vhv_config__offset & 0x3F;
06516   *(pbuffer +  10) =
06517     pdata->vhv_config__init;
06518 
06519   return status;
06520 }
06521 
06522 VL53LX_Error VL53LX::VL53LX_i2c_decode_static_nvm_managed(
06523   uint16_t                   buf_size,
06524   uint8_t                   *pbuffer,
06525   VL53LX_static_nvm_managed_t  *pdata)
06526 {
06527 
06528 
06529   VL53LX_Error status = VL53LX_ERROR_NONE;
06530 
06531   if (buf_size < VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES) {
06532     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
06533   }
06534 
06535   pdata->i2c_slave__device_address =
06536     (*(pbuffer +   0)) & 0x7F;
06537   pdata->ana_config__vhv_ref_sel_vddpix =
06538     (*(pbuffer +   1)) & 0xF;
06539   pdata->ana_config__vhv_ref_sel_vquench =
06540     (*(pbuffer +   2)) & 0x7F;
06541   pdata->ana_config__reg_avdd1v2_sel =
06542     (*(pbuffer +   3)) & 0x3;
06543   pdata->ana_config__fast_osc__trim =
06544     (*(pbuffer +   4)) & 0x7F;
06545   pdata->osc_measured__fast_osc__frequency =
06546     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   5));
06547   pdata->vhv_config__timeout_macrop_loop_bound =
06548     (*(pbuffer +   7));
06549   pdata->vhv_config__count_thresh =
06550     (*(pbuffer +   8));
06551   pdata->vhv_config__offset =
06552     (*(pbuffer +   9)) & 0x3F;
06553   pdata->vhv_config__init =
06554     (*(pbuffer +  10));
06555 
06556   return status;
06557 }
06558 
06559 VL53LX_Error VL53LX::VL53LX_set_static_nvm_managed(
06560   VL53LX_static_nvm_managed_t  *pdata)
06561 {
06562 
06563 
06564   VL53LX_Error status = VL53LX_ERROR_NONE;
06565   uint8_t comms_buffer[VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES];
06566 
06567   if (status == VL53LX_ERROR_NONE)
06568     status = VL53LX_i2c_encode_static_nvm_managed(
06569                pdata,
06570                VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES,
06571                comms_buffer);
06572 
06573   if (status == VL53LX_ERROR_NONE)
06574     status = VL53LX_WriteMulti(
06575                Dev,
06576                VL53LX_I2C_SLAVE__DEVICE_ADDRESS,
06577                comms_buffer,
06578                VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES);
06579 
06580 
06581   return status;
06582 }
06583 
06584 VL53LX_Error VL53LX::VL53LX_get_static_nvm_managed(
06585   VL53LX_static_nvm_managed_t  *pdata)
06586 {
06587   VL53LX_Error status = VL53LX_ERROR_NONE;
06588   uint8_t comms_buffer[VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES];
06589 
06590   if (status == VL53LX_ERROR_NONE)
06591     status = VL53LX_ReadMulti(
06592                Dev,
06593                VL53LX_I2C_SLAVE__DEVICE_ADDRESS,
06594                comms_buffer,
06595                VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES);
06596 
06597   if (status == VL53LX_ERROR_NONE)
06598     status = VL53LX_i2c_decode_static_nvm_managed(
06599                VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES,
06600                comms_buffer,
06601                pdata);
06602 
06603   return status;
06604 }
06605 
06606 
06607 VL53LX_Error VL53LX::VL53LX_i2c_encode_customer_nvm_managed(
06608   VL53LX_customer_nvm_managed_t *pdata,
06609   uint16_t                  buf_size,
06610   uint8_t                  *pbuffer)
06611 {
06612 
06613 
06614   VL53LX_Error status = VL53LX_ERROR_NONE;
06615 
06616   if (buf_size < VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES) {
06617     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
06618   }
06619 
06620   *(pbuffer +   0) =
06621     pdata->global_config__spad_enables_ref_0;
06622   *(pbuffer +   1) =
06623     pdata->global_config__spad_enables_ref_1;
06624   *(pbuffer +   2) =
06625     pdata->global_config__spad_enables_ref_2;
06626   *(pbuffer +   3) =
06627     pdata->global_config__spad_enables_ref_3;
06628   *(pbuffer +   4) =
06629     pdata->global_config__spad_enables_ref_4;
06630   *(pbuffer +   5) =
06631     pdata->global_config__spad_enables_ref_5 & 0xF;
06632   *(pbuffer +   6) =
06633     pdata->global_config__ref_en_start_select;
06634   *(pbuffer +   7) =
06635     pdata->ref_spad_man__num_requested_ref_spads & 0x3F;
06636   *(pbuffer +   8) =
06637     pdata->ref_spad_man__ref_location & 0x3;
06638   VL53LX_i2c_encode_uint16_t(
06639     pdata->algo__crosstalk_compensation_plane_offset_kcps,
06640     2,
06641     pbuffer +   9);
06642   VL53LX_i2c_encode_int16_t(
06643     pdata->algo__crosstalk_compensation_x_plane_gradient_kcps,
06644     2,
06645     pbuffer +  11);
06646   VL53LX_i2c_encode_int16_t(
06647     pdata->algo__crosstalk_compensation_y_plane_gradient_kcps,
06648     2,
06649     pbuffer +  13);
06650   VL53LX_i2c_encode_uint16_t(
06651     pdata->ref_spad_char__total_rate_target_mcps,
06652     2,
06653     pbuffer +  15);
06654   VL53LX_i2c_encode_int16_t(
06655     pdata->algo__part_to_part_range_offset_mm & 0x1FFF,
06656     2,
06657     pbuffer +  17);
06658   VL53LX_i2c_encode_int16_t(
06659     pdata->mm_config__inner_offset_mm,
06660     2,
06661     pbuffer +  19);
06662   VL53LX_i2c_encode_int16_t(
06663     pdata->mm_config__outer_offset_mm,
06664     2,
06665     pbuffer +  21);
06666 
06667   return status;
06668 }
06669 
06670 VL53LX_Error VL53LX::VL53LX_i2c_decode_customer_nvm_managed(
06671   uint16_t                   buf_size,
06672   uint8_t                   *pbuffer,
06673   VL53LX_customer_nvm_managed_t  *pdata)
06674 {
06675 
06676 
06677   VL53LX_Error status = VL53LX_ERROR_NONE;
06678 
06679   if (buf_size < VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES) {
06680     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
06681   }
06682 
06683   pdata->global_config__spad_enables_ref_0 =
06684     (*(pbuffer +   0));
06685   pdata->global_config__spad_enables_ref_1 =
06686     (*(pbuffer +   1));
06687   pdata->global_config__spad_enables_ref_2 =
06688     (*(pbuffer +   2));
06689   pdata->global_config__spad_enables_ref_3 =
06690     (*(pbuffer +   3));
06691   pdata->global_config__spad_enables_ref_4 =
06692     (*(pbuffer +   4));
06693   pdata->global_config__spad_enables_ref_5 =
06694     (*(pbuffer +   5)) & 0xF;
06695   pdata->global_config__ref_en_start_select =
06696     (*(pbuffer +   6));
06697   pdata->ref_spad_man__num_requested_ref_spads =
06698     (*(pbuffer +   7)) & 0x3F;
06699   pdata->ref_spad_man__ref_location =
06700     (*(pbuffer +   8)) & 0x3;
06701   pdata->algo__crosstalk_compensation_plane_offset_kcps =
06702     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   9));
06703   pdata->algo__crosstalk_compensation_x_plane_gradient_kcps =
06704     (VL53LX_i2c_decode_int16_t(2, pbuffer +  11));
06705   pdata->algo__crosstalk_compensation_y_plane_gradient_kcps =
06706     (VL53LX_i2c_decode_int16_t(2, pbuffer +  13));
06707   pdata->ref_spad_char__total_rate_target_mcps =
06708     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  15));
06709   pdata->algo__part_to_part_range_offset_mm =
06710     (VL53LX_i2c_decode_int16_t(2, pbuffer +  17)) & 0x1FFF;
06711   pdata->mm_config__inner_offset_mm =
06712     (VL53LX_i2c_decode_int16_t(2, pbuffer +  19));
06713   pdata->mm_config__outer_offset_mm =
06714     (VL53LX_i2c_decode_int16_t(2, pbuffer +  21));
06715 
06716 
06717   return status;
06718 }
06719 
06720 VL53LX_Error VL53LX::VL53LX_set_customer_nvm_managed(
06721   VL53LX_customer_nvm_managed_t  *pdata)
06722 {
06723   VL53LX_Error status = VL53LX_ERROR_NONE;
06724   uint8_t comms_buffer[VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES];
06725 
06726 
06727   if (status == VL53LX_ERROR_NONE)
06728     status = VL53LX_i2c_encode_customer_nvm_managed(
06729                pdata,
06730                VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES,
06731                comms_buffer);
06732 
06733   if (status == VL53LX_ERROR_NONE)
06734     status = VL53LX_WriteMulti(
06735                Dev,
06736                VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
06737                comms_buffer,
06738                VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES);
06739 
06740   return status;
06741 }
06742 
06743 VL53LX_Error VL53LX::VL53LX_get_customer_nvm_managed(
06744   VL53LX_customer_nvm_managed_t  *pdata)
06745 {
06746 
06747 
06748   VL53LX_Error status = VL53LX_ERROR_NONE;
06749   uint8_t comms_buffer[VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES];
06750 
06751   if (status == VL53LX_ERROR_NONE)
06752     status = VL53LX_ReadMulti(
06753                Dev,
06754                VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
06755                comms_buffer,
06756                VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES);
06757 
06758   if (status == VL53LX_ERROR_NONE)
06759     status = VL53LX_i2c_decode_customer_nvm_managed(
06760                VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES,
06761                comms_buffer,
06762                pdata);
06763 
06764 
06765   return status;
06766 }
06767 
06768 
06769 VL53LX_Error VL53LX::VL53LX_i2c_encode_static_config(
06770   VL53LX_static_config_t   *pdata,
06771   uint16_t                  buf_size,
06772   uint8_t                  *pbuffer)
06773 {
06774 
06775 
06776   VL53LX_Error status = VL53LX_ERROR_NONE;
06777 
06778   if (buf_size < VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES) {
06779     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
06780   }
06781 
06782   VL53LX_i2c_encode_uint16_t(
06783     pdata->dss_config__target_total_rate_mcps,
06784     2,
06785     pbuffer +   0);
06786   *(pbuffer +   2) =
06787     pdata->debug__ctrl & 0x1;
06788   *(pbuffer +   3) =
06789     pdata->test_mode__ctrl & 0xF;
06790   *(pbuffer +   4) =
06791     pdata->clk_gating__ctrl & 0xF;
06792   *(pbuffer +   5) =
06793     pdata->nvm_bist__ctrl & 0x1F;
06794   *(pbuffer +   6) =
06795     pdata->nvm_bist__num_nvm_words & 0x7F;
06796   *(pbuffer +   7) =
06797     pdata->nvm_bist__start_address & 0x7F;
06798   *(pbuffer +   8) =
06799     pdata->host_if__status & 0x1;
06800   *(pbuffer +   9) =
06801     pdata->pad_i2c_hv__config;
06802   *(pbuffer +  10) =
06803     pdata->pad_i2c_hv__extsup_config & 0x1;
06804   *(pbuffer +  11) =
06805     pdata->gpio_hv_pad__ctrl & 0x3;
06806   *(pbuffer +  12) =
06807     pdata->gpio_hv_mux__ctrl & 0x1F;
06808   *(pbuffer +  13) =
06809     pdata->gpio__tio_hv_status & 0x3;
06810   *(pbuffer +  14) =
06811     pdata->gpio__fio_hv_status & 0x3;
06812   *(pbuffer +  15) =
06813     pdata->ana_config__spad_sel_pswidth & 0x7;
06814   *(pbuffer +  16) =
06815     pdata->ana_config__vcsel_pulse_width_offset & 0x1F;
06816   *(pbuffer +  17) =
06817     pdata->ana_config__fast_osc__config_ctrl & 0x1;
06818   *(pbuffer +  18) =
06819     pdata->sigma_estimator__effective_pulse_width_ns;
06820   *(pbuffer +  19) =
06821     pdata->sigma_estimator__effective_ambient_width_ns;
06822   *(pbuffer +  20) =
06823     pdata->sigma_estimator__sigma_ref_mm;
06824   *(pbuffer +  21) =
06825     pdata->algo__crosstalk_compensation_valid_height_mm;
06826   *(pbuffer +  22) =
06827     pdata->spare_host_config__static_config_spare_0;
06828   *(pbuffer +  23) =
06829     pdata->spare_host_config__static_config_spare_1;
06830   VL53LX_i2c_encode_uint16_t(
06831     pdata->algo__range_ignore_threshold_mcps,
06832     2,
06833     pbuffer +  24);
06834   *(pbuffer +  26) =
06835     pdata->algo__range_ignore_valid_height_mm;
06836   *(pbuffer +  27) =
06837     pdata->algo__range_min_clip;
06838   *(pbuffer +  28) =
06839     pdata->algo__consistency_check__tolerance & 0xF;
06840   *(pbuffer +  29) =
06841     pdata->spare_host_config__static_config_spare_2;
06842   *(pbuffer +  30) =
06843     pdata->sd_config__reset_stages_msb & 0xF;
06844   *(pbuffer +  31) =
06845     pdata->sd_config__reset_stages_lsb;
06846 
06847 
06848   return status;
06849 }
06850 
06851 VL53LX_Error VL53LX::VL53LX_i2c_decode_static_config(
06852   uint16_t                   buf_size,
06853   uint8_t                   *pbuffer,
06854   VL53LX_static_config_t    *pdata)
06855 {
06856 
06857 
06858   VL53LX_Error status = VL53LX_ERROR_NONE;
06859 
06860 
06861   if (buf_size < VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES) {
06862     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
06863   }
06864 
06865   pdata->dss_config__target_total_rate_mcps =
06866     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   0));
06867   pdata->debug__ctrl =
06868     (*(pbuffer +   2)) & 0x1;
06869   pdata->test_mode__ctrl =
06870     (*(pbuffer +   3)) & 0xF;
06871   pdata->clk_gating__ctrl =
06872     (*(pbuffer +   4)) & 0xF;
06873   pdata->nvm_bist__ctrl =
06874     (*(pbuffer +   5)) & 0x1F;
06875   pdata->nvm_bist__num_nvm_words =
06876     (*(pbuffer +   6)) & 0x7F;
06877   pdata->nvm_bist__start_address =
06878     (*(pbuffer +   7)) & 0x7F;
06879   pdata->host_if__status =
06880     (*(pbuffer +   8)) & 0x1;
06881   pdata->pad_i2c_hv__config =
06882     (*(pbuffer +   9));
06883   pdata->pad_i2c_hv__extsup_config =
06884     (*(pbuffer +  10)) & 0x1;
06885   pdata->gpio_hv_pad__ctrl =
06886     (*(pbuffer +  11)) & 0x3;
06887   pdata->gpio_hv_mux__ctrl =
06888     (*(pbuffer +  12)) & 0x1F;
06889   pdata->gpio__tio_hv_status =
06890     (*(pbuffer +  13)) & 0x3;
06891   pdata->gpio__fio_hv_status =
06892     (*(pbuffer +  14)) & 0x3;
06893   pdata->ana_config__spad_sel_pswidth =
06894     (*(pbuffer +  15)) & 0x7;
06895   pdata->ana_config__vcsel_pulse_width_offset =
06896     (*(pbuffer +  16)) & 0x1F;
06897   pdata->ana_config__fast_osc__config_ctrl =
06898     (*(pbuffer +  17)) & 0x1;
06899   pdata->sigma_estimator__effective_pulse_width_ns =
06900     (*(pbuffer +  18));
06901   pdata->sigma_estimator__effective_ambient_width_ns =
06902     (*(pbuffer +  19));
06903   pdata->sigma_estimator__sigma_ref_mm =
06904     (*(pbuffer +  20));
06905   pdata->algo__crosstalk_compensation_valid_height_mm =
06906     (*(pbuffer +  21));
06907   pdata->spare_host_config__static_config_spare_0 =
06908     (*(pbuffer +  22));
06909   pdata->spare_host_config__static_config_spare_1 =
06910     (*(pbuffer +  23));
06911   pdata->algo__range_ignore_threshold_mcps =
06912     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  24));
06913   pdata->algo__range_ignore_valid_height_mm =
06914     (*(pbuffer +  26));
06915   pdata->algo__range_min_clip =
06916     (*(pbuffer +  27));
06917   pdata->algo__consistency_check__tolerance =
06918     (*(pbuffer +  28)) & 0xF;
06919   pdata->spare_host_config__static_config_spare_2 =
06920     (*(pbuffer +  29));
06921   pdata->sd_config__reset_stages_msb =
06922     (*(pbuffer +  30)) & 0xF;
06923   pdata->sd_config__reset_stages_lsb =
06924     (*(pbuffer +  31));
06925 
06926 
06927   return status;
06928 }
06929 
06930 VL53LX_Error VL53LX::VL53LX_set_static_config(
06931   VL53LX_static_config_t    *pdata)
06932 {
06933 
06934 
06935   VL53LX_Error status = VL53LX_ERROR_NONE;
06936   uint8_t comms_buffer[VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES];
06937 
06938   if (status == VL53LX_ERROR_NONE)
06939     status = VL53LX_i2c_encode_static_config(
06940                pdata,
06941                VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES,
06942                comms_buffer);
06943 
06944   if (status == VL53LX_ERROR_NONE)
06945     status = VL53LX_WriteMulti(
06946                Dev,
06947                VL53LX_DSS_CONFIG__TARGET_TOTAL_RATE_MCPS,
06948                comms_buffer,
06949                VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES);
06950 
06951 
06952   return status;
06953 }
06954 
06955 VL53LX_Error VL53LX::VL53LX_get_static_config(
06956   VL53LX_static_config_t    *pdata)
06957 {
06958 
06959 
06960   VL53LX_Error status = VL53LX_ERROR_NONE;
06961   uint8_t comms_buffer[VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES];
06962 
06963 
06964   if (status == VL53LX_ERROR_NONE)
06965     status = VL53LX_ReadMulti(
06966                Dev,
06967                VL53LX_DSS_CONFIG__TARGET_TOTAL_RATE_MCPS,
06968                comms_buffer,
06969                VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES);
06970 
06971   if (status == VL53LX_ERROR_NONE)
06972     status = VL53LX_i2c_decode_static_config(
06973                VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES,
06974                comms_buffer,
06975                pdata);
06976 
06977   return status;
06978 }
06979 
06980 
06981 VL53LX_Error VL53LX::VL53LX_i2c_encode_general_config(
06982   VL53LX_general_config_t  *pdata,
06983   uint16_t                  buf_size,
06984   uint8_t                  *pbuffer)
06985 {
06986 
06987 
06988   VL53LX_Error status = VL53LX_ERROR_NONE;
06989 
06990   if (buf_size < VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES) {
06991     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
06992   }
06993 
06994   *(pbuffer +   0) =
06995     pdata->gph_config__stream_count_update_value;
06996   *(pbuffer +   1) =
06997     pdata->global_config__stream_divider;
06998   *(pbuffer +   2) =
06999     pdata->system__interrupt_config_gpio;
07000   *(pbuffer +   3) =
07001     pdata->cal_config__vcsel_start & 0x7F;
07002   VL53LX_i2c_encode_uint16_t(
07003     pdata->cal_config__repeat_rate & 0xFFF,
07004     2,
07005     pbuffer +   4);
07006   *(pbuffer +   6) =
07007     pdata->global_config__vcsel_width & 0x7F;
07008   *(pbuffer +   7) =
07009     pdata->phasecal_config__timeout_macrop;
07010   *(pbuffer +   8) =
07011     pdata->phasecal_config__target;
07012   *(pbuffer +   9) =
07013     pdata->phasecal_config__override & 0x1;
07014   *(pbuffer +  11) =
07015     pdata->dss_config__roi_mode_control & 0x7;
07016   VL53LX_i2c_encode_uint16_t(
07017     pdata->system__thresh_rate_high,
07018     2,
07019     pbuffer +  12);
07020   VL53LX_i2c_encode_uint16_t(
07021     pdata->system__thresh_rate_low,
07022     2,
07023     pbuffer +  14);
07024   VL53LX_i2c_encode_uint16_t(
07025     pdata->dss_config__manual_effective_spads_select,
07026     2,
07027     pbuffer +  16);
07028   *(pbuffer +  18) =
07029     pdata->dss_config__manual_block_select;
07030   *(pbuffer +  19) =
07031     pdata->dss_config__aperture_attenuation;
07032   *(pbuffer +  20) =
07033     pdata->dss_config__max_spads_limit;
07034   *(pbuffer +  21) =
07035     pdata->dss_config__min_spads_limit;
07036 
07037   return status;
07038 }
07039 
07040 
07041 VL53LX_Error VL53LX::VL53LX_i2c_decode_general_config(
07042   uint16_t                   buf_size,
07043   uint8_t                   *pbuffer,
07044   VL53LX_general_config_t   *pdata)
07045 {
07046 
07047 
07048   VL53LX_Error status = VL53LX_ERROR_NONE;
07049 
07050   if (buf_size < VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES) {
07051     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07052   }
07053 
07054   pdata->gph_config__stream_count_update_value =
07055     (*(pbuffer +   0));
07056   pdata->global_config__stream_divider =
07057     (*(pbuffer +   1));
07058   pdata->system__interrupt_config_gpio =
07059     (*(pbuffer +   2));
07060   pdata->cal_config__vcsel_start =
07061     (*(pbuffer +   3)) & 0x7F;
07062   pdata->cal_config__repeat_rate =
07063     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   4)) & 0xFFF;
07064   pdata->global_config__vcsel_width =
07065     (*(pbuffer +   6)) & 0x7F;
07066   pdata->phasecal_config__timeout_macrop =
07067     (*(pbuffer +   7));
07068   pdata->phasecal_config__target =
07069     (*(pbuffer +   8));
07070   pdata->phasecal_config__override =
07071     (*(pbuffer +   9)) & 0x1;
07072   pdata->dss_config__roi_mode_control =
07073     (*(pbuffer +  11)) & 0x7;
07074   pdata->system__thresh_rate_high =
07075     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  12));
07076   pdata->system__thresh_rate_low =
07077     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  14));
07078   pdata->dss_config__manual_effective_spads_select =
07079     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  16));
07080   pdata->dss_config__manual_block_select =
07081     (*(pbuffer +  18));
07082   pdata->dss_config__aperture_attenuation =
07083     (*(pbuffer +  19));
07084   pdata->dss_config__max_spads_limit =
07085     (*(pbuffer +  20));
07086   pdata->dss_config__min_spads_limit =
07087     (*(pbuffer +  21));
07088 
07089 
07090   return status;
07091 }
07092 
07093 VL53LX_Error VL53LX::VL53LX_set_general_config(
07094   VL53LX_general_config_t   *pdata)
07095 {
07096 
07097 
07098   VL53LX_Error status = VL53LX_ERROR_NONE;
07099   uint8_t comms_buffer[VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES];
07100 
07101   if (status == VL53LX_ERROR_NONE)
07102     status = VL53LX_i2c_encode_general_config(
07103                pdata,
07104                VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES,
07105                comms_buffer);
07106 
07107   if (status == VL53LX_ERROR_NONE)
07108     status = VL53LX_WriteMulti(
07109                Dev,
07110                VL53LX_GPH_CONFIG__STREAM_COUNT_UPDATE_VALUE,
07111                comms_buffer,
07112                VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES);
07113 
07114   return status;
07115 }
07116 
07117 
07118 VL53LX_Error VL53LX::VL53LX_get_general_config(
07119   VL53LX_general_config_t   *pdata)
07120 {
07121 
07122 
07123   VL53LX_Error status = VL53LX_ERROR_NONE;
07124   uint8_t comms_buffer[VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES];
07125   if (status == VL53LX_ERROR_NONE)
07126     status = VL53LX_ReadMulti(
07127                Dev,
07128                VL53LX_GPH_CONFIG__STREAM_COUNT_UPDATE_VALUE,
07129                comms_buffer,
07130                VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES);
07131 
07132   if (status == VL53LX_ERROR_NONE)
07133     status = VL53LX_i2c_decode_general_config(
07134                VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES,
07135                comms_buffer,
07136                pdata);
07137 
07138   return status;
07139 }
07140 
07141 
07142 VL53LX_Error VL53LX::VL53LX_i2c_encode_timing_config(
07143   VL53LX_timing_config_t   *pdata,
07144   uint16_t                  buf_size,
07145   uint8_t                  *pbuffer)
07146 {
07147 
07148 
07149   VL53LX_Error status = VL53LX_ERROR_NONE;
07150 
07151 
07152   if (buf_size < VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES) {
07153     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07154   }
07155 
07156   *(pbuffer +   0) =
07157     pdata->mm_config__timeout_macrop_a_hi & 0xF;
07158   *(pbuffer +   1) =
07159     pdata->mm_config__timeout_macrop_a_lo;
07160   *(pbuffer +   2) =
07161     pdata->mm_config__timeout_macrop_b_hi & 0xF;
07162   *(pbuffer +   3) =
07163     pdata->mm_config__timeout_macrop_b_lo;
07164   *(pbuffer +   4) =
07165     pdata->range_config__timeout_macrop_a_hi & 0xF;
07166   *(pbuffer +   5) =
07167     pdata->range_config__timeout_macrop_a_lo;
07168   *(pbuffer +   6) =
07169     pdata->range_config__vcsel_period_a & 0x3F;
07170   *(pbuffer +   7) =
07171     pdata->range_config__timeout_macrop_b_hi & 0xF;
07172   *(pbuffer +   8) =
07173     pdata->range_config__timeout_macrop_b_lo;
07174   *(pbuffer +   9) =
07175     pdata->range_config__vcsel_period_b & 0x3F;
07176   VL53LX_i2c_encode_uint16_t(
07177     pdata->range_config__sigma_thresh,
07178     2,
07179     pbuffer +  10);
07180   VL53LX_i2c_encode_uint16_t(
07181     pdata->range_config__min_count_rate_rtn_limit_mcps,
07182     2,
07183     pbuffer +  12);
07184   *(pbuffer +  14) =
07185     pdata->range_config__valid_phase_low;
07186   *(pbuffer +  15) =
07187     pdata->range_config__valid_phase_high;
07188   VL53LX_i2c_encode_uint32_t(
07189     pdata->system__intermeasurement_period,
07190     4,
07191     pbuffer +  18);
07192   *(pbuffer +  22) =
07193     pdata->system__fractional_enable & 0x1;
07194 
07195   return status;
07196 }
07197 
07198 VL53LX_Error VL53LX::VL53LX_i2c_decode_timing_config(
07199   uint16_t                   buf_size,
07200   uint8_t                   *pbuffer,
07201   VL53LX_timing_config_t    *pdata)
07202 {
07203 
07204 
07205   VL53LX_Error status = VL53LX_ERROR_NONE;
07206 
07207   if (buf_size < VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES) {
07208     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07209   }
07210 
07211   pdata->mm_config__timeout_macrop_a_hi =
07212     (*(pbuffer +   0)) & 0xF;
07213   pdata->mm_config__timeout_macrop_a_lo =
07214     (*(pbuffer +   1));
07215   pdata->mm_config__timeout_macrop_b_hi =
07216     (*(pbuffer +   2)) & 0xF;
07217   pdata->mm_config__timeout_macrop_b_lo =
07218     (*(pbuffer +   3));
07219   pdata->range_config__timeout_macrop_a_hi =
07220     (*(pbuffer +   4)) & 0xF;
07221   pdata->range_config__timeout_macrop_a_lo =
07222     (*(pbuffer +   5));
07223   pdata->range_config__vcsel_period_a =
07224     (*(pbuffer +   6)) & 0x3F;
07225   pdata->range_config__timeout_macrop_b_hi =
07226     (*(pbuffer +   7)) & 0xF;
07227   pdata->range_config__timeout_macrop_b_lo =
07228     (*(pbuffer +   8));
07229   pdata->range_config__vcsel_period_b =
07230     (*(pbuffer +   9)) & 0x3F;
07231   pdata->range_config__sigma_thresh =
07232     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  10));
07233   pdata->range_config__min_count_rate_rtn_limit_mcps =
07234     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  12));
07235   pdata->range_config__valid_phase_low =
07236     (*(pbuffer +  14));
07237   pdata->range_config__valid_phase_high =
07238     (*(pbuffer +  15));
07239   pdata->system__intermeasurement_period =
07240     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  18));
07241   pdata->system__fractional_enable =
07242     (*(pbuffer +  22)) & 0x1;
07243 
07244 
07245   return status;
07246 }
07247 
07248 VL53LX_Error VL53LX::VL53LX_set_timing_config(
07249   VL53LX_timing_config_t    *pdata)
07250 {
07251 
07252 
07253   VL53LX_Error status = VL53LX_ERROR_NONE;
07254   uint8_t comms_buffer[VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES];
07255 
07256   if (status == VL53LX_ERROR_NONE)
07257     status = VL53LX_i2c_encode_timing_config(
07258                pdata,
07259                VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES,
07260                comms_buffer);
07261 
07262   if (status == VL53LX_ERROR_NONE)
07263     status = VL53LX_WriteMulti(
07264                Dev,
07265                VL53LX_MM_CONFIG__TIMEOUT_MACROP_A_HI,
07266                comms_buffer,
07267                VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES);
07268 
07269   return status;
07270 }
07271 
07272 VL53LX_Error VL53LX::VL53LX_get_timing_config(
07273   VL53LX_timing_config_t    *pdata)
07274 {
07275 
07276 
07277   VL53LX_Error status = VL53LX_ERROR_NONE;
07278   uint8_t comms_buffer[VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES];
07279 
07280 
07281   if (status == VL53LX_ERROR_NONE)
07282     status = VL53LX_ReadMulti(
07283                Dev,
07284                VL53LX_MM_CONFIG__TIMEOUT_MACROP_A_HI,
07285                comms_buffer,
07286                VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES);
07287 
07288   if (status == VL53LX_ERROR_NONE)
07289     status = VL53LX_i2c_decode_timing_config(
07290                VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES,
07291                comms_buffer,
07292                pdata);
07293 
07294   return status;
07295 }
07296 
07297 VL53LX_Error VL53LX::VL53LX_i2c_encode_dynamic_config(
07298   VL53LX_dynamic_config_t  *pdata,
07299   uint16_t                  buf_size,
07300   uint8_t                  *pbuffer)
07301 {
07302 
07303 
07304   VL53LX_Error status = VL53LX_ERROR_NONE;
07305 
07306   if (buf_size < VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES) {
07307     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07308   }
07309 
07310   *(pbuffer +   0) =
07311     pdata->system__grouped_parameter_hold_0 & 0x3;
07312   VL53LX_i2c_encode_uint16_t(
07313     pdata->system__thresh_high,
07314     2,
07315     pbuffer +   1);
07316   VL53LX_i2c_encode_uint16_t(
07317     pdata->system__thresh_low,
07318     2,
07319     pbuffer +   3);
07320   *(pbuffer +   5) =
07321     pdata->system__enable_xtalk_per_quadrant & 0x1;
07322   *(pbuffer +   6) =
07323     pdata->system__seed_config & 0x7;
07324   *(pbuffer +   7) =
07325     pdata->sd_config__woi_sd0;
07326   *(pbuffer +   8) =
07327     pdata->sd_config__woi_sd1;
07328   *(pbuffer +   9) =
07329     pdata->sd_config__initial_phase_sd0 & 0x7F;
07330   *(pbuffer +  10) =
07331     pdata->sd_config__initial_phase_sd1 & 0x7F;
07332   *(pbuffer +  11) =
07333     pdata->system__grouped_parameter_hold_1 & 0x3;
07334   *(pbuffer +  12) =
07335     pdata->sd_config__first_order_select & 0x3;
07336   *(pbuffer +  13) =
07337     pdata->sd_config__quantifier & 0xF;
07338   *(pbuffer +  14) =
07339     pdata->roi_config__user_roi_centre_spad;
07340   *(pbuffer +  15) =
07341     pdata->roi_config__user_roi_requested_global_xy_size;
07342   *(pbuffer +  16) =
07343     pdata->system__sequence_config;
07344   *(pbuffer +  17) =
07345     pdata->system__grouped_parameter_hold & 0x3;
07346 
07347   return status;
07348 }
07349 
07350 VL53LX_Error VL53LX::VL53LX_i2c_decode_dynamic_config(
07351   uint16_t                   buf_size,
07352   uint8_t                   *pbuffer,
07353   VL53LX_dynamic_config_t   *pdata)
07354 {
07355 
07356 
07357   VL53LX_Error status = VL53LX_ERROR_NONE;
07358 
07359 
07360   if (buf_size < VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES) {
07361     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07362   }
07363 
07364   pdata->system__grouped_parameter_hold_0 =
07365     (*(pbuffer +   0)) & 0x3;
07366   pdata->system__thresh_high =
07367     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   1));
07368   pdata->system__thresh_low =
07369     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   3));
07370   pdata->system__enable_xtalk_per_quadrant =
07371     (*(pbuffer +   5)) & 0x1;
07372   pdata->system__seed_config =
07373     (*(pbuffer +   6)) & 0x7;
07374   pdata->sd_config__woi_sd0 =
07375     (*(pbuffer +   7));
07376   pdata->sd_config__woi_sd1 =
07377     (*(pbuffer +   8));
07378   pdata->sd_config__initial_phase_sd0 =
07379     (*(pbuffer +   9)) & 0x7F;
07380   pdata->sd_config__initial_phase_sd1 =
07381     (*(pbuffer +  10)) & 0x7F;
07382   pdata->system__grouped_parameter_hold_1 =
07383     (*(pbuffer +  11)) & 0x3;
07384   pdata->sd_config__first_order_select =
07385     (*(pbuffer +  12)) & 0x3;
07386   pdata->sd_config__quantifier =
07387     (*(pbuffer +  13)) & 0xF;
07388   pdata->roi_config__user_roi_centre_spad =
07389     (*(pbuffer +  14));
07390   pdata->roi_config__user_roi_requested_global_xy_size =
07391     (*(pbuffer +  15));
07392   pdata->system__sequence_config =
07393     (*(pbuffer +  16));
07394   pdata->system__grouped_parameter_hold =
07395     (*(pbuffer +  17)) & 0x3;
07396 
07397   return status;
07398 }
07399 
07400 VL53LX_Error VL53LX::VL53LX_set_dynamic_config(
07401   VL53LX_dynamic_config_t   *pdata)
07402 {
07403 
07404 
07405   VL53LX_Error status = VL53LX_ERROR_NONE;
07406   uint8_t comms_buffer[VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES];
07407 
07408 
07409   if (status == VL53LX_ERROR_NONE)
07410     status = VL53LX_i2c_encode_dynamic_config(
07411                pdata,
07412                VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES,
07413                comms_buffer);
07414 
07415   if (status == VL53LX_ERROR_NONE)
07416     status = VL53LX_WriteMulti(
07417                Dev,
07418                VL53LX_SYSTEM__GROUPED_PARAMETER_HOLD_0,
07419                comms_buffer,
07420                VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES);
07421 
07422   return status;
07423 }
07424 
07425 
07426 VL53LX_Error VL53LX::VL53LX_get_dynamic_config(
07427   VL53LX_dynamic_config_t   *pdata)
07428 {
07429 
07430 
07431   VL53LX_Error status = VL53LX_ERROR_NONE;
07432   uint8_t comms_buffer[VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES];
07433 
07434   if (status == VL53LX_ERROR_NONE)
07435     status = VL53LX_ReadMulti(
07436                Dev,
07437                VL53LX_SYSTEM__GROUPED_PARAMETER_HOLD_0,
07438                comms_buffer,
07439                VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES);
07440 
07441   if (status == VL53LX_ERROR_NONE)
07442     status = VL53LX_i2c_decode_dynamic_config(
07443                VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES,
07444                comms_buffer,
07445                pdata);
07446 
07447   return status;
07448 }
07449 
07450 VL53LX_Error VL53LX::VL53LX_i2c_encode_system_control(
07451   VL53LX_system_control_t  *pdata,
07452   uint16_t                  buf_size,
07453   uint8_t                  *pbuffer)
07454 {
07455 
07456 
07457   VL53LX_Error status = VL53LX_ERROR_NONE;
07458 
07459 
07460   if (buf_size < VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES) {
07461     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07462   }
07463 
07464   *(pbuffer +   0) =
07465     pdata->power_management__go1_power_force & 0x1;
07466   *(pbuffer +   1) =
07467     pdata->system__stream_count_ctrl & 0x1;
07468   *(pbuffer +   2) =
07469     pdata->firmware__enable & 0x1;
07470   *(pbuffer +   3) =
07471     pdata->system__interrupt_clear & 0x3;
07472   *(pbuffer +   4) =
07473     pdata->system__mode_start;
07474 
07475   return status;
07476 }
07477 
07478 VL53LX_Error VL53LX::VL53LX_i2c_decode_system_control(
07479   uint16_t                   buf_size,
07480   uint8_t                   *pbuffer,
07481   VL53LX_system_control_t   *pdata)
07482 {
07483 
07484 
07485   VL53LX_Error status = VL53LX_ERROR_NONE;
07486 
07487   if (buf_size < VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES) {
07488     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07489   }
07490 
07491   pdata->power_management__go1_power_force =
07492     (*(pbuffer +   0)) & 0x1;
07493   pdata->system__stream_count_ctrl =
07494     (*(pbuffer +   1)) & 0x1;
07495   pdata->firmware__enable =
07496     (*(pbuffer +   2)) & 0x1;
07497   pdata->system__interrupt_clear =
07498     (*(pbuffer +   3)) & 0x3;
07499   pdata->system__mode_start =
07500     (*(pbuffer +   4));
07501 
07502 
07503   return status;
07504 }
07505 
07506 
07507 VL53LX_Error VL53LX::VL53LX_set_system_control(
07508   VL53LX_system_control_t   *pdata)
07509 {
07510 
07511 
07512   VL53LX_Error status = VL53LX_ERROR_NONE;
07513   uint8_t comms_buffer[VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES];
07514 
07515   if (status == VL53LX_ERROR_NONE)
07516     status = VL53LX_i2c_encode_system_control(
07517                pdata,
07518                VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES,
07519                comms_buffer);
07520 
07521   if (status == VL53LX_ERROR_NONE)
07522     status = VL53LX_WriteMulti(
07523                Dev,
07524                VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE,
07525                comms_buffer,
07526                VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES);
07527 
07528   return status;
07529 }
07530 
07531 
07532 VL53LX_Error VL53LX::VL53LX_get_system_control(
07533   VL53LX_system_control_t   *pdata)
07534 {
07535 
07536 
07537   VL53LX_Error status = VL53LX_ERROR_NONE;
07538   uint8_t comms_buffer[VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES];
07539 
07540 
07541   if (status == VL53LX_ERROR_NONE)
07542     status = VL53LX_ReadMulti(
07543                Dev,
07544                VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE,
07545                comms_buffer,
07546                VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES);
07547 
07548   if (status == VL53LX_ERROR_NONE)
07549     status = VL53LX_i2c_decode_system_control(
07550                VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES,
07551                comms_buffer,
07552                pdata);
07553 
07554   return status;
07555 }
07556 
07557 
07558 VL53LX_Error VL53LX::VL53LX_i2c_encode_system_results(
07559   VL53LX_system_results_t  *pdata,
07560   uint16_t                  buf_size,
07561   uint8_t                  *pbuffer)
07562 {
07563 
07564 
07565   VL53LX_Error status = VL53LX_ERROR_NONE;
07566 
07567 
07568   if (buf_size < VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES) {
07569     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07570   }
07571 
07572   *(pbuffer +   0) =
07573     pdata->result__interrupt_status & 0x3F;
07574   *(pbuffer +   1) =
07575     pdata->result__range_status;
07576   *(pbuffer +   2) =
07577     pdata->result__report_status & 0xF;
07578   *(pbuffer +   3) =
07579     pdata->result__stream_count;
07580   VL53LX_i2c_encode_uint16_t(
07581     pdata->result__dss_actual_effective_spads_sd0,
07582     2,
07583     pbuffer +   4);
07584   VL53LX_i2c_encode_uint16_t(
07585     pdata->result__peak_signal_count_rate_mcps_sd0,
07586     2,
07587     pbuffer +   6);
07588   VL53LX_i2c_encode_uint16_t(
07589     pdata->result__ambient_count_rate_mcps_sd0,
07590     2,
07591     pbuffer +   8);
07592   VL53LX_i2c_encode_uint16_t(
07593     pdata->result__sigma_sd0,
07594     2,
07595     pbuffer +  10);
07596   VL53LX_i2c_encode_uint16_t(
07597     pdata->result__phase_sd0,
07598     2,
07599     pbuffer +  12);
07600   VL53LX_i2c_encode_uint16_t(
07601     pdata->result__final_crosstalk_corrected_range_mm_sd0,
07602     2,
07603     pbuffer +  14);
07604   VL53LX_i2c_encode_uint16_t(
07605     pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0,
07606     2,
07607     pbuffer +  16);
07608   VL53LX_i2c_encode_uint16_t(
07609     pdata->result__mm_inner_actual_effective_spads_sd0,
07610     2,
07611     pbuffer +  18);
07612   VL53LX_i2c_encode_uint16_t(
07613     pdata->result__mm_outer_actual_effective_spads_sd0,
07614     2,
07615     pbuffer +  20);
07616   VL53LX_i2c_encode_uint16_t(
07617     pdata->result__avg_signal_count_rate_mcps_sd0,
07618     2,
07619     pbuffer +  22);
07620   VL53LX_i2c_encode_uint16_t(
07621     pdata->result__dss_actual_effective_spads_sd1,
07622     2,
07623     pbuffer +  24);
07624   VL53LX_i2c_encode_uint16_t(
07625     pdata->result__peak_signal_count_rate_mcps_sd1,
07626     2,
07627     pbuffer +  26);
07628   VL53LX_i2c_encode_uint16_t(
07629     pdata->result__ambient_count_rate_mcps_sd1,
07630     2,
07631     pbuffer +  28);
07632   VL53LX_i2c_encode_uint16_t(
07633     pdata->result__sigma_sd1,
07634     2,
07635     pbuffer +  30);
07636   VL53LX_i2c_encode_uint16_t(
07637     pdata->result__phase_sd1,
07638     2,
07639     pbuffer +  32);
07640   VL53LX_i2c_encode_uint16_t(
07641     pdata->result__final_crosstalk_corrected_range_mm_sd1,
07642     2,
07643     pbuffer +  34);
07644   VL53LX_i2c_encode_uint16_t(
07645     pdata->result__spare_0_sd1,
07646     2,
07647     pbuffer +  36);
07648   VL53LX_i2c_encode_uint16_t(
07649     pdata->result__spare_1_sd1,
07650     2,
07651     pbuffer +  38);
07652   VL53LX_i2c_encode_uint16_t(
07653     pdata->result__spare_2_sd1,
07654     2,
07655     pbuffer +  40);
07656   *(pbuffer +  42) =
07657     pdata->result__spare_3_sd1;
07658   *(pbuffer +  43) =
07659     pdata->result__thresh_info;
07660 
07661   return status;
07662 }
07663 
07664 VL53LX_Error VL53LX::VL53LX_i2c_decode_system_results(
07665   uint16_t                   buf_size,
07666   uint8_t                   *pbuffer,
07667   VL53LX_system_results_t   *pdata)
07668 {
07669 
07670 
07671   VL53LX_Error status = VL53LX_ERROR_NONE;
07672 
07673   if (buf_size < VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES) {
07674     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07675   }
07676 
07677   pdata->result__interrupt_status =
07678     (*(pbuffer +   0)) & 0x3F;
07679   pdata->result__range_status =
07680     (*(pbuffer +   1));
07681   pdata->result__report_status =
07682     (*(pbuffer +   2)) & 0xF;
07683   pdata->result__stream_count =
07684     (*(pbuffer +   3));
07685   pdata->result__dss_actual_effective_spads_sd0 =
07686     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   4));
07687   pdata->result__peak_signal_count_rate_mcps_sd0 =
07688     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   6));
07689   pdata->result__ambient_count_rate_mcps_sd0 =
07690     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   8));
07691   pdata->result__sigma_sd0 =
07692     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  10));
07693   pdata->result__phase_sd0 =
07694     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  12));
07695   pdata->result__final_crosstalk_corrected_range_mm_sd0 =
07696     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  14));
07697   pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 =
07698     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  16));
07699   pdata->result__mm_inner_actual_effective_spads_sd0 =
07700     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  18));
07701   pdata->result__mm_outer_actual_effective_spads_sd0 =
07702     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  20));
07703   pdata->result__avg_signal_count_rate_mcps_sd0 =
07704     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  22));
07705   pdata->result__dss_actual_effective_spads_sd1 =
07706     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  24));
07707   pdata->result__peak_signal_count_rate_mcps_sd1 =
07708     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  26));
07709   pdata->result__ambient_count_rate_mcps_sd1 =
07710     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  28));
07711   pdata->result__sigma_sd1 =
07712     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  30));
07713   pdata->result__phase_sd1 =
07714     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  32));
07715   pdata->result__final_crosstalk_corrected_range_mm_sd1 =
07716     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  34));
07717   pdata->result__spare_0_sd1 =
07718     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  36));
07719   pdata->result__spare_1_sd1 =
07720     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  38));
07721   pdata->result__spare_2_sd1 =
07722     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  40));
07723   pdata->result__spare_3_sd1 =
07724     (*(pbuffer +  42));
07725   pdata->result__thresh_info =
07726     (*(pbuffer +  43));
07727 
07728   return status;
07729 }
07730 VL53LX_Error VL53LX::VL53LX_set_system_results(
07731   VL53LX_system_results_t   *pdata)
07732 {
07733 
07734 
07735   VL53LX_Error status = VL53LX_ERROR_NONE;
07736   uint8_t comms_buffer[VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES];
07737 
07738 
07739   if (status == VL53LX_ERROR_NONE)
07740     status = VL53LX_i2c_encode_system_results(
07741                pdata,
07742                VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES,
07743                comms_buffer);
07744 
07745   if (status == VL53LX_ERROR_NONE)
07746     status = VL53LX_WriteMulti(
07747                Dev,
07748                VL53LX_RESULT__INTERRUPT_STATUS,
07749                comms_buffer,
07750                VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES);
07751 
07752 
07753   return status;
07754 }
07755 
07756 VL53LX_Error VL53LX::VL53LX_get_system_results(
07757   VL53LX_system_results_t   *pdata)
07758 {
07759 
07760 
07761   VL53LX_Error status = VL53LX_ERROR_NONE;
07762   uint8_t comms_buffer[VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES];
07763 
07764   if (status == VL53LX_ERROR_NONE)
07765     status = VL53LX_ReadMulti(
07766                Dev,
07767                VL53LX_RESULT__INTERRUPT_STATUS,
07768                comms_buffer,
07769                VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES);
07770 
07771   if (status == VL53LX_ERROR_NONE)
07772     status = VL53LX_i2c_decode_system_results(
07773                VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES,
07774                comms_buffer,
07775                pdata);
07776 
07777 
07778   return status;
07779 }
07780 VL53LX_Error VL53LX::VL53LX_i2c_encode_core_results(
07781   VL53LX_core_results_t    *pdata,
07782   uint16_t                  buf_size,
07783   uint8_t                  *pbuffer)
07784 {
07785 
07786 
07787   VL53LX_Error status = VL53LX_ERROR_NONE;
07788 
07789   if (buf_size < VL53LX_CORE_RESULTS_I2C_SIZE_BYTES) {
07790     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07791   }
07792 
07793   VL53LX_i2c_encode_uint32_t(
07794     pdata->result_core__ambient_window_events_sd0,
07795     4,
07796     pbuffer +   0);
07797   VL53LX_i2c_encode_uint32_t(
07798     pdata->result_core__ranging_total_events_sd0,
07799     4,
07800     pbuffer +   4);
07801   VL53LX_i2c_encode_int32_t(
07802     pdata->result_core__signal_total_events_sd0,
07803     4,
07804     pbuffer +   8);
07805   VL53LX_i2c_encode_uint32_t(
07806     pdata->result_core__total_periods_elapsed_sd0,
07807     4,
07808     pbuffer +  12);
07809   VL53LX_i2c_encode_uint32_t(
07810     pdata->result_core__ambient_window_events_sd1,
07811     4,
07812     pbuffer +  16);
07813   VL53LX_i2c_encode_uint32_t(
07814     pdata->result_core__ranging_total_events_sd1,
07815     4,
07816     pbuffer +  20);
07817   VL53LX_i2c_encode_int32_t(
07818     pdata->result_core__signal_total_events_sd1,
07819     4,
07820     pbuffer +  24);
07821   VL53LX_i2c_encode_uint32_t(
07822     pdata->result_core__total_periods_elapsed_sd1,
07823     4,
07824     pbuffer +  28);
07825   *(pbuffer +  32) =
07826     pdata->result_core__spare_0;
07827 
07828   return status;
07829 }
07830 
07831 
07832 VL53LX_Error VL53LX::VL53LX_i2c_decode_core_results(
07833   uint16_t                   buf_size,
07834   uint8_t                   *pbuffer,
07835   VL53LX_core_results_t     *pdata)
07836 {
07837 
07838 
07839   VL53LX_Error status = VL53LX_ERROR_NONE;
07840 
07841 
07842   if (buf_size < VL53LX_CORE_RESULTS_I2C_SIZE_BYTES) {
07843     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07844   }
07845 
07846   pdata->result_core__ambient_window_events_sd0 =
07847     (VL53LX_i2c_decode_uint32_t(4, pbuffer +   0));
07848   pdata->result_core__ranging_total_events_sd0 =
07849     (VL53LX_i2c_decode_uint32_t(4, pbuffer +   4));
07850   pdata->result_core__signal_total_events_sd0 =
07851     (VL53LX_i2c_decode_int32_t(4, pbuffer +   8));
07852   pdata->result_core__total_periods_elapsed_sd0 =
07853     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  12));
07854   pdata->result_core__ambient_window_events_sd1 =
07855     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  16));
07856   pdata->result_core__ranging_total_events_sd1 =
07857     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  20));
07858   pdata->result_core__signal_total_events_sd1 =
07859     (VL53LX_i2c_decode_int32_t(4, pbuffer +  24));
07860   pdata->result_core__total_periods_elapsed_sd1 =
07861     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  28));
07862   pdata->result_core__spare_0 =
07863     (*(pbuffer +  32));
07864   return status;
07865 }
07866 
07867 VL53LX_Error VL53LX::VL53LX_set_core_results(
07868   VL53LX_core_results_t     *pdata)
07869 {
07870 
07871 
07872   VL53LX_Error status = VL53LX_ERROR_NONE;
07873   uint8_t comms_buffer[VL53LX_CORE_RESULTS_I2C_SIZE_BYTES];
07874 
07875 
07876   if (status == VL53LX_ERROR_NONE)
07877     status = VL53LX_i2c_encode_core_results(
07878                pdata,
07879                VL53LX_CORE_RESULTS_I2C_SIZE_BYTES,
07880                comms_buffer);
07881 
07882   if (status == VL53LX_ERROR_NONE) {
07883     status = VL53LX_disable_firmware();
07884   }
07885 
07886   if (status == VL53LX_ERROR_NONE)
07887     status = VL53LX_WriteMulti(
07888                Dev,
07889                VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0,
07890                comms_buffer,
07891                VL53LX_CORE_RESULTS_I2C_SIZE_BYTES);
07892 
07893   if (status == VL53LX_ERROR_NONE) {
07894     status = VL53LX_enable_firmware();
07895   }
07896 
07897   return status;
07898 }
07899 
07900 
07901 VL53LX_Error VL53LX::VL53LX_get_core_results(
07902   VL53LX_core_results_t     *pdata)
07903 {
07904 
07905 
07906   VL53LX_Error status = VL53LX_ERROR_NONE;
07907   uint8_t comms_buffer[VL53LX_CORE_RESULTS_I2C_SIZE_BYTES];
07908 
07909   if (status == VL53LX_ERROR_NONE)
07910     status = VL53LX_ReadMulti(
07911                Dev,
07912                VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0,
07913                comms_buffer,
07914                VL53LX_CORE_RESULTS_I2C_SIZE_BYTES);
07915 
07916   if (status == VL53LX_ERROR_NONE)
07917     status = VL53LX_i2c_decode_core_results(
07918                VL53LX_CORE_RESULTS_I2C_SIZE_BYTES,
07919                comms_buffer,
07920                pdata);
07921 
07922 
07923   return status;
07924 }
07925 VL53LX_Error VL53LX::VL53LX_i2c_encode_debug_results(
07926   VL53LX_debug_results_t   *pdata,
07927   uint16_t                  buf_size,
07928   uint8_t                  *pbuffer)
07929 {
07930 
07931 
07932   VL53LX_Error status = VL53LX_ERROR_NONE;
07933 
07934 
07935   if (buf_size < VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES) {
07936     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
07937   }
07938 
07939   VL53LX_i2c_encode_uint16_t(
07940     pdata->phasecal_result__reference_phase,
07941     2,
07942     pbuffer +   0);
07943   *(pbuffer +   2) =
07944     pdata->phasecal_result__vcsel_start & 0x7F;
07945   *(pbuffer +   3) =
07946     pdata->ref_spad_char_result__num_actual_ref_spads & 0x3F;
07947   *(pbuffer +   4) =
07948     pdata->ref_spad_char_result__ref_location & 0x3;
07949   *(pbuffer +   5) =
07950     pdata->vhv_result__coldboot_status & 0x1;
07951   *(pbuffer +   6) =
07952     pdata->vhv_result__search_result & 0x3F;
07953   *(pbuffer +   7) =
07954     pdata->vhv_result__latest_setting & 0x3F;
07955   VL53LX_i2c_encode_uint16_t(
07956     pdata->result__osc_calibrate_val & 0x3FF,
07957     2,
07958     pbuffer +   8);
07959   *(pbuffer +  10) =
07960     pdata->ana_config__powerdown_go1 & 0x3;
07961   *(pbuffer +  11) =
07962     pdata->ana_config__ref_bg_ctrl & 0x3;
07963   *(pbuffer +  12) =
07964     pdata->ana_config__regdvdd1v2_ctrl & 0xF;
07965   *(pbuffer +  13) =
07966     pdata->ana_config__osc_slow_ctrl & 0x7;
07967   *(pbuffer +  14) =
07968     pdata->test_mode__status & 0x1;
07969   *(pbuffer +  15) =
07970     pdata->firmware__system_status & 0x3;
07971   *(pbuffer +  16) =
07972     pdata->firmware__mode_status;
07973   *(pbuffer +  17) =
07974     pdata->firmware__secondary_mode_status;
07975   VL53LX_i2c_encode_uint16_t(
07976     pdata->firmware__cal_repeat_rate_counter & 0xFFF,
07977     2,
07978     pbuffer +  18);
07979   VL53LX_i2c_encode_uint16_t(
07980     pdata->gph__system__thresh_high,
07981     2,
07982     pbuffer +  22);
07983   VL53LX_i2c_encode_uint16_t(
07984     pdata->gph__system__thresh_low,
07985     2,
07986     pbuffer +  24);
07987   *(pbuffer +  26) =
07988     pdata->gph__system__enable_xtalk_per_quadrant & 0x1;
07989   *(pbuffer +  27) =
07990     pdata->gph__spare_0 & 0x7;
07991   *(pbuffer +  28) =
07992     pdata->gph__sd_config__woi_sd0;
07993   *(pbuffer +  29) =
07994     pdata->gph__sd_config__woi_sd1;
07995   *(pbuffer +  30) =
07996     pdata->gph__sd_config__initial_phase_sd0 & 0x7F;
07997   *(pbuffer +  31) =
07998     pdata->gph__sd_config__initial_phase_sd1 & 0x7F;
07999   *(pbuffer +  32) =
08000     pdata->gph__sd_config__first_order_select & 0x3;
08001   *(pbuffer +  33) =
08002     pdata->gph__sd_config__quantifier & 0xF;
08003   *(pbuffer +  34) =
08004     pdata->gph__roi_config__user_roi_centre_spad;
08005   *(pbuffer +  35) =
08006     pdata->gph__roi_config__user_roi_requested_global_xy_size;
08007   *(pbuffer +  36) =
08008     pdata->gph__system__sequence_config;
08009   *(pbuffer +  37) =
08010     pdata->gph__gph_id & 0x1;
08011   *(pbuffer +  38) =
08012     pdata->system__interrupt_set & 0x3;
08013   *(pbuffer +  39) =
08014     pdata->interrupt_manager__enables & 0x1F;
08015   *(pbuffer +  40) =
08016     pdata->interrupt_manager__clear & 0x1F;
08017   *(pbuffer +  41) =
08018     pdata->interrupt_manager__status & 0x1F;
08019   *(pbuffer +  42) =
08020     pdata->mcu_to_host_bank__wr_access_en & 0x1;
08021   *(pbuffer +  43) =
08022     pdata->power_management__go1_reset_status & 0x1;
08023   *(pbuffer +  44) =
08024     pdata->pad_startup_mode__value_ro & 0x3;
08025   *(pbuffer +  45) =
08026     pdata->pad_startup_mode__value_ctrl & 0x3F;
08027   VL53LX_i2c_encode_uint32_t(
08028     pdata->pll_period_us & 0x3FFFF,
08029     4,
08030     pbuffer +  46);
08031   VL53LX_i2c_encode_uint32_t(
08032     pdata->interrupt_scheduler__data_out,
08033     4,
08034     pbuffer +  50);
08035   *(pbuffer +  54) =
08036     pdata->nvm_bist__complete & 0x1;
08037   *(pbuffer +  55) =
08038     pdata->nvm_bist__status & 0x1;
08039 
08040   return status;
08041 }
08042 
08043 VL53LX_Error VL53LX::VL53LX_i2c_decode_debug_results(
08044   uint16_t                   buf_size,
08045   uint8_t                   *pbuffer,
08046   VL53LX_debug_results_t    *pdata)
08047 {
08048 
08049 
08050   VL53LX_Error status = VL53LX_ERROR_NONE;
08051 
08052 
08053   if (buf_size < VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES) {
08054     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08055   }
08056 
08057   pdata->phasecal_result__reference_phase =
08058     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   0));
08059   pdata->phasecal_result__vcsel_start =
08060     (*(pbuffer +   2)) & 0x7F;
08061   pdata->ref_spad_char_result__num_actual_ref_spads =
08062     (*(pbuffer +   3)) & 0x3F;
08063   pdata->ref_spad_char_result__ref_location =
08064     (*(pbuffer +   4)) & 0x3;
08065   pdata->vhv_result__coldboot_status =
08066     (*(pbuffer +   5)) & 0x1;
08067   pdata->vhv_result__search_result =
08068     (*(pbuffer +   6)) & 0x3F;
08069   pdata->vhv_result__latest_setting =
08070     (*(pbuffer +   7)) & 0x3F;
08071   pdata->result__osc_calibrate_val =
08072     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   8)) & 0x3FF;
08073   pdata->ana_config__powerdown_go1 =
08074     (*(pbuffer +  10)) & 0x3;
08075   pdata->ana_config__ref_bg_ctrl =
08076     (*(pbuffer +  11)) & 0x3;
08077   pdata->ana_config__regdvdd1v2_ctrl =
08078     (*(pbuffer +  12)) & 0xF;
08079   pdata->ana_config__osc_slow_ctrl =
08080     (*(pbuffer +  13)) & 0x7;
08081   pdata->test_mode__status =
08082     (*(pbuffer +  14)) & 0x1;
08083   pdata->firmware__system_status =
08084     (*(pbuffer +  15)) & 0x3;
08085   pdata->firmware__mode_status =
08086     (*(pbuffer +  16));
08087   pdata->firmware__secondary_mode_status =
08088     (*(pbuffer +  17));
08089   pdata->firmware__cal_repeat_rate_counter =
08090     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  18)) & 0xFFF;
08091   pdata->gph__system__thresh_high =
08092     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  22));
08093   pdata->gph__system__thresh_low =
08094     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  24));
08095   pdata->gph__system__enable_xtalk_per_quadrant =
08096     (*(pbuffer +  26)) & 0x1;
08097   pdata->gph__spare_0 =
08098     (*(pbuffer +  27)) & 0x7;
08099   pdata->gph__sd_config__woi_sd0 =
08100     (*(pbuffer +  28));
08101   pdata->gph__sd_config__woi_sd1 =
08102     (*(pbuffer +  29));
08103   pdata->gph__sd_config__initial_phase_sd0 =
08104     (*(pbuffer +  30)) & 0x7F;
08105   pdata->gph__sd_config__initial_phase_sd1 =
08106     (*(pbuffer +  31)) & 0x7F;
08107   pdata->gph__sd_config__first_order_select =
08108     (*(pbuffer +  32)) & 0x3;
08109   pdata->gph__sd_config__quantifier =
08110     (*(pbuffer +  33)) & 0xF;
08111   pdata->gph__roi_config__user_roi_centre_spad =
08112     (*(pbuffer +  34));
08113   pdata->gph__roi_config__user_roi_requested_global_xy_size =
08114     (*(pbuffer +  35));
08115   pdata->gph__system__sequence_config =
08116     (*(pbuffer +  36));
08117   pdata->gph__gph_id =
08118     (*(pbuffer +  37)) & 0x1;
08119   pdata->system__interrupt_set =
08120     (*(pbuffer +  38)) & 0x3;
08121   pdata->interrupt_manager__enables =
08122     (*(pbuffer +  39)) & 0x1F;
08123   pdata->interrupt_manager__clear =
08124     (*(pbuffer +  40)) & 0x1F;
08125   pdata->interrupt_manager__status =
08126     (*(pbuffer +  41)) & 0x1F;
08127   pdata->mcu_to_host_bank__wr_access_en =
08128     (*(pbuffer +  42)) & 0x1;
08129   pdata->power_management__go1_reset_status =
08130     (*(pbuffer +  43)) & 0x1;
08131   pdata->pad_startup_mode__value_ro =
08132     (*(pbuffer +  44)) & 0x3;
08133   pdata->pad_startup_mode__value_ctrl =
08134     (*(pbuffer +  45)) & 0x3F;
08135   pdata->pll_period_us =
08136     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  46)) & 0x3FFFF;
08137   pdata->interrupt_scheduler__data_out =
08138     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  50));
08139   pdata->nvm_bist__complete =
08140     (*(pbuffer +  54)) & 0x1;
08141   pdata->nvm_bist__status =
08142     (*(pbuffer +  55)) & 0x1;
08143 
08144 
08145   return status;
08146 }
08147 
08148 VL53LX_Error VL53LX::VL53LX_set_debug_results(
08149   VL53LX_debug_results_t    *pdata)
08150 {
08151 
08152 
08153   VL53LX_Error status = VL53LX_ERROR_NONE;
08154   uint8_t comms_buffer[VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES];
08155 
08156   if (status == VL53LX_ERROR_NONE)
08157     status = VL53LX_i2c_encode_debug_results(
08158                pdata,
08159                VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES,
08160                comms_buffer);
08161 
08162   if (status == VL53LX_ERROR_NONE) {
08163     status = VL53LX_disable_firmware();
08164   }
08165 
08166   if (status == VL53LX_ERROR_NONE)
08167     status = VL53LX_WriteMulti(
08168                Dev,
08169                VL53LX_PHASECAL_RESULT__REFERENCE_PHASE,
08170                comms_buffer,
08171                VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES);
08172 
08173   if (status == VL53LX_ERROR_NONE) {
08174     status = VL53LX_enable_firmware();
08175   }
08176 
08177 
08178   return status;
08179 }
08180 
08181 VL53LX_Error VL53LX::VL53LX_get_debug_results(
08182   VL53LX_debug_results_t    *pdata)
08183 {
08184 
08185 
08186   VL53LX_Error status = VL53LX_ERROR_NONE;
08187   uint8_t comms_buffer[VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES];
08188 
08189 
08190   if (status == VL53LX_ERROR_NONE)
08191     status = VL53LX_ReadMulti(
08192                Dev,
08193                VL53LX_PHASECAL_RESULT__REFERENCE_PHASE,
08194                comms_buffer,
08195                VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES);
08196 
08197   if (status == VL53LX_ERROR_NONE)
08198     status = VL53LX_i2c_decode_debug_results(
08199                VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES,
08200                comms_buffer,
08201                pdata);
08202 
08203   return status;
08204 }
08205 VL53LX_Error VL53LX::VL53LX_i2c_encode_nvm_copy_data(
08206   VL53LX_nvm_copy_data_t   *pdata,
08207   uint16_t                  buf_size,
08208   uint8_t                  *pbuffer)
08209 {
08210 
08211 
08212   VL53LX_Error status = VL53LX_ERROR_NONE;
08213 
08214 
08215   if (buf_size < VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES) {
08216     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08217   }
08218 
08219   *(pbuffer +   0) =
08220     pdata->identification__model_id;
08221   *(pbuffer +   1) =
08222     pdata->identification__module_type;
08223   *(pbuffer +   2) =
08224     pdata->identification__revision_id;
08225   VL53LX_i2c_encode_uint16_t(
08226     pdata->identification__module_id,
08227     2,
08228     pbuffer +   3);
08229   *(pbuffer +   5) =
08230     pdata->ana_config__fast_osc__trim_max & 0x7F;
08231   *(pbuffer +   6) =
08232     pdata->ana_config__fast_osc__freq_set & 0x7;
08233   *(pbuffer +   7) =
08234     pdata->ana_config__vcsel_trim & 0x7;
08235   *(pbuffer +   8) =
08236     pdata->ana_config__vcsel_selion & 0x3F;
08237   *(pbuffer +   9) =
08238     pdata->ana_config__vcsel_selion_max & 0x3F;
08239   *(pbuffer +  10) =
08240     pdata->protected_laser_safety__lock_bit & 0x1;
08241   *(pbuffer +  11) =
08242     pdata->laser_safety__key & 0x7F;
08243   *(pbuffer +  12) =
08244     pdata->laser_safety__key_ro & 0x1;
08245   *(pbuffer +  13) =
08246     pdata->laser_safety__clip & 0x3F;
08247   *(pbuffer +  14) =
08248     pdata->laser_safety__mult & 0x3F;
08249   *(pbuffer +  15) =
08250     pdata->global_config__spad_enables_rtn_0;
08251   *(pbuffer +  16) =
08252     pdata->global_config__spad_enables_rtn_1;
08253   *(pbuffer +  17) =
08254     pdata->global_config__spad_enables_rtn_2;
08255   *(pbuffer +  18) =
08256     pdata->global_config__spad_enables_rtn_3;
08257   *(pbuffer +  19) =
08258     pdata->global_config__spad_enables_rtn_4;
08259   *(pbuffer +  20) =
08260     pdata->global_config__spad_enables_rtn_5;
08261   *(pbuffer +  21) =
08262     pdata->global_config__spad_enables_rtn_6;
08263   *(pbuffer +  22) =
08264     pdata->global_config__spad_enables_rtn_7;
08265   *(pbuffer +  23) =
08266     pdata->global_config__spad_enables_rtn_8;
08267   *(pbuffer +  24) =
08268     pdata->global_config__spad_enables_rtn_9;
08269   *(pbuffer +  25) =
08270     pdata->global_config__spad_enables_rtn_10;
08271   *(pbuffer +  26) =
08272     pdata->global_config__spad_enables_rtn_11;
08273   *(pbuffer +  27) =
08274     pdata->global_config__spad_enables_rtn_12;
08275   *(pbuffer +  28) =
08276     pdata->global_config__spad_enables_rtn_13;
08277   *(pbuffer +  29) =
08278     pdata->global_config__spad_enables_rtn_14;
08279   *(pbuffer +  30) =
08280     pdata->global_config__spad_enables_rtn_15;
08281   *(pbuffer +  31) =
08282     pdata->global_config__spad_enables_rtn_16;
08283   *(pbuffer +  32) =
08284     pdata->global_config__spad_enables_rtn_17;
08285   *(pbuffer +  33) =
08286     pdata->global_config__spad_enables_rtn_18;
08287   *(pbuffer +  34) =
08288     pdata->global_config__spad_enables_rtn_19;
08289   *(pbuffer +  35) =
08290     pdata->global_config__spad_enables_rtn_20;
08291   *(pbuffer +  36) =
08292     pdata->global_config__spad_enables_rtn_21;
08293   *(pbuffer +  37) =
08294     pdata->global_config__spad_enables_rtn_22;
08295   *(pbuffer +  38) =
08296     pdata->global_config__spad_enables_rtn_23;
08297   *(pbuffer +  39) =
08298     pdata->global_config__spad_enables_rtn_24;
08299   *(pbuffer +  40) =
08300     pdata->global_config__spad_enables_rtn_25;
08301   *(pbuffer +  41) =
08302     pdata->global_config__spad_enables_rtn_26;
08303   *(pbuffer +  42) =
08304     pdata->global_config__spad_enables_rtn_27;
08305   *(pbuffer +  43) =
08306     pdata->global_config__spad_enables_rtn_28;
08307   *(pbuffer +  44) =
08308     pdata->global_config__spad_enables_rtn_29;
08309   *(pbuffer +  45) =
08310     pdata->global_config__spad_enables_rtn_30;
08311   *(pbuffer +  46) =
08312     pdata->global_config__spad_enables_rtn_31;
08313   *(pbuffer +  47) =
08314     pdata->roi_config__mode_roi_centre_spad;
08315   *(pbuffer +  48) =
08316     pdata->roi_config__mode_roi_xy_size;
08317 
08318 
08319   return status;
08320 }
08321 
08322 
08323 
08324 VL53LX_Error VL53LX::VL53LX_i2c_decode_nvm_copy_data(
08325   uint16_t                   buf_size,
08326   uint8_t                   *pbuffer,
08327   VL53LX_nvm_copy_data_t    *pdata)
08328 {
08329 
08330 
08331   VL53LX_Error status = VL53LX_ERROR_NONE;
08332 
08333 
08334   if (buf_size < VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES) {
08335     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08336   }
08337 
08338   pdata->identification__model_id =
08339     (*(pbuffer +   0));
08340   pdata->identification__module_type =
08341     (*(pbuffer +   1));
08342   pdata->identification__revision_id =
08343     (*(pbuffer +   2));
08344   pdata->identification__module_id =
08345     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   3));
08346   pdata->ana_config__fast_osc__trim_max =
08347     (*(pbuffer +   5)) & 0x7F;
08348   pdata->ana_config__fast_osc__freq_set =
08349     (*(pbuffer +   6)) & 0x7;
08350   pdata->ana_config__vcsel_trim =
08351     (*(pbuffer +   7)) & 0x7;
08352   pdata->ana_config__vcsel_selion =
08353     (*(pbuffer +   8)) & 0x3F;
08354   pdata->ana_config__vcsel_selion_max =
08355     (*(pbuffer +   9)) & 0x3F;
08356   pdata->protected_laser_safety__lock_bit =
08357     (*(pbuffer +  10)) & 0x1;
08358   pdata->laser_safety__key =
08359     (*(pbuffer +  11)) & 0x7F;
08360   pdata->laser_safety__key_ro =
08361     (*(pbuffer +  12)) & 0x1;
08362   pdata->laser_safety__clip =
08363     (*(pbuffer +  13)) & 0x3F;
08364   pdata->laser_safety__mult =
08365     (*(pbuffer +  14)) & 0x3F;
08366   pdata->global_config__spad_enables_rtn_0 =
08367     (*(pbuffer +  15));
08368   pdata->global_config__spad_enables_rtn_1 =
08369     (*(pbuffer +  16));
08370   pdata->global_config__spad_enables_rtn_2 =
08371     (*(pbuffer +  17));
08372   pdata->global_config__spad_enables_rtn_3 =
08373     (*(pbuffer +  18));
08374   pdata->global_config__spad_enables_rtn_4 =
08375     (*(pbuffer +  19));
08376   pdata->global_config__spad_enables_rtn_5 =
08377     (*(pbuffer +  20));
08378   pdata->global_config__spad_enables_rtn_6 =
08379     (*(pbuffer +  21));
08380   pdata->global_config__spad_enables_rtn_7 =
08381     (*(pbuffer +  22));
08382   pdata->global_config__spad_enables_rtn_8 =
08383     (*(pbuffer +  23));
08384   pdata->global_config__spad_enables_rtn_9 =
08385     (*(pbuffer +  24));
08386   pdata->global_config__spad_enables_rtn_10 =
08387     (*(pbuffer +  25));
08388   pdata->global_config__spad_enables_rtn_11 =
08389     (*(pbuffer +  26));
08390   pdata->global_config__spad_enables_rtn_12 =
08391     (*(pbuffer +  27));
08392   pdata->global_config__spad_enables_rtn_13 =
08393     (*(pbuffer +  28));
08394   pdata->global_config__spad_enables_rtn_14 =
08395     (*(pbuffer +  29));
08396   pdata->global_config__spad_enables_rtn_15 =
08397     (*(pbuffer +  30));
08398   pdata->global_config__spad_enables_rtn_16 =
08399     (*(pbuffer +  31));
08400   pdata->global_config__spad_enables_rtn_17 =
08401     (*(pbuffer +  32));
08402   pdata->global_config__spad_enables_rtn_18 =
08403     (*(pbuffer +  33));
08404   pdata->global_config__spad_enables_rtn_19 =
08405     (*(pbuffer +  34));
08406   pdata->global_config__spad_enables_rtn_20 =
08407     (*(pbuffer +  35));
08408   pdata->global_config__spad_enables_rtn_21 =
08409     (*(pbuffer +  36));
08410   pdata->global_config__spad_enables_rtn_22 =
08411     (*(pbuffer +  37));
08412   pdata->global_config__spad_enables_rtn_23 =
08413     (*(pbuffer +  38));
08414   pdata->global_config__spad_enables_rtn_24 =
08415     (*(pbuffer +  39));
08416   pdata->global_config__spad_enables_rtn_25 =
08417     (*(pbuffer +  40));
08418   pdata->global_config__spad_enables_rtn_26 =
08419     (*(pbuffer +  41));
08420   pdata->global_config__spad_enables_rtn_27 =
08421     (*(pbuffer +  42));
08422   pdata->global_config__spad_enables_rtn_28 =
08423     (*(pbuffer +  43));
08424   pdata->global_config__spad_enables_rtn_29 =
08425     (*(pbuffer +  44));
08426   pdata->global_config__spad_enables_rtn_30 =
08427     (*(pbuffer +  45));
08428   pdata->global_config__spad_enables_rtn_31 =
08429     (*(pbuffer +  46));
08430   pdata->roi_config__mode_roi_centre_spad =
08431     (*(pbuffer +  47));
08432   pdata->roi_config__mode_roi_xy_size =
08433     (*(pbuffer +  48));
08434 
08435 
08436   return status;
08437 }
08438 
08439 
08440 VL53LX_Error VL53LX::VL53LX_set_nvm_copy_data(
08441   VL53LX_nvm_copy_data_t    *pdata)
08442 {
08443 
08444 
08445   VL53LX_Error status = VL53LX_ERROR_NONE;
08446   uint8_t comms_buffer[VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES];
08447 
08448   if (status == VL53LX_ERROR_NONE)
08449     status = VL53LX_i2c_encode_nvm_copy_data(
08450                pdata,
08451                VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES,
08452                comms_buffer);
08453 
08454   if (status == VL53LX_ERROR_NONE) {
08455     status = VL53LX_disable_firmware();
08456   }
08457 
08458   if (status == VL53LX_ERROR_NONE)
08459     status = VL53LX_WriteMulti(
08460                Dev,
08461                VL53LX_IDENTIFICATION__MODEL_ID,
08462                comms_buffer,
08463                VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES);
08464 
08465   if (status == VL53LX_ERROR_NONE) {
08466     status = VL53LX_enable_firmware();
08467   }
08468 
08469 
08470   return status;
08471 }
08472 
08473 VL53LX_Error VL53LX::VL53LX_get_nvm_copy_data(
08474   VL53LX_nvm_copy_data_t    *pdata)
08475 {
08476 
08477 
08478   VL53LX_Error status = VL53LX_ERROR_NONE;
08479   uint8_t comms_buffer[VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES];
08480 
08481   if (status == VL53LX_ERROR_NONE)
08482     status = VL53LX_ReadMulti(
08483                Dev,
08484                VL53LX_IDENTIFICATION__MODEL_ID,
08485                comms_buffer,
08486                VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES);
08487 
08488   if (status == VL53LX_ERROR_NONE)
08489     status = VL53LX_i2c_decode_nvm_copy_data(
08490                VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES,
08491                comms_buffer,
08492                pdata);
08493 
08494   return status;
08495 }
08496 
08497 
08498 VL53LX_Error VL53LX::VL53LX_i2c_encode_prev_shadow_system_results(
08499   VL53LX_prev_shadow_system_results_t *pdata,
08500   uint16_t                  buf_size,
08501   uint8_t                  *pbuffer)
08502 {
08503 
08504 
08505   VL53LX_Error status = VL53LX_ERROR_NONE;
08506 
08507 
08508   if (buf_size < VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES) {
08509     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08510   }
08511 
08512   *(pbuffer +   0) =
08513     pdata->prev_shadow_result__interrupt_status & 0x3F;
08514   *(pbuffer +   1) =
08515     pdata->prev_shadow_result__range_status;
08516   *(pbuffer +   2) =
08517     pdata->prev_shadow_result__report_status & 0xF;
08518   *(pbuffer +   3) =
08519     pdata->prev_shadow_result__stream_count;
08520   VL53LX_i2c_encode_uint16_t(
08521     pdata->prev_shadow_result__dss_actual_effective_spads_sd0,
08522     2,
08523     pbuffer +   4);
08524   VL53LX_i2c_encode_uint16_t(
08525     pdata->prev_shadow_result__peak_signal_count_rate_mcps_sd0,
08526     2,
08527     pbuffer +   6);
08528   VL53LX_i2c_encode_uint16_t(
08529     pdata->prev_shadow_result__ambient_count_rate_mcps_sd0,
08530     2,
08531     pbuffer +   8);
08532   VL53LX_i2c_encode_uint16_t(
08533     pdata->prev_shadow_result__sigma_sd0,
08534     2,
08535     pbuffer +  10);
08536   VL53LX_i2c_encode_uint16_t(
08537     pdata->prev_shadow_result__phase_sd0,
08538     2,
08539     pbuffer +  12);
08540   VL53LX_i2c_encode_uint16_t(
08541     pdata->prev_shadow_result__final_crosstalk_corrected_range_mm_sd0,
08542     2,
08543     pbuffer +  14);
08544   VL53LX_i2c_encode_uint16_t(
08545     pdata->psr__peak_signal_count_rate_crosstalk_corrected_mcps_sd0,
08546     2,
08547     pbuffer +  16);
08548   VL53LX_i2c_encode_uint16_t(
08549     pdata->prev_shadow_result__mm_inner_actual_effective_spads_sd0,
08550     2,
08551     pbuffer +  18);
08552   VL53LX_i2c_encode_uint16_t(
08553     pdata->prev_shadow_result__mm_outer_actual_effective_spads_sd0,
08554     2,
08555     pbuffer +  20);
08556   VL53LX_i2c_encode_uint16_t(
08557     pdata->prev_shadow_result__avg_signal_count_rate_mcps_sd0,
08558     2,
08559     pbuffer +  22);
08560   VL53LX_i2c_encode_uint16_t(
08561     pdata->prev_shadow_result__dss_actual_effective_spads_sd1,
08562     2,
08563     pbuffer +  24);
08564   VL53LX_i2c_encode_uint16_t(
08565     pdata->prev_shadow_result__peak_signal_count_rate_mcps_sd1,
08566     2,
08567     pbuffer +  26);
08568   VL53LX_i2c_encode_uint16_t(
08569     pdata->prev_shadow_result__ambient_count_rate_mcps_sd1,
08570     2,
08571     pbuffer +  28);
08572   VL53LX_i2c_encode_uint16_t(
08573     pdata->prev_shadow_result__sigma_sd1,
08574     2,
08575     pbuffer +  30);
08576   VL53LX_i2c_encode_uint16_t(
08577     pdata->prev_shadow_result__phase_sd1,
08578     2,
08579     pbuffer +  32);
08580   VL53LX_i2c_encode_uint16_t(
08581     pdata->prev_shadow_result__final_crosstalk_corrected_range_mm_sd1,
08582     2,
08583     pbuffer +  34);
08584   VL53LX_i2c_encode_uint16_t(
08585     pdata->prev_shadow_result__spare_0_sd1,
08586     2,
08587     pbuffer +  36);
08588   VL53LX_i2c_encode_uint16_t(
08589     pdata->prev_shadow_result__spare_1_sd1,
08590     2,
08591     pbuffer +  38);
08592   VL53LX_i2c_encode_uint16_t(
08593     pdata->prev_shadow_result__spare_2_sd1,
08594     2,
08595     pbuffer +  40);
08596   VL53LX_i2c_encode_uint16_t(
08597     pdata->prev_shadow_result__spare_3_sd1,
08598     2,
08599     pbuffer +  42);
08600 
08601 
08602   return status;
08603 }
08604 
08605 
08606 
08607 VL53LX_Error VL53LX::VL53LX_i2c_decode_prev_shadow_system_results(
08608   uint16_t                   buf_size,
08609   uint8_t                   *pbuffer,
08610   VL53LX_prev_shadow_system_results_t  *pdata)
08611 {
08612 
08613 
08614   VL53LX_Error status = VL53LX_ERROR_NONE;
08615 
08616 
08617   if (buf_size < VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES) {
08618     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08619   }
08620 
08621   pdata->prev_shadow_result__interrupt_status =
08622     (*(pbuffer +   0)) & 0x3F;
08623   pdata->prev_shadow_result__range_status =
08624     (*(pbuffer +   1));
08625   pdata->prev_shadow_result__report_status =
08626     (*(pbuffer +   2)) & 0xF;
08627   pdata->prev_shadow_result__stream_count =
08628     (*(pbuffer +   3));
08629   pdata->prev_shadow_result__dss_actual_effective_spads_sd0 =
08630     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   4));
08631   pdata->prev_shadow_result__peak_signal_count_rate_mcps_sd0 =
08632     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   6));
08633   pdata->prev_shadow_result__ambient_count_rate_mcps_sd0 =
08634     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   8));
08635   pdata->prev_shadow_result__sigma_sd0 =
08636     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  10));
08637   pdata->prev_shadow_result__phase_sd0 =
08638     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  12));
08639   pdata->prev_shadow_result__final_crosstalk_corrected_range_mm_sd0 =
08640     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  14));
08641   pdata->psr__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 =
08642     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  16));
08643   pdata->prev_shadow_result__mm_inner_actual_effective_spads_sd0 =
08644     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  18));
08645   pdata->prev_shadow_result__mm_outer_actual_effective_spads_sd0 =
08646     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  20));
08647   pdata->prev_shadow_result__avg_signal_count_rate_mcps_sd0 =
08648     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  22));
08649   pdata->prev_shadow_result__dss_actual_effective_spads_sd1 =
08650     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  24));
08651   pdata->prev_shadow_result__peak_signal_count_rate_mcps_sd1 =
08652     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  26));
08653   pdata->prev_shadow_result__ambient_count_rate_mcps_sd1 =
08654     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  28));
08655   pdata->prev_shadow_result__sigma_sd1 =
08656     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  30));
08657   pdata->prev_shadow_result__phase_sd1 =
08658     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  32));
08659   pdata->prev_shadow_result__final_crosstalk_corrected_range_mm_sd1 =
08660     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  34));
08661   pdata->prev_shadow_result__spare_0_sd1 =
08662     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  36));
08663   pdata->prev_shadow_result__spare_1_sd1 =
08664     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  38));
08665   pdata->prev_shadow_result__spare_2_sd1 =
08666     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  40));
08667   pdata->prev_shadow_result__spare_3_sd1 =
08668     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  42));
08669 
08670 
08671   return status;
08672 }
08673 
08674 VL53LX_Error VL53LX::VL53LX_set_prev_shadow_system_results(
08675   VL53LX_prev_shadow_system_results_t  *pdata)
08676 {
08677 
08678 
08679   VL53LX_Error status = VL53LX_ERROR_NONE;
08680   uint8_t comms_buffer[VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES];
08681 
08682 
08683   if (status == VL53LX_ERROR_NONE)
08684     status = VL53LX_i2c_encode_prev_shadow_system_results(
08685                pdata,
08686                VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES,
08687                comms_buffer);
08688 
08689   if (status == VL53LX_ERROR_NONE) {
08690     status = VL53LX_disable_firmware();
08691   }
08692 
08693   if (status == VL53LX_ERROR_NONE)
08694     status = VL53LX_WriteMulti(
08695                Dev,
08696                VL53LX_PREV_SHADOW_RESULT__INTERRUPT_STATUS,
08697                comms_buffer,
08698                VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES);
08699 
08700   if (status == VL53LX_ERROR_NONE) {
08701     status = VL53LX_enable_firmware();
08702   }
08703 
08704 
08705   return status;
08706 }
08707 VL53LX_Error VL53LX::VL53LX_get_prev_shadow_system_results(
08708   VL53LX_prev_shadow_system_results_t  *pdata)
08709 {
08710 
08711 
08712   VL53LX_Error status = VL53LX_ERROR_NONE;
08713   uint8_t comms_buffer[VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES];
08714 
08715   if (status == VL53LX_ERROR_NONE) {
08716     status = VL53LX_disable_firmware();
08717   }
08718 
08719   if (status == VL53LX_ERROR_NONE)
08720     status = VL53LX_ReadMulti(
08721                Dev,
08722                VL53LX_PREV_SHADOW_RESULT__INTERRUPT_STATUS,
08723                comms_buffer,
08724                VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES);
08725 
08726   if (status == VL53LX_ERROR_NONE) {
08727     status = VL53LX_enable_firmware();
08728   }
08729 
08730   if (status == VL53LX_ERROR_NONE)
08731     status = VL53LX_i2c_decode_prev_shadow_system_results(
08732                VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES,
08733                comms_buffer,
08734                pdata);
08735 
08736   return status;
08737 }
08738 VL53LX_Error VL53LX::VL53LX_i2c_encode_prev_shadow_core_results(
08739   VL53LX_prev_shadow_core_results_t *pdata,
08740   uint16_t                  buf_size,
08741   uint8_t                  *pbuffer)
08742 {
08743 
08744 
08745   VL53LX_Error status = VL53LX_ERROR_NONE;
08746 
08747 
08748   if (buf_size < VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES) {
08749     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08750   }
08751 
08752   VL53LX_i2c_encode_uint32_t(
08753     pdata->prev_shadow_result_core__ambient_window_events_sd0,
08754     4,
08755     pbuffer +   0);
08756   VL53LX_i2c_encode_uint32_t(
08757     pdata->prev_shadow_result_core__ranging_total_events_sd0,
08758     4,
08759     pbuffer +   4);
08760   VL53LX_i2c_encode_int32_t(
08761     pdata->prev_shadow_result_core__signal_total_events_sd0,
08762     4,
08763     pbuffer +   8);
08764   VL53LX_i2c_encode_uint32_t(
08765     pdata->prev_shadow_result_core__total_periods_elapsed_sd0,
08766     4,
08767     pbuffer +  12);
08768   VL53LX_i2c_encode_uint32_t(
08769     pdata->prev_shadow_result_core__ambient_window_events_sd1,
08770     4,
08771     pbuffer +  16);
08772   VL53LX_i2c_encode_uint32_t(
08773     pdata->prev_shadow_result_core__ranging_total_events_sd1,
08774     4,
08775     pbuffer +  20);
08776   VL53LX_i2c_encode_int32_t(
08777     pdata->prev_shadow_result_core__signal_total_events_sd1,
08778     4,
08779     pbuffer +  24);
08780   VL53LX_i2c_encode_uint32_t(
08781     pdata->prev_shadow_result_core__total_periods_elapsed_sd1,
08782     4,
08783     pbuffer +  28);
08784   *(pbuffer +  32) =
08785     pdata->prev_shadow_result_core__spare_0;
08786 
08787   return status;
08788 }
08789 
08790 VL53LX_Error VL53LX::VL53LX_i2c_decode_prev_shadow_core_results(
08791   uint16_t                   buf_size,
08792   uint8_t                   *pbuffer,
08793   VL53LX_prev_shadow_core_results_t  *pdata)
08794 {
08795 
08796 
08797   VL53LX_Error status = VL53LX_ERROR_NONE;
08798   ;
08799 
08800   if (buf_size < VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES) {
08801     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08802   }
08803 
08804   pdata->prev_shadow_result_core__ambient_window_events_sd0 =
08805     (VL53LX_i2c_decode_uint32_t(4, pbuffer +   0));
08806   pdata->prev_shadow_result_core__ranging_total_events_sd0 =
08807     (VL53LX_i2c_decode_uint32_t(4, pbuffer +   4));
08808   pdata->prev_shadow_result_core__signal_total_events_sd0 =
08809     (VL53LX_i2c_decode_int32_t(4, pbuffer +   8));
08810   pdata->prev_shadow_result_core__total_periods_elapsed_sd0 =
08811     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  12));
08812   pdata->prev_shadow_result_core__ambient_window_events_sd1 =
08813     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  16));
08814   pdata->prev_shadow_result_core__ranging_total_events_sd1 =
08815     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  20));
08816   pdata->prev_shadow_result_core__signal_total_events_sd1 =
08817     (VL53LX_i2c_decode_int32_t(4, pbuffer +  24));
08818   pdata->prev_shadow_result_core__total_periods_elapsed_sd1 =
08819     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  28));
08820   pdata->prev_shadow_result_core__spare_0 =
08821     (*(pbuffer +  32));
08822 
08823 
08824   return status;
08825 }
08826 
08827 VL53LX_Error VL53LX::VL53LX_set_prev_shadow_core_results(
08828   VL53LX_prev_shadow_core_results_t  *pdata)
08829 {
08830 
08831 
08832   VL53LX_Error status = VL53LX_ERROR_NONE;
08833   uint8_t comms_buffer[VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES];
08834 
08835 
08836   if (status == VL53LX_ERROR_NONE)
08837     status = VL53LX_i2c_encode_prev_shadow_core_results(
08838                pdata,
08839                VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES,
08840                comms_buffer);
08841 
08842   if (status == VL53LX_ERROR_NONE) {
08843     status = VL53LX_disable_firmware();
08844   }
08845 
08846   if (status == VL53LX_ERROR_NONE)
08847     status = VL53LX_WriteMulti(
08848                Dev,
08849                VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0,
08850                comms_buffer,
08851                VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES);
08852 
08853   if (status == VL53LX_ERROR_NONE) {
08854     status = VL53LX_enable_firmware();
08855   }
08856 
08857 
08858   return status;
08859 }
08860 VL53LX_Error VL53LX::VL53LX_get_prev_shadow_core_results(
08861   VL53LX_prev_shadow_core_results_t  *pdata)
08862 {
08863 
08864 
08865   VL53LX_Error status = VL53LX_ERROR_NONE;
08866   uint8_t comms_buffer[VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES];
08867 
08868 
08869   if (status == VL53LX_ERROR_NONE) {
08870     status = VL53LX_disable_firmware();
08871   }
08872 
08873   if (status == VL53LX_ERROR_NONE)
08874     status = VL53LX_ReadMulti(
08875                Dev,
08876                VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0,
08877                comms_buffer,
08878                VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES);
08879 
08880   if (status == VL53LX_ERROR_NONE) {
08881     status = VL53LX_enable_firmware();
08882   }
08883 
08884   if (status == VL53LX_ERROR_NONE)
08885     status = VL53LX_i2c_decode_prev_shadow_core_results(
08886                VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES,
08887                comms_buffer,
08888                pdata);
08889 
08890 
08891   return status;
08892 }
08893 VL53LX_Error VL53LX::VL53LX_i2c_encode_patch_debug(
08894   VL53LX_patch_debug_t     *pdata,
08895   uint16_t                  buf_size,
08896   uint8_t                  *pbuffer)
08897 {
08898 
08899 
08900   VL53LX_Error status = VL53LX_ERROR_NONE;
08901 
08902   if (buf_size < VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES) {
08903     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08904   }
08905 
08906   *(pbuffer +   0) =
08907     pdata->result__debug_status;
08908   *(pbuffer +   1) =
08909     pdata->result__debug_stage;
08910 
08911   return status;
08912 }
08913 
08914 VL53LX_Error VL53LX::VL53LX_i2c_decode_patch_debug(
08915   uint16_t                   buf_size,
08916   uint8_t                   *pbuffer,
08917   VL53LX_patch_debug_t      *pdata)
08918 {
08919 
08920 
08921   VL53LX_Error status = VL53LX_ERROR_NONE;
08922 
08923 
08924   if (buf_size < VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES) {
08925     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
08926   }
08927 
08928   pdata->result__debug_status =
08929     (*(pbuffer +   0));
08930   pdata->result__debug_stage =
08931     (*(pbuffer +   1));
08932 
08933   return status;
08934 }
08935 
08936 VL53LX_Error VL53LX::VL53LX_set_patch_debug(
08937   VL53LX_patch_debug_t      *pdata)
08938 {
08939 
08940 
08941   VL53LX_Error status = VL53LX_ERROR_NONE;
08942   uint8_t comms_buffer[VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES];
08943 
08944   if (status == VL53LX_ERROR_NONE)
08945     status = VL53LX_i2c_encode_patch_debug(
08946                pdata,
08947                VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES,
08948                comms_buffer);
08949 
08950   if (status == VL53LX_ERROR_NONE) {
08951     status = VL53LX_disable_firmware();
08952   }
08953 
08954   if (status == VL53LX_ERROR_NONE)
08955     status = VL53LX_WriteMulti(
08956                Dev,
08957                VL53LX_RESULT__DEBUG_STATUS,
08958                comms_buffer,
08959                VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES);
08960 
08961   if (status == VL53LX_ERROR_NONE) {
08962     status = VL53LX_enable_firmware();
08963   }
08964 
08965 
08966   return status;
08967 }
08968 VL53LX_Error VL53LX::VL53LX_get_patch_debug(
08969   VL53LX_patch_debug_t      *pdata)
08970 {
08971 
08972 
08973   VL53LX_Error status = VL53LX_ERROR_NONE;
08974   uint8_t comms_buffer[VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES];
08975 
08976 
08977   if (status == VL53LX_ERROR_NONE) {
08978     status = VL53LX_disable_firmware();
08979   }
08980 
08981   if (status == VL53LX_ERROR_NONE)
08982     status = VL53LX_ReadMulti(
08983                Dev,
08984                VL53LX_RESULT__DEBUG_STATUS,
08985                comms_buffer,
08986                VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES);
08987 
08988   if (status == VL53LX_ERROR_NONE) {
08989     status = VL53LX_enable_firmware();
08990   }
08991 
08992   if (status == VL53LX_ERROR_NONE)
08993     status = VL53LX_i2c_decode_patch_debug(
08994                VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES,
08995                comms_buffer,
08996                pdata);
08997 
08998 
08999   return status;
09000 }
09001 VL53LX_Error VL53LX::VL53LX_i2c_encode_gph_general_config(
09002   VL53LX_gph_general_config_t *pdata,
09003   uint16_t                  buf_size,
09004   uint8_t                  *pbuffer)
09005 {
09006 
09007 
09008   VL53LX_Error status = VL53LX_ERROR_NONE;
09009 
09010 
09011   if (buf_size < VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES) {
09012     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09013   }
09014 
09015   VL53LX_i2c_encode_uint16_t(
09016     pdata->gph__system__thresh_rate_high,
09017     2,
09018     pbuffer +   0);
09019   VL53LX_i2c_encode_uint16_t(
09020     pdata->gph__system__thresh_rate_low,
09021     2,
09022     pbuffer +   2);
09023   *(pbuffer +   4) =
09024     pdata->gph__system__interrupt_config_gpio;
09025 
09026   return status;
09027 }
09028 VL53LX_Error VL53LX::VL53LX_i2c_decode_gph_general_config(
09029   uint16_t                   buf_size,
09030   uint8_t                   *pbuffer,
09031   VL53LX_gph_general_config_t  *pdata)
09032 {
09033 
09034 
09035   VL53LX_Error status = VL53LX_ERROR_NONE;
09036 
09037 
09038   if (buf_size < VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES) {
09039     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09040   }
09041 
09042   pdata->gph__system__thresh_rate_high =
09043     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   0));
09044   pdata->gph__system__thresh_rate_low =
09045     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   2));
09046   pdata->gph__system__interrupt_config_gpio =
09047     (*(pbuffer +   4));
09048 
09049 
09050   return status;
09051 }
09052 
09053 VL53LX_Error VL53LX::VL53LX_set_gph_general_config(
09054   VL53LX_gph_general_config_t  *pdata)
09055 {
09056 
09057 
09058   VL53LX_Error status = VL53LX_ERROR_NONE;
09059   uint8_t comms_buffer[VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES];
09060 
09061   if (status == VL53LX_ERROR_NONE)
09062     status = VL53LX_i2c_encode_gph_general_config(
09063                pdata,
09064                VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES,
09065                comms_buffer);
09066 
09067   if (status == VL53LX_ERROR_NONE) {
09068     status = VL53LX_disable_firmware();
09069   }
09070 
09071   if (status == VL53LX_ERROR_NONE)
09072     status = VL53LX_WriteMulti(
09073                Dev,
09074                VL53LX_GPH__SYSTEM__THRESH_RATE_HIGH,
09075                comms_buffer,
09076                VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES);
09077 
09078   if (status == VL53LX_ERROR_NONE) {
09079     status = VL53LX_enable_firmware();
09080   }
09081 
09082   return status;
09083 }
09084 VL53LX_Error VL53LX::VL53LX_get_gph_general_config(
09085   VL53LX_gph_general_config_t  *pdata)
09086 {
09087 
09088 
09089   VL53LX_Error status = VL53LX_ERROR_NONE;
09090   uint8_t comms_buffer[VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES];
09091 
09092 
09093   if (status == VL53LX_ERROR_NONE) {
09094     status = VL53LX_disable_firmware();
09095   }
09096 
09097   if (status == VL53LX_ERROR_NONE)
09098     status = VL53LX_ReadMulti(
09099                Dev,
09100                VL53LX_GPH__SYSTEM__THRESH_RATE_HIGH,
09101                comms_buffer,
09102                VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES);
09103 
09104   if (status == VL53LX_ERROR_NONE) {
09105     status = VL53LX_enable_firmware();
09106   }
09107 
09108   if (status == VL53LX_ERROR_NONE)
09109     status = VL53LX_i2c_decode_gph_general_config(
09110                VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES,
09111                comms_buffer,
09112                pdata);
09113 
09114   return status;
09115 }
09116 
09117 VL53LX_Error VL53LX::VL53LX_i2c_encode_gph_static_config(
09118   VL53LX_gph_static_config_t *pdata,
09119   uint16_t                  buf_size,
09120   uint8_t                  *pbuffer)
09121 {
09122 
09123 
09124   VL53LX_Error status = VL53LX_ERROR_NONE;
09125 
09126 
09127   if (buf_size < VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES) {
09128     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09129   }
09130 
09131   *(pbuffer +   0) =
09132     pdata->gph__dss_config__roi_mode_control & 0x7;
09133   VL53LX_i2c_encode_uint16_t(
09134     pdata->gph__dss_config__manual_effective_spads_select,
09135     2,
09136     pbuffer +   1);
09137   *(pbuffer +   3) =
09138     pdata->gph__dss_config__manual_block_select;
09139   *(pbuffer +   4) =
09140     pdata->gph__dss_config__max_spads_limit;
09141   *(pbuffer +   5) =
09142     pdata->gph__dss_config__min_spads_limit;
09143 
09144   return status;
09145 }
09146 VL53LX_Error VL53LX::VL53LX_i2c_decode_gph_static_config(
09147   uint16_t                   buf_size,
09148   uint8_t                   *pbuffer,
09149   VL53LX_gph_static_config_t  *pdata)
09150 {
09151 
09152 
09153   VL53LX_Error status = VL53LX_ERROR_NONE;
09154 
09155 
09156   if (buf_size < VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES) {
09157     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09158   }
09159 
09160   pdata->gph__dss_config__roi_mode_control =
09161     (*(pbuffer +   0)) & 0x7;
09162   pdata->gph__dss_config__manual_effective_spads_select =
09163     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   1));
09164   pdata->gph__dss_config__manual_block_select =
09165     (*(pbuffer +   3));
09166   pdata->gph__dss_config__max_spads_limit =
09167     (*(pbuffer +   4));
09168   pdata->gph__dss_config__min_spads_limit =
09169     (*(pbuffer +   5));
09170 
09171 
09172   return status;
09173 }
09174 VL53LX_Error VL53LX::VL53LX_set_gph_static_config(
09175   VL53LX_gph_static_config_t  *pdata)
09176 {
09177 
09178 
09179   VL53LX_Error status = VL53LX_ERROR_NONE;
09180   uint8_t comms_buffer[VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES];
09181 
09182   if (status == VL53LX_ERROR_NONE)
09183     status = VL53LX_i2c_encode_gph_static_config(
09184                pdata,
09185                VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES,
09186                comms_buffer);
09187 
09188   if (status == VL53LX_ERROR_NONE) {
09189     status = VL53LX_disable_firmware();
09190   }
09191 
09192   if (status == VL53LX_ERROR_NONE)
09193     status = VL53LX_WriteMulti(
09194                Dev,
09195                VL53LX_GPH__DSS_CONFIG__ROI_MODE_CONTROL,
09196                comms_buffer,
09197                VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES);
09198 
09199   if (status == VL53LX_ERROR_NONE) {
09200     status = VL53LX_enable_firmware();
09201   }
09202 
09203   return status;
09204 }
09205 VL53LX_Error VL53LX::VL53LX_get_gph_static_config(
09206   VL53LX_gph_static_config_t  *pdata)
09207 {
09208 
09209 
09210   VL53LX_Error status = VL53LX_ERROR_NONE;
09211   uint8_t comms_buffer[VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES];
09212 
09213   if (status == VL53LX_ERROR_NONE) {
09214     status = VL53LX_disable_firmware();
09215   }
09216 
09217   if (status == VL53LX_ERROR_NONE)
09218     status = VL53LX_ReadMulti(
09219                Dev,
09220                VL53LX_GPH__DSS_CONFIG__ROI_MODE_CONTROL,
09221                comms_buffer,
09222                VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES);
09223 
09224   if (status == VL53LX_ERROR_NONE) {
09225     status = VL53LX_enable_firmware();
09226   }
09227 
09228   if (status == VL53LX_ERROR_NONE)
09229     status = VL53LX_i2c_decode_gph_static_config(
09230                VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES,
09231                comms_buffer,
09232                pdata);
09233 
09234   return status;
09235 }
09236 VL53LX_Error VL53LX::VL53LX_i2c_encode_gph_timing_config(
09237   VL53LX_gph_timing_config_t *pdata,
09238   uint16_t                  buf_size,
09239   uint8_t                  *pbuffer)
09240 {
09241 
09242 
09243   VL53LX_Error status = VL53LX_ERROR_NONE;
09244 
09245 
09246   if (buf_size < VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES) {
09247     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09248   }
09249 
09250   *(pbuffer +   0) =
09251     pdata->gph__mm_config__timeout_macrop_a_hi & 0xF;
09252   *(pbuffer +   1) =
09253     pdata->gph__mm_config__timeout_macrop_a_lo;
09254   *(pbuffer +   2) =
09255     pdata->gph__mm_config__timeout_macrop_b_hi & 0xF;
09256   *(pbuffer +   3) =
09257     pdata->gph__mm_config__timeout_macrop_b_lo;
09258   *(pbuffer +   4) =
09259     pdata->gph__range_config__timeout_macrop_a_hi & 0xF;
09260   *(pbuffer +   5) =
09261     pdata->gph__range_config__timeout_macrop_a_lo;
09262   *(pbuffer +   6) =
09263     pdata->gph__range_config__vcsel_period_a & 0x3F;
09264   *(pbuffer +   7) =
09265     pdata->gph__range_config__vcsel_period_b & 0x3F;
09266   *(pbuffer +   8) =
09267     pdata->gph__range_config__timeout_macrop_b_hi & 0xF;
09268   *(pbuffer +   9) =
09269     pdata->gph__range_config__timeout_macrop_b_lo;
09270   VL53LX_i2c_encode_uint16_t(
09271     pdata->gph__range_config__sigma_thresh,
09272     2,
09273     pbuffer +  10);
09274   VL53LX_i2c_encode_uint16_t(
09275     pdata->gph__range_config__min_count_rate_rtn_limit_mcps,
09276     2,
09277     pbuffer +  12);
09278   *(pbuffer +  14) =
09279     pdata->gph__range_config__valid_phase_low;
09280   *(pbuffer +  15) =
09281     pdata->gph__range_config__valid_phase_high;
09282 
09283   return status;
09284 }
09285 
09286 
09287 VL53LX_Error VL53LX::VL53LX_i2c_decode_gph_timing_config(
09288   uint16_t                   buf_size,
09289   uint8_t                   *pbuffer,
09290   VL53LX_gph_timing_config_t  *pdata)
09291 {
09292 
09293 
09294   VL53LX_Error status = VL53LX_ERROR_NONE;
09295 
09296 
09297   if (buf_size < VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES) {
09298     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09299   }
09300 
09301   pdata->gph__mm_config__timeout_macrop_a_hi =
09302     (*(pbuffer +   0)) & 0xF;
09303   pdata->gph__mm_config__timeout_macrop_a_lo =
09304     (*(pbuffer +   1));
09305   pdata->gph__mm_config__timeout_macrop_b_hi =
09306     (*(pbuffer +   2)) & 0xF;
09307   pdata->gph__mm_config__timeout_macrop_b_lo =
09308     (*(pbuffer +   3));
09309   pdata->gph__range_config__timeout_macrop_a_hi =
09310     (*(pbuffer +   4)) & 0xF;
09311   pdata->gph__range_config__timeout_macrop_a_lo =
09312     (*(pbuffer +   5));
09313   pdata->gph__range_config__vcsel_period_a =
09314     (*(pbuffer +   6)) & 0x3F;
09315   pdata->gph__range_config__vcsel_period_b =
09316     (*(pbuffer +   7)) & 0x3F;
09317   pdata->gph__range_config__timeout_macrop_b_hi =
09318     (*(pbuffer +   8)) & 0xF;
09319   pdata->gph__range_config__timeout_macrop_b_lo =
09320     (*(pbuffer +   9));
09321   pdata->gph__range_config__sigma_thresh =
09322     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  10));
09323   pdata->gph__range_config__min_count_rate_rtn_limit_mcps =
09324     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  12));
09325   pdata->gph__range_config__valid_phase_low =
09326     (*(pbuffer +  14));
09327   pdata->gph__range_config__valid_phase_high =
09328     (*(pbuffer +  15));
09329 
09330 
09331   return status;
09332 }
09333 
09334 VL53LX_Error VL53LX::VL53LX_set_gph_timing_config(
09335   VL53LX_gph_timing_config_t  *pdata)
09336 {
09337 
09338 
09339   VL53LX_Error status = VL53LX_ERROR_NONE;
09340   uint8_t comms_buffer[VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES];
09341 
09342 
09343   if (status == VL53LX_ERROR_NONE)
09344     status = VL53LX_i2c_encode_gph_timing_config(
09345                pdata,
09346                VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES,
09347                comms_buffer);
09348 
09349   if (status == VL53LX_ERROR_NONE) {
09350     status = VL53LX_disable_firmware();
09351   }
09352 
09353   if (status == VL53LX_ERROR_NONE)
09354     status = VL53LX_WriteMulti(
09355                Dev,
09356                VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_A_HI,
09357                comms_buffer,
09358                VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES);
09359 
09360   if (status == VL53LX_ERROR_NONE) {
09361     status = VL53LX_enable_firmware();
09362   }
09363 
09364   return status;
09365 }
09366 VL53LX_Error VL53LX::VL53LX_get_gph_timing_config(
09367   VL53LX_gph_timing_config_t  *pdata)
09368 {
09369 
09370 
09371   VL53LX_Error status = VL53LX_ERROR_NONE;
09372   uint8_t comms_buffer[VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES];
09373 
09374 
09375   if (status == VL53LX_ERROR_NONE) {
09376     status = VL53LX_disable_firmware();
09377   }
09378 
09379   if (status == VL53LX_ERROR_NONE)
09380     status = VL53LX_ReadMulti(
09381                Dev,
09382                VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_A_HI,
09383                comms_buffer,
09384                VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES);
09385 
09386   if (status == VL53LX_ERROR_NONE) {
09387     status = VL53LX_enable_firmware();
09388   }
09389 
09390   if (status == VL53LX_ERROR_NONE)
09391     status = VL53LX_i2c_decode_gph_timing_config(
09392                VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES,
09393                comms_buffer,
09394                pdata);
09395 
09396 
09397   return status;
09398 }
09399 VL53LX_Error VL53LX::VL53LX_i2c_encode_fw_internal(
09400   VL53LX_fw_internal_t     *pdata,
09401   uint16_t                  buf_size,
09402   uint8_t                  *pbuffer)
09403 {
09404 
09405 
09406   VL53LX_Error status = VL53LX_ERROR_NONE;
09407 
09408 
09409   if (buf_size < VL53LX_FW_INTERNAL_I2C_SIZE_BYTES) {
09410     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09411   }
09412 
09413   *(pbuffer +   0) =
09414     pdata->firmware__internal_stream_count_div;
09415   *(pbuffer +   1) =
09416     pdata->firmware__internal_stream_counter_val;
09417 
09418   return status;
09419 }
09420 VL53LX_Error VL53LX::VL53LX_i2c_decode_fw_internal(
09421   uint16_t                   buf_size,
09422   uint8_t                   *pbuffer,
09423   VL53LX_fw_internal_t      *pdata)
09424 {
09425 
09426 
09427   VL53LX_Error status = VL53LX_ERROR_NONE;
09428 
09429   if (buf_size < VL53LX_FW_INTERNAL_I2C_SIZE_BYTES) {
09430     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09431   }
09432 
09433   pdata->firmware__internal_stream_count_div =
09434     (*(pbuffer +   0));
09435   pdata->firmware__internal_stream_counter_val =
09436     (*(pbuffer +   1));
09437 
09438   return status;
09439 }
09440 
09441 VL53LX_Error VL53LX::VL53LX_set_fw_internal(
09442   VL53LX_fw_internal_t      *pdata)
09443 {
09444 
09445 
09446   VL53LX_Error status = VL53LX_ERROR_NONE;
09447   uint8_t comms_buffer[VL53LX_FW_INTERNAL_I2C_SIZE_BYTES];
09448 
09449 
09450   if (status == VL53LX_ERROR_NONE)
09451     status = VL53LX_i2c_encode_fw_internal(
09452                pdata,
09453                VL53LX_FW_INTERNAL_I2C_SIZE_BYTES,
09454                comms_buffer);
09455 
09456   if (status == VL53LX_ERROR_NONE) {
09457     status = VL53LX_disable_firmware();
09458   }
09459 
09460   if (status == VL53LX_ERROR_NONE)
09461     status = VL53LX_WriteMulti(
09462                Dev,
09463                VL53LX_FIRMWARE__INTERNAL_STREAM_COUNT_DIV,
09464                comms_buffer,
09465                VL53LX_FW_INTERNAL_I2C_SIZE_BYTES);
09466 
09467   if (status == VL53LX_ERROR_NONE) {
09468     status = VL53LX_enable_firmware();
09469   }
09470 
09471 
09472   return status;
09473 }
09474 VL53LX_Error VL53LX::VL53LX_get_fw_internal(
09475   VL53LX_fw_internal_t      *pdata)
09476 {
09477 
09478 
09479   VL53LX_Error status = VL53LX_ERROR_NONE;
09480   uint8_t comms_buffer[VL53LX_FW_INTERNAL_I2C_SIZE_BYTES];
09481 
09482   if (status == VL53LX_ERROR_NONE) {
09483     status = VL53LX_disable_firmware();
09484   }
09485 
09486   if (status == VL53LX_ERROR_NONE)
09487     status = VL53LX_ReadMulti(
09488                Dev,
09489                VL53LX_FIRMWARE__INTERNAL_STREAM_COUNT_DIV,
09490                comms_buffer,
09491                VL53LX_FW_INTERNAL_I2C_SIZE_BYTES);
09492 
09493   if (status == VL53LX_ERROR_NONE) {
09494     status = VL53LX_enable_firmware();
09495   }
09496 
09497   if (status == VL53LX_ERROR_NONE)
09498     status = VL53LX_i2c_decode_fw_internal(
09499                VL53LX_FW_INTERNAL_I2C_SIZE_BYTES,
09500                comms_buffer,
09501                pdata);
09502 
09503 
09504   return status;
09505 }
09506 
09507 VL53LX_Error VL53LX::VL53LX_i2c_encode_patch_results(
09508   VL53LX_patch_results_t   *pdata,
09509   uint16_t                  buf_size,
09510   uint8_t                  *pbuffer)
09511 {
09512 
09513 
09514   VL53LX_Error status = VL53LX_ERROR_NONE;
09515 
09516   if (buf_size < VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES) {
09517     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09518   }
09519 
09520   *(pbuffer +   0) =
09521     pdata->dss_calc__roi_ctrl & 0x3;
09522   *(pbuffer +   1) =
09523     pdata->dss_calc__spare_1;
09524   *(pbuffer +   2) =
09525     pdata->dss_calc__spare_2;
09526   *(pbuffer +   3) =
09527     pdata->dss_calc__spare_3;
09528   *(pbuffer +   4) =
09529     pdata->dss_calc__spare_4;
09530   *(pbuffer +   5) =
09531     pdata->dss_calc__spare_5;
09532   *(pbuffer +   6) =
09533     pdata->dss_calc__spare_6;
09534   *(pbuffer +   7) =
09535     pdata->dss_calc__spare_7;
09536   *(pbuffer +   8) =
09537     pdata->dss_calc__user_roi_spad_en_0;
09538   *(pbuffer +   9) =
09539     pdata->dss_calc__user_roi_spad_en_1;
09540   *(pbuffer +  10) =
09541     pdata->dss_calc__user_roi_spad_en_2;
09542   *(pbuffer +  11) =
09543     pdata->dss_calc__user_roi_spad_en_3;
09544   *(pbuffer +  12) =
09545     pdata->dss_calc__user_roi_spad_en_4;
09546   *(pbuffer +  13) =
09547     pdata->dss_calc__user_roi_spad_en_5;
09548   *(pbuffer +  14) =
09549     pdata->dss_calc__user_roi_spad_en_6;
09550   *(pbuffer +  15) =
09551     pdata->dss_calc__user_roi_spad_en_7;
09552   *(pbuffer +  16) =
09553     pdata->dss_calc__user_roi_spad_en_8;
09554   *(pbuffer +  17) =
09555     pdata->dss_calc__user_roi_spad_en_9;
09556   *(pbuffer +  18) =
09557     pdata->dss_calc__user_roi_spad_en_10;
09558   *(pbuffer +  19) =
09559     pdata->dss_calc__user_roi_spad_en_11;
09560   *(pbuffer +  20) =
09561     pdata->dss_calc__user_roi_spad_en_12;
09562   *(pbuffer +  21) =
09563     pdata->dss_calc__user_roi_spad_en_13;
09564   *(pbuffer +  22) =
09565     pdata->dss_calc__user_roi_spad_en_14;
09566   *(pbuffer +  23) =
09567     pdata->dss_calc__user_roi_spad_en_15;
09568   *(pbuffer +  24) =
09569     pdata->dss_calc__user_roi_spad_en_16;
09570   *(pbuffer +  25) =
09571     pdata->dss_calc__user_roi_spad_en_17;
09572   *(pbuffer +  26) =
09573     pdata->dss_calc__user_roi_spad_en_18;
09574   *(pbuffer +  27) =
09575     pdata->dss_calc__user_roi_spad_en_19;
09576   *(pbuffer +  28) =
09577     pdata->dss_calc__user_roi_spad_en_20;
09578   *(pbuffer +  29) =
09579     pdata->dss_calc__user_roi_spad_en_21;
09580   *(pbuffer +  30) =
09581     pdata->dss_calc__user_roi_spad_en_22;
09582   *(pbuffer +  31) =
09583     pdata->dss_calc__user_roi_spad_en_23;
09584   *(pbuffer +  32) =
09585     pdata->dss_calc__user_roi_spad_en_24;
09586   *(pbuffer +  33) =
09587     pdata->dss_calc__user_roi_spad_en_25;
09588   *(pbuffer +  34) =
09589     pdata->dss_calc__user_roi_spad_en_26;
09590   *(pbuffer +  35) =
09591     pdata->dss_calc__user_roi_spad_en_27;
09592   *(pbuffer +  36) =
09593     pdata->dss_calc__user_roi_spad_en_28;
09594   *(pbuffer +  37) =
09595     pdata->dss_calc__user_roi_spad_en_29;
09596   *(pbuffer +  38) =
09597     pdata->dss_calc__user_roi_spad_en_30;
09598   *(pbuffer +  39) =
09599     pdata->dss_calc__user_roi_spad_en_31;
09600   *(pbuffer +  40) =
09601     pdata->dss_calc__user_roi_0;
09602   *(pbuffer +  41) =
09603     pdata->dss_calc__user_roi_1;
09604   *(pbuffer +  42) =
09605     pdata->dss_calc__mode_roi_0;
09606   *(pbuffer +  43) =
09607     pdata->dss_calc__mode_roi_1;
09608   *(pbuffer +  44) =
09609     pdata->sigma_estimator_calc__spare_0;
09610   VL53LX_i2c_encode_uint16_t(
09611     pdata->vhv_result__peak_signal_rate_mcps,
09612     2,
09613     pbuffer +  46);
09614   VL53LX_i2c_encode_uint32_t(
09615     pdata->vhv_result__signal_total_events_ref,
09616     4,
09617     pbuffer +  48);
09618   VL53LX_i2c_encode_uint16_t(
09619     pdata->phasecal_result__phase_output_ref,
09620     2,
09621     pbuffer +  52);
09622   VL53LX_i2c_encode_uint16_t(
09623     pdata->dss_result__total_rate_per_spad,
09624     2,
09625     pbuffer +  54);
09626   *(pbuffer +  56) =
09627     pdata->dss_result__enabled_blocks;
09628   VL53LX_i2c_encode_uint16_t(
09629     pdata->dss_result__num_requested_spads,
09630     2,
09631     pbuffer +  58);
09632   VL53LX_i2c_encode_uint16_t(
09633     pdata->mm_result__inner_intersection_rate,
09634     2,
09635     pbuffer +  62);
09636   VL53LX_i2c_encode_uint16_t(
09637     pdata->mm_result__outer_complement_rate,
09638     2,
09639     pbuffer +  64);
09640   VL53LX_i2c_encode_uint16_t(
09641     pdata->mm_result__total_offset,
09642     2,
09643     pbuffer +  66);
09644   VL53LX_i2c_encode_uint32_t(
09645     pdata->xtalk_calc__xtalk_for_enabled_spads & 0xFFFFFF,
09646     4,
09647     pbuffer +  68);
09648   VL53LX_i2c_encode_uint32_t(
09649     pdata->xtalk_result__avg_xtalk_user_roi_kcps & 0xFFFFFF,
09650     4,
09651     pbuffer +  72);
09652   VL53LX_i2c_encode_uint32_t(
09653     pdata->xtalk_result__avg_xtalk_mm_inner_roi_kcps & 0xFFFFFF,
09654     4,
09655     pbuffer +  76);
09656   VL53LX_i2c_encode_uint32_t(
09657     pdata->xtalk_result__avg_xtalk_mm_outer_roi_kcps & 0xFFFFFF,
09658     4,
09659     pbuffer +  80);
09660   VL53LX_i2c_encode_uint32_t(
09661     pdata->range_result__accum_phase,
09662     4,
09663     pbuffer +  84);
09664   VL53LX_i2c_encode_uint16_t(
09665     pdata->range_result__offset_corrected_range,
09666     2,
09667     pbuffer +  88);
09668 
09669   return status;
09670 }
09671 
09672 VL53LX_Error VL53LX::VL53LX_i2c_decode_patch_results(
09673   uint16_t                   buf_size,
09674   uint8_t                   *pbuffer,
09675   VL53LX_patch_results_t    *pdata)
09676 {
09677 
09678 
09679   VL53LX_Error status = VL53LX_ERROR_NONE;
09680 
09681 
09682   if (buf_size < VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES) {
09683     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09684   }
09685 
09686   pdata->dss_calc__roi_ctrl =
09687     (*(pbuffer +   0)) & 0x3;
09688   pdata->dss_calc__spare_1 =
09689     (*(pbuffer +   1));
09690   pdata->dss_calc__spare_2 =
09691     (*(pbuffer +   2));
09692   pdata->dss_calc__spare_3 =
09693     (*(pbuffer +   3));
09694   pdata->dss_calc__spare_4 =
09695     (*(pbuffer +   4));
09696   pdata->dss_calc__spare_5 =
09697     (*(pbuffer +   5));
09698   pdata->dss_calc__spare_6 =
09699     (*(pbuffer +   6));
09700   pdata->dss_calc__spare_7 =
09701     (*(pbuffer +   7));
09702   pdata->dss_calc__user_roi_spad_en_0 =
09703     (*(pbuffer +   8));
09704   pdata->dss_calc__user_roi_spad_en_1 =
09705     (*(pbuffer +   9));
09706   pdata->dss_calc__user_roi_spad_en_2 =
09707     (*(pbuffer +  10));
09708   pdata->dss_calc__user_roi_spad_en_3 =
09709     (*(pbuffer +  11));
09710   pdata->dss_calc__user_roi_spad_en_4 =
09711     (*(pbuffer +  12));
09712   pdata->dss_calc__user_roi_spad_en_5 =
09713     (*(pbuffer +  13));
09714   pdata->dss_calc__user_roi_spad_en_6 =
09715     (*(pbuffer +  14));
09716   pdata->dss_calc__user_roi_spad_en_7 =
09717     (*(pbuffer +  15));
09718   pdata->dss_calc__user_roi_spad_en_8 =
09719     (*(pbuffer +  16));
09720   pdata->dss_calc__user_roi_spad_en_9 =
09721     (*(pbuffer +  17));
09722   pdata->dss_calc__user_roi_spad_en_10 =
09723     (*(pbuffer +  18));
09724   pdata->dss_calc__user_roi_spad_en_11 =
09725     (*(pbuffer +  19));
09726   pdata->dss_calc__user_roi_spad_en_12 =
09727     (*(pbuffer +  20));
09728   pdata->dss_calc__user_roi_spad_en_13 =
09729     (*(pbuffer +  21));
09730   pdata->dss_calc__user_roi_spad_en_14 =
09731     (*(pbuffer +  22));
09732   pdata->dss_calc__user_roi_spad_en_15 =
09733     (*(pbuffer +  23));
09734   pdata->dss_calc__user_roi_spad_en_16 =
09735     (*(pbuffer +  24));
09736   pdata->dss_calc__user_roi_spad_en_17 =
09737     (*(pbuffer +  25));
09738   pdata->dss_calc__user_roi_spad_en_18 =
09739     (*(pbuffer +  26));
09740   pdata->dss_calc__user_roi_spad_en_19 =
09741     (*(pbuffer +  27));
09742   pdata->dss_calc__user_roi_spad_en_20 =
09743     (*(pbuffer +  28));
09744   pdata->dss_calc__user_roi_spad_en_21 =
09745     (*(pbuffer +  29));
09746   pdata->dss_calc__user_roi_spad_en_22 =
09747     (*(pbuffer +  30));
09748   pdata->dss_calc__user_roi_spad_en_23 =
09749     (*(pbuffer +  31));
09750   pdata->dss_calc__user_roi_spad_en_24 =
09751     (*(pbuffer +  32));
09752   pdata->dss_calc__user_roi_spad_en_25 =
09753     (*(pbuffer +  33));
09754   pdata->dss_calc__user_roi_spad_en_26 =
09755     (*(pbuffer +  34));
09756   pdata->dss_calc__user_roi_spad_en_27 =
09757     (*(pbuffer +  35));
09758   pdata->dss_calc__user_roi_spad_en_28 =
09759     (*(pbuffer +  36));
09760   pdata->dss_calc__user_roi_spad_en_29 =
09761     (*(pbuffer +  37));
09762   pdata->dss_calc__user_roi_spad_en_30 =
09763     (*(pbuffer +  38));
09764   pdata->dss_calc__user_roi_spad_en_31 =
09765     (*(pbuffer +  39));
09766   pdata->dss_calc__user_roi_0 =
09767     (*(pbuffer +  40));
09768   pdata->dss_calc__user_roi_1 =
09769     (*(pbuffer +  41));
09770   pdata->dss_calc__mode_roi_0 =
09771     (*(pbuffer +  42));
09772   pdata->dss_calc__mode_roi_1 =
09773     (*(pbuffer +  43));
09774   pdata->sigma_estimator_calc__spare_0 =
09775     (*(pbuffer +  44));
09776   pdata->vhv_result__peak_signal_rate_mcps =
09777     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  46));
09778   pdata->vhv_result__signal_total_events_ref =
09779     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  48));
09780   pdata->phasecal_result__phase_output_ref =
09781     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  52));
09782   pdata->dss_result__total_rate_per_spad =
09783     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  54));
09784   pdata->dss_result__enabled_blocks =
09785     (*(pbuffer +  56));
09786   pdata->dss_result__num_requested_spads =
09787     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  58));
09788   pdata->mm_result__inner_intersection_rate =
09789     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  62));
09790   pdata->mm_result__outer_complement_rate =
09791     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  64));
09792   pdata->mm_result__total_offset =
09793     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  66));
09794   pdata->xtalk_calc__xtalk_for_enabled_spads =
09795     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  68)) & 0xFFFFFF;
09796   pdata->xtalk_result__avg_xtalk_user_roi_kcps =
09797     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  72)) & 0xFFFFFF;
09798   pdata->xtalk_result__avg_xtalk_mm_inner_roi_kcps =
09799     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  76)) & 0xFFFFFF;
09800   pdata->xtalk_result__avg_xtalk_mm_outer_roi_kcps =
09801     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  80)) & 0xFFFFFF;
09802   pdata->range_result__accum_phase =
09803     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  84));
09804   pdata->range_result__offset_corrected_range =
09805     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  88));
09806 
09807 
09808   return status;
09809 }
09810 
09811 
09812 VL53LX_Error VL53LX::VL53LX_set_patch_results(
09813   VL53LX_patch_results_t    *pdata)
09814 {
09815 
09816 
09817   VL53LX_Error status = VL53LX_ERROR_NONE;
09818   uint8_t comms_buffer[VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES];
09819 
09820 
09821   if (status == VL53LX_ERROR_NONE)
09822     status = VL53LX_i2c_encode_patch_results(
09823                pdata,
09824                VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES,
09825                comms_buffer);
09826 
09827   if (status == VL53LX_ERROR_NONE) {
09828     status = VL53LX_disable_firmware();
09829   }
09830 
09831   if (status == VL53LX_ERROR_NONE)
09832     status = VL53LX_WriteMulti(
09833                Dev,
09834                VL53LX_DSS_CALC__ROI_CTRL,
09835                comms_buffer,
09836                VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES);
09837 
09838   if (status == VL53LX_ERROR_NONE) {
09839     status = VL53LX_enable_firmware();
09840   }
09841 
09842   return status;
09843 }
09844 VL53LX_Error VL53LX::VL53LX_get_patch_results(
09845   VL53LX_patch_results_t    *pdata)
09846 {
09847 
09848 
09849   VL53LX_Error status = VL53LX_ERROR_NONE;
09850   uint8_t comms_buffer[VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES];
09851 
09852 
09853   if (status == VL53LX_ERROR_NONE) {
09854     status = VL53LX_disable_firmware();
09855   }
09856 
09857   if (status == VL53LX_ERROR_NONE)
09858     status = VL53LX_ReadMulti(
09859                Dev,
09860                VL53LX_DSS_CALC__ROI_CTRL,
09861                comms_buffer,
09862                VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES);
09863 
09864   if (status == VL53LX_ERROR_NONE) {
09865     status = VL53LX_enable_firmware();
09866   }
09867 
09868   if (status == VL53LX_ERROR_NONE)
09869     status = VL53LX_i2c_decode_patch_results(
09870                VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES,
09871                comms_buffer,
09872                pdata);
09873 
09874 
09875   return status;
09876 }
09877 
09878 VL53LX_Error VL53LX::VL53LX_i2c_encode_shadow_system_results(
09879   VL53LX_shadow_system_results_t *pdata,
09880   uint16_t                  buf_size,
09881   uint8_t                  *pbuffer)
09882 {
09883 
09884 
09885   VL53LX_Error status = VL53LX_ERROR_NONE;
09886 
09887   if (buf_size < VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES) {
09888     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
09889   }
09890 
09891   *(pbuffer +   0) =
09892     pdata->shadow_phasecal_result__vcsel_start;
09893   *(pbuffer +   2) =
09894     pdata->shadow_result__interrupt_status & 0x3F;
09895   *(pbuffer +   3) =
09896     pdata->shadow_result__range_status;
09897   *(pbuffer +   4) =
09898     pdata->shadow_result__report_status & 0xF;
09899   *(pbuffer +   5) =
09900     pdata->shadow_result__stream_count;
09901   VL53LX_i2c_encode_uint16_t(
09902     pdata->shadow_result__dss_actual_effective_spads_sd0,
09903     2,
09904     pbuffer +   6);
09905   VL53LX_i2c_encode_uint16_t(
09906     pdata->shadow_result__peak_signal_count_rate_mcps_sd0,
09907     2,
09908     pbuffer +   8);
09909   VL53LX_i2c_encode_uint16_t(
09910     pdata->shadow_result__ambient_count_rate_mcps_sd0,
09911     2,
09912     pbuffer +  10);
09913   VL53LX_i2c_encode_uint16_t(
09914     pdata->shadow_result__sigma_sd0,
09915     2,
09916     pbuffer +  12);
09917   VL53LX_i2c_encode_uint16_t(
09918     pdata->shadow_result__phase_sd0,
09919     2,
09920     pbuffer +  14);
09921   VL53LX_i2c_encode_uint16_t(
09922     pdata->shadow_result__final_crosstalk_corrected_range_mm_sd0,
09923     2,
09924     pbuffer +  16);
09925   VL53LX_i2c_encode_uint16_t(
09926     pdata->shr__peak_signal_count_rate_crosstalk_corrected_mcps_sd0,
09927     2,
09928     pbuffer +  18);
09929   VL53LX_i2c_encode_uint16_t(
09930     pdata->shadow_result__mm_inner_actual_effective_spads_sd0,
09931     2,
09932     pbuffer +  20);
09933   VL53LX_i2c_encode_uint16_t(
09934     pdata->shadow_result__mm_outer_actual_effective_spads_sd0,
09935     2,
09936     pbuffer +  22);
09937   VL53LX_i2c_encode_uint16_t(
09938     pdata->shadow_result__avg_signal_count_rate_mcps_sd0,
09939     2,
09940     pbuffer +  24);
09941   VL53LX_i2c_encode_uint16_t(
09942     pdata->shadow_result__dss_actual_effective_spads_sd1,
09943     2,
09944     pbuffer +  26);
09945   VL53LX_i2c_encode_uint16_t(
09946     pdata->shadow_result__peak_signal_count_rate_mcps_sd1,
09947     2,
09948     pbuffer +  28);
09949   VL53LX_i2c_encode_uint16_t(
09950     pdata->shadow_result__ambient_count_rate_mcps_sd1,
09951     2,
09952     pbuffer +  30);
09953   VL53LX_i2c_encode_uint16_t(
09954     pdata->shadow_result__sigma_sd1,
09955     2,
09956     pbuffer +  32);
09957   VL53LX_i2c_encode_uint16_t(
09958     pdata->shadow_result__phase_sd1,
09959     2,
09960     pbuffer +  34);
09961   VL53LX_i2c_encode_uint16_t(
09962     pdata->shadow_result__final_crosstalk_corrected_range_mm_sd1,
09963     2,
09964     pbuffer +  36);
09965   VL53LX_i2c_encode_uint16_t(
09966     pdata->shadow_result__spare_0_sd1,
09967     2,
09968     pbuffer +  38);
09969   VL53LX_i2c_encode_uint16_t(
09970     pdata->shadow_result__spare_1_sd1,
09971     2,
09972     pbuffer +  40);
09973   VL53LX_i2c_encode_uint16_t(
09974     pdata->shadow_result__spare_2_sd1,
09975     2,
09976     pbuffer +  42);
09977   *(pbuffer +  44) =
09978     pdata->shadow_result__spare_3_sd1;
09979   *(pbuffer +  45) =
09980     pdata->shadow_result__thresh_info;
09981   *(pbuffer +  80) =
09982     pdata->shadow_phasecal_result__reference_phase_hi;
09983   *(pbuffer +  81) =
09984     pdata->shadow_phasecal_result__reference_phase_lo;
09985 
09986   return status;
09987 }
09988 
09989 VL53LX_Error VL53LX::VL53LX_i2c_decode_shadow_system_results(
09990   uint16_t                   buf_size,
09991   uint8_t                   *pbuffer,
09992   VL53LX_shadow_system_results_t  *pdata)
09993 {
09994 
09995 
09996   VL53LX_Error status = VL53LX_ERROR_NONE;
09997 
09998 
09999   if (buf_size < VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES) {
10000     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
10001   }
10002 
10003   pdata->shadow_phasecal_result__vcsel_start =
10004     (*(pbuffer +   0));
10005   pdata->shadow_result__interrupt_status =
10006     (*(pbuffer +   2)) & 0x3F;
10007   pdata->shadow_result__range_status =
10008     (*(pbuffer +   3));
10009   pdata->shadow_result__report_status =
10010     (*(pbuffer +   4)) & 0xF;
10011   pdata->shadow_result__stream_count =
10012     (*(pbuffer +   5));
10013   pdata->shadow_result__dss_actual_effective_spads_sd0 =
10014     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   6));
10015   pdata->shadow_result__peak_signal_count_rate_mcps_sd0 =
10016     (VL53LX_i2c_decode_uint16_t(2, pbuffer +   8));
10017   pdata->shadow_result__ambient_count_rate_mcps_sd0 =
10018     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  10));
10019   pdata->shadow_result__sigma_sd0 =
10020     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  12));
10021   pdata->shadow_result__phase_sd0 =
10022     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  14));
10023   pdata->shadow_result__final_crosstalk_corrected_range_mm_sd0 =
10024     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  16));
10025   pdata->shr__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 =
10026     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  18));
10027   pdata->shadow_result__mm_inner_actual_effective_spads_sd0 =
10028     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  20));
10029   pdata->shadow_result__mm_outer_actual_effective_spads_sd0 =
10030     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  22));
10031   pdata->shadow_result__avg_signal_count_rate_mcps_sd0 =
10032     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  24));
10033   pdata->shadow_result__dss_actual_effective_spads_sd1 =
10034     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  26));
10035   pdata->shadow_result__peak_signal_count_rate_mcps_sd1 =
10036     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  28));
10037   pdata->shadow_result__ambient_count_rate_mcps_sd1 =
10038     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  30));
10039   pdata->shadow_result__sigma_sd1 =
10040     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  32));
10041   pdata->shadow_result__phase_sd1 =
10042     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  34));
10043   pdata->shadow_result__final_crosstalk_corrected_range_mm_sd1 =
10044     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  36));
10045   pdata->shadow_result__spare_0_sd1 =
10046     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  38));
10047   pdata->shadow_result__spare_1_sd1 =
10048     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  40));
10049   pdata->shadow_result__spare_2_sd1 =
10050     (VL53LX_i2c_decode_uint16_t(2, pbuffer +  42));
10051   pdata->shadow_result__spare_3_sd1 =
10052     (*(pbuffer +  44));
10053   pdata->shadow_result__thresh_info =
10054     (*(pbuffer +  45));
10055   pdata->shadow_phasecal_result__reference_phase_hi =
10056     (*(pbuffer +  80));
10057   pdata->shadow_phasecal_result__reference_phase_lo =
10058     (*(pbuffer +  81));
10059 
10060 
10061   return status;
10062 }
10063 
10064 VL53LX_Error VL53LX::VL53LX_set_shadow_system_results(
10065   VL53LX_shadow_system_results_t  *pdata)
10066 {
10067 
10068 
10069   VL53LX_Error status = VL53LX_ERROR_NONE;
10070   uint8_t comms_buffer[VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES];
10071 
10072 
10073   if (status == VL53LX_ERROR_NONE)
10074     status = VL53LX_i2c_encode_shadow_system_results(
10075                pdata,
10076                VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES,
10077                comms_buffer);
10078 
10079   if (status == VL53LX_ERROR_NONE) {
10080     status = VL53LX_disable_firmware();
10081   }
10082 
10083   if (status == VL53LX_ERROR_NONE)
10084     status = VL53LX_WriteMulti(
10085                Dev,
10086                VL53LX_SHADOW_PHASECAL_RESULT__VCSEL_START,
10087                comms_buffer,
10088                VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES);
10089 
10090   if (status == VL53LX_ERROR_NONE) {
10091     status = VL53LX_enable_firmware();
10092   }
10093 
10094 
10095   return status;
10096 }
10097 
10098 
10099 VL53LX_Error VL53LX::VL53LX_get_shadow_system_results(
10100   VL53LX_shadow_system_results_t  *pdata)
10101 {
10102 
10103 
10104   VL53LX_Error status = VL53LX_ERROR_NONE;
10105   uint8_t comms_buffer[VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES];
10106 
10107 
10108   if (status == VL53LX_ERROR_NONE) {
10109     status = VL53LX_disable_firmware();
10110   }
10111 
10112   if (status == VL53LX_ERROR_NONE)
10113     status = VL53LX_ReadMulti(
10114                Dev,
10115                VL53LX_SHADOW_PHASECAL_RESULT__VCSEL_START,
10116                comms_buffer,
10117                VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES);
10118 
10119   if (status == VL53LX_ERROR_NONE) {
10120     status = VL53LX_enable_firmware();
10121   }
10122 
10123   if (status == VL53LX_ERROR_NONE)
10124     status = VL53LX_i2c_decode_shadow_system_results(
10125                VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES,
10126                comms_buffer,
10127                pdata);
10128 
10129 
10130   return status;
10131 }
10132 VL53LX_Error VL53LX::VL53LX_i2c_encode_shadow_core_results(
10133   VL53LX_shadow_core_results_t *pdata,
10134   uint16_t                  buf_size,
10135   uint8_t                  *pbuffer)
10136 {
10137 
10138 
10139   VL53LX_Error status = VL53LX_ERROR_NONE;
10140 
10141 
10142   if (buf_size < VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES) {
10143     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
10144   }
10145 
10146   VL53LX_i2c_encode_uint32_t(
10147     pdata->shadow_result_core__ambient_window_events_sd0,
10148     4,
10149     pbuffer +   0);
10150   VL53LX_i2c_encode_uint32_t(
10151     pdata->shadow_result_core__ranging_total_events_sd0,
10152     4,
10153     pbuffer +   4);
10154   VL53LX_i2c_encode_int32_t(
10155     pdata->shadow_result_core__signal_total_events_sd0,
10156     4,
10157     pbuffer +   8);
10158   VL53LX_i2c_encode_uint32_t(
10159     pdata->shadow_result_core__total_periods_elapsed_sd0,
10160     4,
10161     pbuffer +  12);
10162   VL53LX_i2c_encode_uint32_t(
10163     pdata->shadow_result_core__ambient_window_events_sd1,
10164     4,
10165     pbuffer +  16);
10166   VL53LX_i2c_encode_uint32_t(
10167     pdata->shadow_result_core__ranging_total_events_sd1,
10168     4,
10169     pbuffer +  20);
10170   VL53LX_i2c_encode_int32_t(
10171     pdata->shadow_result_core__signal_total_events_sd1,
10172     4,
10173     pbuffer +  24);
10174   VL53LX_i2c_encode_uint32_t(
10175     pdata->shadow_result_core__total_periods_elapsed_sd1,
10176     4,
10177     pbuffer +  28);
10178   *(pbuffer +  32) =
10179     pdata->shadow_result_core__spare_0;
10180 
10181 
10182 
10183   return status;
10184 }
10185 
10186 VL53LX_Error VL53LX::VL53LX_i2c_decode_shadow_core_results(
10187   uint16_t                   buf_size,
10188   uint8_t                   *pbuffer,
10189   VL53LX_shadow_core_results_t  *pdata)
10190 {
10191 
10192 
10193   VL53LX_Error status = VL53LX_ERROR_NONE;
10194 
10195 
10196   if (buf_size < VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES) {
10197     return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
10198   }
10199 
10200   pdata->shadow_result_core__ambient_window_events_sd0 =
10201     (VL53LX_i2c_decode_uint32_t(4, pbuffer +   0));
10202   pdata->shadow_result_core__ranging_total_events_sd0 =
10203     (VL53LX_i2c_decode_uint32_t(4, pbuffer +   4));
10204   pdata->shadow_result_core__signal_total_events_sd0 =
10205     (VL53LX_i2c_decode_int32_t(4, pbuffer +   8));
10206   pdata->shadow_result_core__total_periods_elapsed_sd0 =
10207     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  12));
10208   pdata->shadow_result_core__ambient_window_events_sd1 =
10209     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  16));
10210   pdata->shadow_result_core__ranging_total_events_sd1 =
10211     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  20));
10212   pdata->shadow_result_core__signal_total_events_sd1 =
10213     (VL53LX_i2c_decode_int32_t(4, pbuffer +  24));
10214   pdata->shadow_result_core__total_periods_elapsed_sd1 =
10215     (VL53LX_i2c_decode_uint32_t(4, pbuffer +  28));
10216   pdata->shadow_result_core__spare_0 =
10217     (*(pbuffer +  32));
10218 
10219 
10220   return status;
10221 }
10222 
10223 VL53LX_Error VL53LX::VL53LX_set_shadow_core_results(
10224   VL53LX_shadow_core_results_t  *pdata)
10225 {
10226 
10227 
10228   VL53LX_Error status = VL53LX_ERROR_NONE;
10229   uint8_t comms_buffer[VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES];
10230 
10231 
10232   if (status == VL53LX_ERROR_NONE)
10233     status = VL53LX_i2c_encode_shadow_core_results(
10234                pdata,
10235                VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES,
10236                comms_buffer);
10237 
10238   if (status == VL53LX_ERROR_NONE) {
10239     status = VL53LX_disable_firmware();
10240   }
10241 
10242   if (status == VL53LX_ERROR_NONE)
10243     status = VL53LX_WriteMulti(
10244                Dev,
10245                VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0,
10246                comms_buffer,
10247                VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES);
10248 
10249   if (status == VL53LX_ERROR_NONE) {
10250     status = VL53LX_enable_firmware();
10251   }
10252 
10253 
10254   return status;
10255 }
10256 
10257 VL53LX_Error VL53LX::VL53LX_get_shadow_core_results(
10258   VL53LX_shadow_core_results_t  *pdata)
10259 {
10260 
10261 
10262   VL53LX_Error status = VL53LX_ERROR_NONE;
10263   uint8_t comms_buffer[VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES];
10264 
10265 
10266   if (status == VL53LX_ERROR_NONE) {
10267     status = VL53LX_disable_firmware();
10268   }
10269 
10270   if (status == VL53LX_ERROR_NONE)
10271     status = VL53LX_ReadMulti(
10272                Dev,
10273                VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0,
10274                comms_buffer,
10275                VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES);
10276 
10277   if (status == VL53LX_ERROR_NONE) {
10278     status = VL53LX_enable_firmware();
10279   }
10280 
10281   if (status == VL53LX_ERROR_NONE)
10282     status = VL53LX_i2c_decode_shadow_core_results(
10283                VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES,
10284                comms_buffer,
10285                pdata);
10286 
10287 
10288   return status;
10289 }
10290 
10291 
10292 /* vl53lx_nvm.c */
10293 
10294 VL53LX_Error VL53LX::VL53LX_nvm_enable(
10295   uint16_t        nvm_ctrl_pulse_width,
10296   int32_t         nvm_power_up_delay_us)
10297 {
10298 
10299 
10300   VL53LX_Error status = VL53LX_ERROR_NONE;
10301 
10302 
10303 
10304   if (status == VL53LX_ERROR_NONE) {
10305     status = VL53LX_disable_firmware();
10306   }
10307 
10308 
10309 
10310 
10311   if (status == VL53LX_ERROR_NONE) {
10312     status = VL53LX_enable_powerforce();
10313   }
10314 
10315 
10316 
10317   if (status == VL53LX_ERROR_NONE)
10318     status = VL53LX_WaitUs(
10319                Dev,
10320                VL53LX_ENABLE_POWERFORCE_SETTLING_TIME_US);
10321 
10322 
10323 
10324   if (status == VL53LX_ERROR_NONE)
10325     status = VL53LX_WrByte(
10326                Dev,
10327                VL53LX_RANGING_CORE__NVM_CTRL__PDN,
10328                0x01);
10329 
10330 
10331 
10332   if (status == VL53LX_ERROR_NONE)
10333     status = VL53LX_WrByte(
10334                Dev,
10335                VL53LX_RANGING_CORE__CLK_CTRL1,
10336                0x05);
10337 
10338 
10339 
10340   if (status == VL53LX_ERROR_NONE)
10341     status = VL53LX_WaitUs(
10342                Dev,
10343                nvm_power_up_delay_us);
10344 
10345 
10346 
10347   if (status == VL53LX_ERROR_NONE)
10348     status = VL53LX_WrByte(
10349                Dev,
10350                VL53LX_RANGING_CORE__NVM_CTRL__MODE,
10351                0x01);
10352 
10353   if (status == VL53LX_ERROR_NONE)
10354     status = VL53LX_WrWord(
10355                Dev,
10356                VL53LX_RANGING_CORE__NVM_CTRL__PULSE_WIDTH_MSB,
10357                nvm_ctrl_pulse_width);
10358 
10359   return status;
10360 
10361 }
10362 
10363 VL53LX_Error VL53LX::VL53LX_nvm_read(
10364   uint8_t       start_address,
10365   uint8_t       count,
10366   uint8_t      *pdata)
10367 {
10368 
10369 
10370   VL53LX_Error status   = VL53LX_ERROR_NONE;
10371   uint8_t      nvm_addr = 0;
10372 
10373 
10374 
10375   for (nvm_addr = start_address;
10376        nvm_addr < (start_address + count) ; nvm_addr++) {
10377 
10378 
10379 
10380     if (status == VL53LX_ERROR_NONE)
10381       status = VL53LX_WrByte(
10382                  Dev,
10383                  VL53LX_RANGING_CORE__NVM_CTRL__ADDR,
10384                  nvm_addr);
10385 
10386 
10387 
10388     if (status == VL53LX_ERROR_NONE)
10389       status = VL53LX_WrByte(
10390                  Dev,
10391                  VL53LX_RANGING_CORE__NVM_CTRL__READN,
10392                  0x00);
10393 
10394 
10395 
10396     if (status == VL53LX_ERROR_NONE)
10397       status = VL53LX_WaitUs(
10398                  Dev,
10399                  VL53LX_NVM_READ_TRIGGER_DELAY_US);
10400 
10401     if (status == VL53LX_ERROR_NONE)
10402       status = VL53LX_WrByte(
10403                  Dev,
10404                  VL53LX_RANGING_CORE__NVM_CTRL__READN,
10405                  0x01);
10406 
10407 
10408     if (status == VL53LX_ERROR_NONE)
10409       status = VL53LX_ReadMulti(
10410                  Dev,
10411                  VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT_MMM,
10412                  pdata,
10413                  4);
10414 
10415 
10416     pdata = pdata + 4;
10417 
10418 
10419   }
10420 
10421 
10422   return status;
10423 }
10424 
10425 VL53LX_Error VL53LX::VL53LX_nvm_disable()
10426 {
10427 
10428 
10429   VL53LX_Error status = VL53LX_ERROR_NONE;
10430 
10431 
10432   if (status == VL53LX_ERROR_NONE)
10433     status = VL53LX_WrByte(
10434                Dev,
10435                VL53LX_RANGING_CORE__NVM_CTRL__READN,
10436                0x01);
10437 
10438 
10439 
10440   if (status == VL53LX_ERROR_NONE)
10441     status = VL53LX_WrByte(
10442                Dev,
10443                VL53LX_RANGING_CORE__NVM_CTRL__PDN,
10444                0x00);
10445 
10446 
10447 
10448   if (status == VL53LX_ERROR_NONE) {
10449     status = VL53LX_disable_powerforce();
10450   }
10451 
10452 
10453 
10454   if (status == VL53LX_ERROR_NONE) {
10455     status = VL53LX_enable_firmware();
10456   }
10457 
10458 
10459   return status;
10460 
10461 }
10462 
10463 
10464 VL53LX_Error VL53LX::VL53LX_nvm_format_decode(
10465   uint16_t                   buf_size,
10466   uint8_t                   *pbuffer,
10467   VL53LX_decoded_nvm_data_t *pdata)
10468 {
10469 
10470 
10471 
10472   VL53LX_Error status = VL53LX_ERROR_NONE;
10473 
10474   uint8_t    i        = 0;
10475   uint8_t   *ptmp     = NULL;
10476   int        pptmp[VL53LX_NVM_MAX_FMT_RANGE_DATA];
10477 
10478   if (buf_size < VL53LX_NVM_SIZE_IN_BYTES) {
10479     return VL53LX_ERROR_BUFFER_TOO_SMALL;
10480   }
10481 
10482   pdata->nvm__identification_model_id =
10483     (uint8_t)VL53LX_i2c_decode_with_mask(
10484       1,
10485       pbuffer + VL53LX_NVM__IDENTIFICATION__MODEL_ID,
10486       0x000000FF,
10487       0,
10488       0);
10489   pdata->nvm__identification_module_type =
10490     (uint8_t)VL53LX_i2c_decode_with_mask(
10491       1,
10492       pbuffer + VL53LX_NVM__IDENTIFICATION__MODULE_TYPE,
10493       0x000000FF,
10494       0,
10495       0);
10496   pdata->nvm__identification_revision_id =
10497     (uint8_t)VL53LX_i2c_decode_with_mask(
10498       1,
10499       pbuffer + VL53LX_NVM__IDENTIFICATION__REVISION_ID,
10500       0x0000000F,
10501       0,
10502       0);
10503   pdata->nvm__identification_module_id =
10504     (uint16_t)VL53LX_i2c_decode_with_mask(
10505       2,
10506       pbuffer + VL53LX_NVM__IDENTIFICATION__MODULE_ID,
10507       0x0000FFFF,
10508       0,
10509       0);
10510   pdata->nvm__i2c_valid =
10511     (uint8_t)VL53LX_i2c_decode_with_mask(
10512       1,
10513       pbuffer + VL53LX_NVM__I2C_VALID,
10514       0x000000FF,
10515       0,
10516       0);
10517   pdata->nvm__i2c_device_address_ews =
10518     (uint8_t)VL53LX_i2c_decode_with_mask(
10519       1,
10520       pbuffer + VL53LX_NVM__I2C_SLAVE__DEVICE_ADDRESS,
10521       0x000000FF,
10522       0,
10523       0);
10524   pdata->nvm__ews__fast_osc_frequency =
10525     (uint16_t)VL53LX_i2c_decode_with_mask(
10526       2,
10527       pbuffer +
10528       VL53LX_NVM__EWS__OSC_MEASURED__FAST_OSC_FREQUENCY,
10529       0x0000FFFF,
10530       0,
10531       0);
10532   pdata->nvm__ews__fast_osc_trim_max =
10533     (uint8_t)VL53LX_i2c_decode_with_mask(
10534       1,
10535       pbuffer + VL53LX_NVM__EWS__FAST_OSC_TRIM_MAX,
10536       0x0000007F,
10537       0,
10538       0);
10539   pdata->nvm__ews__fast_osc_freq_set =
10540     (uint8_t)VL53LX_i2c_decode_with_mask(
10541       1,
10542       pbuffer + VL53LX_NVM__EWS__FAST_OSC_FREQ_SET,
10543       0x00000007,
10544       0,
10545       0);
10546   pdata->nvm__ews__slow_osc_calibration =
10547     (uint16_t)VL53LX_i2c_decode_with_mask(
10548       2,
10549       pbuffer + VL53LX_NVM__EWS__SLOW_OSC_CALIBRATION,
10550       0x000003FF,
10551       0,
10552       0);
10553   pdata->nvm__fmt__fast_osc_frequency =
10554     (uint16_t)VL53LX_i2c_decode_with_mask(
10555       2,
10556       pbuffer +
10557       VL53LX_NVM__FMT__OSC_MEASURED__FAST_OSC_FREQUENCY,
10558       0x0000FFFF,
10559       0,
10560       0);
10561   pdata->nvm__fmt__fast_osc_trim_max =
10562     (uint8_t)VL53LX_i2c_decode_with_mask(
10563       1,
10564       pbuffer + VL53LX_NVM__FMT__FAST_OSC_TRIM_MAX,
10565       0x0000007F,
10566       0,
10567       0);
10568   pdata->nvm__fmt__fast_osc_freq_set =
10569     (uint8_t)VL53LX_i2c_decode_with_mask(
10570       1,
10571       pbuffer + VL53LX_NVM__FMT__FAST_OSC_FREQ_SET,
10572       0x00000007,
10573       0,
10574       0);
10575   pdata->nvm__fmt__slow_osc_calibration =
10576     (uint16_t)VL53LX_i2c_decode_with_mask(
10577       2,
10578       pbuffer + VL53LX_NVM__FMT__SLOW_OSC_CALIBRATION,
10579       0x000003FF,
10580       0,
10581       0);
10582   pdata->nvm__vhv_config_unlock =
10583     (uint8_t)VL53LX_i2c_decode_with_mask(
10584       1,
10585       pbuffer + VL53LX_NVM__VHV_CONFIG_UNLOCK,
10586       0x000000FF,
10587       0,
10588       0);
10589   pdata->nvm__ref_selvddpix =
10590     (uint8_t)VL53LX_i2c_decode_with_mask(
10591       1,
10592       pbuffer + VL53LX_NVM__REF_SELVDDPIX,
10593       0x0000000F,
10594       0,
10595       0);
10596   pdata->nvm__ref_selvquench =
10597     (uint8_t)VL53LX_i2c_decode_with_mask(
10598       1,
10599       pbuffer + VL53LX_NVM__REF_SELVQUENCH,
10600       0x00000078,
10601       3,
10602       0);
10603   pdata->nvm__regavdd1v2_sel =
10604     (uint8_t)VL53LX_i2c_decode_with_mask(
10605       1,
10606       pbuffer + VL53LX_NVM__REGAVDD1V2_SEL_REGDVDD1V2_SEL,
10607       0x0000000C,
10608       2,
10609       0);
10610   pdata->nvm__regdvdd1v2_sel =
10611     (uint8_t)VL53LX_i2c_decode_with_mask(
10612       1,
10613       pbuffer + VL53LX_NVM__REGAVDD1V2_SEL_REGDVDD1V2_SEL,
10614       0x00000003,
10615       0,
10616       0);
10617   pdata->nvm__vhv_timeout__macrop =
10618     (uint8_t)VL53LX_i2c_decode_with_mask(
10619       1,
10620       pbuffer +
10621       VL53LX_NVM__VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,
10622       0x00000003,
10623       0,
10624       0);
10625   pdata->nvm__vhv_loop_bound =
10626     (uint8_t)VL53LX_i2c_decode_with_mask(
10627       1,
10628       pbuffer +
10629       VL53LX_NVM__VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,
10630       0x000000FC,
10631       2,
10632       0);
10633   pdata->nvm__vhv_count_threshold =
10634     (uint8_t)VL53LX_i2c_decode_with_mask(
10635       1,
10636       pbuffer + VL53LX_NVM__VHV_CONFIG__COUNT_THRESH,
10637       0x000000FF,
10638       0,
10639       0);
10640   pdata->nvm__vhv_offset =
10641     (uint8_t)VL53LX_i2c_decode_with_mask(
10642       1,
10643       pbuffer + VL53LX_NVM__VHV_CONFIG__OFFSET,
10644       0x0000003F,
10645       0,
10646       0);
10647   pdata->nvm__vhv_init_enable =
10648     (uint8_t)VL53LX_i2c_decode_with_mask(
10649       1,
10650       pbuffer + VL53LX_NVM__VHV_CONFIG__INIT,
10651       0x00000080,
10652       7,
10653       0);
10654   pdata->nvm__vhv_init_value =
10655     (uint8_t)VL53LX_i2c_decode_with_mask(
10656       1,
10657       pbuffer + VL53LX_NVM__VHV_CONFIG__INIT,
10658       0x0000003F,
10659       0,
10660       0);
10661   pdata->nvm__laser_safety_vcsel_trim_ll =
10662     (uint8_t)VL53LX_i2c_decode_with_mask(
10663       1,
10664       pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_TRIM_LL,
10665       0x00000007,
10666       0,
10667       0);
10668   pdata->nvm__laser_safety_vcsel_selion_ll =
10669     (uint8_t)VL53LX_i2c_decode_with_mask(
10670       1,
10671       pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_LL,
10672       0x0000003F,
10673       0,
10674       0);
10675   pdata->nvm__laser_safety_vcsel_selion_max_ll =
10676     (uint8_t)VL53LX_i2c_decode_with_mask(
10677       1,
10678       pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_MAX_LL,
10679       0x0000003F,
10680       0,
10681       0);
10682   pdata->nvm__laser_safety_mult_ll =
10683     (uint8_t)VL53LX_i2c_decode_with_mask(
10684       1,
10685       pbuffer + VL53LX_NVM__LASER_SAFETY__MULT_LL,
10686       0x0000003F,
10687       0,
10688       0);
10689   pdata->nvm__laser_safety_clip_ll =
10690     (uint8_t)VL53LX_i2c_decode_with_mask(
10691       1,
10692       pbuffer + VL53LX_NVM__LASER_SAFETY__CLIP_LL,
10693       0x0000003F,
10694       0,
10695       0);
10696   pdata->nvm__laser_safety_vcsel_trim_ld =
10697     (uint8_t)VL53LX_i2c_decode_with_mask(
10698       1,
10699       pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_TRIM_LD,
10700       0x00000007,
10701       0,
10702       0);
10703   pdata->nvm__laser_safety_vcsel_selion_ld =
10704     (uint8_t)VL53LX_i2c_decode_with_mask(
10705       1,
10706       pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_LD,
10707       0x0000003F,
10708       0,
10709       0);
10710   pdata->nvm__laser_safety_vcsel_selion_max_ld =
10711     (uint8_t)VL53LX_i2c_decode_with_mask(
10712       1,
10713       pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_MAX_LD,
10714       0x0000003F,
10715       0,
10716       0);
10717   pdata->nvm__laser_safety_mult_ld =
10718     (uint8_t)VL53LX_i2c_decode_with_mask(
10719       1,
10720       pbuffer + VL53LX_NVM__LASER_SAFETY__MULT_LD,
10721       0x0000003F,
10722       0,
10723       0);
10724   pdata->nvm__laser_safety_clip_ld =
10725     (uint8_t)VL53LX_i2c_decode_with_mask(
10726       1,
10727       pbuffer + VL53LX_NVM__LASER_SAFETY__CLIP_LD,
10728       0x0000003F,
10729       0,
10730       0);
10731   pdata->nvm__laser_safety_lock_byte =
10732     (uint8_t)VL53LX_i2c_decode_with_mask(
10733       1,
10734       pbuffer + VL53LX_NVM__LASER_SAFETY_LOCK_BYTE,
10735       0x000000FF,
10736       0,
10737       0);
10738   pdata->nvm__laser_safety_unlock_byte =
10739     (uint8_t)VL53LX_i2c_decode_with_mask(
10740       1,
10741       pbuffer + VL53LX_NVM__LASER_SAFETY_UNLOCK_BYTE,
10742       0x000000FF,
10743       0,
10744       0);
10745 
10746 
10747 
10748   ptmp = pbuffer + VL53LX_NVM__EWS__SPAD_ENABLES_RTN_0_;
10749   for (i = 0 ; i < VL53LX_RTN_SPAD_BUFFER_SIZE ; i++) {
10750     pdata->nvm__ews__spad_enables_rtn[i] = *ptmp++;
10751   }
10752 
10753   ptmp = pbuffer + VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC1_0_;
10754   for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) {
10755     pdata->nvm__ews__spad_enables_ref__loc1[i] = *ptmp++;
10756   }
10757 
10758   ptmp = pbuffer + VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC2_0_;
10759   for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) {
10760     pdata->nvm__ews__spad_enables_ref__loc2[i] = *ptmp++;
10761   }
10762 
10763   ptmp = pbuffer + VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC3_0_;
10764   for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) {
10765     pdata->nvm__ews__spad_enables_ref__loc3[i] = *ptmp++;
10766   }
10767 
10768 
10769 
10770   ptmp = pbuffer + VL53LX_NVM__FMT__SPAD_ENABLES_RTN_0_;
10771   for (i = 0 ; i < VL53LX_RTN_SPAD_BUFFER_SIZE ; i++) {
10772     pdata->nvm__fmt__spad_enables_rtn[i] = *ptmp++;
10773   }
10774 
10775   ptmp = pbuffer + VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC1_0_;
10776   for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) {
10777     pdata->nvm__fmt__spad_enables_ref__loc1[i] = *ptmp++;
10778   }
10779 
10780   ptmp = pbuffer + VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC2_0_;
10781   for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) {
10782     pdata->nvm__fmt__spad_enables_ref__loc2[i] = *ptmp++;
10783   }
10784 
10785   ptmp = pbuffer + VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC3_0_;
10786   for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) {
10787     pdata->nvm__fmt__spad_enables_ref__loc3[i] = *ptmp++;
10788   }
10789 
10790 
10791   pdata->nvm__fmt__roi_config__mode_roi_centre_spad =
10792     (uint8_t)VL53LX_i2c_decode_with_mask(
10793       1,
10794       pbuffer +
10795       VL53LX_NVM__FMT__ROI_CONFIG__MODE_ROI_CENTRE_SPAD,
10796       0x000000FF,
10797       0,
10798       0);
10799   pdata->nvm__fmt__roi_config__mode_roi_x_size =
10800     (uint8_t)VL53LX_i2c_decode_with_mask(
10801       1,
10802       pbuffer +
10803       VL53LX_NVM__FMT__ROI_CONFIG__MODE_ROI_XY_SIZE,
10804       0x000000F0,
10805       4,
10806       0);
10807   pdata->nvm__fmt__roi_config__mode_roi_y_size =
10808     (uint8_t)VL53LX_i2c_decode_with_mask(
10809       1,
10810       pbuffer + VL53LX_NVM__FMT__ROI_CONFIG__MODE_ROI_XY_SIZE,
10811       0x0000000F,
10812       0,
10813       0);
10814   pdata->nvm__fmt__ref_spad_apply__num_requested_ref_spad =
10815     (uint8_t)VL53LX_i2c_decode_with_mask(
10816       1,
10817       pbuffer +
10818       VL53LX_NVM__FMT__REF_SPAD_APPLY__NUM_REQUESTED_REF_SPAD,
10819       0x000000FF,
10820       0,
10821       0);
10822   pdata->nvm__fmt__ref_spad_man__ref_location =
10823     (uint8_t)VL53LX_i2c_decode_with_mask(
10824       1,
10825       pbuffer + VL53LX_NVM__FMT__REF_SPAD_MAN__REF_LOCATION,
10826       0x00000003,
10827       0,
10828       0);
10829   pdata->nvm__fmt__mm_config__inner_offset_mm =
10830     (uint16_t)VL53LX_i2c_decode_with_mask(
10831       2,
10832       pbuffer + VL53LX_NVM__FMT__MM_CONFIG__INNER_OFFSET_MM,
10833       0x0000FFFF,
10834       0,
10835       0);
10836   pdata->nvm__fmt__mm_config__outer_offset_mm =
10837     (uint16_t)VL53LX_i2c_decode_with_mask(
10838       2,
10839       pbuffer + VL53LX_NVM__FMT__MM_CONFIG__OUTER_OFFSET_MM,
10840       0x0000FFFF,
10841       0,
10842       0);
10843   pdata->nvm__fmt__algo_part_to_part_range_offset_mm =
10844     (uint16_t)VL53LX_i2c_decode_with_mask(
10845       2,
10846       pbuffer +
10847       VL53LX_NVM__FMT__ALGO__PART_TO_PART_RANGE_OFFSET_MM,
10848       0x00000FFF,
10849       0,
10850       0);
10851   pdata->nvm__fmt__algo__crosstalk_compensation_plane_offset_kcps =
10852     (uint16_t)VL53LX_i2c_decode_with_mask(
10853       2,
10854       pbuffer +
10855       VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS,
10856       0x0000FFFF,
10857       0,
10858       0);
10859   pdata->nvm__fmt__algo__crosstalk_compensation_x_plane_gradient_kcps =
10860     (uint16_t)VL53LX_i2c_decode_with_mask(
10861       2,
10862       pbuffer +
10863       VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS,
10864       0x0000FFFF,
10865       0,
10866       0);
10867   pdata->nvm__fmt__algo__crosstalk_compensation_y_plane_gradient_kcps =
10868     (uint16_t)VL53LX_i2c_decode_with_mask(
10869       2,
10870       pbuffer +
10871       VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS,
10872       0x0000FFFF,
10873       0,
10874       0);
10875   pdata->nvm__fmt__spare__host_config__nvm_config_spare_0 =
10876     (uint8_t)VL53LX_i2c_decode_with_mask(
10877       1,
10878       pbuffer +
10879       VL53LX_NVM__FMT__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_0,
10880       0x000000FF,
10881       0,
10882       0);
10883   pdata->nvm__fmt__spare__host_config__nvm_config_spare_1 =
10884     (uint8_t)VL53LX_i2c_decode_with_mask(
10885       1,
10886       pbuffer +
10887       VL53LX_NVM__FMT__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_1,
10888       0x000000FF,
10889       0,
10890       0);
10891   pdata->nvm__customer_space_programmed =
10892     (uint8_t)VL53LX_i2c_decode_with_mask(
10893       1,
10894       pbuffer + VL53LX_NVM__CUSTOMER_NVM_SPACE_PROGRAMMED,
10895       0x000000FF,
10896       0,
10897       0);
10898   pdata->nvm__cust__i2c_device_address =
10899     (uint8_t)VL53LX_i2c_decode_with_mask(
10900       1,
10901       pbuffer + VL53LX_NVM__CUST__I2C_SLAVE__DEVICE_ADDRESS,
10902       0x000000FF,
10903       0,
10904       0);
10905   pdata->nvm__cust__ref_spad_apply__num_requested_ref_spad =
10906     (uint8_t)VL53LX_i2c_decode_with_mask(
10907       1,
10908       pbuffer +
10909       VL53LX_NVM__CUST__REF_SPAD_APPLY__NUM_REQUESTED_REF_SPAD,
10910       0x000000FF,
10911       0,
10912       0);
10913   pdata->nvm__cust__ref_spad_man__ref_location =
10914     (uint8_t)VL53LX_i2c_decode_with_mask(
10915       1,
10916       pbuffer + VL53LX_NVM__CUST__REF_SPAD_MAN__REF_LOCATION,
10917       0x00000003,
10918       0,
10919       0);
10920   pdata->nvm__cust__mm_config__inner_offset_mm =
10921     (uint16_t)VL53LX_i2c_decode_with_mask(
10922       2,
10923       pbuffer + VL53LX_NVM__CUST__MM_CONFIG__INNER_OFFSET_MM,
10924       0x0000FFFF,
10925       0,
10926       0);
10927   pdata->nvm__cust__mm_config__outer_offset_mm =
10928     (uint16_t)VL53LX_i2c_decode_with_mask(
10929       2,
10930       pbuffer + VL53LX_NVM__CUST__MM_CONFIG__OUTER_OFFSET_MM,
10931       0x0000FFFF,
10932       0,
10933       0);
10934   pdata->nvm__cust__algo_part_to_part_range_offset_mm =
10935     (uint16_t)VL53LX_i2c_decode_with_mask(
10936       2,
10937       pbuffer +
10938       VL53LX_NVM__CUST__ALGO__PART_TO_PART_RANGE_OFFSET_MM,
10939       0x00000FFF,
10940       0,
10941       0);
10942   pdata->nvm__cust__algo__crosstalk_compensation_plane_offset_kcps =
10943     (uint16_t)VL53LX_i2c_decode_with_mask(
10944       2,
10945       pbuffer +
10946       VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS,
10947       0x0000FFFF,
10948       0,
10949       0);
10950   pdata->nvm__cust__algo__crosstalk_compensation_x_plane_gradient_kcps =
10951     (uint16_t)VL53LX_i2c_decode_with_mask(
10952       2,
10953       pbuffer +
10954       VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS,
10955       0x0000FFFF,
10956       0,
10957       0);
10958   pdata->nvm__cust__algo__crosstalk_compensation_y_plane_gradient_kcps =
10959     (uint16_t)VL53LX_i2c_decode_with_mask(
10960       2,
10961       pbuffer +
10962       VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS,
10963       0x0000FFFF,
10964       0,
10965       0);
10966   pdata->nvm__cust__spare__host_config__nvm_config_spare_0 =
10967     (uint8_t)VL53LX_i2c_decode_with_mask(
10968       1,
10969       pbuffer + VL53LX_NVM__CUST__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_0,
10970       0x000000FF,
10971       0,
10972       0);
10973   pdata->nvm__cust__spare__host_config__nvm_config_spare_1 =
10974     (uint8_t)VL53LX_i2c_decode_with_mask(
10975       1,
10976       pbuffer +
10977       VL53LX_NVM__CUST__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_1,
10978       0x000000FF,
10979       0,
10980       0);
10981 
10982 
10983 
10984   if (status == VL53LX_ERROR_NONE)
10985     status =
10986       VL53LX_nvm_decode_optical_centre(
10987         buf_size,
10988         pbuffer + VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_INDEX,
10989         &(pdata->fmt_optical_centre));
10990 
10991 
10992 
10993   if (status == VL53LX_ERROR_NONE)
10994     status =
10995       VL53LX_nvm_decode_cal_peak_rate_map(
10996         buf_size,
10997         pbuffer + VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_INDEX,
10998         &(pdata->fmt_peak_rate_map));
10999 
11000 
11001 
11002   if (status == VL53LX_ERROR_NONE)
11003     status =
11004       VL53LX_nvm_decode_additional_offset_cal_data(
11005         buf_size,
11006         pbuffer +
11007         VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_INDEX,
11008         &(pdata->fmt_add_offset_data));
11009 
11010 
11011 
11012   pptmp[0] = VL53LX_NVM__FMT__RANGE_RESULTS__140MM_MM_PRE_RANGE;
11013   pptmp[1] = VL53LX_NVM__FMT__RANGE_RESULTS__140MM_DARK;
11014   pptmp[2] = VL53LX_NVM__FMT__RANGE_RESULTS__400MM_DARK;
11015   pptmp[3] = VL53LX_NVM__FMT__RANGE_RESULTS__400MM_AMBIENT;
11016 
11017   for (i = 0 ; i < VL53LX_NVM_MAX_FMT_RANGE_DATA ; i++) {
11018     if (status == VL53LX_ERROR_NONE)
11019       status =
11020         VL53LX_nvm_decode_fmt_range_results_data(
11021           buf_size,
11022           pbuffer + pptmp[i],
11023           &(pdata->fmt_range_data[i]));
11024   }
11025 
11026 
11027   if (status == VL53LX_ERROR_NONE)
11028     status =
11029       VL53LX_nvm_decode_fmt_info(
11030         buf_size,
11031         pbuffer,
11032         &(pdata->fmt_info));
11033 
11034   if (status == VL53LX_ERROR_NONE)
11035     status =
11036       VL53LX_nvm_decode_ews_info(
11037         buf_size,
11038         pbuffer,
11039         &(pdata->ews_info));
11040 
11041   return status;
11042 
11043 }
11044 VL53LX_Error VL53LX::VL53LX_nvm_decode_optical_centre(
11045   uint16_t                    buf_size,
11046   uint8_t                    *pbuffer,
11047   VL53LX_optical_centre_t    *pdata)
11048 {
11049 
11050   VL53LX_Error status   = VL53LX_ERROR_NONE;
11051 
11052   uint16_t  tmp = 0;
11053 
11054   if (buf_size < VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE) {
11055     return VL53LX_ERROR_BUFFER_TOO_SMALL;
11056   }
11057 
11058 
11059   tmp  = 0x0100;
11060   tmp -= (uint16_t) * (pbuffer + 2);
11061   if (tmp > 0x0FF) {
11062     tmp = 0;
11063   }
11064 
11065   pdata->x_centre = (uint8_t)tmp;
11066   pdata->y_centre = *(pbuffer + 3);
11067 
11068   return status;
11069 }
11070 
11071 VL53LX_Error VL53LX::VL53LX_nvm_decode_cal_peak_rate_map(
11072   uint16_t                    buf_size,
11073   uint8_t                    *pbuffer,
11074   VL53LX_cal_peak_rate_map_t *pdata)
11075 {
11076 
11077   VL53LX_Error status   = VL53LX_ERROR_NONE;
11078 
11079   uint8_t   *ptmp = NULL;
11080   uint8_t       i = 0;
11081 
11082   if (buf_size < VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE) {
11083     return VL53LX_ERROR_BUFFER_TOO_SMALL;
11084   }
11085 
11086   pdata->cal_distance_mm =
11087     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer);
11088 
11089   pdata->cal_reflectance_pc =
11090     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 2);
11091   pdata->cal_reflectance_pc =
11092     pdata->cal_reflectance_pc >> 6;
11093 
11094   pdata->max_samples = VL53LX_NVM_PEAK_RATE_MAP_SAMPLES;
11095   pdata->width       = VL53LX_NVM_PEAK_RATE_MAP_WIDTH;
11096   pdata->height      = VL53LX_NVM_PEAK_RATE_MAP_HEIGHT;
11097 
11098   ptmp = pbuffer + 4;
11099   for (i = 0 ; i < VL53LX_NVM_PEAK_RATE_MAP_SAMPLES ; i++) {
11100     pdata->peak_rate_mcps[i] =
11101       (uint16_t)VL53LX_i2c_decode_uint16_t(2, ptmp);
11102     ptmp += 2;
11103   }
11104 
11105   return status;
11106 }
11107 VL53LX_Error VL53LX::VL53LX_nvm_decode_additional_offset_cal_data(
11108   uint16_t                             buf_size,
11109   uint8_t                             *pbuffer,
11110   VL53LX_additional_offset_cal_data_t *pdata)
11111 {
11112 
11113   VL53LX_Error status   = VL53LX_ERROR_NONE;
11114 
11115   if (buf_size < VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE) {
11116     return VL53LX_ERROR_BUFFER_TOO_SMALL;
11117   }
11118 
11119   pdata->result__mm_inner_actual_effective_spads =
11120     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer);
11121 
11122   pdata->result__mm_outer_actual_effective_spads =
11123     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 2);
11124 
11125   pdata->result__mm_inner_peak_signal_count_rtn_mcps =
11126     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 4);
11127 
11128   pdata->result__mm_outer_peak_signal_count_rtn_mcps =
11129     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 6);
11130 
11131   return status;
11132 }
11133 
11134 
11135 VL53LX_Error VL53LX::VL53LX_nvm_decode_fmt_range_results_data(
11136   uint16_t                             buf_size,
11137   uint8_t                             *pbuffer,
11138   VL53LX_decoded_nvm_fmt_range_data_t *pdata)
11139 {
11140 
11141   VL53LX_Error status   = VL53LX_ERROR_NONE;
11142 
11143   if (buf_size < VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES) {
11144     return VL53LX_ERROR_BUFFER_TOO_SMALL;
11145   }
11146 
11147   pdata->result__actual_effective_rtn_spads =
11148     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer);
11149 
11150   pdata->ref_spad_array__num_requested_ref_spads =
11151     *(pbuffer + 2);
11152 
11153   pdata->ref_spad_array__ref_location =
11154     *(pbuffer + 3);
11155 
11156   pdata->result__peak_signal_count_rate_rtn_mcps =
11157     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 4);
11158 
11159   pdata->result__ambient_count_rate_rtn_mcps =
11160     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 6);
11161 
11162   pdata->result__peak_signal_count_rate_ref_mcps =
11163     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 8);
11164 
11165   pdata->result__ambient_count_rate_ref_mcps =
11166     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 10);
11167 
11168   pdata->measured_distance_mm =
11169     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 12);
11170 
11171   pdata->measured_distance_stdev_mm =
11172     (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 14);
11173 
11174   return status;
11175 }
11176 
11177 
11178 VL53LX_Error VL53LX::VL53LX_nvm_decode_fmt_info(
11179   uint16_t                       buf_size,
11180   uint8_t                       *pbuffer,
11181   VL53LX_decoded_nvm_fmt_info_t *pdata)
11182 {
11183 
11184   VL53LX_Error status   = VL53LX_ERROR_NONE;
11185 
11186   if (buf_size < VL53LX_NVM_SIZE_IN_BYTES) {
11187     return VL53LX_ERROR_BUFFER_TOO_SMALL;
11188   }
11189 
11190   pdata->nvm__fmt__fgc[0] =
11191     (char)VL53LX_i2c_decode_with_mask(
11192       1,
11193       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_0,
11194       0x000000FE,
11195       1,
11196       0);
11197   pdata->nvm__fmt__fgc[1] =
11198     (char)VL53LX_i2c_decode_with_mask(
11199       1,
11200       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_1,
11201       0x000001FC,
11202       2,
11203       0);
11204   pdata->nvm__fmt__fgc[2] =
11205     (char)VL53LX_i2c_decode_with_mask(
11206       1,
11207       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_2 - 1,
11208       0x000003F8,
11209       3,
11210       0);
11211   pdata->nvm__fmt__fgc[3] =
11212     (char)VL53LX_i2c_decode_with_mask(
11213       1,
11214       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_3 - 1,
11215       0x000007F0,
11216       4,
11217       0);
11218   pdata->nvm__fmt__fgc[4] =
11219     (char)VL53LX_i2c_decode_with_mask(
11220       1,
11221       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_4 - 1,
11222       0x00000FE0,
11223       5,
11224       0);
11225   pdata->nvm__fmt__fgc[5] =
11226     (char)VL53LX_i2c_decode_with_mask(
11227       1,
11228       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_5 - 1,
11229       0x00001FC0,
11230       6,
11231       0);
11232   pdata->nvm__fmt__fgc[6] =
11233     (char)VL53LX_i2c_decode_with_mask(
11234       1,
11235       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_6 - 1,
11236       0x00003F80,
11237       7,
11238       0);
11239   pdata->nvm__fmt__fgc[7] =
11240     (char)VL53LX_i2c_decode_with_mask(
11241       1,
11242       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_6,
11243       0x0000007F,
11244       0,
11245       0);
11246   pdata->nvm__fmt__fgc[8] =
11247     (char)VL53LX_i2c_decode_with_mask(
11248       1,
11249       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_7,
11250       0x000000FE,
11251       1,
11252       0);
11253   pdata->nvm__fmt__fgc[9] =
11254     (char)VL53LX_i2c_decode_with_mask(
11255       1,
11256       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_8,
11257       0x000001FC,
11258       2,
11259       0);
11260   pdata->nvm__fmt__fgc[10] =
11261     (char)VL53LX_i2c_decode_with_mask(
11262       1,
11263       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_9 - 1,
11264       0x000003F8,
11265       3,
11266       0);
11267   pdata->nvm__fmt__fgc[11] =
11268     (char)VL53LX_i2c_decode_with_mask(
11269       1,
11270       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_10 - 1,
11271       0x000007F0,
11272       4,
11273       0);
11274   pdata->nvm__fmt__fgc[12] =
11275     (char)VL53LX_i2c_decode_with_mask(
11276       1,
11277       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_11 - 1,
11278       0x00000FE0,
11279       5,
11280       0);
11281   pdata->nvm__fmt__fgc[13] =
11282     (char)VL53LX_i2c_decode_with_mask(
11283       1,
11284       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_12 - 1,
11285       0x00001FC0,
11286       6,
11287       0);
11288   pdata->nvm__fmt__fgc[14] =
11289     (char)VL53LX_i2c_decode_with_mask(
11290       1,
11291       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_13 - 1,
11292       0x00003F80,
11293       7,
11294       0);
11295   pdata->nvm__fmt__fgc[15] =
11296     (char)VL53LX_i2c_decode_with_mask(
11297       1,
11298       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_13,
11299       0x0000007F,
11300       0,
11301       0);
11302   pdata->nvm__fmt__fgc[16] =
11303     (char)VL53LX_i2c_decode_with_mask(
11304       1,
11305       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_14,
11306       0x000000FE,
11307       1,
11308       0);
11309   pdata->nvm__fmt__fgc[17] =
11310     (char)VL53LX_i2c_decode_with_mask(
11311       1,
11312       pbuffer + VL53LX_NVM__FMT__FGC__BYTE_15,
11313       0x000001FC,
11314       2,
11315       0);
11316   pdata->nvm__fmt__fgc[18] = 0x00;
11317 
11318   pdata->nvm__fmt__test_program_major =
11319     (uint8_t)VL53LX_i2c_decode_with_mask(
11320       1,
11321       pbuffer + VL53LX_NVM__FMT__TEST_PROGRAM_MAJOR_MINOR,
11322       0x000000E0,
11323       5,
11324       0);
11325   pdata->nvm__fmt__test_program_minor =
11326     (uint8_t)VL53LX_i2c_decode_with_mask(
11327       1,
11328       pbuffer + VL53LX_NVM__FMT__TEST_PROGRAM_MAJOR_MINOR,
11329       0x0000001F,
11330       0,
11331       0);
11332   pdata->nvm__fmt__map_major =
11333     (uint8_t)VL53LX_i2c_decode_with_mask(
11334       1,
11335       pbuffer + VL53LX_NVM__FMT__MAP_MAJOR_MINOR,
11336       0x000000E0,
11337       5,
11338       0);
11339   pdata->nvm__fmt__map_minor =
11340     (uint8_t)VL53LX_i2c_decode_with_mask(
11341       1,
11342       pbuffer + VL53LX_NVM__FMT__MAP_MAJOR_MINOR,
11343       0x0000001F,
11344       0,
11345       0);
11346   pdata->nvm__fmt__year =
11347     (uint8_t)VL53LX_i2c_decode_with_mask(
11348       1,
11349       pbuffer + VL53LX_NVM__FMT__YEAR_MONTH,
11350       0x000000F0,
11351       4,
11352       0);
11353   pdata->nvm__fmt__month =
11354     (uint8_t)VL53LX_i2c_decode_with_mask(
11355       1,
11356       pbuffer + VL53LX_NVM__FMT__YEAR_MONTH,
11357       0x0000000F,
11358       0,
11359       0);
11360   pdata->nvm__fmt__day =
11361     (uint8_t)VL53LX_i2c_decode_with_mask(
11362       1,
11363       pbuffer + VL53LX_NVM__FMT__DAY_MODULE_DATE_PHASE,
11364       0x000000F8,
11365       3,
11366       0);
11367   pdata->nvm__fmt__module_date_phase =
11368     (uint8_t)VL53LX_i2c_decode_with_mask(
11369       1,
11370       pbuffer + VL53LX_NVM__FMT__DAY_MODULE_DATE_PHASE,
11371       0x00000007,
11372       0,
11373       0);
11374   pdata->nvm__fmt__time =
11375     (uint16_t)VL53LX_i2c_decode_with_mask(
11376       2,
11377       pbuffer + VL53LX_NVM__FMT__TIME,
11378       0x0000FFFF,
11379       0,
11380       0);
11381   pdata->nvm__fmt__tester_id =
11382     (uint8_t)VL53LX_i2c_decode_with_mask(
11383       1,
11384       pbuffer + VL53LX_NVM__FMT__TESTER_ID,
11385       0x000000FF,
11386       0,
11387       0);
11388   pdata->nvm__fmt__site_id =
11389     (uint8_t)VL53LX_i2c_decode_with_mask(
11390       1,
11391       pbuffer + VL53LX_NVM__FMT__SITE_ID,
11392       0x000000FF,
11393       0,
11394       0);
11395 
11396   return status;
11397 }
11398 
11399 
11400 VL53LX_Error VL53LX::VL53LX_nvm_decode_ews_info(
11401   uint16_t                       buf_size,
11402   uint8_t                       *pbuffer,
11403   VL53LX_decoded_nvm_ews_info_t *pdata)
11404 {
11405 
11406   VL53LX_Error status   = VL53LX_ERROR_NONE;
11407 
11408   if (buf_size < VL53LX_NVM_SIZE_IN_BYTES) {
11409     return VL53LX_ERROR_BUFFER_TOO_SMALL;
11410   }
11411 
11412   pdata->nvm__ews__test_program_major =
11413     (uint8_t)VL53LX_i2c_decode_with_mask(
11414       1,
11415       pbuffer + VL53LX_NVM__EWS__TEST_PROGRAM_MAJOR_MINOR,
11416       0x000000E0,
11417       5,
11418       0);
11419   pdata->nvm__ews__test_program_minor =
11420     (uint8_t)VL53LX_i2c_decode_with_mask(
11421       1,
11422       pbuffer + VL53LX_NVM__EWS__TEST_PROGRAM_MAJOR_MINOR,
11423       0x0000001F,
11424       0,
11425       0);
11426   pdata->nvm__ews__probe_card_major =
11427     (uint8_t)VL53LX_i2c_decode_with_mask(
11428       1,
11429       pbuffer + VL53LX_NVM__EWS__PROBE_CARD_MAJOR_MINOR,
11430       0x000000F0,
11431       4,
11432       0);
11433   pdata->nvm__ews__probe_card_minor =
11434     (uint8_t)VL53LX_i2c_decode_with_mask(
11435       1,
11436       pbuffer + VL53LX_NVM__EWS__PROBE_CARD_MAJOR_MINOR,
11437       0x0000000F,
11438       0,
11439       0);
11440   pdata->nvm__ews__tester_id =
11441     (uint8_t)VL53LX_i2c_decode_with_mask(
11442       1,
11443       pbuffer + VL53LX_NVM__EWS__TESTER_ID,
11444       0x000000FF,
11445       0,
11446       0);
11447   pdata->nvm__ews__lot[0] =
11448     (char)VL53LX_i2c_decode_with_mask(
11449       1,
11450       pbuffer + VL53LX_NVM__EWS__LOT__BYTE_0,
11451       0x000000FC,
11452       2,
11453       32);
11454   pdata->nvm__ews__lot[1] =
11455     (char)VL53LX_i2c_decode_with_mask(
11456       2,
11457       pbuffer + VL53LX_NVM__EWS__LOT__BYTE_1 - 1,
11458       0x000003F0,
11459       4,
11460       32);
11461   pdata->nvm__ews__lot[2] =
11462     (char)VL53LX_i2c_decode_with_mask(
11463       2,
11464       pbuffer + VL53LX_NVM__EWS__LOT__BYTE_2 - 1,
11465       0x00000FC0,
11466       6,
11467       32);
11468   pdata->nvm__ews__lot[3] =
11469     (char)VL53LX_i2c_decode_with_mask(
11470       1,
11471       pbuffer + VL53LX_NVM__EWS__LOT__BYTE_2,
11472       0x0000003F,
11473       0,
11474       32);
11475   pdata->nvm__ews__lot[4] =
11476     (char)VL53LX_i2c_decode_with_mask(
11477       1,
11478       pbuffer + VL53LX_NVM__EWS__LOT__BYTE_3,
11479       0x000000FC,
11480       2,
11481       32);
11482   pdata->nvm__ews__lot[5] =
11483     (char)VL53LX_i2c_decode_with_mask(
11484       2,
11485       pbuffer + VL53LX_NVM__EWS__LOT__BYTE_4 - 1,
11486       0x000003F0,
11487       4,
11488       32);
11489   pdata->nvm__ews__lot[6] =
11490     (char)VL53LX_i2c_decode_with_mask(
11491       2,
11492       pbuffer + VL53LX_NVM__EWS__LOT__BYTE_5 - 1,
11493       0x00000FC0,
11494       6,
11495       32);
11496 
11497   pdata->nvm__ews__lot[7] = 0x00;
11498 
11499   pdata->nvm__ews__wafer =
11500     (uint8_t)VL53LX_i2c_decode_with_mask(
11501       1,
11502       pbuffer + VL53LX_NVM__EWS__WAFER,
11503       0x0000001F,
11504       0,
11505       0);
11506   pdata->nvm__ews__xcoord =
11507     (uint8_t)VL53LX_i2c_decode_with_mask(
11508       1,
11509       pbuffer + VL53LX_NVM__EWS__XCOORD,
11510       0x000000FF,
11511       0,
11512       0);
11513   pdata->nvm__ews__ycoord =
11514     (uint8_t)VL53LX_i2c_decode_with_mask(
11515       1,
11516       pbuffer + VL53LX_NVM__EWS__YCOORD,
11517       0x000000FF,
11518       0,
11519       0);
11520 
11521   return status;
11522 
11523 }
11524 
11525 
11526 void VL53LX::VL53LX_nvm_format_encode(
11527   VL53LX_decoded_nvm_data_t *pnvm_info,
11528   uint8_t                   *pnvm_data)
11529 {
11530   SUPPRESS_UNUSED_WARNING(pnvm_info);
11531   SUPPRESS_UNUSED_WARNING(pnvm_data);
11532 }
11533 
11534 VL53LX_Error VL53LX::VL53LX_read_nvm_raw_data(
11535   uint8_t        start_address,
11536   uint8_t        count,
11537   uint8_t       *pnvm_raw_data)
11538 {
11539 
11540 
11541 
11542   VL53LX_Error status = VL53LX_ERROR_NONE;
11543 
11544 
11545 
11546 
11547   if (status == VL53LX_ERROR_NONE)
11548     status = VL53LX_nvm_enable(
11549                0x0004,
11550                VL53LX_NVM_POWER_UP_DELAY_US);
11551 
11552 
11553 
11554   if (status == VL53LX_ERROR_NONE)
11555     status = VL53LX_nvm_read(
11556                start_address,
11557                count,
11558                pnvm_raw_data);
11559 
11560 
11561 
11562   if (status == VL53LX_ERROR_NONE) {
11563     status = VL53LX_nvm_disable();
11564   }
11565 
11566 
11567   return status;
11568 
11569 }
11570 
11571 VL53LX_Error VL53LX::VL53LX_read_nvm(
11572   uint8_t                    nvm_format,
11573   VL53LX_decoded_nvm_data_t *pnvm_info)
11574 {
11575 
11576   VL53LX_Error status = VL53LX_ERROR_NONE;
11577 
11578 
11579   uint8_t nvm_data[2 * VL53LX_NVM_SIZE_IN_BYTES];
11580 
11581 
11582   SUPPRESS_UNUSED_WARNING(nvm_format);
11583 
11584 
11585 
11586   status = VL53LX_read_nvm_raw_data(
11587              0,
11588              VL53LX_NVM_SIZE_IN_BYTES >> 2,
11589              nvm_data);
11590 
11591 
11592 
11593 
11594 
11595   if (status == VL53LX_ERROR_NONE)
11596     status = VL53LX_nvm_format_decode(
11597                VL53LX_NVM_SIZE_IN_BYTES,
11598                nvm_data,
11599                pnvm_info);
11600 
11601   return status;
11602 
11603 }
11604 
11605 VL53LX_Error VL53LX::VL53LX_read_nvm_optical_centre(
11606   VL53LX_optical_centre_t          *pcentre)
11607 {
11608 
11609 
11610   VL53LX_Error status = VL53LX_ERROR_NONE;
11611 
11612 
11613   uint8_t nvm_data[2 * VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE];
11614 
11615   status =
11616     VL53LX_read_nvm_raw_data(
11617       (uint8_t)(VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_INDEX
11618                 >> 2),
11619       (uint8_t)(VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE
11620                 >> 2),
11621       nvm_data);
11622 
11623 
11624 
11625   if (status == VL53LX_ERROR_NONE)
11626     status =
11627       VL53LX_nvm_decode_optical_centre(
11628         VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE,
11629         nvm_data,
11630         pcentre);
11631 
11632   return status;
11633 }
11634 VL53LX_Error VL53LX::VL53LX_read_nvm_cal_peak_rate_map(
11635   VL53LX_cal_peak_rate_map_t          *pcal_data)
11636 {
11637 
11638 
11639   VL53LX_Error status = VL53LX_ERROR_NONE;
11640 
11641 
11642   uint8_t nvm_data[2 * VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE];
11643 
11644 
11645   status =
11646     VL53LX_read_nvm_raw_data(
11647       (uint8_t)(VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_INDEX
11648                 >> 2),
11649       (uint8_t)(VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE
11650                 >> 2),
11651       nvm_data);
11652 
11653 
11654 
11655   if (status == VL53LX_ERROR_NONE)
11656     status =
11657       VL53LX_nvm_decode_cal_peak_rate_map(
11658         VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE,
11659         nvm_data,
11660         pcal_data);
11661 
11662 
11663   return status;
11664 }
11665 
11666 
11667 VL53LX_Error VL53LX::VL53LX_read_nvm_additional_offset_cal_data(
11668   VL53LX_additional_offset_cal_data_t *pcal_data)
11669 {
11670 
11671 
11672 
11673   VL53LX_Error status = VL53LX_ERROR_NONE;
11674 
11675 
11676   uint8_t nvm_data[2 * VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE];
11677 
11678   status =
11679     VL53LX_read_nvm_raw_data(
11680       (uint8_t)(
11681         VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_INDEX >> 2),
11682       (uint8_t)(
11683         VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE >> 2),
11684       nvm_data);
11685 
11686 
11687 
11688   if (status == VL53LX_ERROR_NONE)
11689     status = VL53LX_nvm_decode_additional_offset_cal_data(
11690                VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE,
11691                nvm_data,
11692                pcal_data);
11693 
11694 
11695   return status;
11696 
11697 }
11698 
11699 VL53LX_Error VL53LX::VL53LX_read_nvm_fmt_range_results_data(
11700   uint16_t                             range_results_select,
11701   VL53LX_decoded_nvm_fmt_range_data_t *prange_data)
11702 {
11703 
11704   VL53LX_Error status = VL53LX_ERROR_NONE;
11705 
11706 
11707   uint8_t nvm_data[2 * VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES];
11708 
11709   status = VL53LX_read_nvm_raw_data(
11710              (uint8_t)(range_results_select >> 2),
11711              (uint8_t)(VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES >> 2),
11712              nvm_data);
11713 
11714 
11715 
11716   if (status == VL53LX_ERROR_NONE)
11717     status =
11718       VL53LX_nvm_decode_fmt_range_results_data(
11719         VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES,
11720         nvm_data,
11721         prange_data);
11722 
11723   return status;
11724 
11725 }
11726 
11727 /* vl53lx_platform_ipp.c */
11728 
11729 VL53LX_Error VL53LX::VL53LX_ipp_hist_process_data(
11730   VL53LX_dmax_calibration_data_t    *pdmax_cal,
11731   VL53LX_hist_gen3_dmax_config_t    *pdmax_cfg,
11732   VL53LX_hist_post_process_config_t *ppost_cfg,
11733   VL53LX_histogram_bin_data_t       *pbins,
11734   VL53LX_xtalk_histogram_data_t     *pxtalk,
11735   uint8_t                           *pArea1,
11736   uint8_t                           *pArea2,
11737   uint8_t                           *phisto_merge_nb,
11738   VL53LX_range_results_t            *presults)
11739 {
11740 
11741   VL53LX_Error status         = VL53LX_ERROR_NONE;
11742 
11743   SUPPRESS_UNUSED_WARNING(Dev);
11744 
11745   status =
11746     VL53LX_hist_process_data(
11747       pdmax_cal,
11748       pdmax_cfg,
11749       ppost_cfg,
11750       pbins,
11751       pxtalk,
11752       pArea1,
11753       pArea2,
11754       presults,
11755       phisto_merge_nb);
11756 
11757   return status;
11758 }
11759 
11760 
11761 VL53LX_Error VL53LX::VL53LX_ipp_hist_ambient_dmax(
11762   uint16_t                           target_reflectance,
11763   VL53LX_dmax_calibration_data_t    *pdmax_cal,
11764   VL53LX_hist_gen3_dmax_config_t    *pdmax_cfg,
11765   VL53LX_histogram_bin_data_t       *pbins,
11766   int16_t                           *pambient_dmax_mm)
11767 {
11768 
11769 
11770 
11771 
11772 
11773 
11774 
11775 
11776 
11777 
11778 
11779   VL53LX_Error status         = VL53LX_ERROR_NONE;
11780 
11781   SUPPRESS_UNUSED_WARNING(Dev);
11782 
11783   status =
11784     VL53LX_hist_ambient_dmax(
11785       target_reflectance,
11786       pdmax_cal,
11787       pdmax_cfg,
11788       pbins,
11789       pambient_dmax_mm);
11790 
11791   return status;
11792 }
11793 
11794 
11795 VL53LX_Error VL53LX::VL53LX_ipp_xtalk_calibration_process_data(
11796   VL53LX_xtalk_range_results_t       *pxtalk_ranges,
11797   VL53LX_xtalk_histogram_data_t      *pxtalk_shape,
11798   VL53LX_xtalk_calibration_results_t *pxtalk_cal)
11799 {
11800 
11801 
11802 
11803 
11804 
11805 
11806   VL53LX_Error status         = VL53LX_ERROR_NONE;
11807 
11808   SUPPRESS_UNUSED_WARNING(Dev);
11809 
11810   status =
11811     VL53LX_xtalk_calibration_process_data(
11812       pxtalk_ranges,
11813       pxtalk_shape,
11814       pxtalk_cal);
11815 
11816   return status;
11817 }
11818 
11819 
11820 VL53LX_Error VL53LX::VL53LX_ipp_hist_xtalk_correction(
11821   VL53LX_customer_nvm_managed_t *pcustomer,
11822   VL53LX_dynamic_config_t       *pdyn_cfg,
11823   VL53LX_xtalk_histogram_data_t *pxtalk_shape,
11824   VL53LX_histogram_bin_data_t   *pip_hist_data,
11825   VL53LX_histogram_bin_data_t   *pop_hist_data,
11826   VL53LX_histogram_bin_data_t   *pxtalk_count_data)
11827 {
11828   VL53LX_Error status         = VL53LX_ERROR_NONE;
11829 
11830   SUPPRESS_UNUSED_WARNING(Dev);
11831 
11832   status =
11833     VL53LX_f_046(
11834       pcustomer,
11835       pdyn_cfg,
11836       pxtalk_shape,
11837       pip_hist_data,
11838       pop_hist_data,
11839       pxtalk_count_data);
11840 
11841   return status;
11842 }
11843 
11844 VL53LX_Error VL53LX::VL53LX_ipp_generate_dual_reflectance_xtalk_samples(
11845   VL53LX_xtalk_range_results_t  *pxtalk_results,
11846   uint16_t                 expected_target_distance_mm,
11847   uint8_t                        higher_reflectance,
11848   VL53LX_histogram_bin_data_t   *pxtalk_avg_samples)
11849 {
11850   VL53LX_Error status         = VL53LX_ERROR_NONE;
11851 
11852   SUPPRESS_UNUSED_WARNING(Dev);
11853 
11854   status = VL53LX_generate_dual_reflectance_xtalk_samples(
11855              pxtalk_results,
11856              expected_target_distance_mm,
11857              higher_reflectance,
11858              pxtalk_avg_samples);
11859 
11860   return status;
11861 
11862 }
11863 
11864 /* vl53lx_hist_funcs.c */
11865 
11866 VL53LX_Error VL53LX::VL53LX_hist_process_data(
11867   VL53LX_dmax_calibration_data_t     *pdmax_cal,
11868   VL53LX_hist_gen3_dmax_config_t     *pdmax_cfg,
11869   VL53LX_hist_post_process_config_t  *ppost_cfg,
11870   VL53LX_histogram_bin_data_t        *pbins_input,
11871   VL53LX_xtalk_histogram_data_t      *pxtalk_shape,
11872   uint8_t                            *pArea1,
11873   uint8_t                            *pArea2,
11874   VL53LX_range_results_t             *presults,
11875   uint8_t                            *HistMergeNumber)
11876 {
11877 
11878   VL53LX_Error  status  = VL53LX_ERROR_NONE;
11879 
11880   VL53LX_hist_gen3_algo_private_data_t  *palgo_gen3 =
11881     (VL53LX_hist_gen3_algo_private_data_t *) pArea1;
11882   VL53LX_hist_gen4_algo_filtered_data_t *pfiltered4 =
11883     (VL53LX_hist_gen4_algo_filtered_data_t *) pArea2;
11884 
11885   VL53LX_hist_gen3_dmax_private_data_t   dmax_algo_gen3;
11886   VL53LX_hist_gen3_dmax_private_data_t  *pdmax_algo_gen3 =
11887     &dmax_algo_gen3;
11888 
11889   VL53LX_histogram_bin_data_t             bins_averaged;
11890   VL53LX_histogram_bin_data_t           *pbins_averaged = &bins_averaged;
11891 
11892   VL53LX_range_data_t                   *pdata;
11893 
11894   uint32_t xtalk_rate_kcps               = 0;
11895   uint32_t max_xtalk_rate_per_spad_kcps  = 0;
11896   uint8_t  xtalk_enable                  = 0;
11897   uint8_t  r                             = 0;
11898   uint8_t  t                             = 0;
11899   uint32_t XtalkDetectMaxSigma           = 0;
11900 
11901 
11902 
11903   int16_t  delta_mm                      = 0;
11904 
11905 
11906   VL53LX_f_031(
11907     pbins_input,
11908     pbins_averaged);
11909 
11910 
11911 
11912 
11913 
11914 
11915   VL53LX_init_histogram_bin_data_struct(
11916     0,
11917     pxtalk_shape->xtalk_shape.VL53LX_p_021,
11918     &(pxtalk_shape->xtalk_hist_removed));
11919 
11920 
11921 
11922 
11923 
11924 
11925 
11926   VL53LX_copy_xtalk_bin_data_to_histogram_data_struct(
11927     &(pxtalk_shape->xtalk_shape),
11928     &(pxtalk_shape->xtalk_hist_removed));
11929 
11930 
11931 
11932 
11933 
11934 
11935 
11936   if ((status == VL53LX_ERROR_NONE) &&
11937       (ppost_cfg->algo__crosstalk_compensation_enable > 0))
11938 
11939     status =
11940       VL53LX_f_032(
11941         ppost_cfg->algo__crosstalk_compensation_plane_offset_kcps,
11942         ppost_cfg->algo__crosstalk_compensation_x_plane_gradient_kcps,
11943         ppost_cfg->algo__crosstalk_compensation_y_plane_gradient_kcps,
11944         0,
11945         0,
11946         pbins_input->result__dss_actual_effective_spads,
11947         pbins_input->roi_config__user_roi_centre_spad,
11948         pbins_input->roi_config__user_roi_requested_global_xy_size,
11949         &(xtalk_rate_kcps));
11950 
11951 
11952 
11953 
11954 
11955 
11956 
11957 
11958   if ((status == VL53LX_ERROR_NONE) &&
11959       (ppost_cfg->algo__crosstalk_compensation_enable > 0))
11960     status =
11961       VL53LX_f_033(
11962         pbins_averaged,
11963         &(pxtalk_shape->xtalk_shape),
11964         xtalk_rate_kcps,
11965         &(pxtalk_shape->xtalk_hist_removed));
11966 
11967 
11968 
11969 
11970 
11971 
11972 
11973 
11974 
11975 
11976 
11977 
11978 
11979   presults->xmonitor.total_periods_elapsed =
11980     pbins_averaged->total_periods_elapsed;
11981   presults->xmonitor.VL53LX_p_004 =
11982     pbins_averaged->result__dss_actual_effective_spads;
11983 
11984   presults->xmonitor.peak_signal_count_rate_mcps = 0;
11985   presults->xmonitor.VL53LX_p_009     = 0;
11986 
11987   presults->xmonitor.range_id     = 0;
11988   presults->xmonitor.range_status = VL53LX_DEVICEERROR_NOUPDATE;
11989 
11990 
11991 
11992 
11993 
11994 
11995   xtalk_enable = 0;
11996   if (ppost_cfg->algo__crosstalk_compensation_enable > 0) {
11997     xtalk_enable = 1;
11998   }
11999 
12000 
12001 
12002 
12003 
12004 
12005 
12006 
12007 
12008   for (r = 0 ; r <= xtalk_enable ; r++) {
12009 
12010 
12011 
12012 
12013 
12014     ppost_cfg->algo__crosstalk_compensation_enable = r;
12015 
12016 
12017 
12018 
12019 
12020 
12021     status =
12022       VL53LX_f_025(
12023         pdmax_cal,
12024         pdmax_cfg,
12025         ppost_cfg,
12026         pbins_averaged,
12027         &(pxtalk_shape->xtalk_hist_removed),
12028         palgo_gen3,
12029         pfiltered4,
12030         pdmax_algo_gen3,
12031         presults);
12032 
12033 
12034 
12035 
12036 
12037     if (!(status == VL53LX_ERROR_NONE && r == 0)) {
12038       continue;
12039     }
12040 
12041 
12042 
12043 
12044 
12045 
12046     if (presults->active_results == 0) {
12047       pdata = &(presults->VL53LX_p_003[0]);
12048       pdata->ambient_count_rate_mcps =
12049         pdmax_algo_gen3->VL53LX_p_034;
12050       pdata->VL53LX_p_004 =
12051         pdmax_algo_gen3->VL53LX_p_004;
12052     }
12053 
12054 
12055 
12056 
12057 
12058 
12059 
12060     max_xtalk_rate_per_spad_kcps = (uint32_t)(
12061                                      ppost_cfg->algo__crosstalk_detect_max_valid_rate_kcps);
12062     max_xtalk_rate_per_spad_kcps *= (uint32_t)(*HistMergeNumber);
12063     max_xtalk_rate_per_spad_kcps <<= 4;
12064 
12065     for (t = 0 ; t < presults->active_results ; t++) {
12066 
12067       pdata = &(presults->VL53LX_p_003[t]);
12068 
12069 
12070 
12071 
12072       if (pdata->max_range_mm > pdata->min_range_mm)
12073         delta_mm =
12074           pdata->max_range_mm -
12075           pdata->min_range_mm;
12076       else
12077         delta_mm =
12078           pdata->min_range_mm -
12079           pdata->max_range_mm;
12080 
12081       XtalkDetectMaxSigma =
12082         ppost_cfg->algo__crosstalk_detect_max_sigma_mm;
12083       XtalkDetectMaxSigma *= (uint32_t)(*HistMergeNumber);
12084       XtalkDetectMaxSigma <<= 5;
12085       if (pdata->median_range_mm  >
12086           ppost_cfg->algo__crosstalk_detect_min_valid_range_mm &&
12087           pdata->median_range_mm  <
12088           ppost_cfg->algo__crosstalk_detect_max_valid_range_mm &&
12089           pdata->VL53LX_p_009 <
12090           max_xtalk_rate_per_spad_kcps &&
12091           pdata->VL53LX_p_002 < XtalkDetectMaxSigma &&
12092           delta_mm <
12093           ppost_cfg->algo__crosstalk_detect_min_max_tolerance) {
12094 
12095 
12096 
12097 
12098         memcpy(
12099           &(presults->xmonitor),
12100           pdata,
12101           sizeof(VL53LX_range_data_t));
12102 
12103       }
12104     }
12105 
12106   }
12107 
12108 
12109 
12110 
12111   ppost_cfg->algo__crosstalk_compensation_enable = xtalk_enable;
12112 
12113 
12114   return status;
12115 }
12116 
12117 VL53LX_Error VL53LX::VL53LX_hist_ambient_dmax(
12118   uint16_t                            target_reflectance,
12119   VL53LX_dmax_calibration_data_t     *pdmax_cal,
12120   VL53LX_hist_gen3_dmax_config_t     *pdmax_cfg,
12121   VL53LX_histogram_bin_data_t        *pbins,
12122   int16_t                            *pambient_dmax_mm)
12123 {
12124 
12125   VL53LX_Error  status  = VL53LX_ERROR_NONE;
12126 
12127   VL53LX_hist_gen3_dmax_private_data_t   dmax_algo;
12128   VL53LX_hist_gen3_dmax_private_data_t  *pdmax_algo = &dmax_algo;
12129 
12130   status =
12131     VL53LX_f_001(
12132       target_reflectance,
12133       pdmax_cal,
12134       pdmax_cfg,
12135       pbins,
12136       pdmax_algo,
12137       pambient_dmax_mm);
12138 
12139   return status;
12140 }
12141 
12142 /* vl53lx_core_support.c */
12143 
12144 uint32_t VL53LX::VL53LX_calc_pll_period_us(
12145   uint16_t  fast_osc_frequency)
12146 {
12147   uint32_t  pll_period_us        = 0;
12148 
12149 
12150   if (fast_osc_frequency > 0) {
12151     pll_period_us = (0x01 << 30) / fast_osc_frequency;
12152   }
12153 
12154 
12155   return pll_period_us;
12156 }
12157 
12158 uint32_t  VL53LX::VL53LX_duration_maths(
12159   uint32_t  pll_period_us,
12160   uint32_t  vcsel_parm_pclks,
12161   uint32_t  window_vclks,
12162   uint32_t  elapsed_mclks)
12163 {
12164   uint64_t  tmp_long_int = 0;
12165   uint32_t  duration_us  = 0;
12166 
12167 
12168   duration_us = window_vclks * pll_period_us;
12169 
12170 
12171   duration_us = duration_us >> 12;
12172 
12173 
12174   tmp_long_int = (uint64_t)duration_us;
12175 
12176 
12177   duration_us = elapsed_mclks * vcsel_parm_pclks;
12178 
12179 
12180   duration_us = duration_us >> 4;
12181 
12182 
12183   tmp_long_int = tmp_long_int * (uint64_t)duration_us;
12184 
12185 
12186   tmp_long_int = tmp_long_int >> 12;
12187 
12188 
12189   if (tmp_long_int > 0xFFFFFFFF) {
12190     tmp_long_int = 0xFFFFFFFF;
12191   }
12192 
12193   duration_us  = (uint32_t)tmp_long_int;
12194 
12195   return duration_us;
12196 }
12197 
12198 uint32_t VL53LX::VL53LX_events_per_spad_maths(
12199   int32_t   VL53LX_p_010,
12200   uint16_t  num_spads,
12201   uint32_t  duration)
12202 {
12203   uint64_t total_hist_counts  = 0;
12204   uint64_t xtalk_per_spad     = 0;
12205   uint32_t rate_per_spad_kcps = 0;
12206 
12207   uint64_t dividend = ((uint64_t)VL53LX_p_010
12208                        * 1000 * 256);
12209 
12210   if (num_spads != 0)
12211     total_hist_counts = do_division_u(
12212                           dividend, (uint64_t)num_spads);
12213 
12214 
12215 
12216   if (duration > 0) {
12217 
12218 
12219     uint64_t dividend = (((uint64_t)(total_hist_counts << 11))
12220                          + ((uint64_t)duration / 2));
12221 
12222     xtalk_per_spad = do_division_u(dividend, (uint64_t)duration);
12223   } else {
12224     xtalk_per_spad = (uint64_t)(total_hist_counts << 11);
12225   }
12226 
12227   rate_per_spad_kcps = (uint32_t)xtalk_per_spad;
12228 
12229   return rate_per_spad_kcps;
12230 }
12231 
12232 uint32_t VL53LX::VL53LX_isqrt(uint32_t num)
12233 {
12234 
12235 
12236 
12237   uint32_t  res = 0;
12238   uint32_t  bit = 1 << 30;
12239 
12240 
12241   while (bit > num) {
12242     bit >>= 2;
12243   }
12244 
12245   while (bit != 0) {
12246     if (num >= res + bit)  {
12247       num -= res + bit;
12248       res = (res >> 1) + bit;
12249     } else {
12250       res >>= 1;
12251     }
12252     bit >>= 2;
12253   }
12254 
12255   return res;
12256 }
12257 
12258 void  VL53LX::VL53LX_hist_calc_zero_distance_phase(
12259   VL53LX_histogram_bin_data_t   *pdata)
12260 {
12261   uint32_t  period        = 0;
12262   uint32_t  VL53LX_p_014         = 0;
12263 
12264 
12265   period = 2048 *
12266            (uint32_t)VL53LX_decode_vcsel_period(pdata->VL53LX_p_005);
12267 
12268   VL53LX_p_014  = period;
12269   VL53LX_p_014 += (uint32_t)pdata->phasecal_result__reference_phase;
12270   VL53LX_p_014 += (2048 * (uint32_t)pdata->phasecal_result__vcsel_start);
12271   VL53LX_p_014 -= (2048 * (uint32_t)pdata->cal_config__vcsel_start);
12272 
12273   VL53LX_p_014  = VL53LX_p_014 % period;
12274 
12275   pdata->zero_distance_phase = (uint16_t)VL53LX_p_014;
12276 
12277 }
12278 
12279 void  VL53LX::VL53LX_hist_estimate_ambient_from_thresholded_bins(
12280   int32_t                        ambient_threshold_sigma,
12281   VL53LX_histogram_bin_data_t   *pdata)
12282 {
12283 
12284 
12285   uint8_t  bin                      = 0;
12286   int32_t  VL53LX_p_031 = 0;
12287 
12288   VL53LX_hist_find_min_max_bin_values(pdata);
12289 
12290 
12291 
12292   VL53LX_p_031  =
12293     (int32_t)VL53LX_isqrt((uint32_t)pdata->min_bin_value);
12294   VL53LX_p_031 *= ambient_threshold_sigma;
12295   VL53LX_p_031 += 0x07;
12296   VL53LX_p_031  = VL53LX_p_031 >> 4;
12297   VL53LX_p_031 += pdata->min_bin_value;
12298 
12299 
12300 
12301   pdata->number_of_ambient_samples = 0;
12302   pdata->ambient_events_sum        = 0;
12303 
12304   for (bin = 0; bin < pdata->VL53LX_p_021; bin++)
12305     if (pdata->bin_data[bin] < VL53LX_p_031) {
12306       pdata->ambient_events_sum += pdata->bin_data[bin];
12307       pdata->number_of_ambient_samples++;
12308     }
12309 
12310 
12311 
12312   if (pdata->number_of_ambient_samples > 0) {
12313     pdata->VL53LX_p_028 =
12314       pdata->ambient_events_sum;
12315     pdata->VL53LX_p_028 +=
12316       ((int32_t)pdata->number_of_ambient_samples / 2);
12317     pdata->VL53LX_p_028 /=
12318       (int32_t)pdata->number_of_ambient_samples;
12319   }
12320 
12321 }
12322 
12323 
12324 void  VL53LX::VL53LX_hist_remove_ambient_bins(
12325   VL53LX_histogram_bin_data_t   *pdata)
12326 {
12327 
12328   uint8_t bin = 0;
12329   uint8_t lc = 0;
12330   uint8_t i = 0;
12331 
12332 
12333 
12334   if ((pdata->bin_seq[0] & 0x07) == 0x07) {
12335 
12336     i = 0;
12337     for (lc = 0; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH; lc++) {
12338       if ((pdata->bin_seq[lc] & 0x07) != 0x07) {
12339         pdata->bin_seq[i] = pdata->bin_seq[lc];
12340         pdata->bin_rep[i] = pdata->bin_rep[lc];
12341         i++;
12342       }
12343     }
12344 
12345 
12346 
12347     for (lc = i; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH; lc++) {
12348       pdata->bin_seq[lc] = VL53LX_MAX_BIN_SEQUENCE_CODE + 1;
12349       pdata->bin_rep[lc] = 0;
12350     }
12351   }
12352 
12353   if (pdata->number_of_ambient_bins > 0) {
12354 
12355 
12356     for (bin = pdata->number_of_ambient_bins;
12357          bin < pdata->VL53LX_p_020; bin++) {
12358       pdata->bin_data[bin - pdata->number_of_ambient_bins] =
12359         pdata->bin_data[bin];
12360     }
12361 
12362 
12363     pdata->VL53LX_p_021 =
12364       pdata->VL53LX_p_021 -
12365       pdata->number_of_ambient_bins;
12366     pdata->number_of_ambient_bins = 0;
12367   }
12368 }
12369 
12370 
12371 uint32_t VL53LX::VL53LX_calc_pll_period_mm(
12372   uint16_t fast_osc_frequency)
12373 {
12374 
12375 
12376   uint32_t pll_period_us = 0;
12377   uint32_t pll_period_mm = 0;
12378 
12379   pll_period_us  = VL53LX_calc_pll_period_us(fast_osc_frequency);
12380 
12381 
12382 
12383 
12384   pll_period_mm =
12385     VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8 *
12386     (pll_period_us >> 2);
12387 
12388 
12389   pll_period_mm = (pll_period_mm + (0x01 << 15)) >> 16;
12390 
12391   return pll_period_mm;
12392 }
12393 
12394 
12395 uint16_t VL53LX::VL53LX_rate_maths(
12396   int32_t   VL53LX_p_018,
12397   uint32_t  time_us)
12398 {
12399 
12400 
12401   uint32_t  tmp_int   = 0;
12402   uint32_t  frac_bits = 7;
12403   uint16_t  rate_mcps = 0;
12404 
12405 
12406 
12407   if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_MAX) {
12408     tmp_int = VL53LX_SPAD_TOTAL_COUNT_MAX;
12409   } else if (VL53LX_p_018 > 0) {
12410     tmp_int = (uint32_t)VL53LX_p_018;
12411   }
12412 
12413 
12414 
12415 
12416   if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_RES_THRES) {
12417     frac_bits = 3;
12418   } else {
12419     frac_bits = 7;
12420   }
12421 
12422 
12423   if (time_us > 0) {
12424     tmp_int = ((tmp_int << frac_bits) + (time_us / 2)) / time_us;
12425   }
12426 
12427 
12428   if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_RES_THRES) {
12429     tmp_int = tmp_int << 4;
12430   }
12431 
12432 
12433 
12434   if (tmp_int > 0xFFFF) {
12435     tmp_int = 0xFFFF;
12436   }
12437 
12438   rate_mcps = (uint16_t)tmp_int;
12439 
12440   return rate_mcps;
12441 }
12442 
12443 uint16_t VL53LX::VL53LX_rate_per_spad_maths(
12444   uint32_t  frac_bits,
12445   uint32_t  peak_count_rate,
12446   uint16_t  num_spads,
12447   uint32_t  max_output_value)
12448 {
12449 
12450   uint32_t  tmp_int   = 0;
12451 
12452 
12453   uint16_t  rate_per_spad = 0;
12454 
12455 
12456 
12457 
12458 
12459   if (num_spads > 0) {
12460     tmp_int = (peak_count_rate << 8) << frac_bits;
12461     tmp_int = (tmp_int +
12462                ((uint32_t)num_spads / 2)) /
12463               (uint32_t)num_spads;
12464   } else {
12465     tmp_int = ((peak_count_rate) << frac_bits);
12466   }
12467 
12468 
12469 
12470   if (tmp_int > max_output_value) {
12471     tmp_int = max_output_value;
12472   }
12473 
12474   rate_per_spad = (uint16_t)tmp_int;
12475 
12476   return rate_per_spad;
12477 }
12478 
12479 int32_t VL53LX::VL53LX_range_maths(
12480   uint16_t  fast_osc_frequency,
12481   uint16_t  VL53LX_p_014,
12482   uint16_t  zero_distance_phase,
12483   uint8_t   fractional_bits,
12484   int32_t   gain_factor,
12485   int32_t   range_offset_mm)
12486 {
12487 
12488 
12489   uint32_t    pll_period_us = 0;
12490   int64_t     tmp_long_int  = 0;
12491   int32_t     range_mm      = 0;
12492   int32_t     range_mm_10   = 0;
12493 
12494 
12495 
12496   pll_period_us  = VL53LX_calc_pll_period_us(fast_osc_frequency);
12497 
12498 
12499 
12500   tmp_long_int = (int64_t)VL53LX_p_014 - (int64_t)zero_distance_phase;
12501 
12502 
12503 
12504   tmp_long_int =  tmp_long_int * (int64_t)pll_period_us;
12505 
12506 
12507 
12508   tmp_long_int =  tmp_long_int / (0x01 << 9);
12509 
12510 
12511 
12512   tmp_long_int =  tmp_long_int * VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8;
12513 
12514 
12515 
12516   tmp_long_int =  tmp_long_int / (0x01 << 22);
12517 
12518 
12519   range_mm  = (int32_t)tmp_long_int + range_offset_mm;
12520 
12521 
12522   range_mm *= gain_factor;
12523   range_mm += 0x0400;
12524   range_mm /= 0x0800;
12525 
12526 
12527   if (fractional_bits == 0) {
12528     range_mm_10 = range_mm * 10;
12529     range_mm_10 = range_mm_10 / (0x01 << 2);
12530     if ((range_mm_10 % 10) < 5) {
12531       range_mm = (int16_t)(range_mm_10 / 10);
12532     } else {
12533       range_mm = (int16_t)(range_mm_10 / 10 + 1);
12534     }
12535   } else if (fractional_bits == 1) {
12536     range_mm = range_mm / (0x01 << 1);
12537   }
12538 
12539   return range_mm;
12540 }
12541 
12542 uint8_t VL53LX::VL53LX_decode_vcsel_period(uint8_t vcsel_period_reg)
12543 {
12544 
12545 
12546   uint8_t VL53LX_p_030 = 0;
12547 
12548   VL53LX_p_030 = (vcsel_period_reg + 1) << 1;
12549 
12550   return VL53LX_p_030;
12551 }
12552 
12553 
12554 void VL53LX::VL53LX_copy_xtalk_bin_data_to_histogram_data_struct(
12555   VL53LX_xtalk_histogram_shape_t *pxtalk,
12556   VL53LX_histogram_bin_data_t    *phist)
12557 {
12558 
12559 
12560   phist->cal_config__vcsel_start =
12561     pxtalk->cal_config__vcsel_start;
12562   phist->VL53LX_p_015 =
12563     pxtalk->VL53LX_p_015;
12564   phist->VL53LX_p_019 =
12565     pxtalk->VL53LX_p_019;
12566 
12567   phist->phasecal_result__reference_phase   =
12568     pxtalk->phasecal_result__reference_phase;
12569   phist->phasecal_result__vcsel_start       =
12570     pxtalk->phasecal_result__vcsel_start;
12571 
12572   phist->vcsel_width =
12573     pxtalk->vcsel_width;
12574   phist->zero_distance_phase =
12575     pxtalk->zero_distance_phase;
12576 
12577   phist->zone_id      = pxtalk->zone_id;
12578   phist->VL53LX_p_020  = pxtalk->VL53LX_p_020;
12579   phist->time_stamp   = pxtalk->time_stamp;
12580 }
12581 
12582 void VL53LX::VL53LX_init_histogram_bin_data_struct(
12583   int32_t                      bin_value,
12584   uint16_t                     VL53LX_p_021,
12585   VL53LX_histogram_bin_data_t *pdata)
12586 {
12587   uint16_t          i = 0;
12588 
12589   pdata->cfg_device_state          = VL53LX_DEVICESTATE_SW_STANDBY;
12590   pdata->rd_device_state           = VL53LX_DEVICESTATE_SW_STANDBY;
12591 
12592   pdata->zone_id                   = 0;
12593   pdata->time_stamp                = 0;
12594 
12595   pdata->VL53LX_p_019                 = 0;
12596   pdata->VL53LX_p_020               = VL53LX_HISTOGRAM_BUFFER_SIZE;
12597   pdata->VL53LX_p_021            = (uint8_t)VL53LX_p_021;
12598   pdata->number_of_ambient_bins    = 0;
12599 
12600   pdata->result__interrupt_status           = 0;
12601   pdata->result__range_status               = 0;
12602   pdata->result__report_status              = 0;
12603   pdata->result__stream_count               = 0;
12604 
12605   pdata->result__dss_actual_effective_spads = 0;
12606   pdata->phasecal_result__reference_phase   = 0;
12607   pdata->phasecal_result__vcsel_start       = 0;
12608   pdata->cal_config__vcsel_start            = 0;
12609 
12610   pdata->vcsel_width                        = 0;
12611   pdata->VL53LX_p_005                       = 0;
12612   pdata->VL53LX_p_015                = 0;
12613   pdata->total_periods_elapsed              = 0;
12614 
12615   pdata->min_bin_value                      = 0;
12616   pdata->max_bin_value                      = 0;
12617 
12618   pdata->zero_distance_phase                = 0;
12619   pdata->number_of_ambient_samples          = 0;
12620   pdata->ambient_events_sum                 = 0;
12621   pdata->VL53LX_p_028             = 0;
12622 
12623   for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) {
12624     pdata->bin_seq[i] = (uint8_t)i;
12625   }
12626 
12627   for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) {
12628     pdata->bin_rep[i] = 1;
12629   }
12630 
12631 
12632   for (i = 0; i < VL53LX_HISTOGRAM_BUFFER_SIZE; i++)
12633     if (i < VL53LX_p_021) {
12634       pdata->bin_data[i] = bin_value;
12635     } else {
12636       pdata->bin_data[i] = 0;
12637     }
12638 
12639 
12640 }
12641 
12642 void VL53LX::VL53LX_decode_row_col(
12643   uint8_t  spad_number,
12644   uint8_t  *prow,
12645   uint8_t  *pcol)
12646 {
12647 
12648 
12649 
12650   if (spad_number > 127) {
12651     *prow = 8 + ((255 - spad_number) & 0x07);
12652     *pcol = (spad_number - 128) >> 3;
12653   } else {
12654     *prow = spad_number & 0x07;
12655     *pcol = (127 - spad_number) >> 3;
12656   }
12657 }
12658 
12659 void  VL53LX::VL53LX_hist_find_min_max_bin_values(
12660   VL53LX_histogram_bin_data_t   *pdata)
12661 {
12662   uint8_t  bin            = 0;
12663 
12664   for (bin = 0; bin < pdata->VL53LX_p_021; bin++) {
12665 
12666     if (bin == 0 || pdata->min_bin_value >= pdata->bin_data[bin]) {
12667       pdata->min_bin_value = pdata->bin_data[bin];
12668     }
12669 
12670     if (bin == 0 || pdata->max_bin_value <= pdata->bin_data[bin]) {
12671       pdata->max_bin_value = pdata->bin_data[bin];
12672     }
12673 
12674   }
12675 
12676 
12677 }
12678 
12679 void  VL53LX::VL53LX_hist_estimate_ambient_from_ambient_bins(
12680   VL53LX_histogram_bin_data_t   *pdata)
12681 {
12682 
12683   uint8_t  bin            = 0;
12684 
12685 
12686   if (pdata->number_of_ambient_bins > 0) {
12687 
12688     pdata->number_of_ambient_samples =
12689       pdata->number_of_ambient_bins;
12690 
12691 
12692 
12693     pdata->ambient_events_sum = 0;
12694     for (bin = 0; bin < pdata->number_of_ambient_bins; bin++) {
12695       pdata->ambient_events_sum += pdata->bin_data[bin];
12696     }
12697 
12698     pdata->VL53LX_p_028 = pdata->ambient_events_sum;
12699     pdata->VL53LX_p_028 +=
12700       ((int32_t)pdata->number_of_ambient_bins / 2);
12701     pdata->VL53LX_p_028 /=
12702       (int32_t)pdata->number_of_ambient_bins;
12703 
12704   }
12705 
12706 }
12707 /* vl53lx_core.c */
12708 void  VL53LX::VL53LX_init_version()
12709 {
12710   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
12711 
12712   pdev->version.ll_major    = VL53LX_LL_API_IMPLEMENTATION_VER_MAJOR;
12713   pdev->version.ll_minor    = VL53LX_LL_API_IMPLEMENTATION_VER_MINOR;
12714   pdev->version.ll_build    = VL53LX_LL_API_IMPLEMENTATION_VER_SUB;
12715   pdev->version.ll_revision = VL53LX_LL_API_IMPLEMENTATION_VER_REVISION;
12716 }
12717 
12718 void  VL53LX::VL53LX_init_ll_driver_state(
12719   VL53LX_DeviceState device_state)
12720 {
12721   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
12722   VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
12723 
12724   pstate->cfg_device_state  = device_state;
12725   pstate->cfg_stream_count  = 0;
12726   pstate->cfg_gph_id        = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
12727   pstate->cfg_timing_status = 0;
12728   pstate->cfg_zone_id       = 0;
12729 
12730   pstate->rd_device_state   = device_state;
12731   pstate->rd_stream_count   = 0;
12732   pstate->rd_gph_id         = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
12733   pstate->rd_timing_status  = 0;
12734   pstate->rd_zone_id        = 0;
12735 
12736 }
12737 
12738 
12739 VL53LX_Error  VL53LX::VL53LX_update_ll_driver_rd_state()
12740 {
12741 
12742 
12743   VL53LX_Error        status  = VL53LX_ERROR_NONE;
12744   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
12745   VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
12746 
12747 
12748   if ((pdev->sys_ctrl.system__mode_start &
12749        VL53LX_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) {
12750 
12751     pstate->rd_device_state  = VL53LX_DEVICESTATE_SW_STANDBY;
12752     pstate->rd_stream_count  = 0;
12753     pstate->rd_internal_stream_count = 0;
12754     pstate->rd_internal_stream_count_val = 0;
12755     pstate->rd_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
12756     pstate->rd_timing_status = 0;
12757     pstate->rd_zone_id       = 0;
12758 
12759   } else {
12760 
12761 
12762 
12763     if (pstate->rd_stream_count == 0xFF) {
12764       pstate->rd_stream_count = 0x80;
12765     } else {
12766       pstate->rd_stream_count++;
12767     }
12768 
12769 
12770     status = VL53LX_update_internal_stream_counters(
12771                pstate->rd_stream_count,
12772                &(pstate->rd_internal_stream_count),
12773                &(pstate->rd_internal_stream_count_val));
12774 
12775 
12776 
12777     pstate->rd_gph_id ^= VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
12778 
12779 
12780 
12781     switch (pstate->rd_device_state) {
12782 
12783       case VL53LX_DEVICESTATE_SW_STANDBY:
12784 
12785         if ((pdev->dyn_cfg.system__grouped_parameter_hold &
12786              VL53LX_GROUPEDPARAMETERHOLD_ID_MASK) > 0) {
12787           pstate->rd_device_state =
12788             VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC;
12789         } else {
12790           if (pstate->rd_zone_id >=
12791               pdev->zone_cfg.active_zones)
12792             pstate->rd_device_state =
12793               VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA;
12794           else
12795             pstate->rd_device_state =
12796               VL53LX_DEVICESTATE_RANGING_GATHER_DATA;
12797         }
12798 
12799         pstate->rd_stream_count  = 0;
12800         pstate->rd_internal_stream_count = 0;
12801         pstate->rd_internal_stream_count_val = 0;
12802         pstate->rd_timing_status = 0;
12803         pstate->rd_zone_id       = 0;
12804 
12805         break;
12806 
12807       case VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC:
12808         pstate->rd_stream_count = 0;
12809         pstate->rd_internal_stream_count = 0;
12810         pstate->rd_internal_stream_count_val = 0;
12811         pstate->rd_zone_id      = 0;
12812         if (pstate->rd_zone_id >=
12813             pdev->zone_cfg.active_zones)
12814           pstate->rd_device_state =
12815             VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA;
12816         else
12817           pstate->rd_device_state =
12818             VL53LX_DEVICESTATE_RANGING_GATHER_DATA;
12819 
12820         break;
12821 
12822       case VL53LX_DEVICESTATE_RANGING_GATHER_DATA:
12823         pstate->rd_zone_id++;
12824         if (pstate->rd_zone_id >=
12825             pdev->zone_cfg.active_zones)
12826           pstate->rd_device_state =
12827             VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA;
12828         else
12829           pstate->rd_device_state =
12830             VL53LX_DEVICESTATE_RANGING_GATHER_DATA;
12831 
12832         break;
12833 
12834       case VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA:
12835         pstate->rd_zone_id        = 0;
12836         pstate->rd_timing_status ^= 0x01;
12837 
12838         if (pstate->rd_zone_id >=
12839             pdev->zone_cfg.active_zones)
12840           pstate->rd_device_state =
12841             VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA;
12842         else
12843           pstate->rd_device_state =
12844             VL53LX_DEVICESTATE_RANGING_GATHER_DATA;
12845         break;
12846 
12847       default:
12848         pstate->rd_device_state  =
12849           VL53LX_DEVICESTATE_SW_STANDBY;
12850         pstate->rd_stream_count  = 0;
12851         pstate->rd_internal_stream_count = 0;
12852         pstate->rd_internal_stream_count_val = 0;
12853         pstate->rd_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
12854         pstate->rd_timing_status = 0;
12855         pstate->rd_zone_id       = 0;
12856         break;
12857     }
12858   }
12859 
12860 
12861   return status;
12862 }
12863 
12864 VL53LX_Error VL53LX::VL53LX_check_ll_driver_rd_state()
12865 {
12866 
12867 
12868   VL53LX_Error         status = VL53LX_ERROR_NONE;
12869   VL53LX_LLDriverData_t  *pdev =
12870     VL53LXDevStructGetLLDriverHandle(Dev);
12871   VL53LX_LLDriverResults_t  *pres =
12872     VL53LXDevStructGetLLResultsHandle(Dev);
12873 
12874   VL53LX_ll_driver_state_t  *pstate       = &(pdev->ll_state);
12875   VL53LX_system_results_t   *psys_results = &(pdev->sys_results);
12876   VL53LX_histogram_bin_data_t *phist_data = &(pdev->hist_data);
12877   VL53LX_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
12878 
12879   uint8_t   device_range_status   = 0;
12880   uint8_t   device_stream_count   = 0;
12881   uint8_t   device_gph_id         = 0;
12882   uint8_t   histogram_mode        = 0;
12883   uint8_t   expected_stream_count = 0;
12884   uint8_t   expected_gph_id       = 0;
12885 
12886 
12887   device_range_status =
12888     psys_results->result__range_status &
12889     VL53LX_RANGE_STATUS__RANGE_STATUS_MASK;
12890 
12891   device_stream_count = psys_results->result__stream_count;
12892 
12893 
12894 
12895   histogram_mode =
12896     (pdev->sys_ctrl.system__mode_start &
12897      VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) ==
12898     VL53LX_DEVICESCHEDULERMODE_HISTOGRAM;
12899 
12900 
12901   device_gph_id = (psys_results->result__interrupt_status &
12902                    VL53LX_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4;
12903 
12904   if (histogram_mode)
12905     device_gph_id = (phist_data->result__interrupt_status &
12906                      VL53LX_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4;
12907 
12908 
12909 
12910   if (!((pdev->sys_ctrl.system__mode_start &
12911          VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) ==
12912         VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK)) {
12913     goto ENDFUNC;
12914   }
12915 
12916 
12917 
12918   if (pstate->rd_device_state ==
12919       VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) {
12920 
12921     if (histogram_mode == 0) {
12922       if (device_range_status !=
12923           VL53LX_DEVICEERROR_GPHSTREAMCOUNT0READY)
12924         status =
12925           VL53LX_ERROR_GPH_SYNC_CHECK_FAIL;
12926 
12927     }
12928   } else {
12929     if (pstate->rd_stream_count != device_stream_count) {
12930       status = VL53LX_ERROR_STREAM_COUNT_CHECK_FAIL;
12931     }
12932 
12933 
12934     if (pstate->rd_gph_id != device_gph_id) {
12935       status = VL53LX_ERROR_GPH_ID_CHECK_FAIL;
12936     }
12937 
12938 
12939 
12940 
12941     expected_stream_count =
12942       pZ->VL53LX_p_003[pstate->rd_zone_id].expected_stream_count;
12943     expected_gph_id =
12944       pZ->VL53LX_p_003[pstate->rd_zone_id].expected_gph_id;
12945 
12946 
12947 
12948     if (expected_stream_count != device_stream_count) {
12949 
12950 
12951       if (!((pdev->zone_cfg.active_zones == 0) &&
12952             (device_stream_count == 255)))
12953         status =
12954           VL53LX_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL;
12955 
12956 
12957     }
12958 
12959 
12960 
12961     if (expected_gph_id != device_gph_id) {
12962       status = VL53LX_ERROR_ZONE_GPH_ID_CHECK_FAIL;
12963     }
12964 
12965   }
12966 ENDFUNC:
12967 
12968   return status;
12969 }
12970 
12971 
12972 VL53LX_Error  VL53LX::VL53LX_update_ll_driver_cfg_state()
12973 {
12974 
12975 
12976   VL53LX_Error         status = VL53LX_ERROR_NONE;
12977   VL53LX_LLDriverData_t  *pdev =
12978     VL53LXDevStructGetLLDriverHandle(Dev);
12979   VL53LX_LLDriverResults_t  *pres =
12980     VL53LXDevStructGetLLResultsHandle(Dev);
12981 
12982   VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
12983   VL53LX_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
12984 
12985   uint8_t prev_cfg_zone_id;
12986   uint8_t prev_cfg_gph_id;
12987   uint8_t prev_cfg_stream_count;
12988 
12989   if ((pdev->sys_ctrl.system__mode_start &
12990        VL53LX_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) {
12991 
12992     pstate->cfg_device_state  = VL53LX_DEVICESTATE_SW_STANDBY;
12993     pstate->cfg_stream_count  = 0;
12994     pstate->cfg_internal_stream_count = 0;
12995     pstate->cfg_internal_stream_count_val = 0;
12996     pstate->cfg_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
12997     pstate->cfg_timing_status = 0;
12998     pstate->cfg_zone_id       = 0;
12999     prev_cfg_zone_id          = 0;
13000     prev_cfg_gph_id           = 0;
13001     prev_cfg_stream_count     = 0;
13002 
13003   } else {
13004 
13005     prev_cfg_gph_id           = pstate->cfg_gph_id;
13006     prev_cfg_zone_id          = pstate->cfg_zone_id;
13007     prev_cfg_stream_count     = pstate->cfg_stream_count;
13008 
13009 
13010 
13011     if (pstate->cfg_stream_count == 0xFF) {
13012       pstate->cfg_stream_count = 0x80;
13013     } else {
13014       pstate->cfg_stream_count++;
13015     }
13016 
13017 
13018     status = VL53LX_update_internal_stream_counters(
13019                pstate->cfg_stream_count,
13020                &(pstate->cfg_internal_stream_count),
13021                &(pstate->cfg_internal_stream_count_val));
13022 
13023 
13024 
13025     pstate->cfg_gph_id ^= VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
13026 
13027 
13028 
13029     switch (pstate->cfg_device_state) {
13030 
13031       case VL53LX_DEVICESTATE_SW_STANDBY:
13032         pstate->cfg_zone_id = 1;
13033         if (pstate->cfg_zone_id >
13034             pdev->zone_cfg.active_zones) {
13035           pstate->cfg_zone_id = 0;
13036           pstate->cfg_timing_status ^= 0x01;
13037         }
13038         pstate->cfg_stream_count = 1;
13039 
13040         if (pdev->gen_cfg.global_config__stream_divider == 0) {
13041           pstate->cfg_internal_stream_count = 1;
13042           pstate->cfg_internal_stream_count_val = 0;
13043         } else {
13044           pstate->cfg_internal_stream_count = 0;
13045           pstate->cfg_internal_stream_count_val = 1;
13046         }
13047         pstate->cfg_device_state =
13048           VL53LX_DEVICESTATE_RANGING_DSS_AUTO;
13049         break;
13050 
13051       case VL53LX_DEVICESTATE_RANGING_DSS_AUTO:
13052         pstate->cfg_zone_id++;
13053         if (pstate->cfg_zone_id >
13054             pdev->zone_cfg.active_zones) {
13055 
13056           pstate->cfg_zone_id = 0;
13057           pstate->cfg_timing_status ^= 0x01;
13058 
13059 
13060 
13061 
13062           if (pdev->zone_cfg.active_zones > 0) {
13063             pstate->cfg_device_state =
13064               VL53LX_DEVICESTATE_RANGING_DSS_MANUAL;
13065           }
13066         }
13067         break;
13068 
13069       case VL53LX_DEVICESTATE_RANGING_DSS_MANUAL:
13070         pstate->cfg_zone_id++;
13071         if (pstate->cfg_zone_id >
13072             pdev->zone_cfg.active_zones) {
13073           pstate->cfg_zone_id = 0;
13074           pstate->cfg_timing_status ^= 0x01;
13075         }
13076         break;
13077 
13078       default:
13079         pstate->cfg_device_state =
13080           VL53LX_DEVICESTATE_SW_STANDBY;
13081         pstate->cfg_stream_count = 0;
13082         pstate->cfg_internal_stream_count = 0;
13083         pstate->cfg_internal_stream_count_val = 0;
13084         pstate->cfg_gph_id =
13085           VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
13086         pstate->cfg_timing_status = 0;
13087         pstate->cfg_zone_id       = 0;
13088         break;
13089     }
13090   }
13091 
13092 
13093   if (pdev->zone_cfg.active_zones == 0) {
13094 
13095     pZ->VL53LX_p_003[prev_cfg_zone_id].expected_stream_count
13096       = prev_cfg_stream_count - 1;
13097 
13098     pZ->VL53LX_p_003[pstate->rd_zone_id].expected_gph_id =
13099       prev_cfg_gph_id ^ VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
13100   } else {
13101     pZ->VL53LX_p_003[prev_cfg_zone_id].expected_stream_count
13102       = prev_cfg_stream_count;
13103     pZ->VL53LX_p_003[prev_cfg_zone_id].expected_gph_id =
13104       prev_cfg_gph_id;
13105   }
13106 
13107 
13108 
13109   return status;
13110 }
13111 
13112 void VL53LX::VL53LX_copy_rtn_good_spads_to_buffer(
13113   VL53LX_nvm_copy_data_t  *pdata,
13114   uint8_t                 *pbuffer)
13115 {
13116 
13117 
13118   *(pbuffer +  0) = pdata->global_config__spad_enables_rtn_0;
13119   *(pbuffer +  1) = pdata->global_config__spad_enables_rtn_1;
13120   *(pbuffer +  2) = pdata->global_config__spad_enables_rtn_2;
13121   *(pbuffer +  3) = pdata->global_config__spad_enables_rtn_3;
13122   *(pbuffer +  4) = pdata->global_config__spad_enables_rtn_4;
13123   *(pbuffer +  5) = pdata->global_config__spad_enables_rtn_5;
13124   *(pbuffer +  6) = pdata->global_config__spad_enables_rtn_6;
13125   *(pbuffer +  7) = pdata->global_config__spad_enables_rtn_7;
13126   *(pbuffer +  8) = pdata->global_config__spad_enables_rtn_8;
13127   *(pbuffer +  9) = pdata->global_config__spad_enables_rtn_9;
13128   *(pbuffer + 10) = pdata->global_config__spad_enables_rtn_10;
13129   *(pbuffer + 11) = pdata->global_config__spad_enables_rtn_11;
13130   *(pbuffer + 12) = pdata->global_config__spad_enables_rtn_12;
13131   *(pbuffer + 13) = pdata->global_config__spad_enables_rtn_13;
13132   *(pbuffer + 14) = pdata->global_config__spad_enables_rtn_14;
13133   *(pbuffer + 15) = pdata->global_config__spad_enables_rtn_15;
13134   *(pbuffer + 16) = pdata->global_config__spad_enables_rtn_16;
13135   *(pbuffer + 17) = pdata->global_config__spad_enables_rtn_17;
13136   *(pbuffer + 18) = pdata->global_config__spad_enables_rtn_18;
13137   *(pbuffer + 19) = pdata->global_config__spad_enables_rtn_19;
13138   *(pbuffer + 20) = pdata->global_config__spad_enables_rtn_20;
13139   *(pbuffer + 21) = pdata->global_config__spad_enables_rtn_21;
13140   *(pbuffer + 22) = pdata->global_config__spad_enables_rtn_22;
13141   *(pbuffer + 23) = pdata->global_config__spad_enables_rtn_23;
13142   *(pbuffer + 24) = pdata->global_config__spad_enables_rtn_24;
13143   *(pbuffer + 25) = pdata->global_config__spad_enables_rtn_25;
13144   *(pbuffer + 26) = pdata->global_config__spad_enables_rtn_26;
13145   *(pbuffer + 27) = pdata->global_config__spad_enables_rtn_27;
13146   *(pbuffer + 28) = pdata->global_config__spad_enables_rtn_28;
13147   *(pbuffer + 29) = pdata->global_config__spad_enables_rtn_29;
13148   *(pbuffer + 30) = pdata->global_config__spad_enables_rtn_30;
13149   *(pbuffer + 31) = pdata->global_config__spad_enables_rtn_31;
13150 }
13151 
13152 void VL53LX::VL53LX_init_system_results(
13153   VL53LX_system_results_t  *pdata)
13154 {
13155 
13156 
13157   pdata->result__interrupt_status                       = 0xFF;
13158   pdata->result__range_status                           = 0xFF;
13159   pdata->result__report_status                          = 0xFF;
13160   pdata->result__stream_count                           = 0xFF;
13161 
13162   pdata->result__dss_actual_effective_spads_sd0         = 0xFFFF;
13163   pdata->result__peak_signal_count_rate_mcps_sd0        = 0xFFFF;
13164   pdata->result__ambient_count_rate_mcps_sd0            = 0xFFFF;
13165   pdata->result__sigma_sd0                              = 0xFFFF;
13166   pdata->result__phase_sd0                              = 0xFFFF;
13167   pdata->result__final_crosstalk_corrected_range_mm_sd0 = 0xFFFF;
13168   pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 =
13169     0xFFFF;
13170   pdata->result__mm_inner_actual_effective_spads_sd0    = 0xFFFF;
13171   pdata->result__mm_outer_actual_effective_spads_sd0    = 0xFFFF;
13172   pdata->result__avg_signal_count_rate_mcps_sd0         = 0xFFFF;
13173 
13174   pdata->result__dss_actual_effective_spads_sd1         = 0xFFFF;
13175   pdata->result__peak_signal_count_rate_mcps_sd1        = 0xFFFF;
13176   pdata->result__ambient_count_rate_mcps_sd1            = 0xFFFF;
13177   pdata->result__sigma_sd1                              = 0xFFFF;
13178   pdata->result__phase_sd1                              = 0xFFFF;
13179   pdata->result__final_crosstalk_corrected_range_mm_sd1 = 0xFFFF;
13180   pdata->result__spare_0_sd1                            = 0xFFFF;
13181   pdata->result__spare_1_sd1                            = 0xFFFF;
13182   pdata->result__spare_2_sd1                            = 0xFFFF;
13183   pdata->result__spare_3_sd1                            = 0xFF;
13184 
13185 }
13186 void VL53LX::V53L1_init_zone_results_structure(
13187   uint8_t                 active_zones,
13188   VL53LX_zone_results_t  *pdata)
13189 {
13190 
13191 
13192 
13193   uint8_t  z = 0;
13194   VL53LX_zone_objects_t *pobjects;
13195 
13196   pdata->max_zones    = VL53LX_MAX_USER_ZONES;
13197   pdata->active_zones = active_zones;
13198 
13199   for (z = 0; z < pdata->max_zones; z++) {
13200     pobjects = &(pdata->VL53LX_p_003[z]);
13201     pobjects->cfg_device_state = VL53LX_DEVICESTATE_SW_STANDBY;
13202     pobjects->rd_device_state  = VL53LX_DEVICESTATE_SW_STANDBY;
13203     pobjects->max_objects      = VL53LX_MAX_RANGE_RESULTS;
13204     pobjects->active_objects   = 0;
13205   }
13206 }
13207 
13208 void VL53LX::V53L1_init_zone_dss_configs()
13209 {
13210 
13211   VL53LX_LLDriverResults_t  *pres =
13212     VL53LXDevStructGetLLResultsHandle(Dev);
13213   uint8_t  z = 0;
13214   uint8_t max_zones    = VL53LX_MAX_USER_ZONES;
13215   VL53LX_zone_private_dyn_cfgs_t *pdata = &(pres->zone_dyn_cfgs);
13216 
13217   for (z = 0; z < max_zones; z++) {
13218     pdata->VL53LX_p_003[z].dss_mode =
13219       VL53LX_DSS_CONTROL__MODE_TARGET_RATE;
13220     pdata->VL53LX_p_003[z].dss_requested_effective_spad_count = 0;
13221   }
13222 }
13223 
13224 void VL53LX::VL53LX_init_histogram_config_structure(
13225   uint8_t   even_bin0,
13226   uint8_t   even_bin1,
13227   uint8_t   even_bin2,
13228   uint8_t   even_bin3,
13229   uint8_t   even_bin4,
13230   uint8_t   even_bin5,
13231   uint8_t   odd_bin0,
13232   uint8_t   odd_bin1,
13233   uint8_t   odd_bin2,
13234   uint8_t   odd_bin3,
13235   uint8_t   odd_bin4,
13236   uint8_t   odd_bin5,
13237   VL53LX_histogram_config_t  *pdata)
13238 {
13239 
13240 
13241   pdata->histogram_config__low_amb_even_bin_0_1  =
13242     (even_bin1 << 4) + even_bin0;
13243   pdata->histogram_config__low_amb_even_bin_2_3  =
13244     (even_bin3 << 4) + even_bin2;
13245   pdata->histogram_config__low_amb_even_bin_4_5  =
13246     (even_bin5 << 4) + even_bin4;
13247 
13248   pdata->histogram_config__low_amb_odd_bin_0_1   =
13249     (odd_bin1 << 4) + odd_bin0;
13250   pdata->histogram_config__low_amb_odd_bin_2_3   =
13251     (odd_bin3 << 4) + odd_bin2;
13252   pdata->histogram_config__low_amb_odd_bin_4_5   =
13253     (odd_bin5 << 4) + odd_bin4;
13254 
13255   pdata->histogram_config__mid_amb_even_bin_0_1  =
13256     pdata->histogram_config__low_amb_even_bin_0_1;
13257   pdata->histogram_config__mid_amb_even_bin_2_3  =
13258     pdata->histogram_config__low_amb_even_bin_2_3;
13259   pdata->histogram_config__mid_amb_even_bin_4_5  =
13260     pdata->histogram_config__low_amb_even_bin_4_5;
13261 
13262   pdata->histogram_config__mid_amb_odd_bin_0_1   =
13263     pdata->histogram_config__low_amb_odd_bin_0_1;
13264   pdata->histogram_config__mid_amb_odd_bin_2     = odd_bin2;
13265   pdata->histogram_config__mid_amb_odd_bin_3_4   =
13266     (odd_bin4 << 4) + odd_bin3;
13267   pdata->histogram_config__mid_amb_odd_bin_5     = odd_bin5;
13268 
13269   pdata->histogram_config__user_bin_offset       = 0x00;
13270 
13271   pdata->histogram_config__high_amb_even_bin_0_1 =
13272     pdata->histogram_config__low_amb_even_bin_0_1;
13273   pdata->histogram_config__high_amb_even_bin_2_3 =
13274     pdata->histogram_config__low_amb_even_bin_2_3;
13275   pdata->histogram_config__high_amb_even_bin_4_5 =
13276     pdata->histogram_config__low_amb_even_bin_4_5;
13277 
13278   pdata->histogram_config__high_amb_odd_bin_0_1  =
13279     pdata->histogram_config__low_amb_odd_bin_0_1;
13280   pdata->histogram_config__high_amb_odd_bin_2_3  =
13281     pdata->histogram_config__low_amb_odd_bin_2_3;
13282   pdata->histogram_config__high_amb_odd_bin_4_5  =
13283     pdata->histogram_config__low_amb_odd_bin_4_5;
13284 
13285 
13286 
13287   pdata->histogram_config__amb_thresh_low        = 0xFFFF;
13288   pdata->histogram_config__amb_thresh_high       = 0xFFFF;
13289 
13290 
13291 
13292   pdata->histogram_config__spad_array_selection  = 0x00;
13293 
13294 }
13295 
13296 void VL53LX::VL53LX_init_histogram_multizone_config_structure(
13297   uint8_t   even_bin0,
13298   uint8_t   even_bin1,
13299   uint8_t   even_bin2,
13300   uint8_t   even_bin3,
13301   uint8_t   even_bin4,
13302   uint8_t   even_bin5,
13303   uint8_t   odd_bin0,
13304   uint8_t   odd_bin1,
13305   uint8_t   odd_bin2,
13306   uint8_t   odd_bin3,
13307   uint8_t   odd_bin4,
13308   uint8_t   odd_bin5,
13309   VL53LX_histogram_config_t  *pdata)
13310 {
13311 
13312 
13313   pdata->histogram_config__low_amb_even_bin_0_1  =
13314     (even_bin1 << 4) + even_bin0;
13315   pdata->histogram_config__low_amb_even_bin_2_3  =
13316     (even_bin3 << 4) + even_bin2;
13317   pdata->histogram_config__low_amb_even_bin_4_5  =
13318     (even_bin5 << 4) + even_bin4;
13319 
13320   pdata->histogram_config__low_amb_odd_bin_0_1   =
13321     pdata->histogram_config__low_amb_even_bin_0_1;
13322   pdata->histogram_config__low_amb_odd_bin_2_3
13323     = pdata->histogram_config__low_amb_even_bin_2_3;
13324   pdata->histogram_config__low_amb_odd_bin_4_5
13325     = pdata->histogram_config__low_amb_even_bin_4_5;
13326 
13327   pdata->histogram_config__mid_amb_even_bin_0_1  =
13328     pdata->histogram_config__low_amb_even_bin_0_1;
13329   pdata->histogram_config__mid_amb_even_bin_2_3
13330     = pdata->histogram_config__low_amb_even_bin_2_3;
13331   pdata->histogram_config__mid_amb_even_bin_4_5
13332     = pdata->histogram_config__low_amb_even_bin_4_5;
13333 
13334   pdata->histogram_config__mid_amb_odd_bin_0_1
13335     = pdata->histogram_config__low_amb_odd_bin_0_1;
13336   pdata->histogram_config__mid_amb_odd_bin_2     = odd_bin2;
13337   pdata->histogram_config__mid_amb_odd_bin_3_4   =
13338     (odd_bin4 << 4) + odd_bin3;
13339   pdata->histogram_config__mid_amb_odd_bin_5     = odd_bin5;
13340 
13341   pdata->histogram_config__user_bin_offset       = 0x00;
13342 
13343   pdata->histogram_config__high_amb_even_bin_0_1 =
13344     (odd_bin1 << 4) + odd_bin0;
13345   pdata->histogram_config__high_amb_even_bin_2_3 =
13346     (odd_bin3 << 4) + odd_bin2;
13347   pdata->histogram_config__high_amb_even_bin_4_5 =
13348     (odd_bin5 << 4) + odd_bin4;
13349 
13350   pdata->histogram_config__high_amb_odd_bin_0_1
13351     = pdata->histogram_config__high_amb_even_bin_0_1;
13352   pdata->histogram_config__high_amb_odd_bin_2_3
13353     = pdata->histogram_config__high_amb_even_bin_2_3;
13354   pdata->histogram_config__high_amb_odd_bin_4_5
13355     = pdata->histogram_config__high_amb_even_bin_4_5;
13356 
13357 
13358 
13359   pdata->histogram_config__amb_thresh_low        = 0xFFFF;
13360   pdata->histogram_config__amb_thresh_high       = 0xFFFF;
13361 
13362 
13363 
13364   pdata->histogram_config__spad_array_selection  = 0x00;
13365 }
13366 
13367 void VL53LX::VL53LX_init_xtalk_bin_data_struct(
13368   uint32_t                        bin_value,
13369   uint16_t                        VL53LX_p_021,
13370   VL53LX_xtalk_histogram_shape_t *pdata)
13371 {
13372 
13373 
13374 
13375   uint16_t          i = 0;
13376 
13377   pdata->zone_id                   = 0;
13378   pdata->time_stamp                = 0;
13379 
13380   pdata->VL53LX_p_019                 = 0;
13381   pdata->VL53LX_p_020               = VL53LX_XTALK_HISTO_BINS;
13382   pdata->VL53LX_p_021            = (uint8_t)VL53LX_p_021;
13383 
13384   pdata->phasecal_result__reference_phase   = 0;
13385   pdata->phasecal_result__vcsel_start       = 0;
13386   pdata->cal_config__vcsel_start            = 0;
13387 
13388   pdata->vcsel_width                        = 0;
13389   pdata->VL53LX_p_015                = 0;
13390 
13391   pdata->zero_distance_phase                = 0;
13392 
13393   for (i = 0; i < VL53LX_XTALK_HISTO_BINS; i++) {
13394     if (i < VL53LX_p_021) {
13395       pdata->bin_data[i] = bin_value;
13396     } else {
13397       pdata->bin_data[i] = 0;
13398     }
13399   }
13400 }
13401 void VL53LX::VL53LX_i2c_encode_uint16_t(
13402   uint16_t    ip_value,
13403   uint16_t    count,
13404   uint8_t    *pbuffer)
13405 {
13406 
13407 
13408   uint16_t   i    = 0;
13409   uint16_t   VL53LX_p_003 = 0;
13410 
13411   VL53LX_p_003 =  ip_value;
13412 
13413   for (i = 0; i < count; i++) {
13414     pbuffer[count - i - 1] = (uint8_t)(VL53LX_p_003 & 0x00FF);
13415     VL53LX_p_003 = VL53LX_p_003 >> 8;
13416   }
13417 }
13418 
13419 uint16_t VL53LX::VL53LX_i2c_decode_uint16_t(
13420   uint16_t    count,
13421   uint8_t    *pbuffer)
13422 {
13423 
13424 
13425   uint16_t   value = 0x00;
13426 
13427   while (count-- > 0) {
13428     value = (value << 8) | (uint16_t) * pbuffer++;
13429   }
13430 
13431   return value;
13432 }
13433 
13434 void VL53LX::VL53LX_i2c_encode_int16_t(
13435   int16_t     ip_value,
13436   uint16_t    count,
13437   uint8_t    *pbuffer)
13438 {
13439 
13440 
13441   uint16_t   i    = 0;
13442   int16_t    VL53LX_p_003 = 0;
13443 
13444   VL53LX_p_003 =  ip_value;
13445 
13446   for (i = 0; i < count; i++) {
13447     pbuffer[count - i - 1] = (uint8_t)(VL53LX_p_003 & 0x00FF);
13448     VL53LX_p_003 = VL53LX_p_003 >> 8;
13449   }
13450 }
13451 int16_t VL53LX::VL53LX_i2c_decode_int16_t(
13452   uint16_t    count,
13453   uint8_t    *pbuffer)
13454 {
13455 
13456 
13457   int16_t    value = 0x00;
13458 
13459 
13460   if (*pbuffer >= 0x80) {
13461     value = 0xFFFF;
13462   }
13463 
13464   while (count-- > 0) {
13465     value = (value << 8) | (int16_t) * pbuffer++;
13466   }
13467 
13468   return value;
13469 }
13470 
13471 void VL53LX::VL53LX_i2c_encode_uint32_t(
13472   uint32_t    ip_value,
13473   uint16_t    count,
13474   uint8_t    *pbuffer)
13475 {
13476 
13477 
13478   uint16_t   i    = 0;
13479   uint32_t   VL53LX_p_003 = 0;
13480 
13481   VL53LX_p_003 =  ip_value;
13482 
13483   for (i = 0; i < count; i++) {
13484     pbuffer[count - i - 1] = (uint8_t)(VL53LX_p_003 & 0x00FF);
13485     VL53LX_p_003 = VL53LX_p_003 >> 8;
13486   }
13487 }
13488 
13489 
13490 uint32_t VL53LX::VL53LX_i2c_decode_uint32_t(
13491   uint16_t    count,
13492   uint8_t    *pbuffer)
13493 {
13494 
13495 
13496   uint32_t   value = 0x00;
13497 
13498   while (count-- > 0) {
13499     value = (value << 8) | (uint32_t) * pbuffer++;
13500   }
13501 
13502   return value;
13503 }
13504 uint32_t VL53LX::VL53LX_i2c_decode_with_mask(
13505   uint16_t    count,
13506   uint8_t    *pbuffer,
13507   uint32_t    bit_mask,
13508   uint32_t    down_shift,
13509   uint32_t    offset)
13510 {
13511 
13512 
13513   uint32_t   value = 0x00;
13514 
13515 
13516   while (count-- > 0) {
13517     value = (value << 8) | (uint32_t) * pbuffer++;
13518   }
13519 
13520 
13521   value =  value & bit_mask;
13522   if (down_shift > 0) {
13523     value = value >> down_shift;
13524   }
13525 
13526 
13527   value = value + offset;
13528 
13529   return value;
13530 }
13531 
13532 void VL53LX::VL53LX_i2c_encode_int32_t(
13533   int32_t     ip_value,
13534   uint16_t    count,
13535   uint8_t    *pbuffer)
13536 {
13537 
13538 
13539   uint16_t   i    = 0;
13540   int32_t    VL53LX_p_003 = 0;
13541 
13542   VL53LX_p_003 =  ip_value;
13543 
13544   for (i = 0; i < count; i++) {
13545     pbuffer[count - i - 1] = (uint8_t)(VL53LX_p_003 & 0x00FF);
13546     VL53LX_p_003 = VL53LX_p_003 >> 8;
13547   }
13548 }
13549 
13550 int32_t VL53LX::VL53LX_i2c_decode_int32_t(
13551   uint16_t    count,
13552   uint8_t    *pbuffer)
13553 {
13554 
13555 
13556   int32_t    value = 0x00;
13557 
13558 
13559   if (*pbuffer >= 0x80) {
13560     value = 0xFFFFFFFF;
13561   }
13562 
13563   while (count-- > 0) {
13564     value = (value << 8) | (int32_t) * pbuffer++;
13565   }
13566 
13567   return value;
13568 }
13569 VL53LX_Error VL53LX::VL53LX_start_test(
13570   uint8_t       test_mode__ctrl)
13571 {
13572 
13573 
13574   VL53LX_Error status = VL53LX_ERROR_NONE;
13575 
13576 
13577   if (status == VL53LX_ERROR_NONE) {
13578     status = VL53LX_WrByte(
13579                Dev,
13580                VL53LX_TEST_MODE__CTRL,
13581                test_mode__ctrl);
13582   }
13583 
13584 
13585   return status;
13586 }
13587 VL53LX_Error VL53LX::VL53LX_set_firmware_enable_register(uint8_t  value)
13588 {
13589 
13590 
13591   VL53LX_Error status         = VL53LX_ERROR_NONE;
13592   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
13593 
13594   pdev->sys_ctrl.firmware__enable = value;
13595 
13596   status = VL53LX_WrByte(
13597              Dev,
13598              VL53LX_FIRMWARE__ENABLE,
13599              pdev->sys_ctrl.firmware__enable);
13600 
13601   return status;
13602 }
13603 
13604 VL53LX_Error VL53LX::VL53LX_enable_firmware()
13605 {
13606   VL53LX_Error status       = VL53LX_ERROR_NONE;
13607 
13608   status = VL53LX_set_firmware_enable_register(0x01);
13609 
13610 
13611   return status;
13612 }
13613 
13614 VL53LX_Error VL53LX::VL53LX_disable_firmware()
13615 {
13616   VL53LX_Error status       = VL53LX_ERROR_NONE;
13617 
13618   status = VL53LX_set_firmware_enable_register(0x00);
13619 
13620   return status;
13621 }
13622 
13623 
13624 VL53LX_Error VL53LX::VL53LX_set_powerforce_register(
13625   uint8_t       value)
13626 {
13627 
13628 
13629   VL53LX_Error status       = VL53LX_ERROR_NONE;
13630   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
13631 
13632   pdev->sys_ctrl.power_management__go1_power_force = value;
13633 
13634   status = VL53LX_WrByte(
13635              Dev,
13636              VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE,
13637              pdev->sys_ctrl.power_management__go1_power_force);
13638 
13639   return status;
13640 }
13641 
13642 
13643 VL53LX_Error VL53LX::VL53LX_enable_powerforce()
13644 {
13645   VL53LX_Error status       = VL53LX_ERROR_NONE;
13646 
13647   status = VL53LX_set_powerforce_register(0x01);
13648 
13649   return status;
13650 }
13651 VL53LX_Error VL53LX::VL53LX_disable_powerforce()
13652 {
13653 
13654   VL53LX_Error status       = VL53LX_ERROR_NONE;
13655 
13656   status = VL53LX_set_powerforce_register(0x00);
13657 
13658   return status;
13659 }
13660 
13661 VL53LX_Error VL53LX::VL53LX_clear_interrupt()
13662 {
13663 
13664 
13665   VL53LX_Error status       = VL53LX_ERROR_NONE;
13666   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
13667 
13668   pdev->sys_ctrl.system__interrupt_clear = VL53LX_CLEAR_RANGE_INT;
13669 
13670   status = VL53LX_WrByte(
13671              Dev,
13672              VL53LX_SYSTEM__INTERRUPT_CLEAR,
13673              pdev->sys_ctrl.system__interrupt_clear);
13674 
13675 
13676   return status;
13677 }
13678 
13679 
13680 VL53LX_Error VL53LX::VL53LX_force_shadow_stream_count_to_zero()
13681 {
13682 
13683 
13684   VL53LX_Error status       = VL53LX_ERROR_NONE;
13685 
13686   if (status == VL53LX_ERROR_NONE) {
13687     status = VL53LX_disable_firmware();
13688   }
13689 
13690   if (status == VL53LX_ERROR_NONE) {
13691     status = VL53LX_WrByte(
13692                Dev,
13693                VL53LX_SHADOW_RESULT__STREAM_COUNT,
13694                0x00);
13695   }
13696 
13697   if (status == VL53LX_ERROR_NONE) {
13698     status = VL53LX_enable_firmware();
13699   }
13700 
13701   return status;
13702 }
13703 uint32_t VL53LX::VL53LX_calc_macro_period_us(
13704   uint16_t  fast_osc_frequency,
13705   uint8_t   VL53LX_p_005)
13706 {
13707 
13708   uint32_t  pll_period_us        = 0;
13709   uint8_t   VL53LX_p_030   = 0;
13710   uint32_t  macro_period_us      = 0;
13711 
13712 
13713   pll_period_us = VL53LX_calc_pll_period_us(fast_osc_frequency);
13714 
13715 
13716 
13717   VL53LX_p_030 = VL53LX_decode_vcsel_period(VL53LX_p_005);
13718 
13719 
13720 
13721   macro_period_us =
13722     (uint32_t)VL53LX_MACRO_PERIOD_VCSEL_PERIODS *
13723     pll_period_us;
13724   macro_period_us = macro_period_us >> 6;
13725 
13726   macro_period_us = macro_period_us * (uint32_t)VL53LX_p_030;
13727   macro_period_us = macro_period_us >> 6;
13728 
13729   return macro_period_us;
13730 }
13731 
13732 uint16_t VL53LX::VL53LX_calc_range_ignore_threshold(
13733   uint32_t central_rate,
13734   int16_t  x_gradient,
13735   int16_t  y_gradient,
13736   uint8_t  rate_mult)
13737 {
13738 
13739 
13740   int32_t    range_ignore_thresh_int  = 0;
13741   uint16_t   range_ignore_thresh_kcps = 0;
13742   int32_t    central_rate_int         = 0;
13743   int16_t    x_gradient_int           = 0;
13744   int16_t    y_gradient_int           = 0;
13745 
13746   central_rate_int = ((int32_t)central_rate * (1 << 4)) / (1000);
13747 
13748   if (x_gradient < 0) {
13749     x_gradient_int = x_gradient * -1;
13750   }
13751 
13752   if (y_gradient < 0) {
13753     y_gradient_int = y_gradient * -1;
13754   }
13755 
13756 
13757 
13758 
13759 
13760   range_ignore_thresh_int = (8 * x_gradient_int * 4) +
13761                             (8 * y_gradient_int * 4);
13762 
13763 
13764 
13765   range_ignore_thresh_int = range_ignore_thresh_int / 1000;
13766 
13767 
13768 
13769   range_ignore_thresh_int = range_ignore_thresh_int + central_rate_int;
13770 
13771 
13772 
13773   range_ignore_thresh_int = (int32_t)rate_mult * range_ignore_thresh_int;
13774 
13775   range_ignore_thresh_int = (range_ignore_thresh_int + (1 << 4)) / (1 << 5);
13776 
13777 
13778 
13779   if (range_ignore_thresh_int > 0xFFFF) {
13780     range_ignore_thresh_kcps = 0xFFFF;
13781   } else {
13782     range_ignore_thresh_kcps = (uint16_t)range_ignore_thresh_int;
13783   }
13784 
13785   return range_ignore_thresh_kcps;
13786 }
13787 
13788 uint32_t VL53LX::VL53LX_calc_timeout_mclks(
13789   uint32_t timeout_us,
13790   uint32_t macro_period_us)
13791 {
13792   uint32_t timeout_mclks   = 0;
13793 
13794   timeout_mclks   =
13795     ((timeout_us << 12) + (macro_period_us >> 1)) /
13796     macro_period_us;
13797 
13798   return timeout_mclks;
13799 }
13800 uint16_t VL53LX::VL53LX_calc_encoded_timeout(
13801   uint32_t timeout_us,
13802   uint32_t macro_period_us)
13803 {
13804 
13805 
13806   uint32_t timeout_mclks   = 0;
13807   uint16_t timeout_encoded = 0;
13808 
13809 
13810   timeout_mclks   =
13811     VL53LX_calc_timeout_mclks(timeout_us, macro_period_us);
13812 
13813   timeout_encoded =
13814     VL53LX_encode_timeout(timeout_mclks);
13815 
13816   return timeout_encoded;
13817 }
13818 
13819 uint32_t VL53LX::VL53LX_calc_timeout_us(
13820   uint32_t timeout_mclks,
13821   uint32_t macro_period_us)
13822 {
13823 
13824 
13825   uint32_t timeout_us     = 0;
13826   uint64_t tmp            = 0;
13827 
13828 
13829   tmp  = (uint64_t)timeout_mclks * (uint64_t)macro_period_us;
13830   tmp += 0x00800;
13831   tmp  = tmp >> 12;
13832 
13833   timeout_us = (uint32_t)tmp;
13834 
13835 
13836   return timeout_us;
13837 }
13838 
13839 uint32_t VL53LX::VL53LX_calc_crosstalk_plane_offset_with_margin(
13840   uint32_t     plane_offset_kcps,
13841   int16_t      margin_offset_kcps)
13842 {
13843   uint32_t plane_offset_with_margin = 0;
13844   int32_t  plane_offset_kcps_temp   = 0;
13845 
13846   plane_offset_kcps_temp =
13847     (int32_t)plane_offset_kcps +
13848     (int32_t)margin_offset_kcps;
13849 
13850   if (plane_offset_kcps_temp < 0) {
13851     plane_offset_kcps_temp = 0;
13852   } else if (plane_offset_kcps_temp > 0x3FFFF) {
13853     plane_offset_kcps_temp = 0x3FFFF;
13854   }
13855 
13856   plane_offset_with_margin = (uint32_t) plane_offset_kcps_temp;
13857 
13858   return plane_offset_with_margin;
13859 
13860 }
13861 
13862 uint32_t VL53LX::VL53LX_calc_decoded_timeout_us(
13863   uint16_t timeout_encoded,
13864   uint32_t macro_period_us)
13865 {
13866 
13867 
13868   uint32_t timeout_mclks  = 0;
13869   uint32_t timeout_us     = 0;
13870 
13871   timeout_mclks =
13872     VL53LX_decode_timeout(timeout_encoded);
13873 
13874   timeout_us    =
13875     VL53LX_calc_timeout_us(timeout_mclks, macro_period_us);
13876 
13877   return timeout_us;
13878 }
13879 
13880 uint16_t VL53LX::VL53LX_encode_timeout(uint32_t timeout_mclks)
13881 {
13882 
13883 
13884   uint16_t encoded_timeout = 0;
13885   uint32_t ls_byte = 0;
13886   uint16_t ms_byte = 0;
13887 
13888   if (timeout_mclks > 0) {
13889     ls_byte = timeout_mclks - 1;
13890 
13891     while ((ls_byte & 0xFFFFFF00) > 0) {
13892       ls_byte = ls_byte >> 1;
13893       ms_byte++;
13894     }
13895 
13896     encoded_timeout = (ms_byte << 8)
13897                       + (uint16_t)(ls_byte & 0x000000FF);
13898   }
13899 
13900   return encoded_timeout;
13901 }
13902 
13903 uint32_t VL53LX::VL53LX_decode_timeout(uint16_t encoded_timeout)
13904 {
13905 
13906 
13907   uint32_t timeout_macro_clks = 0;
13908 
13909   timeout_macro_clks = ((uint32_t)(encoded_timeout & 0x00FF)
13910                         << (uint32_t)((encoded_timeout & 0xFF00) >> 8)) + 1;
13911 
13912   return timeout_macro_clks;
13913 }
13914 
13915 
13916 
13917 
13918 VL53LX_Error VL53LX::VL53LX_calc_timeout_register_values(
13919   uint32_t                 phasecal_config_timeout_us,
13920   uint32_t                 mm_config_timeout_us,
13921   uint32_t                 range_config_timeout_us,
13922   uint16_t                 fast_osc_frequency,
13923   VL53LX_general_config_t *pgeneral,
13924   VL53LX_timing_config_t  *ptiming)
13925 {
13926 
13927   VL53LX_Error status = VL53LX_ERROR_NONE;
13928 
13929   uint32_t macro_period_us    = 0;
13930   uint32_t timeout_mclks      = 0;
13931   uint16_t timeout_encoded    = 0;
13932 
13933   if (fast_osc_frequency == 0) {
13934     status = VL53LX_ERROR_DIVISION_BY_ZERO;
13935   } else {
13936 
13937     macro_period_us =
13938       VL53LX_calc_macro_period_us(
13939         fast_osc_frequency,
13940         ptiming->range_config__vcsel_period_a);
13941 
13942 
13943     timeout_mclks =
13944       VL53LX_calc_timeout_mclks(
13945         phasecal_config_timeout_us,
13946         macro_period_us);
13947 
13948 
13949     if (timeout_mclks > 0xFF) {
13950       timeout_mclks = 0xFF;
13951     }
13952 
13953     pgeneral->phasecal_config__timeout_macrop =
13954       (uint8_t)timeout_mclks;
13955 
13956 
13957     timeout_encoded =
13958       VL53LX_calc_encoded_timeout(
13959         mm_config_timeout_us,
13960         macro_period_us);
13961 
13962     ptiming->mm_config__timeout_macrop_a_hi =
13963       (uint8_t)((timeout_encoded & 0xFF00) >> 8);
13964     ptiming->mm_config__timeout_macrop_a_lo =
13965       (uint8_t)(timeout_encoded & 0x00FF);
13966 
13967 
13968     timeout_encoded =
13969       VL53LX_calc_encoded_timeout(
13970         range_config_timeout_us,
13971         macro_period_us);
13972 
13973     ptiming->range_config__timeout_macrop_a_hi =
13974       (uint8_t)((timeout_encoded & 0xFF00) >> 8);
13975     ptiming->range_config__timeout_macrop_a_lo =
13976       (uint8_t)(timeout_encoded & 0x00FF);
13977 
13978 
13979     macro_period_us =
13980       VL53LX_calc_macro_period_us(
13981         fast_osc_frequency,
13982         ptiming->range_config__vcsel_period_b);
13983 
13984 
13985     timeout_encoded =
13986       VL53LX_calc_encoded_timeout(
13987         mm_config_timeout_us,
13988         macro_period_us);
13989 
13990     ptiming->mm_config__timeout_macrop_b_hi =
13991       (uint8_t)((timeout_encoded & 0xFF00) >> 8);
13992     ptiming->mm_config__timeout_macrop_b_lo =
13993       (uint8_t)(timeout_encoded & 0x00FF);
13994 
13995 
13996     timeout_encoded = VL53LX_calc_encoded_timeout(
13997                         range_config_timeout_us,
13998                         macro_period_us);
13999 
14000     ptiming->range_config__timeout_macrop_b_hi =
14001       (uint8_t)((timeout_encoded & 0xFF00) >> 8);
14002     ptiming->range_config__timeout_macrop_b_lo =
14003       (uint8_t)(timeout_encoded & 0x00FF);
14004   }
14005 
14006   return status;
14007 
14008 }
14009 
14010 uint8_t VL53LX::VL53LX_encode_vcsel_period(uint8_t VL53LX_p_030)
14011 {
14012 
14013 
14014   uint8_t vcsel_period_reg = 0;
14015 
14016   vcsel_period_reg = (VL53LX_p_030 >> 1) - 1;
14017 
14018   return vcsel_period_reg;
14019 }
14020 
14021 uint32_t VL53LX::VL53LX_decode_unsigned_integer(
14022   uint8_t  *pbuffer,
14023   uint8_t   no_of_bytes)
14024 {
14025 
14026 
14027   uint8_t   i = 0;
14028   uint32_t  decoded_value = 0;
14029 
14030   for (i = 0; i < no_of_bytes; i++) {
14031     decoded_value = (decoded_value << 8) + (uint32_t)pbuffer[i];
14032   }
14033 
14034   return decoded_value;
14035 }
14036 
14037 
14038 void VL53LX::VL53LX_encode_unsigned_integer(
14039   uint32_t  ip_value,
14040   uint8_t   no_of_bytes,
14041   uint8_t  *pbuffer)
14042 {
14043 
14044 
14045   uint8_t   i    = 0;
14046   uint32_t  VL53LX_p_003 = 0;
14047 
14048   VL53LX_p_003 = ip_value;
14049   for (i = 0; i < no_of_bytes; i++) {
14050     pbuffer[no_of_bytes - i - 1] = VL53LX_p_003 & 0x00FF;
14051     VL53LX_p_003 = VL53LX_p_003 >> 8;
14052   }
14053 }
14054 
14055 VL53LX_Error  VL53LX::VL53LX_hist_copy_and_scale_ambient_info(
14056   VL53LX_zone_hist_info_t       *pidata,
14057   VL53LX_histogram_bin_data_t   *podata)
14058 {
14059 
14060 
14061   VL53LX_Error status = VL53LX_ERROR_NONE;
14062 
14063   int64_t  evts              = 0;
14064   int64_t  tmpi              = 0;
14065   int64_t  tmpo              = 0;
14066 
14067 
14068   if (pidata->result__dss_actual_effective_spads == 0) {
14069     status = VL53LX_ERROR_DIVISION_BY_ZERO;
14070   } else {
14071     if (pidata->number_of_ambient_bins >  0 &&
14072         podata->number_of_ambient_bins == 0) {
14073 
14074 
14075 
14076       tmpo    = 1 + (int64_t)podata->total_periods_elapsed;
14077       tmpo   *=
14078         (int64_t)podata->result__dss_actual_effective_spads;
14079 
14080       tmpi    = 1 + (int64_t)pidata->total_periods_elapsed;
14081       tmpi   *=
14082         (int64_t)pidata->result__dss_actual_effective_spads;
14083 
14084       evts  = tmpo *
14085               (int64_t)pidata->ambient_events_sum;
14086       evts += (tmpi / 2);
14087 
14088 
14089       if (tmpi != 0) {
14090         evts = do_division_s(evts, tmpi);
14091       }
14092 
14093       podata->ambient_events_sum = (int32_t)evts;
14094 
14095 
14096 
14097       podata->VL53LX_p_028 =
14098         podata->ambient_events_sum;
14099       podata->VL53LX_p_028 +=
14100         ((int32_t)pidata->number_of_ambient_bins / 2);
14101       podata->VL53LX_p_028 /=
14102         (int32_t)pidata->number_of_ambient_bins;
14103     }
14104   }
14105 
14106 
14107   return status;
14108 }
14109 
14110 
14111 void  VL53LX::VL53LX_hist_get_bin_sequence_config(
14112   VL53LX_histogram_bin_data_t   *pdata)
14113 {
14114 
14115 
14116   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
14117 
14118   int32_t amb_thresh_low   = 0;
14119   int32_t amb_thresh_high  = 0;
14120 
14121   uint8_t i = 0;
14122 
14123   amb_thresh_low  = 1024 *
14124                     (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_low;
14125   amb_thresh_high = 1024 *
14126                     (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_high;
14127 
14128 
14129 
14130   if ((pdev->ll_state.rd_stream_count & 0x01) == 0) {
14131 
14132     pdata->bin_seq[5] =
14133       pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 >> 4;
14134     pdata->bin_seq[4] =
14135       pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 & 0x0F;
14136     pdata->bin_seq[3] =
14137       pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 >> 4;
14138     pdata->bin_seq[2] =
14139       pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 & 0x0F;
14140     pdata->bin_seq[1] =
14141       pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 >> 4;
14142     pdata->bin_seq[0] =
14143       pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 & 0x0F;
14144 
14145     if (pdata->ambient_events_sum > amb_thresh_high) {
14146       pdata->bin_seq[5] =
14147         pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5
14148         >> 4;
14149       pdata->bin_seq[4] =
14150         pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5
14151         & 0x0F;
14152       pdata->bin_seq[3] =
14153         pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3
14154         >> 4;
14155       pdata->bin_seq[2] =
14156         pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3
14157         & 0x0F;
14158       pdata->bin_seq[1] =
14159         pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1
14160         >> 4;
14161       pdata->bin_seq[0] =
14162         pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1
14163         & 0x0F;
14164     }
14165 
14166     if (pdata->ambient_events_sum < amb_thresh_low) {
14167       pdata->bin_seq[5] =
14168         pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5
14169         >> 4;
14170       pdata->bin_seq[4] =
14171         pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5
14172         & 0x0F;
14173       pdata->bin_seq[3] =
14174         pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3
14175         >> 4;
14176       pdata->bin_seq[2] =
14177         pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3
14178         & 0x0F;
14179       pdata->bin_seq[1] =
14180         pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1
14181         >> 4;
14182       pdata->bin_seq[0] =
14183         pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1
14184         & 0x0F;
14185     }
14186 
14187   } else {
14188     pdata->bin_seq[5] =
14189       pdev->hist_cfg.histogram_config__mid_amb_odd_bin_5
14190       & 0x0F;
14191     pdata->bin_seq[4] =
14192       pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4
14193       & 0x0F;
14194     pdata->bin_seq[3] =
14195       pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4
14196       >> 4;
14197     pdata->bin_seq[2] =
14198       pdev->hist_cfg.histogram_config__mid_amb_odd_bin_2 &
14199       0x0F;
14200     pdata->bin_seq[1] =
14201       pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1
14202       >> 4;
14203     pdata->bin_seq[0] =
14204       pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1
14205       & 0x0F;
14206 
14207     if (pdata->ambient_events_sum > amb_thresh_high) {
14208       pdata->bin_seq[5] =
14209         pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5
14210         >> 4;
14211       pdata->bin_seq[4] =
14212         pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5
14213         & 0x0F;
14214       pdata->bin_seq[3] =
14215         pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3
14216         >> 4;
14217       pdata->bin_seq[2] =
14218         pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3
14219         & 0x0F;
14220       pdata->bin_seq[1] =
14221         pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1
14222         >> 4;
14223       pdata->bin_seq[0] =
14224         pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1
14225         & 0x0F;
14226     }
14227 
14228     if (pdata->ambient_events_sum < amb_thresh_low) {
14229       pdata->bin_seq[5] =
14230         pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5
14231         >> 4;
14232       pdata->bin_seq[4] =
14233         pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5
14234         & 0x0F;
14235       pdata->bin_seq[3] =
14236         pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3
14237         >> 4;
14238       pdata->bin_seq[2] =
14239         pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3
14240         & 0x0F;
14241       pdata->bin_seq[1] =
14242         pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1
14243         >> 4;
14244       pdata->bin_seq[0] =
14245         pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1
14246         & 0x0F;
14247     }
14248   }
14249 
14250 
14251 
14252   for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) {
14253     pdata->bin_rep[i] = 1;
14254   }
14255 
14256 }
14257 
14258 
14259 VL53LX_Error  VL53LX::VL53LX_hist_phase_consistency_check(
14260   VL53LX_zone_hist_info_t     *phist_prev,
14261   VL53LX_zone_objects_t       *prange_prev,
14262   VL53LX_range_results_t      *prange_curr)
14263 {
14264 
14265 
14266 
14267   VL53LX_Error  status = VL53LX_ERROR_NONE;
14268   VL53LX_LLDriverData_t *pdev =
14269     VL53LXDevStructGetLLDriverHandle(Dev);
14270 
14271   uint8_t   lc = 0;
14272   uint8_t   p = 0;
14273 
14274   uint16_t  phase_delta      = 0;
14275   uint16_t  phase_tolerance  = 0;
14276 
14277   int32_t   events_delta     = 0;
14278   int32_t   events_tolerance = 0;
14279 
14280 
14281   uint8_t event_sigma;
14282   uint16_t event_min_spad_count;
14283   uint16_t min_max_tolerance;
14284   uint8_t pht;
14285 
14286   VL53LX_DeviceError  range_status = 0;
14287 
14288 
14289   event_sigma =
14290     pdev->histpostprocess.algo__consistency_check__event_sigma;
14291   event_min_spad_count =
14292     pdev->histpostprocess.algo__consistency_check__event_min_spad_count;
14293   min_max_tolerance =
14294     pdev->histpostprocess.algo__consistency_check__min_max_tolerance;
14295 
14296 
14297   pht = pdev->histpostprocess.algo__consistency_check__phase_tolerance;
14298   phase_tolerance = (uint16_t)pht;
14299   phase_tolerance = phase_tolerance << 8;
14300 
14301 
14302 
14303   if (prange_prev->rd_device_state !=
14304       VL53LX_DEVICESTATE_RANGING_GATHER_DATA &&
14305       prange_prev->rd_device_state !=
14306       VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA) {
14307     return status;
14308   }
14309 
14310 
14311 
14312   if (phase_tolerance == 0) {
14313     return status;
14314   }
14315 
14316   for (lc = 0; lc < prange_curr->active_results; lc++) {
14317 
14318     if (!((prange_curr->VL53LX_p_003[lc].range_status ==
14319            VL53LX_DEVICEERROR_RANGECOMPLETE) ||
14320           (prange_curr->VL53LX_p_003[lc].range_status ==
14321            VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK))) {
14322       continue;
14323     }
14324 
14325 
14326 
14327 
14328 
14329 
14330     if (prange_prev->active_objects == 0)
14331       prange_curr->VL53LX_p_003[lc].range_status =
14332         VL53LX_DEVICEERROR_PREV_RANGE_NO_TARGETS;
14333     else
14334       prange_curr->VL53LX_p_003[lc].range_status =
14335         VL53LX_DEVICEERROR_PHASECONSISTENCY;
14336 
14337 
14338 
14339 
14340 
14341     for (p = 0; p < prange_prev->active_objects; p++) {
14342 
14343       if (prange_curr->VL53LX_p_003[lc].VL53LX_p_011 >
14344           prange_prev->VL53LX_p_003[p].VL53LX_p_011) {
14345         phase_delta =
14346           prange_curr->VL53LX_p_003[lc].VL53LX_p_011 -
14347           prange_prev->VL53LX_p_003[p].VL53LX_p_011;
14348       } else {
14349         phase_delta =
14350           prange_prev->VL53LX_p_003[p].VL53LX_p_011 -
14351           prange_curr->VL53LX_p_003[lc].VL53LX_p_011;
14352       }
14353 
14354       if (phase_delta < phase_tolerance) {
14355 
14356 
14357 
14358 
14359 
14360         if (status == VL53LX_ERROR_NONE)
14361           status =
14362             VL53LX_hist_events_consistency_check(
14363               event_sigma,
14364               event_min_spad_count,
14365               phist_prev,
14366               &(prange_prev->VL53LX_p_003[p]),
14367               &(prange_curr->VL53LX_p_003[lc]),
14368               &events_tolerance,
14369               &events_delta,
14370               &range_status);
14371 
14372 
14373 
14374 
14375         if (status == VL53LX_ERROR_NONE &&
14376             range_status ==
14377             VL53LX_DEVICEERROR_RANGECOMPLETE)
14378           status =
14379             VL53LX_hist_merged_pulse_check(
14380               min_max_tolerance,
14381               &(prange_curr->VL53LX_p_003[lc]),
14382               &range_status);
14383 
14384         prange_curr->VL53LX_p_003[lc].range_status =
14385           range_status;
14386       }
14387     }
14388 
14389   }
14390 
14391   return status;
14392 }
14393 
14394 
14395 
14396 VL53LX_Error  VL53LX::VL53LX_hist_events_consistency_check(
14397   uint8_t                      event_sigma,
14398   uint16_t                     min_effective_spad_count,
14399   VL53LX_zone_hist_info_t     *phist_prev,
14400   VL53LX_object_data_t        *prange_prev,
14401   VL53LX_range_data_t         *prange_curr,
14402   int32_t                     *pevents_tolerance,
14403   int32_t                     *pevents_delta,
14404   VL53LX_DeviceError          *prange_status)
14405 {
14406 
14407 
14408   VL53LX_Error  status = VL53LX_ERROR_NONE;
14409 
14410   int64_t   tmpp                   = 0;
14411   int64_t   tmpc                   = 0;
14412   int64_t   events_scaler          = 0;
14413   int64_t   events_scaler_sq       = 0;
14414   int64_t   c_signal_events        = 0;
14415   int64_t   c_sig_noise_sq         = 0;
14416   int64_t   c_amb_noise_sq         = 0;
14417   int64_t   p_amb_noise_sq         = 0;
14418 
14419   int32_t   p_signal_events        = 0;
14420   uint32_t  noise_sq_sum           = 0;
14421 
14422 
14423 
14424   if (event_sigma == 0) {
14425     *prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE;
14426     return status;
14427   }
14428 
14429 
14430 
14431   tmpp  = 1 + (int64_t)phist_prev->total_periods_elapsed;
14432   tmpp *= (int64_t)phist_prev->result__dss_actual_effective_spads;
14433 
14434 
14435 
14436   tmpc  = 1 + (int64_t)prange_curr->total_periods_elapsed;
14437   tmpc *= (int64_t)prange_curr->VL53LX_p_004;
14438 
14439 
14440 
14441   events_scaler  = tmpp * 4096;
14442   if (tmpc != 0) {
14443     events_scaler += (tmpc / 2);
14444     events_scaler  = do_division_s(events_scaler, tmpc);
14445   }
14446 
14447   events_scaler_sq  = events_scaler * events_scaler;
14448   events_scaler_sq += 2048;
14449   events_scaler_sq /= 4096;
14450 
14451 
14452 
14453   c_signal_events  = (int64_t)prange_curr->VL53LX_p_017;
14454   c_signal_events -= (int64_t)prange_curr->VL53LX_p_016;
14455   c_signal_events *= (int64_t)events_scaler;
14456   c_signal_events += 2048;
14457   c_signal_events /= 4096;
14458 
14459   c_sig_noise_sq  = (int64_t)events_scaler_sq;
14460   c_sig_noise_sq *= (int64_t)prange_curr->VL53LX_p_017;
14461   c_sig_noise_sq += 2048;
14462   c_sig_noise_sq /= 4096;
14463 
14464   c_amb_noise_sq  = (int64_t)events_scaler_sq;
14465   c_amb_noise_sq *= (int64_t)prange_curr->VL53LX_p_016;
14466   c_amb_noise_sq += 2048;
14467   c_amb_noise_sq /= 4096;
14468 
14469 
14470   c_amb_noise_sq += 2;
14471   c_amb_noise_sq /= 4;
14472 
14473 
14474 
14475   p_amb_noise_sq  =
14476     (int64_t)prange_prev->VL53LX_p_016;
14477 
14478 
14479   p_amb_noise_sq += 2;
14480   p_amb_noise_sq /= 4;
14481 
14482   noise_sq_sum =
14483     (uint32_t)prange_prev->VL53LX_p_017 +
14484     (uint32_t)c_sig_noise_sq +
14485     (uint32_t)p_amb_noise_sq +
14486     (uint32_t)c_amb_noise_sq;
14487 
14488   *pevents_tolerance =
14489     (int32_t)VL53LX_isqrt(noise_sq_sum * 16);
14490 
14491   *pevents_tolerance *= (int32_t)event_sigma;
14492   *pevents_tolerance += 32;
14493   *pevents_tolerance /= 64;
14494 
14495   p_signal_events  = (int32_t)prange_prev->VL53LX_p_017;
14496   p_signal_events -= (int32_t)prange_prev->VL53LX_p_016;
14497 
14498   if ((int32_t)c_signal_events > p_signal_events)
14499     *pevents_delta =
14500       (int32_t)c_signal_events - p_signal_events;
14501   else
14502     *pevents_delta =
14503       p_signal_events - (int32_t)c_signal_events;
14504 
14505   if (*pevents_delta > *pevents_tolerance &&
14506       prange_curr->VL53LX_p_004 > min_effective_spad_count) {
14507     *prange_status = VL53LX_DEVICEERROR_EVENTCONSISTENCY;
14508   } else {
14509     *prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE;
14510   }
14511   return status;
14512 }
14513 
14514 
14515 VL53LX_Error  VL53LX::VL53LX_hist_merged_pulse_check(
14516   int16_t                      min_max_tolerance_mm,
14517   VL53LX_range_data_t         *pdata,
14518   VL53LX_DeviceError          *prange_status)
14519 {
14520 
14521 
14522   VL53LX_Error  status   = VL53LX_ERROR_NONE;
14523   int16_t       delta_mm = 0;
14524 
14525   if (pdata->max_range_mm > pdata->min_range_mm)
14526     delta_mm =
14527       pdata->max_range_mm - pdata->min_range_mm;
14528   else
14529     delta_mm =
14530       pdata->min_range_mm - pdata->max_range_mm;
14531 
14532   if (min_max_tolerance_mm > 0 &&
14533       delta_mm > min_max_tolerance_mm) {
14534     *prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE;
14535   } else {
14536     *prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE;
14537   }
14538 
14539   return status;
14540 }
14541 
14542 
14543 VL53LX_Error  VL53LX::VL53LX_hist_xmonitor_consistency_check(
14544   VL53LX_zone_hist_info_t     *phist_prev,
14545   VL53LX_zone_objects_t       *prange_prev,
14546   VL53LX_range_data_t         *prange_curr)
14547 {
14548 
14549 
14550   VL53LX_Error  status = VL53LX_ERROR_NONE;
14551   VL53LX_LLDriverData_t *pdev =
14552     VL53LXDevStructGetLLDriverHandle(Dev);
14553 
14554   int32_t   events_delta     = 0;
14555   int32_t   events_tolerance = 0;
14556   uint8_t event_sigma;
14557   uint16_t min_spad_count;
14558 
14559   event_sigma = pdev->histpostprocess.algo__crosstalk_detect_event_sigma;
14560   min_spad_count =
14561     pdev->histpostprocess.algo__consistency_check__event_min_spad_count;
14562 
14563   if (prange_curr->range_status == VL53LX_DEVICEERROR_RANGECOMPLETE ||
14564       prange_curr->range_status ==
14565       VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK ||
14566       prange_curr->range_status ==
14567       VL53LX_DEVICEERROR_EVENTCONSISTENCY) {
14568 
14569     if (prange_prev->xmonitor.range_status ==
14570         VL53LX_DEVICEERROR_RANGECOMPLETE ||
14571         prange_prev->xmonitor.range_status ==
14572         VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK ||
14573         prange_prev->xmonitor.range_status ==
14574         VL53LX_DEVICEERROR_EVENTCONSISTENCY) {
14575 
14576       prange_curr->range_status =
14577         VL53LX_DEVICEERROR_RANGECOMPLETE;
14578 
14579       status =
14580         VL53LX_hist_events_consistency_check(
14581           event_sigma,
14582           min_spad_count,
14583           phist_prev,
14584           &(prange_prev->xmonitor),
14585           prange_curr,
14586           &events_tolerance,
14587           &events_delta,
14588           &(prange_curr->range_status));
14589 
14590     }
14591   }
14592 
14593   return status;
14594 }
14595 
14596 VL53LX_Error  VL53LX::VL53LX_hist_wrap_dmax(
14597   VL53LX_hist_post_process_config_t  *phistpostprocess,
14598   VL53LX_histogram_bin_data_t        *pcurrent,
14599   int16_t                            *pwrap_dmax_mm)
14600 {
14601 
14602   VL53LX_Error  status = VL53LX_ERROR_NONE;
14603 
14604   uint32_t  pll_period_mm        = 0;
14605   uint32_t  wrap_dmax_phase      = 0;
14606   uint32_t  range_mm             = 0;
14607 
14608   *pwrap_dmax_mm = 0;
14609 
14610 
14611   if (pcurrent->VL53LX_p_015 != 0) {
14612 
14613 
14614 
14615     pll_period_mm =
14616       VL53LX_calc_pll_period_mm(
14617         pcurrent->VL53LX_p_015);
14618 
14619 
14620 
14621     wrap_dmax_phase =
14622       (uint32_t)phistpostprocess->valid_phase_high << 8;
14623 
14624 
14625 
14626     range_mm = wrap_dmax_phase * pll_period_mm;
14627     range_mm = (range_mm + (1 << 14)) >> 15;
14628 
14629     *pwrap_dmax_mm = (int16_t)range_mm;
14630   }
14631 
14632   return status;
14633 }
14634 
14635 void VL53LX::VL53LX_hist_combine_mm1_mm2_offsets(
14636   int16_t                               mm1_offset_mm,
14637   int16_t                               mm2_offset_mm,
14638   uint8_t                               encoded_mm_roi_centre,
14639   uint8_t                               encoded_mm_roi_size,
14640   uint8_t                               encoded_zone_centre,
14641   uint8_t                               encoded_zone_size,
14642   VL53LX_additional_offset_cal_data_t  *pcal_data,
14643   uint8_t                              *pgood_spads,
14644   uint16_t                              aperture_attenuation,
14645   int16_t                               *prange_offset_mm)
14646 {
14647 
14648 
14649 
14650   uint16_t max_mm_inner_effective_spads = 0;
14651   uint16_t max_mm_outer_effective_spads = 0;
14652   uint16_t mm_inner_effective_spads     = 0;
14653   uint16_t mm_outer_effective_spads     = 0;
14654 
14655   uint32_t scaled_mm1_peak_rate_mcps    = 0;
14656   uint32_t scaled_mm2_peak_rate_mcps    = 0;
14657 
14658   int32_t tmp0 = 0;
14659   int32_t tmp1 = 0;
14660 
14661 
14662 
14663   VL53LX_calc_mm_effective_spads(
14664     encoded_mm_roi_centre,
14665     encoded_mm_roi_size,
14666     0xC7,
14667     0xFF,
14668     pgood_spads,
14669     aperture_attenuation,
14670     &max_mm_inner_effective_spads,
14671     &max_mm_outer_effective_spads);
14672 
14673   if ((max_mm_inner_effective_spads == 0) ||
14674       (max_mm_outer_effective_spads == 0)) {
14675     goto FAIL;
14676   }
14677 
14678 
14679   VL53LX_calc_mm_effective_spads(
14680     encoded_mm_roi_centre,
14681     encoded_mm_roi_size,
14682     encoded_zone_centre,
14683     encoded_zone_size,
14684     pgood_spads,
14685     aperture_attenuation,
14686     &mm_inner_effective_spads,
14687     &mm_outer_effective_spads);
14688 
14689 
14690 
14691   scaled_mm1_peak_rate_mcps  =
14692     (uint32_t)pcal_data->result__mm_inner_peak_signal_count_rtn_mcps;
14693   scaled_mm1_peak_rate_mcps *= (uint32_t)mm_inner_effective_spads;
14694   scaled_mm1_peak_rate_mcps /= (uint32_t)max_mm_inner_effective_spads;
14695 
14696   scaled_mm2_peak_rate_mcps  =
14697     (uint32_t)pcal_data->result__mm_outer_peak_signal_count_rtn_mcps;
14698   scaled_mm2_peak_rate_mcps *= (uint32_t)mm_outer_effective_spads;
14699   scaled_mm2_peak_rate_mcps /= (uint32_t)max_mm_outer_effective_spads;
14700 
14701 
14702 
14703   tmp0  = ((int32_t)mm1_offset_mm * (int32_t)scaled_mm1_peak_rate_mcps);
14704   tmp0 += ((int32_t)mm2_offset_mm * (int32_t)scaled_mm2_peak_rate_mcps);
14705 
14706   tmp1 = (int32_t)scaled_mm1_peak_rate_mcps +
14707          (int32_t)scaled_mm2_peak_rate_mcps;
14708 
14709 
14710 
14711   if (tmp1 != 0) {
14712     tmp0 = (tmp0 * 4) / tmp1;
14713   }
14714 FAIL:
14715   *prange_offset_mm = (int16_t)tmp0;
14716 
14717 }
14718 
14719 VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_calc_window(
14720   int16_t                             target_distance_mm,
14721   uint16_t                            target_width_oversize,
14722   VL53LX_histogram_bin_data_t        *phist_bins,
14723   VL53LX_hist_xtalk_extract_data_t   *pxtalk_data)
14724 {
14725 
14726 
14727   VL53LX_Error  status = VL53LX_ERROR_NONE;
14728 
14729   pxtalk_data->pll_period_mm =
14730     VL53LX_calc_pll_period_mm(phist_bins->VL53LX_p_015);
14731   if (pxtalk_data->pll_period_mm == 0) {
14732     pxtalk_data->pll_period_mm = 1;
14733   }
14734 
14735 
14736   pxtalk_data->xtalk_width_phase =
14737     (int32_t)phist_bins->vcsel_width * 128;
14738   pxtalk_data->target_width_phase =
14739     pxtalk_data->xtalk_width_phase +
14740     (int32_t)target_width_oversize * 128;
14741 
14742 
14743 
14744   pxtalk_data->xtalk_start_phase =
14745     (int32_t)phist_bins->zero_distance_phase -
14746     (pxtalk_data->xtalk_width_phase / 2);
14747   pxtalk_data->xtalk_end_phase  =
14748     (int32_t)pxtalk_data->xtalk_start_phase +
14749     pxtalk_data->xtalk_width_phase;
14750 
14751   if (pxtalk_data->xtalk_start_phase < 0) {
14752     pxtalk_data->xtalk_start_phase = 0;
14753   }
14754 
14755 
14756 
14757 
14758   pxtalk_data->VL53LX_p_012 =
14759     (uint8_t)(pxtalk_data->xtalk_start_phase / 2048);
14760 
14761 
14762   pxtalk_data->VL53LX_p_013 =
14763     (uint8_t)((pxtalk_data->xtalk_end_phase + 2047) / 2048);
14764 
14765 
14766 
14767   pxtalk_data->target_start_phase  =
14768     (int32_t)target_distance_mm * 2048 * 16;
14769   pxtalk_data->target_start_phase +=
14770     ((int32_t)pxtalk_data->pll_period_mm / 2);
14771   pxtalk_data->target_start_phase /= (int32_t)pxtalk_data->pll_period_mm;
14772   pxtalk_data->target_start_phase +=
14773     (int32_t)phist_bins->zero_distance_phase;
14774 
14775 
14776 
14777   pxtalk_data->target_start_phase -=
14778     (pxtalk_data->target_width_phase / 2);
14779   pxtalk_data->target_end_phase  =
14780     (int32_t)pxtalk_data->target_start_phase +
14781     pxtalk_data->target_width_phase;
14782 
14783   if (pxtalk_data->target_start_phase < 0) {
14784     pxtalk_data->target_start_phase = 0;
14785   }
14786 
14787 
14788   pxtalk_data->target_start =
14789     (uint8_t)(pxtalk_data->target_start_phase / 2048);
14790 
14791 
14792   if (pxtalk_data->VL53LX_p_013 > (pxtalk_data->target_start - 1)) {
14793     pxtalk_data->VL53LX_p_013 = pxtalk_data->target_start - 1;
14794   }
14795 
14796 
14797   pxtalk_data->effective_width =
14798     (2048 * ((int32_t)pxtalk_data->VL53LX_p_013 + 1));
14799   pxtalk_data->effective_width -= pxtalk_data->xtalk_start_phase;
14800 
14801 
14802   if (pxtalk_data->effective_width > pxtalk_data->xtalk_width_phase) {
14803     pxtalk_data->effective_width = pxtalk_data->xtalk_width_phase;
14804   }
14805 
14806   if (pxtalk_data->effective_width < 1) {
14807     pxtalk_data->effective_width = 1;
14808   }
14809 
14810 
14811   pxtalk_data->event_scaler  =  pxtalk_data->xtalk_width_phase * 1000;
14812   pxtalk_data->event_scaler += (pxtalk_data->effective_width / 2);
14813   pxtalk_data->event_scaler /=  pxtalk_data->effective_width;
14814 
14815 
14816   if (pxtalk_data->event_scaler < 1000) {
14817     pxtalk_data->event_scaler = 1000;
14818   }
14819 
14820   if (pxtalk_data->event_scaler > 4000) {
14821     pxtalk_data->event_scaler = 4000;
14822   }
14823 
14824 
14825   pxtalk_data->event_scaler_sum += pxtalk_data->event_scaler;
14826 
14827 
14828   pxtalk_data->peak_duration_us_sum +=
14829     (uint32_t)phist_bins->peak_duration_us;
14830 
14831 
14832   pxtalk_data->effective_spad_count_sum +=
14833     (uint32_t)phist_bins->result__dss_actual_effective_spads;
14834 
14835 
14836   pxtalk_data->zero_distance_phase_sum +=
14837     (uint32_t)phist_bins->zero_distance_phase;
14838 
14839   return status;
14840 }
14841 
14842 
14843 VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_calc_event_sums(
14844   VL53LX_histogram_bin_data_t        *phist_bins,
14845   VL53LX_hist_xtalk_extract_data_t   *pxtalk_data)
14846 {
14847 
14848 
14849 
14850   VL53LX_Error  status = VL53LX_ERROR_NONE;
14851 
14852   uint8_t   lb = 0;
14853   uint8_t   i = 0;
14854 
14855 
14856   for (lb  = pxtalk_data->VL53LX_p_012;
14857        lb <= pxtalk_data->VL53LX_p_013;
14858        lb++) {
14859 
14860 
14861     i = (lb + phist_bins->number_of_ambient_bins +
14862          phist_bins->VL53LX_p_021) %
14863         phist_bins->VL53LX_p_021;
14864 
14865 
14866     pxtalk_data->signal_events_sum += phist_bins->bin_data[i];
14867     pxtalk_data->signal_events_sum -=
14868       phist_bins->VL53LX_p_028;
14869   }
14870 
14871 
14872 
14873   for (lb  = 0; lb < VL53LX_XTALK_HISTO_BINS  &&
14874        lb < phist_bins->VL53LX_p_021; lb++) {
14875 
14876 
14877     i = (lb + phist_bins->number_of_ambient_bins +
14878          phist_bins->VL53LX_p_021) %
14879         phist_bins->VL53LX_p_021;
14880 
14881 
14882     pxtalk_data->bin_data_sums[lb] += phist_bins->bin_data[i];
14883     pxtalk_data->bin_data_sums[lb] -=
14884       phist_bins->VL53LX_p_028;
14885   }
14886 
14887   pxtalk_data->sample_count += 1;
14888 
14889 
14890   return status;
14891 }
14892 VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_calc_rate_per_spad(
14893   VL53LX_hist_xtalk_extract_data_t   *pxtalk_data)
14894 {
14895 
14896 
14897   VL53LX_Error  status = VL53LX_ERROR_NONE;
14898 
14899   uint64_t tmp64_0        = 0;
14900   uint64_t tmp64_1        = 0;
14901   uint64_t xtalk_per_spad = 0;
14902 
14903 
14904   if (pxtalk_data->signal_events_sum > 0) {
14905     tmp64_0 =
14906       ((uint64_t)pxtalk_data->signal_events_sum *
14907        (uint64_t)pxtalk_data->sample_count *
14908        (uint64_t)pxtalk_data->event_scaler_avg * 256U) << 9U;
14909     tmp64_1 =
14910       (uint64_t)pxtalk_data->effective_spad_count_sum *
14911       (uint64_t)pxtalk_data->peak_duration_us_sum;
14912 
14913 
14914 
14915     if (tmp64_1 > 0U) {
14916 
14917       tmp64_0 = tmp64_0 + (tmp64_1 >> 1U);
14918       xtalk_per_spad = do_division_u(tmp64_0, tmp64_1);
14919     } else {
14920       xtalk_per_spad = (uint64_t)tmp64_0;
14921     }
14922 
14923   } else {
14924     status = VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
14925   }
14926 
14927   pxtalk_data->xtalk_rate_kcps_per_spad = (uint32_t)xtalk_per_spad;
14928 
14929 
14930   return status;
14931 }
14932 
14933 VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_calc_shape(
14934   VL53LX_hist_xtalk_extract_data_t  *pxtalk_data,
14935   VL53LX_xtalk_histogram_shape_t    *pxtalk_shape)
14936 {
14937 
14938 
14939   VL53LX_Error  status = VL53LX_ERROR_NONE;
14940 
14941   int32_t  lb = 0;
14942   uint64_t total_events    = 0U;
14943   uint64_t tmp64_0         = 0U;
14944   int32_t  remaining_area  = 1024;
14945 
14946   pxtalk_shape->VL53LX_p_019      = 0;
14947   pxtalk_shape->VL53LX_p_020    = VL53LX_XTALK_HISTO_BINS;
14948   pxtalk_shape->VL53LX_p_021 = VL53LX_XTALK_HISTO_BINS;
14949 
14950   pxtalk_shape->zero_distance_phase =
14951     (uint16_t)pxtalk_data->zero_distance_phase_avg;
14952   pxtalk_shape->phasecal_result__reference_phase =
14953     (uint16_t)pxtalk_data->zero_distance_phase_avg + (3 * 2048);
14954 
14955 
14956 
14957   if (pxtalk_data->signal_events_sum > 0)
14958     total_events =
14959       (uint64_t)pxtalk_data->signal_events_sum *
14960       (uint64_t)pxtalk_data->event_scaler_avg;
14961   else {
14962     total_events = 1;
14963   }
14964   if (total_events == 0) {
14965     total_events = 1;
14966   }
14967 
14968 
14969   remaining_area  = 1024;
14970   pxtalk_data->max_shape_value = 0;
14971 
14972   for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) {
14973 
14974     if ((lb < (int32_t)pxtalk_data->VL53LX_p_012 ||
14975          lb > (int32_t)pxtalk_data->VL53LX_p_013)  ||
14976         pxtalk_data->bin_data_sums[lb] < 0) {
14977 
14978 
14979       if (remaining_area > 0 && remaining_area < 1024) {
14980         if (remaining_area >
14981             pxtalk_data->max_shape_value) {
14982           pxtalk_shape->bin_data[lb] =
14983             (uint32_t)pxtalk_data->max_shape_value;
14984           remaining_area -=
14985             pxtalk_data->max_shape_value;
14986         } else {
14987           pxtalk_shape->bin_data[lb] =
14988             (uint32_t)remaining_area;
14989           remaining_area = 0;
14990         }
14991       } else {
14992         pxtalk_shape->bin_data[lb] = 0;
14993       }
14994 
14995     } else {
14996 
14997       tmp64_0 =
14998         (uint64_t)pxtalk_data->bin_data_sums[lb]
14999         * 1024U * 1000U;
15000       tmp64_0 += (total_events >> 1);
15001       tmp64_0 = do_division_u(tmp64_0, total_events);
15002       if (tmp64_0 > 0xFFFFU) {
15003         tmp64_0 = 0xFFFFU;
15004       }
15005 
15006       pxtalk_shape->bin_data[lb] = (uint32_t)tmp64_0;
15007 
15008 
15009       if ((int32_t)pxtalk_shape->bin_data[lb] >
15010           pxtalk_data->max_shape_value)
15011         pxtalk_data->max_shape_value =
15012           (int32_t)pxtalk_shape->bin_data[lb];
15013 
15014       remaining_area -= (int32_t)pxtalk_shape->bin_data[lb];
15015     }
15016   }
15017 
15018 
15019   return status;
15020 }
15021 
15022 
15023 
15024 VL53LX_Error VL53LX::VL53LX_hist_xtalk_shape_model(
15025   uint16_t                         events_per_bin,
15026   uint16_t                         pulse_centre,
15027   uint16_t                         pulse_width,
15028   VL53LX_xtalk_histogram_shape_t  *pxtalk_shape)
15029 {
15030 
15031 
15032   VL53LX_Error  status = VL53LX_ERROR_NONE;
15033 
15034   uint32_t phase_start  = 0;
15035   uint32_t phase_stop   = 0;
15036   uint32_t phase_bin    = 0;
15037 
15038   uint32_t bin_start    = 0;
15039   uint32_t bin_stop     = 0;
15040 
15041   uint32_t  lb           = 0;
15042   uint16_t  VL53LX_p_018      = 0;
15043 
15044   pxtalk_shape->VL53LX_p_019      = 0;
15045   pxtalk_shape->VL53LX_p_020    = VL53LX_XTALK_HISTO_BINS;
15046   pxtalk_shape->VL53LX_p_021 = VL53LX_XTALK_HISTO_BINS;
15047 
15048   pxtalk_shape->zero_distance_phase              = pulse_centre;
15049   pxtalk_shape->phasecal_result__reference_phase =
15050     pulse_centre + (3 * 2048);
15051 
15052 
15053   if (pulse_centre > (pulse_width >> 1))
15054     phase_start = (uint32_t)pulse_centre -
15055                   ((uint32_t)pulse_width >> 1);
15056   else {
15057     phase_start = 0;
15058   }
15059 
15060   phase_stop = (uint32_t)pulse_centre  +
15061                ((uint32_t)pulse_width >> 1);
15062 
15063 
15064   bin_start = (phase_start / 2048);
15065   bin_stop  = (phase_stop  / 2048);
15066 
15067   for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) {
15068     VL53LX_p_018 = 0;
15069 
15070 
15071     if (lb == bin_start && lb == bin_stop) {
15072       VL53LX_p_018 =
15073         VL53LX_hist_xtalk_shape_model_interp(
15074           events_per_bin,
15075           phase_stop - phase_start);
15076 
15077     } else if (lb > bin_start && lb < bin_stop) {
15078 
15079 
15080       VL53LX_p_018 = events_per_bin;
15081 
15082     } else if (lb == bin_start) {
15083 
15084 
15085       phase_bin = (lb + 1) * 2048;
15086       VL53LX_p_018 =
15087         VL53LX_hist_xtalk_shape_model_interp(
15088           events_per_bin,
15089           (phase_bin - phase_start));
15090 
15091     } else if (lb == bin_stop) {
15092 
15093 
15094       phase_bin = lb * 2048;
15095       VL53LX_p_018 =
15096         VL53LX_hist_xtalk_shape_model_interp(
15097           events_per_bin,
15098           (phase_stop - phase_bin));
15099     }
15100 
15101     pxtalk_shape->bin_data[lb] = VL53LX_p_018;
15102   }
15103 
15104 
15105   return status;
15106 }
15107 
15108 uint16_t VL53LX::VL53LX_hist_xtalk_shape_model_interp(
15109   uint16_t      events_per_bin,
15110   uint32_t      phase_delta)
15111 {
15112 
15113   uint32_t  VL53LX_p_018  = 0;
15114 
15115   VL53LX_p_018  = (uint32_t)events_per_bin * phase_delta;
15116   VL53LX_p_018 +=  1024;
15117   VL53LX_p_018 /=  2048;
15118 
15119 
15120   if (VL53LX_p_018 > 0xFFFFU) {
15121     VL53LX_p_018 = 0xFFFFU;
15122   }
15123 
15124   return (uint16_t)VL53LX_p_018;
15125 }
15126 
15127 void VL53LX::VL53LX_spad_number_to_byte_bit_index(
15128   uint8_t  spad_number,
15129   uint8_t *pbyte_index,
15130   uint8_t *pbit_index,
15131   uint8_t *pbit_mask)
15132 {
15133 
15134 
15135 
15136   *pbyte_index  = spad_number >> 3;
15137   *pbit_index   = spad_number & 0x07;
15138   *pbit_mask    = 0x01 << *pbit_index;
15139 
15140 }
15141 
15142 void VL53LX::VL53LX_encode_row_col(
15143   uint8_t  row,
15144   uint8_t  col,
15145   uint8_t *pspad_number)
15146 {
15147 
15148 
15149   if (row > 7) {
15150     *pspad_number = 128 + (col << 3) + (15 - row);
15151   } else {
15152     *pspad_number = ((15 - col) << 3) + row;
15153   }
15154 
15155 }
15156 void VL53LX::VL53LX_decode_zone_size(
15157   uint8_t  encoded_xy_size,
15158   uint8_t  *pwidth,
15159   uint8_t  *pheight)
15160 {
15161 
15162 
15163 
15164   *pheight = encoded_xy_size >> 4;
15165   *pwidth  = encoded_xy_size & 0x0F;
15166 
15167 }
15168 
15169 void VL53LX::VL53LX_encode_zone_size(
15170   uint8_t  width,
15171   uint8_t  height,
15172   uint8_t *pencoded_xy_size)
15173 {
15174 
15175 
15176   *pencoded_xy_size = (height << 4) + width;
15177 
15178 }
15179 
15180 void VL53LX::VL53LX_decode_zone_limits(
15181   uint8_t   encoded_xy_centre,
15182   uint8_t   encoded_xy_size,
15183   int16_t  *px_ll,
15184   int16_t  *py_ll,
15185   int16_t  *px_ur,
15186   int16_t  *py_ur)
15187 {
15188 
15189 
15190 
15191   uint8_t x_centre = 0;
15192   uint8_t y_centre = 0;
15193   uint8_t width    = 0;
15194   uint8_t height   = 0;
15195 
15196 
15197 
15198   VL53LX_decode_row_col(
15199     encoded_xy_centre,
15200     &y_centre,
15201     &x_centre);
15202 
15203   VL53LX_decode_zone_size(
15204     encoded_xy_size,
15205     &width,
15206     &height);
15207 
15208 
15209 
15210   *px_ll = (int16_t)x_centre - ((int16_t)width + 1) / 2;
15211   if (*px_ll < 0) {
15212     *px_ll = 0;
15213   }
15214 
15215   *px_ur = *px_ll + (int16_t)width;
15216   if (*px_ur > (VL53LX_SPAD_ARRAY_WIDTH - 1)) {
15217     *px_ur = VL53LX_SPAD_ARRAY_WIDTH - 1;
15218   }
15219 
15220   *py_ll = (int16_t)y_centre - ((int16_t)height + 1) / 2;
15221   if (*py_ll < 0) {
15222     *py_ll = 0;
15223   }
15224 
15225   *py_ur = *py_ll + (int16_t)height;
15226   if (*py_ur > (VL53LX_SPAD_ARRAY_HEIGHT - 1)) {
15227     *py_ur = VL53LX_SPAD_ARRAY_HEIGHT - 1;
15228   }
15229 }
15230 
15231 uint8_t VL53LX::VL53LX_is_aperture_location(
15232   uint8_t row,
15233   uint8_t col)
15234 {
15235 
15236 
15237   uint8_t is_aperture = 0;
15238   uint8_t mod_row     = row % 4;
15239   uint8_t mod_col     = col % 4;
15240 
15241   if (mod_row == 0 && mod_col == 2) {
15242     is_aperture = 1;
15243   }
15244 
15245   if (mod_row == 2 && mod_col == 0) {
15246     is_aperture = 1;
15247   }
15248 
15249   return is_aperture;
15250 }
15251 
15252 void VL53LX::VL53LX_calc_max_effective_spads(
15253   uint8_t     encoded_zone_centre,
15254   uint8_t     encoded_zone_size,
15255   uint8_t    *pgood_spads,
15256   uint16_t    aperture_attenuation,
15257   uint16_t   *pmax_effective_spads)
15258 {
15259 
15260 
15261 
15262   int16_t   x         = 0;
15263   int16_t   y         = 0;
15264 
15265   int16_t   zone_x_ll = 0;
15266   int16_t   zone_y_ll = 0;
15267   int16_t   zone_x_ur = 0;
15268   int16_t   zone_y_ur = 0;
15269 
15270   uint8_t   spad_number = 0;
15271   uint8_t   byte_index  = 0;
15272   uint8_t   bit_index   = 0;
15273   uint8_t   bit_mask    = 0;
15274 
15275   uint8_t   is_aperture = 0;
15276 
15277 
15278 
15279   VL53LX_decode_zone_limits(
15280     encoded_zone_centre,
15281     encoded_zone_size,
15282     &zone_x_ll,
15283     &zone_y_ll,
15284     &zone_x_ur,
15285     &zone_y_ur);
15286 
15287 
15288 
15289   *pmax_effective_spads = 0;
15290 
15291   for (y = zone_y_ll; y <= zone_y_ur; y++) {
15292     for (x = zone_x_ll; x <= zone_x_ur; x++) {
15293 
15294 
15295 
15296       VL53LX_encode_row_col(
15297         (uint8_t)y,
15298         (uint8_t)x,
15299         &spad_number);
15300 
15301 
15302 
15303       VL53LX_spad_number_to_byte_bit_index(
15304         spad_number,
15305         &byte_index,
15306         &bit_index,
15307         &bit_mask);
15308 
15309 
15310 
15311       if ((pgood_spads[byte_index] & bit_mask) > 0) {
15312 
15313 
15314         is_aperture = VL53LX_is_aperture_location(
15315                         (uint8_t)y,
15316                         (uint8_t)x);
15317 
15318         if (is_aperture > 0)
15319           *pmax_effective_spads +=
15320             aperture_attenuation;
15321         else {
15322           *pmax_effective_spads += 0x0100;
15323         }
15324 
15325       }
15326     }
15327   }
15328 }
15329 
15330 
15331 
15332 
15333 void VL53LX::VL53LX_calc_mm_effective_spads(
15334   uint8_t     encoded_mm_roi_centre,
15335   uint8_t     encoded_mm_roi_size,
15336   uint8_t     encoded_zone_centre,
15337   uint8_t     encoded_zone_size,
15338   uint8_t    *pgood_spads,
15339   uint16_t    aperture_attenuation,
15340   uint16_t   *pmm_inner_effective_spads,
15341   uint16_t   *pmm_outer_effective_spads)
15342 {
15343 
15344   int16_t   x         = 0;
15345   int16_t   y         = 0;
15346 
15347   int16_t   mm_x_ll   = 0;
15348   int16_t   mm_y_ll   = 0;
15349   int16_t   mm_x_ur   = 0;
15350   int16_t   mm_y_ur   = 0;
15351 
15352   int16_t   zone_x_ll = 0;
15353   int16_t   zone_y_ll = 0;
15354   int16_t   zone_x_ur = 0;
15355   int16_t   zone_y_ur = 0;
15356 
15357   uint8_t   spad_number = 0;
15358   uint8_t   byte_index  = 0;
15359   uint8_t   bit_index   = 0;
15360   uint8_t   bit_mask    = 0;
15361 
15362   uint8_t   is_aperture = 0;
15363   uint16_t  spad_attenuation = 0;
15364 
15365 
15366 
15367   VL53LX_decode_zone_limits(
15368     encoded_mm_roi_centre,
15369     encoded_mm_roi_size,
15370     &mm_x_ll,
15371     &mm_y_ll,
15372     &mm_x_ur,
15373     &mm_y_ur);
15374 
15375   VL53LX_decode_zone_limits(
15376     encoded_zone_centre,
15377     encoded_zone_size,
15378     &zone_x_ll,
15379     &zone_y_ll,
15380     &zone_x_ur,
15381     &zone_y_ur);
15382 
15383 
15384 
15385   *pmm_inner_effective_spads = 0;
15386   *pmm_outer_effective_spads = 0;
15387 
15388   for (y = zone_y_ll; y <= zone_y_ur; y++) {
15389     for (x = zone_x_ll; x <= zone_x_ur; x++) {
15390 
15391 
15392 
15393       VL53LX_encode_row_col(
15394         (uint8_t)y,
15395         (uint8_t)x,
15396         &spad_number);
15397 
15398 
15399 
15400       VL53LX_spad_number_to_byte_bit_index(
15401         spad_number,
15402         &byte_index,
15403         &bit_index,
15404         &bit_mask);
15405 
15406 
15407 
15408       if ((pgood_spads[byte_index] & bit_mask) > 0) {
15409 
15410 
15411         is_aperture = VL53LX_is_aperture_location(
15412                         (uint8_t)y,
15413                         (uint8_t)x);
15414 
15415         if (is_aperture > 0) {
15416           spad_attenuation = aperture_attenuation;
15417         } else {
15418           spad_attenuation = 0x0100;
15419         }
15420 
15421 
15422 
15423         if (x >= mm_x_ll && x <= mm_x_ur &&
15424             y >= mm_y_ll && y <= mm_y_ur)
15425           *pmm_inner_effective_spads +=
15426             spad_attenuation;
15427         else
15428           *pmm_outer_effective_spads +=
15429             spad_attenuation;
15430       }
15431     }
15432   }
15433 }
15434 
15435 
15436 void VL53LX::VL53LX_hist_copy_results_to_sys_and_core(
15437   VL53LX_histogram_bin_data_t      *pbins,
15438   VL53LX_range_results_t           *phist,
15439   VL53LX_system_results_t          *psys,
15440   VL53LX_core_results_t            *pcore)
15441 {
15442 
15443 
15444   uint8_t  i = 0;
15445 
15446   VL53LX_range_data_t  *pdata;
15447 
15448   VL53LX_init_system_results(psys);
15449 
15450   psys->result__interrupt_status = pbins->result__interrupt_status;
15451   psys->result__range_status     = phist->active_results;
15452   psys->result__report_status    = pbins->result__report_status;
15453   psys->result__stream_count     = pbins->result__stream_count;
15454 
15455   pdata = &(phist->VL53LX_p_003[0]);
15456 
15457   for (i = 0; i < phist->active_results; i++) {
15458 
15459     switch (i) {
15460       case 0:
15461         psys->result__dss_actual_effective_spads_sd0 =
15462           pdata->VL53LX_p_004;
15463         psys->result__peak_signal_count_rate_mcps_sd0 =
15464           pdata->peak_signal_count_rate_mcps;
15465         psys->result__avg_signal_count_rate_mcps_sd0 =
15466           pdata->avg_signal_count_rate_mcps;
15467         psys->result__ambient_count_rate_mcps_sd0 =
15468           pdata->ambient_count_rate_mcps;
15469 
15470         psys->result__sigma_sd0 = pdata->VL53LX_p_002;
15471         psys->result__phase_sd0 = pdata->VL53LX_p_011;
15472 
15473         psys->result__final_crosstalk_corrected_range_mm_sd0 =
15474           (uint16_t)pdata->median_range_mm;
15475 
15476         psys->result__phase_sd1  = pdata->zero_distance_phase;
15477 
15478         pcore->result_core__ranging_total_events_sd0 =
15479           pdata->VL53LX_p_017;
15480         pcore->result_core__signal_total_events_sd0 =
15481           pdata->VL53LX_p_010;
15482         pcore->result_core__total_periods_elapsed_sd0 =
15483           pdata->total_periods_elapsed;
15484         pcore->result_core__ambient_window_events_sd0 =
15485           pdata->VL53LX_p_016;
15486 
15487         break;
15488       case 1:
15489         psys->result__dss_actual_effective_spads_sd1 =
15490           pdata->VL53LX_p_004;
15491         psys->result__peak_signal_count_rate_mcps_sd1 =
15492           pdata->peak_signal_count_rate_mcps;
15493         psys->result__ambient_count_rate_mcps_sd1 =
15494           pdata->ambient_count_rate_mcps;
15495 
15496         psys->result__sigma_sd1 = pdata->VL53LX_p_002;
15497         psys->result__phase_sd1 = pdata->VL53LX_p_011;
15498 
15499         psys->result__final_crosstalk_corrected_range_mm_sd1 =
15500           (uint16_t)pdata->median_range_mm;
15501 
15502         pcore->result_core__ranging_total_events_sd1 =
15503           pdata->VL53LX_p_017;
15504         pcore->result_core__signal_total_events_sd1 =
15505           pdata->VL53LX_p_010;
15506         pcore->result_core__total_periods_elapsed_sd1 =
15507           pdata->total_periods_elapsed;
15508         pcore->result_core__ambient_window_events_sd1 =
15509           pdata->VL53LX_p_016;
15510         break;
15511     }
15512 
15513     pdata++;
15514   }
15515 
15516 }
15517 
15518 VL53LX_Error VL53LX::VL53LX_sum_histogram_data(
15519   VL53LX_histogram_bin_data_t *phist_input,
15520   VL53LX_histogram_bin_data_t *phist_output)
15521 {
15522 
15523 
15524   VL53LX_Error status = VL53LX_ERROR_NONE;
15525 
15526   uint8_t i = 0;
15527   uint8_t smallest_bin_num = 0;
15528 
15529 
15530   if (status == VL53LX_ERROR_NONE) {
15531     if (phist_output->VL53LX_p_021 >=
15532         phist_input->VL53LX_p_021) {
15533       smallest_bin_num = phist_input->VL53LX_p_021;
15534     } else {
15535       smallest_bin_num = phist_output->VL53LX_p_021;
15536     }
15537   }
15538 
15539 
15540 
15541 
15542 
15543   if (status == VL53LX_ERROR_NONE)
15544     for (i = 0; i < smallest_bin_num; i++)
15545 
15546     {
15547       phist_output->bin_data[i] += phist_input->bin_data[i];
15548     }
15549 
15550   if (status == VL53LX_ERROR_NONE)
15551     phist_output->VL53LX_p_028 +=
15552       phist_input->VL53LX_p_028;
15553 
15554 
15555   return status;
15556 }
15557 
15558 
15559 
15560 VL53LX_Error VL53LX::VL53LX_avg_histogram_data(
15561   uint8_t no_of_samples,
15562   VL53LX_histogram_bin_data_t *phist_sum,
15563   VL53LX_histogram_bin_data_t *phist_avg)
15564 {
15565 
15566 
15567   VL53LX_Error status = VL53LX_ERROR_NONE;
15568 
15569   uint8_t i = 0;
15570 
15571 
15572   if (status == VL53LX_ERROR_NONE) {
15573     for (i = 0; i < phist_sum->VL53LX_p_021; i++) {
15574 
15575 
15576 
15577       if (no_of_samples > 0)
15578         phist_avg->bin_data[i] =
15579           phist_sum->bin_data[i] /
15580           (int32_t)no_of_samples;
15581       else {
15582         phist_avg->bin_data[i] = phist_sum->bin_data[i];
15583       }
15584     }
15585   }
15586 
15587   if (status == VL53LX_ERROR_NONE) {
15588     if (no_of_samples > 0)
15589       phist_avg->VL53LX_p_028 =
15590         phist_sum->VL53LX_p_028 /
15591         (int32_t)no_of_samples;
15592     else
15593       phist_avg->VL53LX_p_028 =
15594         phist_sum->VL53LX_p_028;
15595   }
15596 
15597   return status;
15598 }
15599 
15600 
15601 VL53LX_Error VL53LX::VL53LX_save_cfg_data()
15602 {
15603 
15604   VL53LX_Error status = VL53LX_ERROR_NONE;
15605 
15606   VL53LX_LLDriverData_t  *pdev =
15607     VL53LXDevStructGetLLDriverHandle(Dev);
15608   VL53LX_LLDriverResults_t  *pres =
15609     VL53LXDevStructGetLLResultsHandle(Dev);
15610 
15611   VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg;
15612   VL53LX_dynamic_config_t       *pdynamic = &(pdev->dyn_cfg);
15613 
15614 
15615   pzone_dyn_cfg =
15616     &(pres->zone_dyn_cfgs.VL53LX_p_003[pdev->ll_state.cfg_zone_id]);
15617 
15618   pzone_dyn_cfg->expected_stream_count =
15619     pdev->ll_state.cfg_stream_count;
15620 
15621   pzone_dyn_cfg->expected_gph_id =
15622     pdev->ll_state.cfg_gph_id;
15623 
15624   pzone_dyn_cfg->roi_config__user_roi_centre_spad =
15625     pdynamic->roi_config__user_roi_centre_spad;
15626 
15627   pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size =
15628     pdynamic->roi_config__user_roi_requested_global_xy_size;
15629 
15630   return status;
15631 }
15632 
15633 
15634 VL53LX_Error VL53LX::VL53LX_dynamic_zone_update(
15635   VL53LX_range_results_t *presults)
15636 {
15637 
15638   VL53LX_Error status = VL53LX_ERROR_NONE;
15639 
15640   VL53LX_LLDriverData_t  *pdev =
15641     VL53LXDevStructGetLLDriverHandle(Dev);
15642   VL53LX_LLDriverResults_t  *pres =
15643     VL53LXDevStructGetLLResultsHandle(Dev);
15644   VL53LX_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
15645 
15646   uint8_t   zone_id = pdev->ll_state.rd_zone_id;
15647   uint8_t   i;
15648   uint16_t  max_total_rate_per_spads;
15649   uint16_t  target_rate =
15650     pdev->stat_cfg.dss_config__target_total_rate_mcps;
15651   uint32_t  temp = 0xFFFF;
15652 
15653   pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count = 0;
15654 
15655 
15656   max_total_rate_per_spads =
15657     presults->VL53LX_p_003[0].total_rate_per_spad_mcps;
15658 
15659 
15660   for (i = 1; i < presults->active_results; i++) {
15661 
15662 
15663     if (presults->VL53LX_p_003[i].total_rate_per_spad_mcps >
15664         max_total_rate_per_spads)
15665       max_total_rate_per_spads =
15666         presults->VL53LX_p_003[i].total_rate_per_spad_mcps;
15667 
15668   }
15669 
15670   if (max_total_rate_per_spads == 0) {
15671 
15672     temp = 0xFFFF;
15673   } else {
15674 
15675     temp = target_rate << 14;
15676 
15677     temp = temp / max_total_rate_per_spads;
15678 
15679 
15680     if (temp > 0xFFFF) {
15681       temp = 0xFFFF;
15682     }
15683 
15684   }
15685 
15686   pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count =
15687     (uint16_t)temp;
15688 
15689 
15690   return status;
15691 }
15692 
15693 VL53LX_Error VL53LX::VL53LX_multizone_hist_bins_update()
15694 {
15695 
15696 
15697   VL53LX_Error status = VL53LX_ERROR_NONE;
15698 
15699   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
15700   VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
15701   VL53LX_zone_config_t *pzone_cfg = &(pdev->zone_cfg);
15702   VL53LX_histogram_config_t *phist_cfg = &(pdev->hist_cfg);
15703   VL53LX_histogram_config_t *pmulti_hist =
15704     &(pzone_cfg->multizone_hist_cfg);
15705 
15706   uint8_t   next_range_is_odd_timing = (pstate->cfg_stream_count) % 2;
15707 
15708   if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
15709       VL53LX_ZONECONFIG_BINCONFIG__LOWAMB) {
15710     if (!next_range_is_odd_timing) {
15711       phist_cfg->histogram_config__low_amb_even_bin_0_1  =
15712         pmulti_hist->histogram_config__low_amb_even_bin_0_1;
15713       phist_cfg->histogram_config__low_amb_even_bin_2_3  =
15714         pmulti_hist->histogram_config__low_amb_even_bin_2_3;
15715       phist_cfg->histogram_config__low_amb_even_bin_4_5  =
15716         pmulti_hist->histogram_config__low_amb_even_bin_4_5;
15717     }
15718 
15719     if (next_range_is_odd_timing) {
15720       phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
15721         pmulti_hist->histogram_config__low_amb_even_bin_0_1;
15722       phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
15723         pmulti_hist->histogram_config__low_amb_even_bin_2_3;
15724       phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
15725         pmulti_hist->histogram_config__low_amb_even_bin_4_5;
15726     }
15727   } else if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
15728              VL53LX_ZONECONFIG_BINCONFIG__MIDAMB) {
15729     if (!next_range_is_odd_timing) {
15730       phist_cfg->histogram_config__low_amb_even_bin_0_1  =
15731         pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
15732       phist_cfg->histogram_config__low_amb_even_bin_2_3  =
15733         pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
15734       phist_cfg->histogram_config__low_amb_even_bin_4_5  =
15735         pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
15736     }
15737 
15738     if (next_range_is_odd_timing) {
15739       phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
15740         pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
15741       phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
15742         pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
15743       phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
15744         pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
15745     }
15746   } else if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] ==
15747              VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB) {
15748     if (!next_range_is_odd_timing) {
15749       phist_cfg->histogram_config__low_amb_even_bin_0_1  =
15750         pmulti_hist->histogram_config__high_amb_even_bin_0_1;
15751       phist_cfg->histogram_config__low_amb_even_bin_2_3  =
15752         pmulti_hist->histogram_config__high_amb_even_bin_2_3;
15753       phist_cfg->histogram_config__low_amb_even_bin_4_5  =
15754         pmulti_hist->histogram_config__high_amb_even_bin_4_5;
15755     }
15756 
15757     if (next_range_is_odd_timing) {
15758       phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
15759         pmulti_hist->histogram_config__high_amb_even_bin_0_1;
15760       phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
15761         pmulti_hist->histogram_config__high_amb_even_bin_2_3;
15762       phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
15763         pmulti_hist->histogram_config__high_amb_even_bin_4_5;
15764     }
15765   }
15766 
15767 
15768 
15769   if (status == VL53LX_ERROR_NONE) {
15770     VL53LX_copy_hist_bins_to_static_cfg(
15771       phist_cfg,
15772       &(pdev->stat_cfg),
15773       &(pdev->tim_cfg));
15774   }
15775 
15776   return status;
15777 }
15778 
15779 VL53LX_Error VL53LX::VL53LX_update_internal_stream_counters(
15780   uint8_t     external_stream_count,
15781   uint8_t    *pinternal_stream_count,
15782   uint8_t    *pinternal_stream_count_val)
15783 {
15784 
15785   VL53LX_Error status = VL53LX_ERROR_NONE;
15786   uint8_t stream_divider;
15787 
15788   VL53LX_LLDriverData_t  *pdev =
15789     VL53LXDevStructGetLLDriverHandle(Dev);
15790 
15791   stream_divider = pdev->gen_cfg.global_config__stream_divider;
15792 
15793   if (stream_divider == 0) {
15794 
15795 
15796     *pinternal_stream_count = external_stream_count;
15797 
15798   } else if (*pinternal_stream_count_val == (stream_divider - 1)) {
15799 
15800 
15801     if (*pinternal_stream_count == 0xFF) {
15802       *pinternal_stream_count = 0x80;
15803     } else {
15804       *pinternal_stream_count = *pinternal_stream_count + 1;
15805     }
15806 
15807 
15808     *pinternal_stream_count_val = 0;
15809 
15810   } else {
15811 
15812 
15813     *pinternal_stream_count_val = *pinternal_stream_count_val + 1;
15814   }
15815 
15816 
15817   return status;
15818 }
15819 
15820 
15821 VL53LX_Error VL53LX::VL53LX_set_histogram_multizone_initial_bin_config(
15822   VL53LX_zone_config_t    *pzone_cfg,
15823   VL53LX_histogram_config_t *phist_cfg,
15824   VL53LX_histogram_config_t *pmulti_hist)
15825 {
15826   VL53LX_Error  status = VL53LX_ERROR_NONE;
15827 
15828   if (pzone_cfg->bin_config[0] ==
15829       VL53LX_ZONECONFIG_BINCONFIG__LOWAMB) {
15830     phist_cfg->histogram_config__low_amb_even_bin_0_1  =
15831       pmulti_hist->histogram_config__low_amb_even_bin_0_1;
15832     phist_cfg->histogram_config__low_amb_even_bin_2_3  =
15833       pmulti_hist->histogram_config__low_amb_even_bin_2_3;
15834     phist_cfg->histogram_config__low_amb_even_bin_4_5  =
15835       pmulti_hist->histogram_config__low_amb_even_bin_4_5;
15836 
15837     phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
15838       pmulti_hist->histogram_config__low_amb_even_bin_0_1;
15839     phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
15840       pmulti_hist->histogram_config__low_amb_even_bin_2_3;
15841     phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
15842       pmulti_hist->histogram_config__low_amb_even_bin_4_5;
15843   } else if (pzone_cfg->bin_config[0] ==
15844              VL53LX_ZONECONFIG_BINCONFIG__MIDAMB) {
15845     phist_cfg->histogram_config__low_amb_even_bin_0_1  =
15846       pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
15847     phist_cfg->histogram_config__low_amb_even_bin_2_3  =
15848       pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
15849     phist_cfg->histogram_config__low_amb_even_bin_4_5  =
15850       pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
15851 
15852     phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
15853       pmulti_hist->histogram_config__mid_amb_even_bin_0_1;
15854     phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
15855       pmulti_hist->histogram_config__mid_amb_even_bin_2_3;
15856     phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
15857       pmulti_hist->histogram_config__mid_amb_even_bin_4_5;
15858   } else if (pzone_cfg->bin_config[0] ==
15859              VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB) {
15860     phist_cfg->histogram_config__low_amb_even_bin_0_1  =
15861       pmulti_hist->histogram_config__high_amb_even_bin_0_1;
15862     phist_cfg->histogram_config__low_amb_even_bin_2_3  =
15863       pmulti_hist->histogram_config__high_amb_even_bin_2_3;
15864     phist_cfg->histogram_config__low_amb_even_bin_4_5  =
15865       pmulti_hist->histogram_config__high_amb_even_bin_4_5;
15866     phist_cfg->histogram_config__low_amb_odd_bin_0_1  =
15867       pmulti_hist->histogram_config__high_amb_even_bin_0_1;
15868     phist_cfg->histogram_config__low_amb_odd_bin_2_3  =
15869       pmulti_hist->histogram_config__high_amb_even_bin_2_3;
15870     phist_cfg->histogram_config__low_amb_odd_bin_4_5  =
15871       pmulti_hist->histogram_config__high_amb_even_bin_4_5;
15872   }
15873 
15874   return status;
15875 }
15876 
15877 uint8_t VL53LX::VL53LX_encode_GPIO_interrupt_config(
15878   VL53LX_GPIO_interrupt_config_t  *pintconf)
15879 {
15880   uint8_t system__interrupt_config;
15881 
15882   system__interrupt_config = pintconf->intr_mode_distance;
15883   system__interrupt_config |= ((pintconf->intr_mode_rate) << 2);
15884   system__interrupt_config |= ((pintconf->intr_new_measure_ready) << 5);
15885   system__interrupt_config |= ((pintconf->intr_no_target) << 6);
15886   system__interrupt_config |= ((pintconf->intr_combined_mode) << 7);
15887 
15888   return system__interrupt_config;
15889 }
15890 
15891 VL53LX_GPIO_interrupt_config_t VL53LX::VL53LX_decode_GPIO_interrupt_config(
15892   uint8_t   system__interrupt_config)
15893 {
15894   VL53LX_GPIO_interrupt_config_t  intconf;
15895 
15896   intconf.intr_mode_distance = system__interrupt_config & 0x03;
15897   intconf.intr_mode_rate = (system__interrupt_config >> 2) & 0x03;
15898   intconf.intr_new_measure_ready = (system__interrupt_config >> 5) & 0x01;
15899   intconf.intr_no_target = (system__interrupt_config >> 6) & 0x01;
15900   intconf.intr_combined_mode = (system__interrupt_config >> 7) & 0x01;
15901 
15902 
15903   intconf.threshold_rate_low = 0;
15904   intconf.threshold_rate_high = 0;
15905   intconf.threshold_distance_low = 0;
15906   intconf.threshold_distance_high = 0;
15907 
15908   return intconf;
15909 }
15910 
15911 VL53LX_Error VL53LX::VL53LX_set_GPIO_distance_threshold(
15912   uint16_t      threshold_high,
15913   uint16_t      threshold_low)
15914 {
15915   VL53LX_Error  status = VL53LX_ERROR_NONE;
15916 
15917   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
15918 
15919 
15920   pdev->dyn_cfg.system__thresh_high = threshold_high;
15921   pdev->dyn_cfg.system__thresh_low = threshold_low;
15922 
15923   return status;
15924 }
15925 
15926 
15927 VL53LX_Error VL53LX::VL53LX_set_GPIO_rate_threshold(
15928   uint16_t      threshold_high,
15929   uint16_t      threshold_low)
15930 {
15931   VL53LX_Error  status = VL53LX_ERROR_NONE;
15932 
15933   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
15934 
15935 
15936   pdev->gen_cfg.system__thresh_rate_high = threshold_high;
15937   pdev->gen_cfg.system__thresh_rate_low = threshold_low;
15938 
15939   return status;
15940 }
15941 VL53LX_Error VL53LX::VL53LX_set_GPIO_thresholds_from_struct(
15942   VL53LX_GPIO_interrupt_config_t *pintconf)
15943 {
15944   VL53LX_Error  status = VL53LX_ERROR_NONE;
15945 
15946   status = VL53LX_set_GPIO_distance_threshold(
15947              pintconf->threshold_distance_high,
15948              pintconf->threshold_distance_low);
15949 
15950   if (status == VL53LX_ERROR_NONE) {
15951     status =
15952       VL53LX_set_GPIO_rate_threshold(
15953         pintconf->threshold_rate_high,
15954         pintconf->threshold_rate_low);
15955   }
15956 
15957   return status;
15958 }
15959 
15960 
15961 VL53LX_Error VL53LX::VL53LX_set_ref_spad_char_config(
15962   uint8_t       vcsel_period_a,
15963   uint32_t      phasecal_timeout_us,
15964   uint16_t      total_rate_target_mcps,
15965   uint16_t      max_count_rate_rtn_limit_mcps,
15966   uint16_t      min_count_rate_rtn_limit_mcps,
15967   uint16_t      fast_osc_frequency)
15968 {
15969 
15970 
15971   VL53LX_Error status = VL53LX_ERROR_NONE;
15972   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
15973 
15974   uint8_t buffer[2];
15975 
15976   uint32_t macro_period_us = 0;
15977   uint32_t timeout_mclks   = 0;
15978 
15979   macro_period_us =
15980     VL53LX_calc_macro_period_us(
15981       fast_osc_frequency,
15982       vcsel_period_a);
15983   if (macro_period_us == 0) {
15984     macro_period_us = 1;
15985   }
15986 
15987 
15988   timeout_mclks = phasecal_timeout_us << 12;
15989   timeout_mclks = timeout_mclks + (macro_period_us >> 1);
15990   timeout_mclks = timeout_mclks / macro_period_us;
15991 
15992   if (timeout_mclks > 0xFF) {
15993     pdev->gen_cfg.phasecal_config__timeout_macrop = 0xFF;
15994   } else
15995     pdev->gen_cfg.phasecal_config__timeout_macrop =
15996       (uint8_t)timeout_mclks;
15997 
15998   pdev->tim_cfg.range_config__vcsel_period_a = vcsel_period_a;
15999 
16000 
16001 
16002   if (status == VL53LX_ERROR_NONE)
16003     status =
16004       VL53LX_WrByte(
16005         Dev,
16006         VL53LX_PHASECAL_CONFIG__TIMEOUT_MACROP,
16007         pdev->gen_cfg.phasecal_config__timeout_macrop);
16008 
16009   if (status == VL53LX_ERROR_NONE)
16010     status =
16011       VL53LX_WrByte(
16012         Dev,
16013         VL53LX_RANGE_CONFIG__VCSEL_PERIOD_A,
16014         pdev->tim_cfg.range_config__vcsel_period_a);
16015 
16016 
16017 
16018   buffer[0] = pdev->tim_cfg.range_config__vcsel_period_a;
16019   buffer[1] = pdev->tim_cfg.range_config__vcsel_period_a;
16020 
16021   if (status == VL53LX_ERROR_NONE)
16022     status =
16023       VL53LX_WriteMulti(
16024         Dev,
16025         VL53LX_SD_CONFIG__WOI_SD0,
16026         buffer,
16027         2);
16028 
16029 
16030 
16031   pdev->customer.ref_spad_char__total_rate_target_mcps =
16032     total_rate_target_mcps;
16033 
16034   if (status == VL53LX_ERROR_NONE)
16035     status =
16036       VL53LX_WrWord(
16037         Dev,
16038         VL53LX_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS,
16039         total_rate_target_mcps);
16040 
16041   if (status == VL53LX_ERROR_NONE)
16042     status =
16043       VL53LX_WrWord(
16044         Dev,
16045         VL53LX_RANGE_CONFIG__SIGMA_THRESH,
16046         max_count_rate_rtn_limit_mcps);
16047 
16048   if (status == VL53LX_ERROR_NONE)
16049     status =
16050       VL53LX_WrWord(
16051         Dev,
16052         VL53LX_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS,
16053         min_count_rate_rtn_limit_mcps);
16054 
16055   return status;
16056 }
16057 
16058 VL53LX_Error VL53LX::VL53LX_set_ssc_config(
16059   VL53LX_ssc_config_t  *pssc_cfg,
16060   uint16_t              fast_osc_frequency)
16061 {
16062 
16063 
16064   VL53LX_Error status = VL53LX_ERROR_NONE;
16065   uint8_t buffer[5];
16066 
16067   uint32_t macro_period_us = 0;
16068   uint16_t timeout_encoded = 0;
16069 
16070   macro_period_us =
16071     VL53LX_calc_macro_period_us(
16072       fast_osc_frequency,
16073       pssc_cfg->VL53LX_p_005);
16074 
16075 
16076   timeout_encoded =
16077     VL53LX_calc_encoded_timeout(
16078       pssc_cfg->timeout_us,
16079       macro_period_us);
16080 
16081 
16082 
16083   if (status == VL53LX_ERROR_NONE)
16084     status =
16085       VL53LX_WrByte(
16086         Dev,
16087         VL53LX_CAL_CONFIG__VCSEL_START,
16088         pssc_cfg->vcsel_start);
16089 
16090   if (status == VL53LX_ERROR_NONE)
16091     status =
16092       VL53LX_WrByte(
16093         Dev,
16094         VL53LX_GLOBAL_CONFIG__VCSEL_WIDTH,
16095         pssc_cfg->vcsel_width);
16096 
16097 
16098 
16099   buffer[0] = (uint8_t)((timeout_encoded &  0x0000FF00) >> 8);
16100   buffer[1] = (uint8_t)(timeout_encoded &  0x000000FF);
16101   buffer[2] = pssc_cfg->VL53LX_p_005;
16102   buffer[3] = (uint8_t)((pssc_cfg->rate_limit_mcps &  0x0000FF00) >> 8);
16103   buffer[4] = (uint8_t)(pssc_cfg->rate_limit_mcps &  0x000000FF);
16104 
16105   if (status == VL53LX_ERROR_NONE)
16106     status =
16107       VL53LX_WriteMulti(
16108         Dev,
16109         VL53LX_RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
16110         buffer,
16111         5);
16112 
16113 
16114 
16115   buffer[0] = pssc_cfg->VL53LX_p_005;
16116   buffer[1] = pssc_cfg->VL53LX_p_005;
16117 
16118   if (status == VL53LX_ERROR_NONE)
16119     status =
16120       VL53LX_WriteMulti(
16121         Dev,
16122         VL53LX_SD_CONFIG__WOI_SD0,
16123         buffer,
16124         2);
16125 
16126 
16127   if (status == VL53LX_ERROR_NONE)
16128     status =
16129       VL53LX_WrByte(
16130         Dev,
16131         VL53LX_NVM_BIST__CTRL,
16132         pssc_cfg->array_select);
16133 
16134   return status;
16135 }
16136 
16137 
16138 VL53LX_Error VL53LX::VL53LX_get_spad_rate_data(
16139   VL53LX_spad_rate_data_t  *pspad_rates)
16140 {
16141   VL53LX_Error status = VL53LX_ERROR_NONE;
16142   int               i = 0;
16143 
16144   uint8_t  VL53LX_p_003[512];
16145   uint8_t *pdata = &VL53LX_p_003[0];
16146 
16147   if (status == VL53LX_ERROR_NONE) {
16148     status = VL53LX_disable_firmware();
16149   }
16150 
16151 
16152 
16153   if (status == VL53LX_ERROR_NONE)
16154     status =
16155       VL53LX_ReadMulti(
16156         Dev,
16157         VL53LX_PRIVATE__PATCH_BASE_ADDR_RSLV,
16158         pdata,
16159         512);
16160 
16161 
16162   pdata = &VL53LX_p_003[0];
16163   for (i = 0; i < VL53LX_NO_OF_SPAD_ENABLES; i++) {
16164     pspad_rates->rate_data[i] =
16165       (uint16_t)VL53LX_decode_unsigned_integer(pdata, 2);
16166     pdata += 2;
16167   }
16168 
16169 
16170 
16171   pspad_rates->VL53LX_p_020     = VL53LX_NO_OF_SPAD_ENABLES;
16172   pspad_rates->no_of_values    = VL53LX_NO_OF_SPAD_ENABLES;
16173   pspad_rates->fractional_bits = 15;
16174 
16175 
16176 
16177   if (status == VL53LX_ERROR_NONE) {
16178     status = VL53LX_enable_firmware();
16179   }
16180 
16181   return status;
16182 }
16183 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_calc_required_samples()
16184 {
16185 
16186   VL53LX_Error  status = VL53LX_ERROR_NONE;
16187 
16188   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16189   VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
16190   VL53LX_smudge_corrector_config_t *pconfig =
16191     &(pdev->smudge_correct_config);
16192   VL53LX_smudge_corrector_internals_t *pint =
16193     &(pdev->smudge_corrector_internals);
16194 
16195   VL53LX_range_results_t *presults = &(pres->range_results);
16196   VL53LX_range_data_t *pxmonitor = &(presults->xmonitor);
16197 
16198   uint32_t peak_duration_us = pxmonitor->peak_duration_us;
16199 
16200   uint64_t temp64a;
16201   uint64_t temp64z;
16202 
16203   temp64a = pxmonitor->VL53LX_p_017 +
16204             pxmonitor->VL53LX_p_016;
16205   if (peak_duration_us == 0) {
16206     peak_duration_us = 1000;
16207   }
16208   temp64a = do_division_u((temp64a * 1000), peak_duration_us);
16209   temp64a = do_division_u((temp64a * 1000), peak_duration_us);
16210 
16211   temp64z = pconfig->noise_margin * pxmonitor->VL53LX_p_004;
16212   if (temp64z == 0) {
16213     temp64z = 1;
16214   }
16215   temp64a = temp64a * 1000 * 256;
16216   temp64a = do_division_u(temp64a, temp64z);
16217   temp64a = temp64a * 1000 * 256;
16218   temp64a = do_division_u(temp64a, temp64z);
16219 
16220   pint->required_samples = (uint32_t)temp64a;
16221 
16222 
16223   if (pint->required_samples < 2) {
16224     pint->required_samples = 2;
16225   }
16226 
16227   return status;
16228 }
16229 
16230 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_calc_new_xtalk(
16231   uint32_t        xtalk_offset_out,
16232   VL53LX_smudge_corrector_config_t  *pconfig,
16233   VL53LX_smudge_corrector_data_t    *pout,
16234   uint8_t         add_smudge,
16235   uint8_t         soft_update
16236 )
16237 {
16238 
16239 
16240 
16241   VL53LX_Error  status = VL53LX_ERROR_NONE;
16242   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16243 
16244   int16_t  x_gradient_scaler;
16245   int16_t  y_gradient_scaler;
16246   uint32_t orig_xtalk_offset;
16247   int16_t  orig_x_gradient;
16248   int16_t  orig_y_gradient;
16249   uint8_t  histo_merge_nb;
16250   uint8_t  i;
16251   int32_t  itemp32;
16252   uint32_t SmudgeFactor;
16253   VL53LX_xtalk_config_t  *pX = &(pdev->xtalk_cfg);
16254   VL53LX_xtalk_calibration_results_t  *pC = &(pdev->xtalk_cal);
16255   uint32_t *pcpo;
16256   uint32_t max, nXtalk, cXtalk;
16257 
16258   if (add_smudge == 1) {
16259     pout->algo__crosstalk_compensation_plane_offset_kcps =
16260       (uint32_t)xtalk_offset_out +
16261       (uint32_t)pconfig->smudge_margin;
16262   } else {
16263     pout->algo__crosstalk_compensation_plane_offset_kcps =
16264       (uint32_t)xtalk_offset_out;
16265   }
16266 
16267 
16268   orig_xtalk_offset =
16269     pX->nvm_default__crosstalk_compensation_plane_offset_kcps;
16270 
16271   orig_x_gradient =
16272     pX->nvm_default__crosstalk_compensation_x_plane_gradient_kcps;
16273 
16274   orig_y_gradient =
16275     pX->nvm_default__crosstalk_compensation_y_plane_gradient_kcps;
16276 
16277   if (((pconfig->user_scaler_set == 0) ||
16278        (pconfig->scaler_calc_method == 1)) &&
16279       (pC->algo__crosstalk_compensation_plane_offset_kcps != 0)) {
16280 
16281     VL53LX_compute_histo_merge_nb(&histo_merge_nb);
16282 
16283     if (histo_merge_nb == 0) {
16284       histo_merge_nb = 1;
16285     }
16286     if (pdev->tuning_parms.tp_hist_merge != 1)
16287       orig_xtalk_offset =
16288         pC->algo__crosstalk_compensation_plane_offset_kcps;
16289     else
16290       orig_xtalk_offset =
16291         pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb - 1];
16292 
16293     orig_x_gradient =
16294       pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
16295 
16296     orig_y_gradient =
16297       pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
16298   }
16299 
16300 
16301   if ((pconfig->user_scaler_set == 0) && (orig_x_gradient == 0)) {
16302     pout->gradient_zero_flag |= 0x01;
16303   }
16304 
16305   if ((pconfig->user_scaler_set == 0) && (orig_y_gradient == 0)) {
16306     pout->gradient_zero_flag |= 0x02;
16307   }
16308 
16309 
16310 
16311   if (orig_xtalk_offset == 0) {
16312     orig_xtalk_offset = 1;
16313   }
16314 
16315 
16316 
16317   if (pconfig->user_scaler_set == 1) {
16318     x_gradient_scaler = pconfig->x_gradient_scaler;
16319     y_gradient_scaler = pconfig->y_gradient_scaler;
16320   } else {
16321 
16322     x_gradient_scaler = (int16_t)do_division_s(
16323                           (((int32_t)orig_x_gradient) << 6),
16324                           orig_xtalk_offset);
16325     pconfig->x_gradient_scaler = x_gradient_scaler;
16326     y_gradient_scaler = (int16_t)do_division_s(
16327                           (((int32_t)orig_y_gradient) << 6),
16328                           orig_xtalk_offset);
16329     pconfig->y_gradient_scaler = y_gradient_scaler;
16330   }
16331 
16332 
16333 
16334   if (pconfig->scaler_calc_method == 0) {
16335 
16336 
16337     itemp32 = (int32_t)(
16338                 pout->algo__crosstalk_compensation_plane_offset_kcps *
16339                 x_gradient_scaler);
16340     itemp32 = itemp32 >> 6;
16341     if (itemp32 > 0xFFFF) {
16342       itemp32 = 0xFFFF;
16343     }
16344 
16345     pout->algo__crosstalk_compensation_x_plane_gradient_kcps =
16346       (int16_t)itemp32;
16347 
16348     itemp32 = (int32_t)(
16349                 pout->algo__crosstalk_compensation_plane_offset_kcps *
16350                 y_gradient_scaler);
16351     itemp32 = itemp32 >> 6;
16352     if (itemp32 > 0xFFFF) {
16353       itemp32 = 0xFFFF;
16354     }
16355 
16356     pout->algo__crosstalk_compensation_y_plane_gradient_kcps =
16357       (int16_t)itemp32;
16358   } else if (pconfig->scaler_calc_method == 1) {
16359 
16360 
16361     itemp32 = (int32_t)(orig_xtalk_offset -
16362                         pout->algo__crosstalk_compensation_plane_offset_kcps);
16363     itemp32 = (int32_t)(do_division_s(itemp32, 16));
16364     itemp32 = itemp32 << 2;
16365     itemp32 = itemp32 + (int32_t)(orig_x_gradient);
16366     if (itemp32 > 0xFFFF) {
16367       itemp32 = 0xFFFF;
16368     }
16369 
16370     pout->algo__crosstalk_compensation_x_plane_gradient_kcps =
16371       (int16_t)itemp32;
16372 
16373     itemp32 = (int32_t)(orig_xtalk_offset -
16374                         pout->algo__crosstalk_compensation_plane_offset_kcps);
16375     itemp32 = (int32_t)(do_division_s(itemp32, 80));
16376     itemp32 = itemp32 << 2;
16377     itemp32 = itemp32 + (int32_t)(orig_y_gradient);
16378     if (itemp32 > 0xFFFF) {
16379       itemp32 = 0xFFFF;
16380     }
16381 
16382     pout->algo__crosstalk_compensation_y_plane_gradient_kcps =
16383       (int16_t)itemp32;
16384   }
16385 
16386 
16387   if ((pconfig->smudge_corr_apply_enabled == 1) &&
16388       (soft_update != 1)) {
16389 
16390     pout->new_xtalk_applied_flag = 1;
16391     nXtalk = pout->algo__crosstalk_compensation_plane_offset_kcps;
16392 
16393     VL53LX_compute_histo_merge_nb(&histo_merge_nb);
16394     max = pdev->tuning_parms.tp_hist_merge_max_size;
16395     pcpo = &(pC->algo__xtalk_cpo_HistoMerge_kcps[0]);
16396     if ((histo_merge_nb > 0) &&
16397         (pdev->tuning_parms.tp_hist_merge == 1) &&
16398         (nXtalk != 0)) {
16399       cXtalk =
16400         pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb - 1];
16401       SmudgeFactor = cXtalk * 1000 / nXtalk;
16402       if (SmudgeFactor >= pconfig->max_smudge_factor) {
16403         pout->new_xtalk_applied_flag = 0;
16404       } else if (SmudgeFactor > 0)
16405         for (i = 0; i < max; i++) {
16406           *pcpo *= 1000;
16407           *pcpo /= SmudgeFactor;
16408           pcpo++;
16409         }
16410     }
16411     if (pout->new_xtalk_applied_flag) {
16412 
16413       pX->algo__crosstalk_compensation_plane_offset_kcps =
16414         pout->algo__crosstalk_compensation_plane_offset_kcps;
16415       pX->algo__crosstalk_compensation_x_plane_gradient_kcps =
16416         pout->algo__crosstalk_compensation_x_plane_gradient_kcps;
16417       pX->algo__crosstalk_compensation_y_plane_gradient_kcps =
16418         pout->algo__crosstalk_compensation_y_plane_gradient_kcps;
16419 
16420       if (pconfig->smudge_corr_single_apply == 1) {
16421 
16422         pconfig->smudge_corr_apply_enabled = 0;
16423         pconfig->smudge_corr_single_apply = 0;
16424       }
16425     }
16426   }
16427 
16428 
16429   if (soft_update != 1) {
16430     pout->smudge_corr_valid = 1;
16431   }
16432 
16433   return status;
16434 }
16435 
16436 
16437 
16438 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_corrector()
16439 {
16440   VL53LX_Error  status = VL53LX_ERROR_NONE;
16441 
16442   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16443   VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
16444   VL53LX_smudge_corrector_config_t *pconfig =
16445     &(pdev->smudge_correct_config);
16446   VL53LX_smudge_corrector_internals_t *pint =
16447     &(pdev->smudge_corrector_internals);
16448   VL53LX_smudge_corrector_data_t *pout =
16449     &(pres->range_results.smudge_corrector_data);
16450   VL53LX_range_results_t  *pR = &(pres->range_results);
16451   VL53LX_xtalk_config_t  *pX = &(pdev->xtalk_cfg);
16452 
16453   uint8_t run_smudge_detection = 0;
16454   uint8_t merging_complete = 0;
16455   uint8_t run_nodetect = 0;
16456   uint8_t ambient_check = 0;
16457   int32_t itemp32 = 0;
16458   uint64_t utemp64 = 0;
16459   uint8_t continue_processing = CONT_CONTINUE;
16460   uint32_t xtalk_offset_out = 0;
16461   uint32_t xtalk_offset_in = 0;
16462   uint32_t current_xtalk = 0;
16463   uint32_t smudge_margin_adjusted = 0;
16464   uint8_t i = 0;
16465   uint8_t nodetect_index = 0;
16466   uint16_t    amr;
16467   uint32_t    cco;
16468   uint8_t histo_merge_nb;
16469 
16470 
16471   VL53LX_compute_histo_merge_nb(&histo_merge_nb);
16472   if ((histo_merge_nb == 0) ||
16473       (pdev->tuning_parms.tp_hist_merge != 1)) {
16474     histo_merge_nb = 1;
16475   }
16476 
16477 
16478   VL53LX_dynamic_xtalk_correction_output_init(pres);
16479 
16480 
16481   ambient_check = (pconfig->smudge_corr_ambient_threshold == 0) ||
16482                   ((pconfig->smudge_corr_ambient_threshold * histo_merge_nb)  >
16483                    ((uint32_t)pR->xmonitor.ambient_count_rate_mcps));
16484 
16485 
16486   merging_complete =
16487     ((pdev->tuning_parms.tp_hist_merge != 1) ||
16488      (histo_merge_nb == pdev->tuning_parms.tp_hist_merge_max_size));
16489   run_smudge_detection =
16490     (pconfig->smudge_corr_enabled == 1) &&
16491     ambient_check &&
16492     (pR->xmonitor.range_status
16493      == VL53LX_DEVICEERROR_RANGECOMPLETE) &&
16494     merging_complete;
16495 
16496 
16497   if ((pR->xmonitor.range_status
16498        != VL53LX_DEVICEERROR_RANGECOMPLETE) &&
16499       (pconfig->smudge_corr_enabled == 1)) {
16500 
16501     run_nodetect = 2;
16502     for (i = 0; i < pR->active_results; i++) {
16503       if (pR->VL53LX_p_003[i].range_status ==
16504           VL53LX_DEVICEERROR_RANGECOMPLETE) {
16505         if (pR->VL53LX_p_003[i].median_range_mm
16506             <=
16507             pconfig->nodetect_min_range_mm) {
16508           run_nodetect = 0;
16509         } else {
16510           if (run_nodetect == 2) {
16511             run_nodetect = 1;
16512             nodetect_index = i;
16513           }
16514         }
16515       }
16516     }
16517 
16518     if (run_nodetect == 2)
16519 
16520     {
16521       run_nodetect = 0;
16522     }
16523 
16524     amr =
16525       pR->VL53LX_p_003[nodetect_index].ambient_count_rate_mcps;
16526 
16527     if (run_nodetect == 1) {
16528 
16529 
16530 
16531 
16532       utemp64 = 1000 * ((uint64_t)amr);
16533 
16534 
16535       utemp64 = utemp64 << 9;
16536 
16537 
16538       if (utemp64 < pconfig->nodetect_ambient_threshold) {
16539         run_nodetect = 1;
16540       } else {
16541         run_nodetect = 0;
16542       }
16543 
16544     }
16545   }
16546 
16547 
16548   if (run_smudge_detection) {
16549 
16550     pint->nodetect_counter = 0;
16551 
16552 
16553     VL53LX_dynamic_xtalk_correction_calc_required_samples();
16554 
16555 
16556     xtalk_offset_in =
16557       pR->xmonitor.VL53LX_p_009;
16558 
16559 
16560     cco = pX->algo__crosstalk_compensation_plane_offset_kcps;
16561     current_xtalk = ((uint32_t)cco) << 2;
16562 
16563 
16564     smudge_margin_adjusted =
16565       ((uint32_t)(pconfig->smudge_margin)) << 2;
16566 
16567 
16568     itemp32 = xtalk_offset_in - current_xtalk +
16569               smudge_margin_adjusted;
16570 
16571     if (itemp32 < 0) {
16572       itemp32 = itemp32 * (-1);
16573     }
16574 
16575 
16576     if (itemp32 > ((int32_t)pconfig->single_xtalk_delta)) {
16577       if ((int32_t)xtalk_offset_in >
16578           ((int32_t)current_xtalk -
16579            (int32_t)smudge_margin_adjusted)) {
16580         pout->single_xtalk_delta_flag = 1;
16581       } else {
16582         pout->single_xtalk_delta_flag = 2;
16583       }
16584     }
16585 
16586 
16587     pint->current_samples = pint->current_samples + 1;
16588 
16589 
16590     if (pint->current_samples > pconfig->sample_limit) {
16591       pout->sample_limit_exceeded_flag = 1;
16592       continue_processing = CONT_RESET;
16593     } else {
16594       pint->accumulator = pint->accumulator +
16595                           xtalk_offset_in;
16596     }
16597 
16598     if (pint->current_samples < pint->required_samples) {
16599       continue_processing = CONT_NEXT_LOOP;
16600     }
16601 
16602 
16603     xtalk_offset_out =
16604       (uint32_t)(do_division_u(pint->accumulator,
16605                                pint->current_samples));
16606 
16607 
16608     itemp32 = xtalk_offset_out - current_xtalk +
16609               smudge_margin_adjusted;
16610 
16611     if (itemp32 < 0) {
16612       itemp32 = itemp32 * (-1);
16613     }
16614 
16615     if (continue_processing == CONT_CONTINUE &&
16616         (itemp32 >= ((int32_t)(pconfig->averaged_xtalk_delta)))
16617        ) {
16618       if ((int32_t)xtalk_offset_out >
16619           ((int32_t)current_xtalk -
16620            (int32_t)smudge_margin_adjusted)) {
16621         pout->averaged_xtalk_delta_flag = 1;
16622       } else {
16623         pout->averaged_xtalk_delta_flag = 2;
16624       }
16625     }
16626 
16627     if (continue_processing == CONT_CONTINUE &&
16628         (itemp32 < ((int32_t)(pconfig->averaged_xtalk_delta)))
16629        )
16630 
16631     {
16632       continue_processing = CONT_RESET;
16633     }
16634 
16635 
16636 
16637     pout->smudge_corr_clipped = 0;
16638     if ((continue_processing == CONT_CONTINUE) &&
16639         (pconfig->smudge_corr_clip_limit != 0)) {
16640       if (xtalk_offset_out >
16641           (pconfig->smudge_corr_clip_limit * histo_merge_nb)) {
16642         pout->smudge_corr_clipped = 1;
16643         continue_processing = CONT_RESET;
16644       }
16645     }
16646 
16647 
16648 
16649     if (pconfig->user_xtalk_offset_limit_hi &&
16650         (xtalk_offset_out >
16651          pconfig->user_xtalk_offset_limit))
16652       xtalk_offset_out =
16653         pconfig->user_xtalk_offset_limit;
16654 
16655 
16656 
16657     if ((pconfig->user_xtalk_offset_limit_hi == 0) &&
16658         (xtalk_offset_out <
16659          pconfig->user_xtalk_offset_limit))
16660       xtalk_offset_out =
16661         pconfig->user_xtalk_offset_limit;
16662 
16663 
16664 
16665     xtalk_offset_out = xtalk_offset_out >> 2;
16666     if (xtalk_offset_out > 0x3FFFF) {
16667       xtalk_offset_out = 0x3FFFF;
16668     }
16669 
16670 
16671     if (continue_processing == CONT_CONTINUE) {
16672 
16673       VL53LX_dynamic_xtalk_correction_calc_new_xtalk(
16674         xtalk_offset_out,
16675         pconfig,
16676         pout,
16677         1,
16678         0
16679       );
16680 
16681 
16682       continue_processing = CONT_RESET;
16683     } else {
16684 
16685       VL53LX_dynamic_xtalk_correction_calc_new_xtalk(
16686         xtalk_offset_out,
16687         pconfig,
16688         pout,
16689         1,
16690         1
16691       );
16692     }
16693 
16694 
16695     if (continue_processing == CONT_RESET) {
16696       pint->accumulator = 0;
16697       pint->current_samples = 0;
16698       pint->nodetect_counter = 0;
16699     }
16700 
16701   }
16702 
16703   continue_processing = CONT_CONTINUE;
16704   if (run_nodetect == 1) {
16705 
16706     pint->nodetect_counter += 1;
16707 
16708 
16709     if (pint->nodetect_counter < pconfig->nodetect_sample_limit) {
16710       continue_processing = CONT_NEXT_LOOP;
16711     }
16712 
16713 
16714     xtalk_offset_out = (uint32_t)(pconfig->nodetect_xtalk_offset);
16715 
16716     if (continue_processing == CONT_CONTINUE) {
16717 
16718       VL53LX_dynamic_xtalk_correction_calc_new_xtalk(
16719         xtalk_offset_out,
16720         pconfig,
16721         pout,
16722         0,
16723         0
16724       );
16725 
16726 
16727       pout->smudge_corr_valid = 2;
16728 
16729 
16730       continue_processing = CONT_RESET;
16731     } else {
16732 
16733       VL53LX_dynamic_xtalk_correction_calc_new_xtalk(
16734         xtalk_offset_out,
16735         pconfig,
16736         pout,
16737         0,
16738         1
16739       );
16740     }
16741 
16742 
16743     if (continue_processing == CONT_RESET) {
16744       pint->accumulator = 0;
16745       pint->current_samples = 0;
16746       pint->nodetect_counter = 0;
16747     }
16748   }
16749 
16750   return status;
16751 }
16752 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_data_init()
16753 {
16754   VL53LX_Error  status = VL53LX_ERROR_NONE;
16755 
16756   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16757   VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
16758 
16759   pdev->smudge_correct_config.smudge_corr_enabled       = 1;
16760   pdev->smudge_correct_config.smudge_corr_apply_enabled = 1;
16761   pdev->smudge_correct_config.smudge_corr_single_apply  =
16762     VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY_DEFAULT;
16763 
16764   pdev->smudge_correct_config.smudge_margin =
16765     VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN_DEFAULT;
16766   pdev->smudge_correct_config.noise_margin =
16767     VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN_DEFAULT;
16768   pdev->smudge_correct_config.user_xtalk_offset_limit =
16769     VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_DEFAULT;
16770   pdev->smudge_correct_config.user_xtalk_offset_limit_hi =
16771     VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI_DEFAULT;
16772   pdev->smudge_correct_config.sample_limit =
16773     VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT_DEFAULT;
16774   pdev->smudge_correct_config.single_xtalk_delta =
16775     VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA_DEFAULT;
16776   pdev->smudge_correct_config.averaged_xtalk_delta =
16777     VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA_DEFAULT;
16778   pdev->smudge_correct_config.smudge_corr_clip_limit =
16779     VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT_DEFAULT;
16780   pdev->smudge_correct_config.smudge_corr_ambient_threshold =
16781     VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD_DEFAULT;
16782   pdev->smudge_correct_config.scaler_calc_method =
16783     0;
16784   pdev->smudge_correct_config.x_gradient_scaler =
16785     VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER_DEFAULT;
16786   pdev->smudge_correct_config.y_gradient_scaler =
16787     VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER_DEFAULT;
16788   pdev->smudge_correct_config.user_scaler_set =
16789     VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET_DEFAULT;
16790   pdev->smudge_correct_config.nodetect_ambient_threshold =
16791     VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS_DEFAULT;
16792   pdev->smudge_correct_config.nodetect_sample_limit =
16793     VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT_DEFAULT;
16794   pdev->smudge_correct_config.nodetect_xtalk_offset =
16795     VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS_DEFAULT;
16796   pdev->smudge_correct_config.nodetect_min_range_mm =
16797     VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM_DEFAULT;
16798   pdev->smudge_correct_config.max_smudge_factor =
16799     VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR_DEFAULT;
16800 
16801 
16802   pdev->smudge_corrector_internals.current_samples = 0;
16803   pdev->smudge_corrector_internals.required_samples = 0;
16804   pdev->smudge_corrector_internals.accumulator = 0;
16805   pdev->smudge_corrector_internals.nodetect_counter = 0;
16806 
16807 
16808   VL53LX_dynamic_xtalk_correction_output_init(pres);
16809 
16810   return status;
16811 }
16812 
16813 
16814 VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_output_init(
16815   VL53LX_LLDriverResults_t *pres
16816 )
16817 {
16818   VL53LX_Error  status = VL53LX_ERROR_NONE;
16819 
16820   VL53LX_smudge_corrector_data_t *pdata;
16821 
16822   pdata = &(pres->range_results.smudge_corrector_data);
16823 
16824   pdata->smudge_corr_valid = 0;
16825   pdata->smudge_corr_clipped = 0;
16826   pdata->single_xtalk_delta_flag = 0;
16827   pdata->averaged_xtalk_delta_flag = 0;
16828   pdata->sample_limit_exceeded_flag = 0;
16829   pdata->gradient_zero_flag = 0;
16830   pdata->new_xtalk_applied_flag = 0;
16831 
16832   pdata->algo__crosstalk_compensation_plane_offset_kcps = 0;
16833   pdata->algo__crosstalk_compensation_x_plane_gradient_kcps = 0;
16834   pdata->algo__crosstalk_compensation_y_plane_gradient_kcps = 0;
16835 
16836   return status;
16837 }
16838 
16839 VL53LX_Error VL53LX::VL53LX_xtalk_cal_data_init()
16840 {
16841   VL53LX_Error  status = VL53LX_ERROR_NONE;
16842 
16843   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16844 
16845   pdev->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps = 0;
16846   pdev->xtalk_cal.algo__crosstalk_compensation_x_plane_gradient_kcps = 0;
16847   pdev->xtalk_cal.algo__crosstalk_compensation_y_plane_gradient_kcps = 0;
16848   memset(&pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0], 0,
16849          sizeof(pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps));
16850 
16851   return status;
16852 }
16853 
16854 VL53LX_Error VL53LX::VL53LX_low_power_auto_data_init()
16855 {
16856   VL53LX_Error  status = VL53LX_ERROR_NONE;
16857 
16858   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16859 
16860   pdev->low_power_auto_data.vhv_loop_bound =
16861     VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND_DEFAULT;
16862   pdev->low_power_auto_data.is_low_power_auto_mode = 0;
16863   pdev->low_power_auto_data.low_power_auto_range_count = 0;
16864   pdev->low_power_auto_data.saved_interrupt_config = 0;
16865   pdev->low_power_auto_data.saved_vhv_init = 0;
16866   pdev->low_power_auto_data.saved_vhv_timeout = 0;
16867   pdev->low_power_auto_data.first_run_phasecal_result = 0;
16868   pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
16869   pdev->low_power_auto_data.dss__required_spads = 0;
16870 
16871   return status;
16872 }
16873 VL53LX_Error VL53LX::VL53LX_low_power_auto_data_stop_range()
16874 {
16875 
16876   VL53LX_Error  status = VL53LX_ERROR_NONE;
16877 
16878   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16879 
16880   pdev->low_power_auto_data.low_power_auto_range_count = 0xFF;
16881 
16882   pdev->low_power_auto_data.first_run_phasecal_result = 0;
16883   pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
16884   pdev->low_power_auto_data.dss__required_spads = 0;
16885 
16886 
16887   if (pdev->low_power_auto_data.saved_vhv_init != 0)
16888     pdev->stat_nvm.vhv_config__init =
16889       pdev->low_power_auto_data.saved_vhv_init;
16890   if (pdev->low_power_auto_data.saved_vhv_timeout != 0)
16891     pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
16892       pdev->low_power_auto_data.saved_vhv_timeout;
16893 
16894   pdev->gen_cfg.phasecal_config__override = 0x00;
16895 
16896   return status;
16897 }
16898 
16899 VL53LX_Error VL53LX::VL53LX_config_low_power_auto_mode(
16900   VL53LX_general_config_t   *pgeneral,
16901   VL53LX_dynamic_config_t   *pdynamic,
16902   VL53LX_low_power_auto_data_t *plpadata
16903 )
16904 {
16905   VL53LX_Error  status = VL53LX_ERROR_NONE;
16906 
16907   plpadata->is_low_power_auto_mode = 1;
16908 
16909 
16910   plpadata->low_power_auto_range_count = 0;
16911 
16912 
16913   pdynamic->system__sequence_config =
16914     VL53LX_SEQUENCE_VHV_EN |
16915     VL53LX_SEQUENCE_PHASECAL_EN |
16916     VL53LX_SEQUENCE_DSS1_EN |
16917 
16918 
16919 
16920     VL53LX_SEQUENCE_RANGE_EN;
16921 
16922 
16923   pgeneral->dss_config__manual_effective_spads_select = 200 << 8;
16924   pgeneral->dss_config__roi_mode_control =
16925     VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
16926 
16927   return status;
16928 }
16929 
16930 
16931 VL53LX_Error VL53LX::VL53LX_low_power_auto_setup_manual_calibration()
16932 {
16933   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16934 
16935   VL53LX_Error  status = VL53LX_ERROR_NONE;
16936 
16937   pdev->low_power_auto_data.saved_vhv_init =
16938     pdev->stat_nvm.vhv_config__init;
16939   pdev->low_power_auto_data.saved_vhv_timeout =
16940     pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound;
16941 
16942 
16943   pdev->stat_nvm.vhv_config__init &= 0x7F;
16944 
16945   pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
16946     (pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound & 0x03) +
16947     (pdev->low_power_auto_data.vhv_loop_bound << 2);
16948 
16949   pdev->gen_cfg.phasecal_config__override = 0x01;
16950   pdev->low_power_auto_data.first_run_phasecal_result =
16951     pdev->dbg_results.phasecal_result__vcsel_start;
16952   pdev->gen_cfg.cal_config__vcsel_start =
16953     pdev->low_power_auto_data.first_run_phasecal_result;
16954 
16955   return status;
16956 }
16957 
16958 
16959 VL53LX_Error VL53LX::VL53LX_low_power_auto_update_DSS()
16960 {
16961 
16962 
16963 
16964   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
16965 
16966   VL53LX_system_results_t *pS = &(pdev->sys_results);
16967 
16968 
16969   VL53LX_Error  status = VL53LX_ERROR_NONE;
16970 
16971   uint32_t utemp32a;
16972 
16973   utemp32a =
16974     pS->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0
16975     + pS->result__ambient_count_rate_mcps_sd0;
16976 
16977 
16978   if (utemp32a > 0xFFFF) {
16979     utemp32a = 0xFFFF;
16980   }
16981 
16982 
16983 
16984   utemp32a = utemp32a << 16;
16985 
16986 
16987   if (pdev->sys_results.result__dss_actual_effective_spads_sd0 == 0) {
16988     status = VL53LX_ERROR_DIVISION_BY_ZERO;
16989   } else {
16990 
16991     utemp32a = utemp32a /
16992                pdev->sys_results.result__dss_actual_effective_spads_sd0;
16993 
16994     pdev->low_power_auto_data.dss__total_rate_per_spad_mcps =
16995       utemp32a;
16996 
16997 
16998     utemp32a = pdev->stat_cfg.dss_config__target_total_rate_mcps <<
16999                16;
17000 
17001 
17002     if (pdev->low_power_auto_data.dss__total_rate_per_spad_mcps
17003         == 0) {
17004       status = VL53LX_ERROR_DIVISION_BY_ZERO;
17005     } else {
17006 
17007       utemp32a = utemp32a /
17008                  pdev->low_power_auto_data.dss__total_rate_per_spad_mcps;
17009 
17010 
17011       if (utemp32a > 0xFFFF) {
17012         utemp32a = 0xFFFF;
17013       }
17014 
17015 
17016       pdev->low_power_auto_data.dss__required_spads =
17017         (uint16_t)utemp32a;
17018 
17019 
17020       pdev->gen_cfg.dss_config__manual_effective_spads_select
17021         = pdev->low_power_auto_data.dss__required_spads;
17022       pdev->gen_cfg.dss_config__roi_mode_control =
17023         VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
17024     }
17025 
17026   }
17027 
17028   if (status == VL53LX_ERROR_DIVISION_BY_ZERO) {
17029 
17030 
17031 
17032     pdev->low_power_auto_data.dss__required_spads = 0x8000;
17033 
17034 
17035     pdev->gen_cfg.dss_config__manual_effective_spads_select =
17036       pdev->low_power_auto_data.dss__required_spads;
17037     pdev->gen_cfg.dss_config__roi_mode_control =
17038       VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
17039 
17040 
17041     status = VL53LX_ERROR_NONE;
17042   }
17043 
17044   return status;
17045 }
17046 
17047 VL53LX_Error VL53LX::VL53LX_compute_histo_merge_nb(uint8_t *histo_merge_nb)
17048 {
17049   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17050   VL53LX_Error  status = VL53LX_ERROR_NONE;
17051   uint8_t i, timing;
17052   uint8_t sum = 0;
17053 
17054   timing = (pdev->hist_data.bin_seq[0] == 7 ? 1 : 0);
17055   for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
17056     if (pdev->multi_bins_rec[i][timing][7] > 0) {
17057       sum++;
17058     }
17059   *histo_merge_nb = sum;
17060 
17061   return status;
17062 }
17063 
17064 /* vl53lx_wait.c */
17065 
17066 
17067 VL53LX_Error VL53LX::VL53LX_wait_for_boot_completion()
17068 {
17069 
17070   VL53LX_Error status = VL53LX_ERROR_NONE;
17071   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17072 
17073   uint8_t      fw_ready  = 0;
17074 
17075   if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) {
17076 
17077 
17078 
17079     status =
17080       VL53LX_poll_for_boot_completion(VL53LX_BOOT_COMPLETION_POLLING_TIMEOUT_MS);
17081 
17082   } else {
17083 
17084 
17085 
17086     fw_ready = 0;
17087     while (fw_ready == 0x00 && status == VL53LX_ERROR_NONE) {
17088       status = VL53LX_is_boot_complete(
17089                  &fw_ready);
17090 
17091       if (status == VL53LX_ERROR_NONE) {
17092         status = VL53LX_WaitMs(
17093                    Dev,
17094                    VL53LX_POLLING_DELAY_MS);
17095       }
17096     }
17097   }
17098 
17099   return status;
17100 
17101 }
17102 
17103 VL53LX_Error VL53LX::VL53LX_wait_for_firmware_ready()
17104 {
17105 
17106   VL53LX_Error status = VL53LX_ERROR_NONE;
17107   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17108 
17109   uint8_t      fw_ready  = 0;
17110   uint8_t      mode_start  = 0;
17111 
17112   mode_start =
17113     pdev->sys_ctrl.system__mode_start &
17114     VL53LX_DEVICEMEASUREMENTMODE_MODE_MASK;
17115 
17116 
17117 
17118   if ((mode_start == VL53LX_DEVICEMEASUREMENTMODE_TIMED) ||
17119       (mode_start == VL53LX_DEVICEMEASUREMENTMODE_SINGLESHOT)) {
17120 
17121     if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) {
17122 
17123 
17124 
17125       status =
17126         VL53LX_poll_for_firmware_ready(
17127           VL53LX_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
17128 
17129     } else {
17130 
17131 
17132 
17133       fw_ready = 0;
17134       while (fw_ready == 0x00 && status ==
17135              VL53LX_ERROR_NONE) {
17136         status = VL53LX_is_firmware_ready(
17137                    &fw_ready);
17138 
17139         if (status == VL53LX_ERROR_NONE) {
17140           status = VL53LX_WaitMs(
17141                      Dev,
17142                      VL53LX_POLLING_DELAY_MS);
17143         }
17144       }
17145     }
17146   }
17147 
17148   return status;
17149 }
17150 
17151 
17152 VL53LX_Error VL53LX::VL53LX_wait_for_range_completion()
17153 {
17154 
17155   VL53LX_Error status = VL53LX_ERROR_NONE;
17156   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17157 
17158   uint8_t      data_ready  = 0;
17159 
17160   if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) {
17161 
17162 
17163 
17164     status =
17165       VL53LX_poll_for_range_completion(
17166         VL53LX_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
17167 
17168   } else {
17169 
17170 
17171 
17172     data_ready = 0;
17173     while (data_ready == 0x00 && status == VL53LX_ERROR_NONE) {
17174       status = VL53LX_is_new_data_ready(
17175                  &data_ready);
17176 
17177       if (status == VL53LX_ERROR_NONE) {
17178         status = VL53LX_WaitMs(
17179                    Dev,
17180                    VL53LX_POLLING_DELAY_MS);
17181       }
17182     }
17183   }
17184 
17185   return status;
17186 }
17187 VL53LX_Error VL53LX::VL53LX_wait_for_test_completion()
17188 {
17189 
17190   VL53LX_Error status = VL53LX_ERROR_NONE;
17191   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17192 
17193   uint8_t      data_ready  = 0;
17194 
17195 
17196   if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) {
17197 
17198 
17199 
17200     status =
17201       VL53LX_poll_for_range_completion(
17202         VL53LX_TEST_COMPLETION_POLLING_TIMEOUT_MS);
17203 
17204   } else {
17205 
17206 
17207 
17208     data_ready = 0;
17209     while (data_ready == 0x00 && status == VL53LX_ERROR_NONE) {
17210       status = VL53LX_is_new_data_ready(
17211                  &data_ready);
17212 
17213       if (status == VL53LX_ERROR_NONE) {
17214         status = VL53LX_WaitMs(
17215                    Dev,
17216                    VL53LX_POLLING_DELAY_MS);
17217       }
17218     }
17219   }
17220 
17221   return status;
17222 }
17223 
17224 VL53LX_Error VL53LX::VL53LX_is_boot_complete(
17225   uint8_t       *pready)
17226 {
17227   VL53LX_Error status = VL53LX_ERROR_NONE;
17228   uint8_t  firmware__system_status = 0;
17229 
17230   status =
17231     VL53LX_RdByte(
17232       Dev,
17233       VL53LX_FIRMWARE__SYSTEM_STATUS,
17234       &firmware__system_status);
17235 
17236 
17237 
17238   if ((firmware__system_status & 0x01) == 0x01) {
17239     *pready = 0x01;
17240     VL53LX_init_ll_driver_state(
17241       VL53LX_DEVICESTATE_SW_STANDBY);
17242   } else {
17243     *pready = 0x00;
17244     VL53LX_init_ll_driver_state(
17245       VL53LX_DEVICESTATE_FW_COLDBOOT);
17246   }
17247 
17248   return status;
17249 }
17250 
17251 VL53LX_Error VL53LX::VL53LX_is_firmware_ready(
17252   uint8_t       *pready)
17253 {
17254 
17255   VL53LX_Error status = VL53LX_ERROR_NONE;
17256   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17257 
17258   status = VL53LX_is_firmware_ready_silicon(
17259              pready);
17260 
17261   pdev->fw_ready = *pready;
17262 
17263   return status;
17264 }
17265 VL53LX_Error VL53LX::VL53LX_is_new_data_ready(
17266   uint8_t       *pready)
17267 {
17268   VL53LX_Error status = VL53LX_ERROR_NONE;
17269   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17270 
17271   uint8_t  gpio__mux_active_high_hv = 0;
17272   uint8_t  gpio__tio_hv_status      = 0;
17273   uint8_t  interrupt_ready          = 0;
17274 
17275   gpio__mux_active_high_hv =
17276     pdev->stat_cfg.gpio_hv_mux__ctrl &
17277     VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_MASK;
17278 
17279   if (gpio__mux_active_high_hv == VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH) {
17280     interrupt_ready = 0x01;
17281   } else {
17282     interrupt_ready = 0x00;
17283   }
17284 
17285 
17286   status = VL53LX_RdByte(
17287              Dev,
17288              VL53LX_GPIO__TIO_HV_STATUS,
17289              &gpio__tio_hv_status);
17290 
17291 
17292 
17293   if ((gpio__tio_hv_status & 0x01) == interrupt_ready) {
17294     *pready = 0x01;
17295   } else {
17296     *pready = 0x00;
17297   }
17298 
17299   return status;
17300 }
17301 
17302 VL53LX_Error VL53LX::VL53LX_poll_for_boot_completion(
17303   uint32_t      timeout_ms)
17304 {
17305 
17306 
17307   VL53LX_Error status       = VL53LX_ERROR_NONE;
17308 
17309 
17310  // status = VL53LX_WaitUs(
17311 //             Dev,
17312  //            VL53LX_FIRMWARE_BOOT_TIME_US);
17313   wait_us(VL53LX_FIRMWARE_BOOT_TIME_US*10);
17314 
17315   if (status == VL53LX_ERROR_NONE)
17316     status =
17317       VL53LX_WaitValueMaskEx(
17318         Dev,
17319         timeout_ms,
17320         VL53LX_FIRMWARE__SYSTEM_STATUS,
17321         0x01,
17322         0x01,
17323         VL53LX_POLLING_DELAY_MS);
17324 printf("VL53LX_poll_for_boot_completion %d \n",status);
17325   if (status == VL53LX_ERROR_NONE) {
17326     VL53LX_init_ll_driver_state(VL53LX_DEVICESTATE_SW_STANDBY);
17327   }
17328 
17329   return status;
17330 }
17331 VL53LX_Error VL53LX::VL53LX_poll_for_firmware_ready(
17332   uint32_t      timeout_ms)
17333 {
17334 
17335   VL53LX_Error status          = VL53LX_ERROR_NONE;
17336   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17337 
17338   uint32_t     start_time_ms   = 0;
17339   uint32_t     current_time_ms = 0;
17340   int32_t      poll_delay_ms   = VL53LX_POLLING_DELAY_MS;
17341   uint8_t      fw_ready        = 0;
17342 
17343 
17344 
17345   VL53LX_GetTickCount(&start_time_ms);
17346   pdev->fw_ready_poll_duration_ms = 0;
17347 
17348   while ((status == VL53LX_ERROR_NONE) &&
17349          (pdev->fw_ready_poll_duration_ms < timeout_ms) &&
17350          (fw_ready == 0)) {
17351 
17352     status = VL53LX_is_firmware_ready(
17353                &fw_ready);
17354 
17355     if (status == VL53LX_ERROR_NONE &&
17356         fw_ready == 0 &&
17357         poll_delay_ms > 0) {
17358       status = VL53LX_WaitMs(
17359                  Dev,
17360                  poll_delay_ms);
17361     }
17362 
17363 
17364     VL53LX_GetTickCount(&current_time_ms);
17365     pdev->fw_ready_poll_duration_ms =
17366       current_time_ms - start_time_ms;
17367   }
17368 
17369   if (fw_ready == 0 && status == VL53LX_ERROR_NONE) {
17370     status = VL53LX_ERROR_TIME_OUT;
17371   }
17372 
17373   return status;
17374 }
17375 
17376 VL53LX_Error VL53LX::VL53LX_poll_for_range_completion(
17377   uint32_t       timeout_ms)
17378 {
17379   VL53LX_Error status = VL53LX_ERROR_NONE;
17380   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
17381 
17382   uint8_t  gpio__mux_active_high_hv = 0;
17383   uint8_t  interrupt_ready          = 0;
17384 
17385   gpio__mux_active_high_hv =
17386     pdev->stat_cfg.gpio_hv_mux__ctrl &
17387     VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_MASK;
17388 
17389   if (gpio__mux_active_high_hv == VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH) {
17390     interrupt_ready = 0x01;
17391   } else {
17392     interrupt_ready = 0x00;
17393   }
17394 
17395   status =
17396     VL53LX_WaitValueMaskEx(
17397       Dev,
17398       timeout_ms,
17399       VL53LX_GPIO__TIO_HV_STATUS,
17400       interrupt_ready,
17401       0x01,
17402       VL53LX_POLLING_DELAY_MS);
17403 
17404   return status;
17405 }
17406 
17407 /* vl53lx_zone_presets.c */
17408 
17409 VL53LX_Error VL53LX::VL53LX_init_zone_config_structure(
17410   uint8_t x_off,
17411   uint8_t x_inc,
17412   uint8_t x_zones,
17413   uint8_t y_off,
17414   uint8_t y_inc,
17415   uint8_t y_zones,
17416   uint8_t width,
17417   uint8_t height,
17418   VL53LX_zone_config_t   *pdata)
17419 {
17420 
17421 
17422   VL53LX_Error  status = VL53LX_ERROR_NONE;
17423 
17424   uint8_t  x  = 0;
17425   uint8_t  y  = 0;
17426   uint16_t  i  = 0;
17427 
17428 
17429   pdata->max_zones = VL53LX_MAX_USER_ZONES;
17430 
17431   i = 0;
17432 
17433   for (x = 0 ; x < x_zones ; x++) {
17434     for (y = 0 ; y <  y_zones ; y++) {
17435 
17436       if (i < VL53LX_MAX_USER_ZONES) {
17437 
17438         pdata->active_zones = (uint8_t)i;
17439         pdata->user_zones[i].height   = height;
17440         pdata->user_zones[i].width    = width;
17441         pdata->user_zones[i].x_centre =
17442           x_off + (x * x_inc);
17443         pdata->user_zones[i].y_centre =
17444           y_off + (y * y_inc);
17445       }
17446 
17447       i++;
17448     }
17449   }
17450 
17451   status = VL53LX_init_zone_config_histogram_bins(pdata);
17452 
17453   return status;
17454 }
17455 
17456 VL53LX_Error VL53LX::VL53LX_zone_preset_xtalk_planar(
17457   VL53LX_general_config_t *pgeneral,
17458   VL53LX_zone_config_t    *pzone_cfg)
17459 {
17460   VL53LX_Error  status = VL53LX_ERROR_NONE;
17461 
17462   pgeneral->global_config__stream_divider = 0x05;
17463 
17464 
17465   pzone_cfg->active_zones                 = 0x04;
17466 
17467   pzone_cfg->user_zones[0].height         = 15;
17468   pzone_cfg->user_zones[0].width          = 7;
17469   pzone_cfg->user_zones[0].x_centre       = 4;
17470   pzone_cfg->user_zones[0].y_centre       = 8;
17471 
17472   pzone_cfg->user_zones[1].height         = 15;
17473   pzone_cfg->user_zones[1].width          = 7;
17474   pzone_cfg->user_zones[1].x_centre       = 12;
17475   pzone_cfg->user_zones[1].y_centre       = 8;
17476 
17477   pzone_cfg->user_zones[2].height         = 7;
17478   pzone_cfg->user_zones[2].width          = 15;
17479   pzone_cfg->user_zones[2].x_centre       = 8;
17480   pzone_cfg->user_zones[2].y_centre       = 4;
17481 
17482   pzone_cfg->user_zones[3].height         = 7;
17483   pzone_cfg->user_zones[3].width          = 15;
17484   pzone_cfg->user_zones[3].x_centre       = 8;
17485   pzone_cfg->user_zones[3].y_centre       = 12;
17486 
17487 
17488 
17489   pzone_cfg->user_zones[4].height         = 15;
17490   pzone_cfg->user_zones[4].width          = 15;
17491   pzone_cfg->user_zones[4].x_centre       = 8;
17492   pzone_cfg->user_zones[4].y_centre       = 8;
17493 
17494   status = VL53LX_init_zone_config_histogram_bins(pzone_cfg);
17495 
17496   return status;
17497 }
17498 
17499 VL53LX_Error VL53LX::VL53LX_init_zone_config_histogram_bins(
17500   VL53LX_zone_config_t   *pdata)
17501 {
17502 
17503   VL53LX_Error  status = VL53LX_ERROR_NONE;
17504 
17505   uint8_t i;
17506 
17507 
17508   for (i = 0; i < pdata->max_zones; i++) {
17509     pdata->bin_config[i] = VL53LX_ZONECONFIG_BINCONFIG__LOWAMB;
17510   }
17511 
17512   return status;
17513 }
17514 
17515 /* vl53lx_api_preset_modes.h */
17516 
17517 VL53LX_Error VL53LX::VL53LX_init_refspadchar_config_struct(
17518   VL53LX_refspadchar_config_t   *pdata)
17519 {
17520   VL53LX_Error  status = VL53LX_ERROR_NONE;
17521 
17522   pdata->device_test_mode =
17523     VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE_DEFAULT;
17524   pdata->VL53LX_p_005              =
17525     VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD_DEFAULT;
17526   pdata->timeout_us                =
17527     VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US_DEFAULT;
17528   pdata->target_count_rate_mcps    =
17529     VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS_DEFAULT;
17530   pdata->min_count_rate_limit_mcps =
17531     VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS_DEFAULT;
17532   pdata->max_count_rate_limit_mcps =
17533     VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS_DEFAULT;
17534 
17535   return status;
17536 }
17537 
17538 VL53LX_Error VL53LX::VL53LX_init_ssc_config_struct(
17539   VL53LX_ssc_config_t   *pdata)
17540 {
17541 
17542   VL53LX_Error  status = VL53LX_ERROR_NONE;
17543 
17544   pdata->array_select = VL53LX_DEVICESSCARRAY_RTN;
17545 
17546 
17547   pdata->VL53LX_p_005 =
17548     VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD_DEFAULT;
17549 
17550 
17551   pdata->vcsel_start  =
17552     VL53LX_TUNINGPARM_SPADMAP_VCSEL_START_DEFAULT;
17553 
17554 
17555   pdata->vcsel_width = 0x02;
17556 
17557 
17558   pdata->timeout_us   = 36000;
17559 
17560 
17561   pdata->rate_limit_mcps =
17562     VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS_DEFAULT;
17563 
17564 
17565   return status;
17566 }
17567 
17568 
17569 VL53LX_Error VL53LX::VL53LX_init_xtalk_config_struct(
17570   VL53LX_customer_nvm_managed_t *pnvm,
17571   VL53LX_xtalk_config_t   *pdata)
17572 {
17573 
17574   VL53LX_Error  status = VL53LX_ERROR_NONE;
17575 
17576   pdata->algo__crosstalk_compensation_plane_offset_kcps      =
17577     pnvm->algo__crosstalk_compensation_plane_offset_kcps;
17578   pdata->algo__crosstalk_compensation_x_plane_gradient_kcps  =
17579     pnvm->algo__crosstalk_compensation_x_plane_gradient_kcps;
17580   pdata->algo__crosstalk_compensation_y_plane_gradient_kcps  =
17581     pnvm->algo__crosstalk_compensation_y_plane_gradient_kcps;
17582 
17583 
17584 
17585   pdata->nvm_default__crosstalk_compensation_plane_offset_kcps      =
17586     (uint32_t)pnvm->algo__crosstalk_compensation_plane_offset_kcps;
17587   pdata->nvm_default__crosstalk_compensation_x_plane_gradient_kcps  =
17588     pnvm->algo__crosstalk_compensation_x_plane_gradient_kcps;
17589   pdata->nvm_default__crosstalk_compensation_y_plane_gradient_kcps  =
17590     pnvm->algo__crosstalk_compensation_y_plane_gradient_kcps;
17591 
17592   pdata->histogram_mode_crosstalk_margin_kcps                =
17593     VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS_DEFAULT;
17594   pdata->lite_mode_crosstalk_margin_kcps                     =
17595     VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS_DEFAULT;
17596 
17597 
17598 
17599   pdata->crosstalk_range_ignore_threshold_mult =
17600     VL53LX_TUNINGPARM_LITE_RIT_MULT_DEFAULT;
17601 
17602   if ((pdata->algo__crosstalk_compensation_plane_offset_kcps == 0x00)
17603       && (pdata->algo__crosstalk_compensation_x_plane_gradient_kcps
17604           == 0x00)
17605       && (pdata->algo__crosstalk_compensation_y_plane_gradient_kcps
17606           == 0x00)) {
17607     pdata->global_crosstalk_compensation_enable = 0x00;
17608   } else {
17609     pdata->global_crosstalk_compensation_enable = 0x01;
17610   }
17611 
17612 
17613   if ((status == VL53LX_ERROR_NONE) &&
17614       (pdata->global_crosstalk_compensation_enable == 0x01)) {
17615     pdata->crosstalk_range_ignore_threshold_rate_mcps =
17616       VL53LX_calc_range_ignore_threshold(
17617         pdata->algo__crosstalk_compensation_plane_offset_kcps,
17618         pdata->algo__crosstalk_compensation_x_plane_gradient_kcps,
17619         pdata->algo__crosstalk_compensation_y_plane_gradient_kcps,
17620         pdata->crosstalk_range_ignore_threshold_mult);
17621   } else {
17622     pdata->crosstalk_range_ignore_threshold_rate_mcps = 0;
17623   }
17624 
17625 
17626 
17627 
17628   pdata->algo__crosstalk_detect_min_valid_range_mm  =
17629     VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT;
17630   pdata->algo__crosstalk_detect_max_valid_range_mm  =
17631     VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT;
17632   pdata->algo__crosstalk_detect_max_valid_rate_kcps =
17633     VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT;
17634   pdata->algo__crosstalk_detect_max_sigma_mm        =
17635     VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM_DEFAULT;
17636 
17637   return status;
17638 }
17639 
17640 VL53LX_Error VL53LX::VL53LX_init_xtalk_extract_config_struct(
17641   VL53LX_xtalkextract_config_t   *pdata)
17642 {
17643 
17644   VL53LX_Error  status = VL53LX_ERROR_NONE;
17645 
17646   pdata->dss_config__target_total_rate_mcps          =
17647     VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS_DEFAULT;
17648 
17649   pdata->mm_config_timeout_us                        =
17650     VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US_DEFAULT;
17651 
17652   pdata->num_of_samples                              =
17653     VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES_DEFAULT;
17654 
17655   pdata->phasecal_config_timeout_us                  =
17656     VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US_DEFAULT;
17657 
17658   pdata->range_config_timeout_us                     =
17659     VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US_DEFAULT;
17660 
17661 
17662 
17663   pdata->algo__crosstalk_extract_min_valid_range_mm  =
17664     VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM_DEFAULT;
17665   pdata->algo__crosstalk_extract_max_valid_range_mm  =
17666     VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM_DEFAULT;
17667   pdata->algo__crosstalk_extract_max_valid_rate_kcps =
17668     VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS_DEFAULT;
17669   pdata->algo__crosstalk_extract_max_sigma_mm        =
17670     VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM_DEFAULT;
17671 
17672 
17673   return status;
17674 }
17675 
17676 
17677 VL53LX_Error VL53LX::VL53LX_init_offset_cal_config_struct(
17678   VL53LX_offsetcal_config_t   *pdata)
17679 {
17680 
17681   VL53LX_Error  status = VL53LX_ERROR_NONE;
17682 
17683   pdata->dss_config__target_total_rate_mcps          =
17684     VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS_DEFAULT;
17685 
17686   pdata->phasecal_config_timeout_us                  =
17687     VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US_DEFAULT;
17688 
17689   pdata->range_config_timeout_us                     =
17690     VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US_DEFAULT;
17691 
17692   pdata->mm_config_timeout_us                        =
17693     VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US_DEFAULT;
17694 
17695 
17696   pdata->pre_num_of_samples                          =
17697     VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES_DEFAULT;
17698   pdata->mm1_num_of_samples                          =
17699     VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES_DEFAULT;
17700   pdata->mm2_num_of_samples                          =
17701     VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES_DEFAULT;
17702 
17703   return status;
17704 }
17705 
17706 VL53LX_Error VL53LX::VL53LX_init_zone_cal_config_struct(
17707   VL53LX_zonecal_config_t   *pdata)
17708 {
17709 
17710   VL53LX_Error  status = VL53LX_ERROR_NONE;
17711 
17712   pdata->dss_config__target_total_rate_mcps          =
17713     VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS_DEFAULT;
17714 
17715   pdata->phasecal_config_timeout_us                  =
17716     VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US_DEFAULT;
17717 
17718   pdata->range_config_timeout_us                     =
17719     VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US_DEFAULT;
17720 
17721   pdata->mm_config_timeout_us                        =
17722     VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US_DEFAULT;
17723 
17724   pdata->phasecal_num_of_samples                     =
17725     VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES_DEFAULT;
17726   pdata->zone_num_of_samples                         =
17727     VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES_DEFAULT;
17728 
17729 
17730   return status;
17731 }
17732 
17733 VL53LX_Error VL53LX::VL53LX_init_hist_post_process_config_struct(
17734   uint8_t                             xtalk_compensation_enable,
17735   VL53LX_hist_post_process_config_t   *pdata)
17736 {
17737 
17738   VL53LX_Error  status = VL53LX_ERROR_NONE;
17739 
17740   pdata->hist_algo_select =
17741     VL53LX_TUNINGPARM_HIST_ALGO_SELECT_DEFAULT;
17742 
17743 
17744 
17745   pdata->hist_target_order =
17746     VL53LX_TUNINGPARM_HIST_TARGET_ORDER_DEFAULT;
17747 
17748 
17749 
17750   pdata->filter_woi0                   =
17751     VL53LX_TUNINGPARM_HIST_FILTER_WOI_0_DEFAULT;
17752   pdata->filter_woi1                   =
17753     VL53LX_TUNINGPARM_HIST_FILTER_WOI_1_DEFAULT;
17754 
17755 
17756   pdata->hist_amb_est_method =
17757     VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD_DEFAULT;
17758 
17759   pdata->ambient_thresh_sigma0         =
17760     VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0_DEFAULT;
17761   pdata->ambient_thresh_sigma1         =
17762     VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1_DEFAULT;
17763 
17764 
17765   pdata->ambient_thresh_events_scaler     =
17766     VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER_DEFAULT;
17767 
17768 
17769   pdata->min_ambient_thresh_events     =
17770     VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS_DEFAULT;
17771 
17772   pdata->noise_threshold               =
17773     VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD_DEFAULT;
17774 
17775   pdata->signal_total_events_limit     =
17776     VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT_DEFAULT;
17777   pdata->sigma_estimator__sigma_ref_mm =
17778     VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM_DEFAULT;
17779 
17780 
17781   pdata->sigma_thresh                  =
17782     VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM_DEFAULT;
17783 
17784   pdata->range_offset_mm            =      0;
17785 
17786   pdata->gain_factor                =
17787     VL53LX_TUNINGPARM_HIST_GAIN_FACTOR_DEFAULT;
17788 
17789 
17790 
17791   pdata->valid_phase_low = 0x08;
17792   pdata->valid_phase_high = 0x88;
17793 
17794 
17795 
17796   pdata->algo__consistency_check__phase_tolerance =
17797     VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE_DEFAULT;
17798 
17799 
17800 
17801   pdata->algo__consistency_check__event_sigma =
17802     VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_DEFAULT;
17803 
17804 
17805   pdata->algo__consistency_check__event_min_spad_count =
17806     VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT_DEFAULT;
17807 
17808 
17809 
17810   pdata->algo__consistency_check__min_max_tolerance =
17811     VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM_DEFAULT;
17812 
17813 
17814   pdata->algo__crosstalk_compensation_enable = xtalk_compensation_enable;
17815 
17816 
17817   pdata->algo__crosstalk_detect_min_valid_range_mm  =
17818     VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT;
17819   pdata->algo__crosstalk_detect_max_valid_range_mm  =
17820     VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT;
17821   pdata->algo__crosstalk_detect_max_valid_rate_kcps =
17822     VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT;
17823   pdata->algo__crosstalk_detect_max_sigma_mm        =
17824     VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM_DEFAULT;
17825 
17826 
17827 
17828 
17829 
17830   pdata->algo__crosstalk_detect_event_sigma       =
17831     VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA_DEFAULT;
17832 
17833 
17834 
17835   pdata->algo__crosstalk_detect_min_max_tolerance   =
17836     VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE_DEFAULT;
17837 
17838 
17839   return status;
17840 }
17841 
17842 
17843 VL53LX_Error VL53LX::VL53LX_init_dmax_calibration_data_struct(
17844   VL53LX_dmax_calibration_data_t   *pdata)
17845 {
17846 
17847   VL53LX_Error  status = VL53LX_ERROR_NONE;
17848 
17849   pdata->ref__actual_effective_spads = 0x5F2D;
17850 
17851   pdata->ref__peak_signal_count_rate_mcps = 0x0844;
17852 
17853   pdata->ref__distance_mm = 0x08A5;
17854 
17855 
17856   pdata->ref_reflectance_pc = 0x0014;
17857 
17858   pdata->coverglass_transmission = 0x0100;
17859 
17860   return status;
17861 }
17862 
17863 VL53LX_Error VL53LX::VL53LX_init_tuning_parm_storage_struct(
17864   VL53LX_tuning_parm_storage_t   *pdata)
17865 {
17866   VL53LX_Error  status = VL53LX_ERROR_NONE;
17867 
17868   pdata->tp_tuning_parm_version              =
17869     VL53LX_TUNINGPARM_VERSION_DEFAULT;
17870   pdata->tp_tuning_parm_key_table_version    =
17871     VL53LX_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT;
17872   pdata->tp_tuning_parm_lld_version          =
17873     VL53LX_TUNINGPARM_LLD_VERSION_DEFAULT;
17874   pdata->tp_init_phase_rtn_lite_long         =
17875     VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE_DEFAULT;
17876   pdata->tp_init_phase_rtn_lite_med          =
17877     VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE_DEFAULT;
17878   pdata->tp_init_phase_rtn_lite_short        =
17879     VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE_DEFAULT;
17880   pdata->tp_init_phase_ref_lite_long         =
17881     VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE_DEFAULT;
17882   pdata->tp_init_phase_ref_lite_med          =
17883     VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE_DEFAULT;
17884   pdata->tp_init_phase_ref_lite_short        =
17885     VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE_DEFAULT;
17886   pdata->tp_init_phase_rtn_hist_long         =
17887     VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE_DEFAULT;
17888   pdata->tp_init_phase_rtn_hist_med          =
17889     VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE_DEFAULT;
17890   pdata->tp_init_phase_rtn_hist_short        =
17891     VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE_DEFAULT;
17892   pdata->tp_init_phase_ref_hist_long         =
17893     VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE_DEFAULT;
17894   pdata->tp_init_phase_ref_hist_med          =
17895     VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE_DEFAULT;
17896   pdata->tp_init_phase_ref_hist_short        =
17897     VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE_DEFAULT;
17898   pdata->tp_consistency_lite_phase_tolerance =
17899     VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE_DEFAULT;
17900   pdata->tp_phasecal_target                  =
17901     VL53LX_TUNINGPARM_PHASECAL_TARGET_DEFAULT;
17902   pdata->tp_cal_repeat_rate                  =
17903     VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE_DEFAULT;
17904   pdata->tp_lite_min_clip                    =
17905     VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM_DEFAULT;
17906   pdata->tp_lite_long_sigma_thresh_mm        =
17907     VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM_DEFAULT;
17908   pdata->tp_lite_med_sigma_thresh_mm         =
17909     VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM_DEFAULT;
17910   pdata->tp_lite_short_sigma_thresh_mm       =
17911     VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM_DEFAULT;
17912   pdata->tp_lite_long_min_count_rate_rtn_mcps  =
17913     VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS_DEFAULT;
17914   pdata->tp_lite_med_min_count_rate_rtn_mcps   =
17915     VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS_DEFAULT;
17916   pdata->tp_lite_short_min_count_rate_rtn_mcps =
17917     VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS_DEFAULT;
17918   pdata->tp_lite_sigma_est_pulse_width_ns      =
17919     VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH_DEFAULT;
17920   pdata->tp_lite_sigma_est_amb_width_ns        =
17921     VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS_DEFAULT;
17922   pdata->tp_lite_sigma_ref_mm                  =
17923     VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM_DEFAULT;
17924   pdata->tp_lite_seed_cfg                      =
17925     VL53LX_TUNINGPARM_LITE_SEED_CONFIG_DEFAULT;
17926   pdata->tp_timed_seed_cfg                     =
17927     VL53LX_TUNINGPARM_TIMED_SEED_CONFIG_DEFAULT;
17928   pdata->tp_lite_quantifier                    =
17929     VL53LX_TUNINGPARM_LITE_QUANTIFIER_DEFAULT;
17930   pdata->tp_lite_first_order_select            =
17931     VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT_DEFAULT;
17932 
17933 
17934 
17935 
17936   pdata->tp_dss_target_lite_mcps               =
17937     VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT;
17938   pdata->tp_dss_target_histo_mcps              =
17939     VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT;
17940   pdata->tp_dss_target_histo_mz_mcps           =
17941     VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT;
17942   pdata->tp_dss_target_timed_mcps              =
17943     VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT;
17944   pdata->tp_phasecal_timeout_lite_us           =
17945     VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
17946   pdata->tp_phasecal_timeout_hist_long_us      =
17947     VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
17948   pdata->tp_phasecal_timeout_hist_med_us       =
17949     VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
17950   pdata->tp_phasecal_timeout_hist_short_us     =
17951     VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
17952   pdata->tp_phasecal_timeout_mz_long_us        =
17953     VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
17954   pdata->tp_phasecal_timeout_mz_med_us         =
17955     VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
17956   pdata->tp_phasecal_timeout_mz_short_us       =
17957     VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
17958   pdata->tp_phasecal_timeout_timed_us          =
17959     VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
17960   pdata->tp_mm_timeout_lite_us                 =
17961     VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US_DEFAULT;
17962   pdata->tp_mm_timeout_histo_us                =
17963     VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US_DEFAULT;
17964   pdata->tp_mm_timeout_mz_us                   =
17965     VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US_DEFAULT;
17966   pdata->tp_mm_timeout_timed_us                =
17967     VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US_DEFAULT;
17968   pdata->tp_range_timeout_lite_us              =
17969     VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
17970   pdata->tp_range_timeout_histo_us             =
17971     VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
17972   pdata->tp_range_timeout_mz_us                =
17973     VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
17974   pdata->tp_range_timeout_timed_us             =
17975     VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
17976 
17977 
17978 
17979   pdata->tp_mm_timeout_lpa_us =
17980     VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US_DEFAULT;
17981   pdata->tp_range_timeout_lpa_us =
17982     VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
17983 
17984   pdata->tp_dss_target_very_short_mcps =
17985     VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS_DEFAULT;
17986 
17987   pdata->tp_phasecal_patch_power =
17988     VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER_DEFAULT;
17989 
17990   pdata->tp_hist_merge =
17991     VL53LX_TUNINGPARM_HIST_MERGE_DEFAULT;
17992 
17993   pdata->tp_reset_merge_threshold =
17994     VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD_DEFAULT;
17995 
17996   pdata->tp_hist_merge_max_size =
17997     VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE_DEFAULT;
17998 
17999   return status;
18000 }
18001 
18002 VL53LX_Error VL53LX::VL53LX_init_hist_gen3_dmax_config_struct(
18003   VL53LX_hist_gen3_dmax_config_t   *pdata)
18004 {
18005 
18006 
18007   VL53LX_Error  status = VL53LX_ERROR_NONE;
18008 
18009   pdata->dss_config__target_total_rate_mcps = 0x1400;
18010   pdata->dss_config__aperture_attenuation = 0x38;
18011 
18012   pdata->signal_thresh_sigma                 =
18013     VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA_DEFAULT;
18014   pdata->ambient_thresh_sigma = 0x70;
18015   pdata->min_ambient_thresh_events           = 16;
18016   pdata->signal_total_events_limit           = 100;
18017   pdata->max_effective_spads = 0xFFFF;
18018 
18019 
18020 
18021   pdata->target_reflectance_for_dmax_calc[0] =
18022     VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0_DEFAULT;
18023   pdata->target_reflectance_for_dmax_calc[1] =
18024     VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1_DEFAULT;
18025   pdata->target_reflectance_for_dmax_calc[2] =
18026     VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2_DEFAULT;
18027   pdata->target_reflectance_for_dmax_calc[3] =
18028     VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3_DEFAULT;
18029   pdata->target_reflectance_for_dmax_calc[4] =
18030     VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4_DEFAULT;
18031 
18032   return status;
18033 }
18034 
18035 
18036 VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging(
18037   VL53LX_static_config_t    *pstatic,
18038   VL53LX_histogram_config_t *phistogram,
18039   VL53LX_general_config_t   *pgeneral,
18040   VL53LX_timing_config_t    *ptiming,
18041   VL53LX_dynamic_config_t   *pdynamic,
18042   VL53LX_system_control_t   *psystem,
18043   VL53LX_tuning_parm_storage_t *ptuning_parms,
18044   VL53LX_zone_config_t      *pzone_cfg)
18045 {
18046 
18047 
18048   VL53LX_Error  status = VL53LX_ERROR_NONE;
18049 
18050   pstatic->dss_config__target_total_rate_mcps = 0x0A00;
18051   pstatic->debug__ctrl = 0x00;
18052   pstatic->test_mode__ctrl = 0x00;
18053   pstatic->clk_gating__ctrl = 0x00;
18054   pstatic->nvm_bist__ctrl = 0x00;
18055   pstatic->nvm_bist__num_nvm_words = 0x00;
18056   pstatic->nvm_bist__start_address = 0x00;
18057   pstatic->host_if__status = 0x00;
18058   pstatic->pad_i2c_hv__config = 0x00;
18059   pstatic->pad_i2c_hv__extsup_config = 0x00;
18060 
18061 
18062   pstatic->gpio_hv_pad__ctrl = 0x00;
18063 
18064 
18065   pstatic->gpio_hv_mux__ctrl  =
18066     VL53LX_DEVICEINTERRUPTPOLARITY_ACTIVE_LOW |
18067     VL53LX_DEVICEGPIOMODE_OUTPUT_RANGE_AND_ERROR_INTERRUPTS;
18068 
18069   pstatic->gpio__tio_hv_status = 0x02;
18070   pstatic->gpio__fio_hv_status = 0x00;
18071   pstatic->ana_config__spad_sel_pswidth = 0x02;
18072   pstatic->ana_config__vcsel_pulse_width_offset = 0x08;
18073   pstatic->ana_config__fast_osc__config_ctrl = 0x00;
18074 
18075   pstatic->sigma_estimator__effective_pulse_width_ns        =
18076     ptuning_parms->tp_lite_sigma_est_pulse_width_ns;
18077   pstatic->sigma_estimator__effective_ambient_width_ns      =
18078     ptuning_parms->tp_lite_sigma_est_amb_width_ns;
18079   pstatic->sigma_estimator__sigma_ref_mm                    =
18080     ptuning_parms->tp_lite_sigma_ref_mm;
18081 
18082   pstatic->algo__crosstalk_compensation_valid_height_mm = 0x01;
18083   pstatic->spare_host_config__static_config_spare_0 = 0x00;
18084   pstatic->spare_host_config__static_config_spare_1 = 0x00;
18085 
18086   pstatic->algo__range_ignore_threshold_mcps = 0x0000;
18087 
18088 
18089   pstatic->algo__range_ignore_valid_height_mm = 0xff;
18090   pstatic->algo__range_min_clip                             =
18091     ptuning_parms->tp_lite_min_clip;
18092 
18093   pstatic->algo__consistency_check__tolerance               =
18094     ptuning_parms->tp_consistency_lite_phase_tolerance;
18095   pstatic->spare_host_config__static_config_spare_2 = 0x00;
18096   pstatic->sd_config__reset_stages_msb = 0x00;
18097   pstatic->sd_config__reset_stages_lsb = 0x00;
18098 
18099   pgeneral->gph_config__stream_count_update_value = 0x00;
18100   pgeneral->global_config__stream_divider = 0x00;
18101   pgeneral->system__interrupt_config_gpio =
18102     VL53LX_INTERRUPT_CONFIG_NEW_SAMPLE_READY;
18103   pgeneral->cal_config__vcsel_start = 0x0B;
18104 
18105 
18106   pgeneral->cal_config__repeat_rate                         =
18107     ptuning_parms->tp_cal_repeat_rate;
18108   pgeneral->global_config__vcsel_width = 0x02;
18109 
18110   pgeneral->phasecal_config__timeout_macrop = 0x0D;
18111 
18112   pgeneral->phasecal_config__target                         =
18113     ptuning_parms->tp_phasecal_target;
18114   pgeneral->phasecal_config__override = 0x00;
18115   pgeneral->dss_config__roi_mode_control =
18116     VL53LX_DEVICEDSSMODE__TARGET_RATE;
18117 
18118   pgeneral->system__thresh_rate_high = 0x0000;
18119   pgeneral->system__thresh_rate_low = 0x0000;
18120 
18121   pgeneral->dss_config__manual_effective_spads_select = 0x8C00;
18122   pgeneral->dss_config__manual_block_select = 0x00;
18123 
18124 
18125   pgeneral->dss_config__aperture_attenuation = 0x38;
18126   pgeneral->dss_config__max_spads_limit = 0xFF;
18127   pgeneral->dss_config__min_spads_limit = 0x01;
18128 
18129 
18130 
18131 
18132   ptiming->mm_config__timeout_macrop_a_hi = 0x00;
18133   ptiming->mm_config__timeout_macrop_a_lo = 0x1a;
18134   ptiming->mm_config__timeout_macrop_b_hi = 0x00;
18135   ptiming->mm_config__timeout_macrop_b_lo = 0x20;
18136 
18137   ptiming->range_config__timeout_macrop_a_hi = 0x01;
18138   ptiming->range_config__timeout_macrop_a_lo = 0xCC;
18139 
18140   ptiming->range_config__vcsel_period_a = 0x0B;
18141 
18142   ptiming->range_config__timeout_macrop_b_hi = 0x01;
18143   ptiming->range_config__timeout_macrop_b_lo = 0xF5;
18144 
18145   ptiming->range_config__vcsel_period_b = 0x09;
18146 
18147   ptiming->range_config__sigma_thresh                       =
18148     ptuning_parms->tp_lite_med_sigma_thresh_mm;
18149 
18150   ptiming->range_config__min_count_rate_rtn_limit_mcps      =
18151     ptuning_parms->tp_lite_med_min_count_rate_rtn_mcps;
18152 
18153 
18154   ptiming->range_config__valid_phase_low = 0x08;
18155   ptiming->range_config__valid_phase_high = 0x78;
18156   ptiming->system__intermeasurement_period = 0x00000000;
18157   ptiming->system__fractional_enable = 0x00;
18158 
18159 
18160 
18161   phistogram->histogram_config__low_amb_even_bin_0_1 = 0x07;
18162   phistogram->histogram_config__low_amb_even_bin_2_3 = 0x21;
18163   phistogram->histogram_config__low_amb_even_bin_4_5 = 0x43;
18164 
18165   phistogram->histogram_config__low_amb_odd_bin_0_1 = 0x10;
18166   phistogram->histogram_config__low_amb_odd_bin_2_3 = 0x32;
18167   phistogram->histogram_config__low_amb_odd_bin_4_5 = 0x54;
18168 
18169   phistogram->histogram_config__mid_amb_even_bin_0_1 = 0x07;
18170   phistogram->histogram_config__mid_amb_even_bin_2_3 = 0x21;
18171   phistogram->histogram_config__mid_amb_even_bin_4_5 = 0x43;
18172 
18173   phistogram->histogram_config__mid_amb_odd_bin_0_1 = 0x10;
18174   phistogram->histogram_config__mid_amb_odd_bin_2 = 0x02;
18175   phistogram->histogram_config__mid_amb_odd_bin_3_4 = 0x43;
18176   phistogram->histogram_config__mid_amb_odd_bin_5 = 0x05;
18177 
18178   phistogram->histogram_config__user_bin_offset = 0x00;
18179 
18180   phistogram->histogram_config__high_amb_even_bin_0_1 = 0x07;
18181   phistogram->histogram_config__high_amb_even_bin_2_3 = 0x21;
18182   phistogram->histogram_config__high_amb_even_bin_4_5 = 0x43;
18183 
18184   phistogram->histogram_config__high_amb_odd_bin_0_1 = 0x10;
18185   phistogram->histogram_config__high_amb_odd_bin_2_3 = 0x32;
18186   phistogram->histogram_config__high_amb_odd_bin_4_5 = 0x54;
18187 
18188   phistogram->histogram_config__amb_thresh_low = 0xFFFF;
18189   phistogram->histogram_config__amb_thresh_high = 0xFFFF;
18190 
18191   phistogram->histogram_config__spad_array_selection = 0x00;
18192 
18193 
18194   pzone_cfg->max_zones                     = VL53LX_MAX_USER_ZONES;
18195   pzone_cfg->active_zones = 0x00;
18196   pzone_cfg->user_zones[0].height = 0x0f;
18197   pzone_cfg->user_zones[0].width = 0x0f;
18198   pzone_cfg->user_zones[0].x_centre = 0x08;
18199   pzone_cfg->user_zones[0].y_centre = 0x08;
18200 
18201 
18202 
18203   pdynamic->system__grouped_parameter_hold_0 = 0x01;
18204 
18205   pdynamic->system__thresh_high = 0x0000;
18206   pdynamic->system__thresh_low = 0x0000;
18207   pdynamic->system__enable_xtalk_per_quadrant = 0x00;
18208   pdynamic->system__seed_config =
18209     ptuning_parms->tp_lite_seed_cfg;
18210 
18211 
18212   pdynamic->sd_config__woi_sd0 = 0x0B;
18213 
18214   pdynamic->sd_config__woi_sd1 = 0x09;
18215 
18216   pdynamic->sd_config__initial_phase_sd0                     =
18217     ptuning_parms->tp_init_phase_rtn_lite_med;
18218   pdynamic->sd_config__initial_phase_sd1                     =
18219     ptuning_parms->tp_init_phase_ref_lite_med;
18220 
18221   pdynamic->system__grouped_parameter_hold_1 = 0x01;
18222 
18223 
18224 
18225   pdynamic->sd_config__first_order_select =
18226     ptuning_parms->tp_lite_first_order_select;
18227   pdynamic->sd_config__quantifier         =
18228     ptuning_parms->tp_lite_quantifier;
18229 
18230 
18231   pdynamic->roi_config__user_roi_centre_spad = 0xC7;
18232 
18233   pdynamic->roi_config__user_roi_requested_global_xy_size = 0xFF;
18234 
18235 
18236   pdynamic->system__sequence_config                          =
18237     VL53LX_SEQUENCE_VHV_EN |
18238     VL53LX_SEQUENCE_PHASECAL_EN |
18239     VL53LX_SEQUENCE_DSS1_EN |
18240     VL53LX_SEQUENCE_DSS2_EN |
18241     VL53LX_SEQUENCE_MM2_EN |
18242     VL53LX_SEQUENCE_RANGE_EN;
18243 
18244   pdynamic->system__grouped_parameter_hold = 0x02;
18245 
18246 
18247 
18248 
18249   psystem->system__stream_count_ctrl = 0x00;
18250   psystem->firmware__enable = 0x01;
18251   psystem->system__interrupt_clear                           =
18252     VL53LX_CLEAR_RANGE_INT;
18253 
18254   psystem->system__mode_start                                =
18255     VL53LX_DEVICESCHEDULERMODE_STREAMING |
18256     VL53LX_DEVICEREADOUTMODE_SINGLE_SD |
18257     VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
18258 
18259   return status;
18260 }
18261 
18262 VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging_short_range(
18263   VL53LX_static_config_t    *pstatic,
18264   VL53LX_histogram_config_t *phistogram,
18265   VL53LX_general_config_t   *pgeneral,
18266   VL53LX_timing_config_t    *ptiming,
18267   VL53LX_dynamic_config_t   *pdynamic,
18268   VL53LX_system_control_t   *psystem,
18269   VL53LX_tuning_parm_storage_t *ptuning_parms,
18270   VL53LX_zone_config_t      *pzone_cfg)
18271 {
18272 
18273 
18274   VL53LX_Error  status = VL53LX_ERROR_NONE;
18275 
18276   status = VL53LX_preset_mode_standard_ranging(
18277              pstatic,
18278              phistogram,
18279              pgeneral,
18280              ptiming,
18281              pdynamic,
18282              psystem,
18283              ptuning_parms,
18284              pzone_cfg);
18285 
18286 
18287 
18288   if (status == VL53LX_ERROR_NONE) {
18289 
18290 
18291 
18292     ptiming->range_config__vcsel_period_a = 0x07;
18293     ptiming->range_config__vcsel_period_b = 0x05;
18294     ptiming->range_config__sigma_thresh                  =
18295       ptuning_parms->tp_lite_short_sigma_thresh_mm;
18296     ptiming->range_config__min_count_rate_rtn_limit_mcps =
18297       ptuning_parms->tp_lite_short_min_count_rate_rtn_mcps;
18298     ptiming->range_config__valid_phase_low = 0x08;
18299     ptiming->range_config__valid_phase_high = 0x38;
18300 
18301 
18302 
18303     pdynamic->sd_config__woi_sd0 = 0x07;
18304     pdynamic->sd_config__woi_sd1 = 0x05;
18305     pdynamic->sd_config__initial_phase_sd0               =
18306       ptuning_parms->tp_init_phase_rtn_lite_short;
18307     pdynamic->sd_config__initial_phase_sd1               =
18308       ptuning_parms->tp_init_phase_ref_lite_short;
18309   }
18310 
18311   return status;
18312 }
18313 
18314 VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging_long_range(
18315   VL53LX_static_config_t    *pstatic,
18316   VL53LX_histogram_config_t *phistogram,
18317   VL53LX_general_config_t   *pgeneral,
18318   VL53LX_timing_config_t    *ptiming,
18319   VL53LX_dynamic_config_t   *pdynamic,
18320   VL53LX_system_control_t   *psystem,
18321   VL53LX_tuning_parm_storage_t *ptuning_parms,
18322   VL53LX_zone_config_t      *pzone_cfg)
18323 {
18324 
18325 
18326   VL53LX_Error  status = VL53LX_ERROR_NONE;
18327 
18328   status = VL53LX_preset_mode_standard_ranging(
18329              pstatic,
18330              phistogram,
18331              pgeneral,
18332              ptiming,
18333              pdynamic,
18334              psystem,
18335              ptuning_parms,
18336              pzone_cfg);
18337 
18338 
18339 
18340   if (status == VL53LX_ERROR_NONE) {
18341 
18342 
18343 
18344     ptiming->range_config__vcsel_period_a = 0x0F;
18345     ptiming->range_config__vcsel_period_b = 0x0D;
18346     ptiming->range_config__sigma_thresh                  =
18347       ptuning_parms->tp_lite_long_sigma_thresh_mm;
18348     ptiming->range_config__min_count_rate_rtn_limit_mcps =
18349       ptuning_parms->tp_lite_long_min_count_rate_rtn_mcps;
18350     ptiming->range_config__valid_phase_low = 0x08;
18351     ptiming->range_config__valid_phase_high = 0xB8;
18352 
18353 
18354 
18355     pdynamic->sd_config__woi_sd0 = 0x0F;
18356     pdynamic->sd_config__woi_sd1 = 0x0D;
18357     pdynamic->sd_config__initial_phase_sd0               =
18358       ptuning_parms->tp_init_phase_rtn_lite_long;
18359     pdynamic->sd_config__initial_phase_sd1               =
18360       ptuning_parms->tp_init_phase_ref_lite_long;
18361   }
18362 
18363 
18364   return status;
18365 }
18366 
18367 
18368 VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging_mm1_cal(
18369   VL53LX_static_config_t    *pstatic,
18370   VL53LX_histogram_config_t *phistogram,
18371   VL53LX_general_config_t   *pgeneral,
18372   VL53LX_timing_config_t    *ptiming,
18373   VL53LX_dynamic_config_t   *pdynamic,
18374   VL53LX_system_control_t   *psystem,
18375   VL53LX_tuning_parm_storage_t *ptuning_parms,
18376   VL53LX_zone_config_t      *pzone_cfg)
18377 {
18378 
18379 
18380   VL53LX_Error  status = VL53LX_ERROR_NONE;
18381 
18382   status = VL53LX_preset_mode_standard_ranging(
18383              pstatic,
18384              phistogram,
18385              pgeneral,
18386              ptiming,
18387              pdynamic,
18388              psystem,
18389              ptuning_parms,
18390              pzone_cfg);
18391 
18392 
18393 
18394   if (status == VL53LX_ERROR_NONE) {
18395 
18396     pgeneral->dss_config__roi_mode_control =
18397       VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
18398 
18399     pdynamic->system__sequence_config  =
18400       VL53LX_SEQUENCE_VHV_EN |
18401       VL53LX_SEQUENCE_PHASECAL_EN |
18402       VL53LX_SEQUENCE_DSS1_EN |
18403       VL53LX_SEQUENCE_DSS2_EN |
18404       VL53LX_SEQUENCE_MM1_EN;
18405   }
18406 
18407   return status;
18408 }
18409 
18410 VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging_mm2_cal(
18411   VL53LX_static_config_t    *pstatic,
18412   VL53LX_histogram_config_t *phistogram,
18413   VL53LX_general_config_t   *pgeneral,
18414   VL53LX_timing_config_t    *ptiming,
18415   VL53LX_dynamic_config_t   *pdynamic,
18416   VL53LX_system_control_t   *psystem,
18417   VL53LX_tuning_parm_storage_t *ptuning_parms,
18418   VL53LX_zone_config_t      *pzone_cfg)
18419 {
18420 
18421 
18422   VL53LX_Error  status = VL53LX_ERROR_NONE;
18423 
18424 
18425 
18426   status = VL53LX_preset_mode_standard_ranging(
18427              pstatic,
18428              phistogram,
18429              pgeneral,
18430              ptiming,
18431              pdynamic,
18432              psystem,
18433              ptuning_parms,
18434              pzone_cfg);
18435 
18436 
18437 
18438   if (status == VL53LX_ERROR_NONE) {
18439 
18440     pgeneral->dss_config__roi_mode_control =
18441       VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
18442 
18443     pdynamic->system__sequence_config  =
18444       VL53LX_SEQUENCE_VHV_EN |
18445       VL53LX_SEQUENCE_PHASECAL_EN |
18446       VL53LX_SEQUENCE_DSS1_EN |
18447       VL53LX_SEQUENCE_DSS2_EN |
18448       VL53LX_SEQUENCE_MM2_EN;
18449   }
18450 
18451 
18452   return status;
18453 }
18454 
18455 
18456 VL53LX_Error VL53LX::VL53LX_preset_mode_timed_ranging(
18457 
18458   VL53LX_static_config_t    *pstatic,
18459   VL53LX_histogram_config_t *phistogram,
18460   VL53LX_general_config_t   *pgeneral,
18461   VL53LX_timing_config_t    *ptiming,
18462   VL53LX_dynamic_config_t   *pdynamic,
18463   VL53LX_system_control_t   *psystem,
18464   VL53LX_tuning_parm_storage_t *ptuning_parms,
18465   VL53LX_zone_config_t      *pzone_cfg)
18466 {
18467 
18468 
18469   VL53LX_Error  status = VL53LX_ERROR_NONE;
18470 
18471   status = VL53LX_preset_mode_standard_ranging(
18472              pstatic,
18473              phistogram,
18474              pgeneral,
18475              ptiming,
18476              pdynamic,
18477              psystem,
18478              ptuning_parms,
18479              pzone_cfg);
18480 
18481 
18482 
18483   if (status == VL53LX_ERROR_NONE) {
18484 
18485 
18486 
18487 
18488     pdynamic->system__grouped_parameter_hold = 0x00;
18489 
18490 
18491     ptiming->range_config__timeout_macrop_a_hi = 0x00;
18492     ptiming->range_config__timeout_macrop_a_lo = 0xB1;
18493 
18494     ptiming->range_config__timeout_macrop_b_hi = 0x00;
18495     ptiming->range_config__timeout_macrop_b_lo = 0xD4;
18496 
18497 
18498 
18499     ptiming->system__intermeasurement_period = 0x00000600;
18500     pdynamic->system__seed_config =
18501       ptuning_parms->tp_timed_seed_cfg;
18502 
18503 
18504 
18505 
18506     psystem->system__mode_start =
18507       VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO |
18508       VL53LX_DEVICEREADOUTMODE_SINGLE_SD     |
18509       VL53LX_DEVICEMEASUREMENTMODE_TIMED;
18510   }
18511 
18512   return status;
18513 }
18514 
18515 
18516 VL53LX_Error VL53LX::VL53LX_preset_mode_timed_ranging_short_range(
18517 
18518   VL53LX_static_config_t    *pstatic,
18519   VL53LX_histogram_config_t *phistogram,
18520   VL53LX_general_config_t   *pgeneral,
18521   VL53LX_timing_config_t    *ptiming,
18522   VL53LX_dynamic_config_t   *pdynamic,
18523   VL53LX_system_control_t   *psystem,
18524   VL53LX_tuning_parm_storage_t *ptuning_parms,
18525   VL53LX_zone_config_t      *pzone_cfg)
18526 {
18527 
18528 
18529   VL53LX_Error  status = VL53LX_ERROR_NONE;
18530 
18531 
18532   status = VL53LX_preset_mode_standard_ranging_short_range(
18533              pstatic,
18534              phistogram,
18535              pgeneral,
18536              ptiming,
18537              pdynamic,
18538              psystem,
18539              ptuning_parms,
18540              pzone_cfg);
18541 
18542 
18543 
18544   if (status == VL53LX_ERROR_NONE) {
18545 
18546 
18547 
18548 
18549     pdynamic->system__grouped_parameter_hold = 0x00;
18550 
18551 
18552 
18553 
18554 
18555     ptiming->range_config__timeout_macrop_a_hi = 0x01;
18556     ptiming->range_config__timeout_macrop_a_lo = 0x84;
18557 
18558     ptiming->range_config__timeout_macrop_b_hi = 0x01;
18559     ptiming->range_config__timeout_macrop_b_lo = 0xB1;
18560 
18561     ptiming->system__intermeasurement_period = 0x00000600;
18562     pdynamic->system__seed_config =
18563       ptuning_parms->tp_timed_seed_cfg;
18564 
18565 
18566 
18567 
18568     psystem->system__mode_start =
18569       VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO |
18570       VL53LX_DEVICEREADOUTMODE_SINGLE_SD     |
18571       VL53LX_DEVICEMEASUREMENTMODE_TIMED;
18572   }
18573 
18574   return status;
18575 }
18576 
18577 
18578 VL53LX_Error VL53LX::VL53LX_preset_mode_timed_ranging_long_range(
18579 
18580   VL53LX_static_config_t    *pstatic,
18581   VL53LX_histogram_config_t *phistogram,
18582   VL53LX_general_config_t   *pgeneral,
18583   VL53LX_timing_config_t    *ptiming,
18584   VL53LX_dynamic_config_t   *pdynamic,
18585   VL53LX_system_control_t   *psystem,
18586   VL53LX_tuning_parm_storage_t *ptuning_parms,
18587   VL53LX_zone_config_t      *pzone_cfg)
18588 {
18589 
18590 
18591   VL53LX_Error  status = VL53LX_ERROR_NONE;
18592   status = VL53LX_preset_mode_standard_ranging_long_range(
18593              pstatic,
18594              phistogram,
18595              pgeneral,
18596              ptiming,
18597              pdynamic,
18598              psystem,
18599              ptuning_parms,
18600              pzone_cfg);
18601 
18602 
18603 
18604   if (status == VL53LX_ERROR_NONE) {
18605 
18606 
18607 
18608 
18609     pdynamic->system__grouped_parameter_hold = 0x00;
18610 
18611 
18612 
18613 
18614 
18615     ptiming->range_config__timeout_macrop_a_hi = 0x00;
18616     ptiming->range_config__timeout_macrop_a_lo = 0x97;
18617 
18618     ptiming->range_config__timeout_macrop_b_hi = 0x00;
18619     ptiming->range_config__timeout_macrop_b_lo = 0xB1;
18620 
18621     ptiming->system__intermeasurement_period = 0x00000600;
18622     pdynamic->system__seed_config =
18623       ptuning_parms->tp_timed_seed_cfg;
18624 
18625 
18626 
18627 
18628     psystem->system__mode_start =
18629       VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO |
18630       VL53LX_DEVICEREADOUTMODE_SINGLE_SD     |
18631       VL53LX_DEVICEMEASUREMENTMODE_TIMED;
18632   }
18633 
18634   return status;
18635 }
18636 
18637 VL53LX_Error VL53LX::VL53LX_preset_mode_low_power_auto_ranging(
18638 
18639   VL53LX_static_config_t    *pstatic,
18640   VL53LX_histogram_config_t *phistogram,
18641   VL53LX_general_config_t   *pgeneral,
18642   VL53LX_timing_config_t    *ptiming,
18643   VL53LX_dynamic_config_t   *pdynamic,
18644   VL53LX_system_control_t   *psystem,
18645   VL53LX_tuning_parm_storage_t *ptuning_parms,
18646   VL53LX_zone_config_t      *pzone_cfg,
18647   VL53LX_low_power_auto_data_t *plpadata)
18648 {
18649 
18650 
18651   VL53LX_Error  status = VL53LX_ERROR_NONE;
18652 
18653   status = VL53LX_preset_mode_timed_ranging(
18654              pstatic,
18655              phistogram,
18656              pgeneral,
18657              ptiming,
18658              pdynamic,
18659              psystem,
18660              ptuning_parms,
18661              pzone_cfg);
18662 
18663 
18664 
18665   if (status == VL53LX_ERROR_NONE) {
18666     status = VL53LX_config_low_power_auto_mode(
18667                pgeneral,
18668                pdynamic,
18669                plpadata
18670              );
18671   }
18672 
18673   return status;
18674 }
18675 VL53LX_Error VL53LX::VL53LX_preset_mode_low_power_auto_short_ranging(
18676 
18677   VL53LX_static_config_t    *pstatic,
18678   VL53LX_histogram_config_t *phistogram,
18679   VL53LX_general_config_t   *pgeneral,
18680   VL53LX_timing_config_t    *ptiming,
18681   VL53LX_dynamic_config_t   *pdynamic,
18682   VL53LX_system_control_t   *psystem,
18683   VL53LX_tuning_parm_storage_t *ptuning_parms,
18684   VL53LX_zone_config_t      *pzone_cfg,
18685   VL53LX_low_power_auto_data_t *plpadata)
18686 {
18687 
18688 
18689   VL53LX_Error  status = VL53LX_ERROR_NONE;
18690 
18691   status = VL53LX_preset_mode_timed_ranging_short_range(
18692              pstatic,
18693              phistogram,
18694              pgeneral,
18695              ptiming,
18696              pdynamic,
18697              psystem,
18698              ptuning_parms,
18699              pzone_cfg);
18700 
18701 
18702 
18703   if (status == VL53LX_ERROR_NONE) {
18704     status = VL53LX_config_low_power_auto_mode(
18705                pgeneral,
18706                pdynamic,
18707                plpadata
18708              );
18709   }
18710 
18711   return status;
18712 }
18713 
18714 VL53LX_Error VL53LX::VL53LX_preset_mode_low_power_auto_long_ranging(
18715 
18716   VL53LX_static_config_t    *pstatic,
18717   VL53LX_histogram_config_t *phistogram,
18718   VL53LX_general_config_t   *pgeneral,
18719   VL53LX_timing_config_t    *ptiming,
18720   VL53LX_dynamic_config_t   *pdynamic,
18721   VL53LX_system_control_t   *psystem,
18722   VL53LX_tuning_parm_storage_t *ptuning_parms,
18723   VL53LX_zone_config_t      *pzone_cfg,
18724   VL53LX_low_power_auto_data_t *plpadata)
18725 {
18726 
18727 
18728   VL53LX_Error  status = VL53LX_ERROR_NONE;
18729 
18730   status = VL53LX_preset_mode_timed_ranging_long_range(
18731              pstatic,
18732              phistogram,
18733              pgeneral,
18734              ptiming,
18735              pdynamic,
18736              psystem,
18737              ptuning_parms,
18738              pzone_cfg);
18739 
18740 
18741 
18742   if (status == VL53LX_ERROR_NONE) {
18743     status = VL53LX_config_low_power_auto_mode(
18744                pgeneral,
18745                pdynamic,
18746                plpadata
18747              );
18748   }
18749 
18750   return status;
18751 }
18752 
18753 VL53LX_Error VL53LX::VL53LX_preset_mode_singleshot_ranging(
18754 
18755   VL53LX_static_config_t    *pstatic,
18756   VL53LX_histogram_config_t *phistogram,
18757   VL53LX_general_config_t   *pgeneral,
18758   VL53LX_timing_config_t    *ptiming,
18759   VL53LX_dynamic_config_t   *pdynamic,
18760   VL53LX_system_control_t   *psystem,
18761   VL53LX_tuning_parm_storage_t *ptuning_parms,
18762   VL53LX_zone_config_t      *pzone_cfg)
18763 {
18764 
18765 
18766   VL53LX_Error  status = VL53LX_ERROR_NONE;
18767 
18768   status = VL53LX_preset_mode_standard_ranging(
18769              pstatic,
18770              phistogram,
18771              pgeneral,
18772              ptiming,
18773              pdynamic,
18774              psystem,
18775              ptuning_parms,
18776              pzone_cfg);
18777 
18778 
18779 
18780   if (status == VL53LX_ERROR_NONE) {
18781 
18782     pdynamic->system__grouped_parameter_hold = 0x00;
18783 
18784 
18785 
18786 
18787     ptiming->range_config__timeout_macrop_a_hi = 0x00;
18788     ptiming->range_config__timeout_macrop_a_lo = 0xB1;
18789 
18790     ptiming->range_config__timeout_macrop_b_hi = 0x00;
18791     ptiming->range_config__timeout_macrop_b_lo = 0xD4;
18792 
18793     pdynamic->system__seed_config =
18794       ptuning_parms->tp_timed_seed_cfg;
18795 
18796 
18797 
18798 
18799     psystem->system__mode_start =
18800       VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO |
18801       VL53LX_DEVICEREADOUTMODE_SINGLE_SD     |
18802       VL53LX_DEVICEMEASUREMENTMODE_SINGLESHOT;
18803   }
18804 
18805   return status;
18806 }
18807 
18808 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging(
18809   VL53LX_hist_post_process_config_t  *phistpostprocess,
18810   VL53LX_static_config_t             *pstatic,
18811   VL53LX_histogram_config_t          *phistogram,
18812   VL53LX_general_config_t            *pgeneral,
18813   VL53LX_timing_config_t             *ptiming,
18814   VL53LX_dynamic_config_t            *pdynamic,
18815   VL53LX_system_control_t            *psystem,
18816   VL53LX_tuning_parm_storage_t       *ptuning_parms,
18817   VL53LX_zone_config_t               *pzone_cfg)
18818 {
18819 
18820 
18821   VL53LX_Error  status = VL53LX_ERROR_NONE;
18822 
18823   status =
18824     VL53LX_preset_mode_standard_ranging(
18825       pstatic,
18826       phistogram,
18827       pgeneral,
18828       ptiming,
18829       pdynamic,
18830       psystem,
18831       ptuning_parms,
18832       pzone_cfg);
18833 
18834 
18835 
18836   if (status == VL53LX_ERROR_NONE) {
18837 
18838 
18839 
18840     pstatic->dss_config__target_total_rate_mcps = 0x1400;
18841 
18842 
18843 
18844     VL53LX_init_histogram_config_structure(
18845       7, 0, 1, 2, 3, 4,
18846       0, 1, 2, 3, 4, 5,
18847       phistogram);
18848 
18849 
18850     VL53LX_init_histogram_multizone_config_structure(
18851       7, 0, 1, 2, 3, 4,
18852       0, 1, 2, 3, 4, 5,
18853       &(pzone_cfg->multizone_hist_cfg));
18854 
18855 
18856 
18857 
18858     ptiming->range_config__vcsel_period_a = 0x09;
18859     ptiming->range_config__vcsel_period_b = 0x0B;
18860     pdynamic->sd_config__woi_sd0 = 0x09;
18861     pdynamic->sd_config__woi_sd1 = 0x0B;
18862 
18863 
18864 
18865 
18866     ptiming->mm_config__timeout_macrop_a_hi = 0x00;
18867     ptiming->mm_config__timeout_macrop_a_lo = 0x20;
18868     ptiming->mm_config__timeout_macrop_b_hi = 0x00;
18869     ptiming->mm_config__timeout_macrop_b_lo = 0x1A;
18870 
18871 
18872     ptiming->range_config__timeout_macrop_a_hi = 0x00;
18873     ptiming->range_config__timeout_macrop_a_lo = 0x28;
18874 
18875 
18876     ptiming->range_config__timeout_macrop_b_hi = 0x00;
18877     ptiming->range_config__timeout_macrop_b_lo = 0x21;
18878 
18879 
18880     pgeneral->phasecal_config__timeout_macrop = 0xF5;
18881 
18882 
18883 
18884     phistpostprocess->valid_phase_low = 0x08;
18885     phistpostprocess->valid_phase_high = 0x88;
18886 
18887 
18888 
18889     VL53LX_copy_hist_cfg_to_static_cfg(
18890       phistogram,
18891       pstatic,
18892       pgeneral,
18893       ptiming,
18894       pdynamic);
18895 
18896 
18897 
18898 
18899     pdynamic->system__sequence_config =
18900       VL53LX_SEQUENCE_VHV_EN |
18901       VL53LX_SEQUENCE_PHASECAL_EN |
18902       VL53LX_SEQUENCE_DSS1_EN |
18903       VL53LX_SEQUENCE_DSS2_EN |
18904 
18905 
18906       VL53LX_SEQUENCE_RANGE_EN;
18907 
18908 
18909 
18910 
18911     psystem->system__mode_start =
18912       VL53LX_DEVICESCHEDULERMODE_HISTOGRAM |
18913       VL53LX_DEVICEREADOUTMODE_DUAL_SD |
18914       VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
18915   }
18916 
18917 
18918   return status;
18919 }
18920 
18921 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_with_mm1(
18922   VL53LX_hist_post_process_config_t  *phistpostprocess,
18923   VL53LX_static_config_t             *pstatic,
18924   VL53LX_histogram_config_t          *phistogram,
18925   VL53LX_general_config_t            *pgeneral,
18926   VL53LX_timing_config_t             *ptiming,
18927   VL53LX_dynamic_config_t            *pdynamic,
18928   VL53LX_system_control_t            *psystem,
18929   VL53LX_tuning_parm_storage_t       *ptuning_parms,
18930   VL53LX_zone_config_t               *pzone_cfg)
18931 {
18932 
18933 
18934   VL53LX_Error  status = VL53LX_ERROR_NONE;
18935 
18936   status =
18937     VL53LX_preset_mode_histogram_ranging(
18938       phistpostprocess,
18939       pstatic,
18940       phistogram,
18941       pgeneral,
18942       ptiming,
18943       pdynamic,
18944       psystem,
18945       ptuning_parms,
18946       pzone_cfg);
18947 
18948 
18949 
18950   if (status == VL53LX_ERROR_NONE) {
18951 
18952 
18953 
18954     VL53LX_init_histogram_config_structure(
18955       7,   0,   1, 2, 3, 4,
18956       8 + 0, 8 + 1, 8 + 2, 3, 4, 5,
18957       phistogram);
18958 
18959 
18960     VL53LX_init_histogram_multizone_config_structure(
18961       7,  0,    1, 2, 3, 4,
18962       8 + 0, 8 + 1, 8 + 2, 3, 4, 5,
18963       &(pzone_cfg->multizone_hist_cfg));
18964 
18965 
18966 
18967     VL53LX_copy_hist_cfg_to_static_cfg(
18968       phistogram,
18969       pstatic,
18970       pgeneral,
18971       ptiming,
18972       pdynamic);
18973 
18974 
18975 
18976     pdynamic->system__sequence_config =
18977       VL53LX_SEQUENCE_VHV_EN |
18978       VL53LX_SEQUENCE_PHASECAL_EN |
18979       VL53LX_SEQUENCE_DSS1_EN |
18980       VL53LX_SEQUENCE_DSS2_EN |
18981       VL53LX_SEQUENCE_MM1_EN |
18982       VL53LX_SEQUENCE_RANGE_EN;
18983 
18984 
18985 
18986     psystem->system__mode_start =
18987       VL53LX_DEVICESCHEDULERMODE_HISTOGRAM |
18988       VL53LX_DEVICEREADOUTMODE_DUAL_SD |
18989       VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
18990   }
18991 
18992   return status;
18993 }
18994 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_with_mm2(
18995   VL53LX_hist_post_process_config_t  *phistpostprocess,
18996   VL53LX_static_config_t             *pstatic,
18997   VL53LX_histogram_config_t          *phistogram,
18998   VL53LX_general_config_t            *pgeneral,
18999   VL53LX_timing_config_t             *ptiming,
19000   VL53LX_dynamic_config_t            *pdynamic,
19001   VL53LX_system_control_t            *psystem,
19002   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19003   VL53LX_zone_config_t               *pzone_cfg)
19004 {
19005 
19006 
19007   VL53LX_Error  status = VL53LX_ERROR_NONE;
19008 
19009   status =
19010     VL53LX_preset_mode_histogram_ranging_with_mm1(
19011       phistpostprocess,
19012       pstatic,
19013       phistogram,
19014       pgeneral,
19015       ptiming,
19016       pdynamic,
19017       psystem,
19018       ptuning_parms,
19019       pzone_cfg);
19020 
19021 
19022 
19023   if (status == VL53LX_ERROR_NONE) {
19024 
19025 
19026 
19027     pdynamic->system__sequence_config =
19028       VL53LX_SEQUENCE_VHV_EN |
19029       VL53LX_SEQUENCE_PHASECAL_EN |
19030       VL53LX_SEQUENCE_DSS1_EN |
19031       VL53LX_SEQUENCE_DSS2_EN |
19032       VL53LX_SEQUENCE_MM2_EN |
19033       VL53LX_SEQUENCE_RANGE_EN;
19034   }
19035 
19036   return status;
19037 }
19038 
19039 
19040 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_mm1_cal(
19041   VL53LX_hist_post_process_config_t  *phistpostprocess,
19042   VL53LX_static_config_t             *pstatic,
19043   VL53LX_histogram_config_t          *phistogram,
19044   VL53LX_general_config_t            *pgeneral,
19045   VL53LX_timing_config_t             *ptiming,
19046   VL53LX_dynamic_config_t            *pdynamic,
19047   VL53LX_system_control_t            *psystem,
19048   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19049   VL53LX_zone_config_t               *pzone_cfg)
19050 {
19051 
19052 
19053   VL53LX_Error  status = VL53LX_ERROR_NONE;
19054 
19055   status =
19056     VL53LX_preset_mode_histogram_ranging(
19057       phistpostprocess,
19058       pstatic,
19059       phistogram,
19060       pgeneral,
19061       ptiming,
19062       pdynamic,
19063       psystem,
19064       ptuning_parms,
19065       pzone_cfg);
19066 
19067 
19068 
19069   if (status == VL53LX_ERROR_NONE) {
19070 
19071 
19072 
19073     VL53LX_init_histogram_config_structure(
19074       7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4,
19075       8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, 8 + 5,
19076       phistogram);
19077 
19078 
19079     VL53LX_init_histogram_multizone_config_structure(
19080       7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4,
19081       8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, 8 + 5,
19082       &(pzone_cfg->multizone_hist_cfg));
19083 
19084 
19085 
19086     VL53LX_copy_hist_cfg_to_static_cfg(
19087       phistogram,
19088       pstatic,
19089       pgeneral,
19090       ptiming,
19091       pdynamic);
19092 
19093 
19094 
19095     pgeneral->dss_config__roi_mode_control =
19096       VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
19097 
19098 
19099 
19100     pdynamic->system__sequence_config =
19101       VL53LX_SEQUENCE_VHV_EN |
19102       VL53LX_SEQUENCE_PHASECAL_EN |
19103       VL53LX_SEQUENCE_DSS1_EN |
19104       VL53LX_SEQUENCE_DSS2_EN |
19105       VL53LX_SEQUENCE_MM1_EN |
19106       VL53LX_SEQUENCE_RANGE_EN;
19107 
19108   }
19109 
19110   return status;
19111 }
19112 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_mm2_cal(
19113   VL53LX_hist_post_process_config_t  *phistpostprocess,
19114   VL53LX_static_config_t             *pstatic,
19115   VL53LX_histogram_config_t          *phistogram,
19116   VL53LX_general_config_t            *pgeneral,
19117   VL53LX_timing_config_t             *ptiming,
19118   VL53LX_dynamic_config_t            *pdynamic,
19119   VL53LX_system_control_t            *psystem,
19120   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19121   VL53LX_zone_config_t               *pzone_cfg)
19122 {
19123 
19124 
19125   VL53LX_Error  status = VL53LX_ERROR_NONE;
19126 
19127   status =
19128     VL53LX_preset_mode_histogram_ranging_mm1_cal(
19129       phistpostprocess,
19130       pstatic,
19131       phistogram,
19132       pgeneral,
19133       ptiming,
19134       pdynamic,
19135       psystem,
19136       ptuning_parms,
19137       pzone_cfg);
19138 
19139   if (status == VL53LX_ERROR_NONE) {
19140 
19141 
19142 
19143     pdynamic->system__sequence_config =
19144       VL53LX_SEQUENCE_VHV_EN |
19145       VL53LX_SEQUENCE_PHASECAL_EN |
19146       VL53LX_SEQUENCE_DSS1_EN |
19147       VL53LX_SEQUENCE_DSS2_EN |
19148       VL53LX_SEQUENCE_MM2_EN |
19149       VL53LX_SEQUENCE_RANGE_EN;
19150 
19151   }
19152 
19153   return status;
19154 }
19155 
19156 
19157 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_short_timing(
19158   VL53LX_hist_post_process_config_t  *phistpostprocess,
19159   VL53LX_static_config_t             *pstatic,
19160   VL53LX_histogram_config_t          *phistogram,
19161   VL53LX_general_config_t            *pgeneral,
19162   VL53LX_timing_config_t             *ptiming,
19163   VL53LX_dynamic_config_t            *pdynamic,
19164   VL53LX_system_control_t            *psystem,
19165   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19166   VL53LX_zone_config_t               *pzone_cfg)
19167 {
19168 
19169 
19170   VL53LX_Error  status = VL53LX_ERROR_NONE;
19171 
19172   status =
19173     VL53LX_preset_mode_histogram_ranging(
19174       phistpostprocess,
19175       pstatic,
19176       phistogram,
19177       pgeneral,
19178       ptiming,
19179       pdynamic,
19180       psystem,
19181       ptuning_parms,
19182       pzone_cfg);
19183 
19184 
19185 
19186   if (status == VL53LX_ERROR_NONE) {
19187 
19188 
19189 
19190     pstatic->dss_config__target_total_rate_mcps = 0x1400;
19191 
19192 
19193 
19194     VL53LX_init_histogram_config_structure(
19195       7, 0, 1, 2, 3, 4,
19196       7, 0, 1, 2, 3, 4,
19197       phistogram);
19198 
19199 
19200     VL53LX_init_histogram_multizone_config_structure(
19201       7, 0, 1, 2, 3, 4,
19202       7, 0, 1, 2, 3, 4,
19203       &(pzone_cfg->multizone_hist_cfg));
19204 
19205 
19206 
19207     VL53LX_copy_hist_cfg_to_static_cfg(
19208       phistogram,
19209       pstatic,
19210       pgeneral,
19211       ptiming,
19212       pdynamic);
19213 
19214 
19215 
19216     ptiming->range_config__vcsel_period_a = 0x04;
19217     ptiming->range_config__vcsel_period_b = 0x03;
19218     ptiming->mm_config__timeout_macrop_a_hi = 0x00;
19219     ptiming->mm_config__timeout_macrop_a_lo = 0x42;
19220     ptiming->mm_config__timeout_macrop_b_hi = 0x00;
19221     ptiming->mm_config__timeout_macrop_b_lo = 0x42;
19222     ptiming->range_config__timeout_macrop_a_hi = 0x00;
19223     ptiming->range_config__timeout_macrop_a_lo = 0x52;
19224     ptiming->range_config__timeout_macrop_b_hi = 0x00;
19225     ptiming->range_config__timeout_macrop_b_lo = 0x66;
19226 
19227     pgeneral->cal_config__vcsel_start = 0x04;
19228 
19229 
19230 
19231     pgeneral->phasecal_config__timeout_macrop = 0xa4;
19232 
19233 
19234 
19235     pdynamic->system__sequence_config =
19236       VL53LX_SEQUENCE_VHV_EN |
19237       VL53LX_SEQUENCE_PHASECAL_EN |
19238       VL53LX_SEQUENCE_DSS1_EN |
19239       VL53LX_SEQUENCE_DSS2_EN |
19240 
19241 
19242       VL53LX_SEQUENCE_RANGE_EN;
19243 
19244 
19245 
19246 
19247     psystem->system__mode_start =
19248       VL53LX_DEVICESCHEDULERMODE_HISTOGRAM |
19249       VL53LX_DEVICEREADOUTMODE_DUAL_SD |
19250       VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
19251   }
19252 
19253   return status;
19254 }
19255 
19256 
19257 
19258 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_long_range(
19259   VL53LX_hist_post_process_config_t  *phistpostprocess,
19260   VL53LX_static_config_t             *pstatic,
19261   VL53LX_histogram_config_t          *phistogram,
19262   VL53LX_general_config_t            *pgeneral,
19263   VL53LX_timing_config_t             *ptiming,
19264   VL53LX_dynamic_config_t            *pdynamic,
19265   VL53LX_system_control_t            *psystem,
19266   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19267   VL53LX_zone_config_t               *pzone_cfg)
19268 {
19269 
19270 
19271   VL53LX_Error  status = VL53LX_ERROR_NONE;
19272 
19273   status =
19274     VL53LX_preset_mode_histogram_ranging(
19275       phistpostprocess,
19276       pstatic,
19277       phistogram,
19278       pgeneral,
19279       ptiming,
19280       pdynamic,
19281       psystem,
19282       ptuning_parms,
19283       pzone_cfg);
19284 
19285 
19286 
19287   if (status == VL53LX_ERROR_NONE) {
19288 
19289 
19290 
19291 
19292 
19293     VL53LX_init_histogram_config_structure(
19294       7, 0, 1, 2, 3, 4,
19295       0, 1, 2, 3, 4, 5,
19296       phistogram);
19297 
19298 
19299     VL53LX_init_histogram_multizone_config_structure(
19300       7, 0, 1, 2, 3, 4,
19301       0, 1, 2, 3, 4, 5,
19302       &(pzone_cfg->multizone_hist_cfg));
19303 
19304 
19305 
19306     VL53LX_copy_hist_cfg_to_static_cfg(
19307       phistogram,
19308       pstatic,
19309       pgeneral,
19310       ptiming,
19311       pdynamic);
19312 
19313 
19314 
19315     ptiming->range_config__vcsel_period_a = 0x09;
19316     ptiming->range_config__vcsel_period_b = 0x0b;
19317 
19318 
19319 
19320     ptiming->mm_config__timeout_macrop_a_hi = 0x00;
19321     ptiming->mm_config__timeout_macrop_a_lo = 0x21;
19322     ptiming->mm_config__timeout_macrop_b_hi = 0x00;
19323     ptiming->mm_config__timeout_macrop_b_lo = 0x1b;
19324 
19325 
19326 
19327     ptiming->range_config__timeout_macrop_a_hi = 0x00;
19328     ptiming->range_config__timeout_macrop_a_lo = 0x29;
19329     ptiming->range_config__timeout_macrop_b_hi = 0x00;
19330     ptiming->range_config__timeout_macrop_b_lo = 0x22;
19331 
19332 
19333 
19334     pgeneral->cal_config__vcsel_start = 0x09;
19335 
19336 
19337 
19338     pgeneral->phasecal_config__timeout_macrop = 0xF5;
19339 
19340 
19341 
19342     pdynamic->sd_config__woi_sd0 = 0x09;
19343     pdynamic->sd_config__woi_sd1 = 0x0B;
19344     pdynamic->sd_config__initial_phase_sd0            =
19345       ptuning_parms->tp_init_phase_rtn_hist_long;
19346     pdynamic->sd_config__initial_phase_sd1            =
19347       ptuning_parms->tp_init_phase_ref_hist_long;
19348 
19349 
19350 
19351     phistpostprocess->valid_phase_low = 0x08;
19352     phistpostprocess->valid_phase_high = 0x88;
19353 
19354     pdynamic->system__sequence_config =
19355       VL53LX_SEQUENCE_VHV_EN |
19356       VL53LX_SEQUENCE_PHASECAL_EN |
19357       VL53LX_SEQUENCE_DSS1_EN |
19358       VL53LX_SEQUENCE_DSS2_EN |
19359       VL53LX_SEQUENCE_RANGE_EN;
19360 
19361 
19362 
19363 
19364     psystem->system__mode_start =
19365       VL53LX_DEVICESCHEDULERMODE_HISTOGRAM |
19366       VL53LX_DEVICEREADOUTMODE_DUAL_SD |
19367       VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
19368   }
19369 
19370   return status;
19371 }
19372 
19373 
19374 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_long_range_mm1(
19375   VL53LX_hist_post_process_config_t  *phistpostprocess,
19376   VL53LX_static_config_t             *pstatic,
19377   VL53LX_histogram_config_t          *phistogram,
19378   VL53LX_general_config_t            *pgeneral,
19379   VL53LX_timing_config_t             *ptiming,
19380   VL53LX_dynamic_config_t            *pdynamic,
19381   VL53LX_system_control_t            *psystem,
19382   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19383   VL53LX_zone_config_t               *pzone_cfg)
19384 {
19385 
19386 
19387   VL53LX_Error  status = VL53LX_ERROR_NONE;
19388 
19389   status =
19390     VL53LX_preset_mode_histogram_long_range(
19391       phistpostprocess,
19392       pstatic,
19393       phistogram,
19394       pgeneral,
19395       ptiming,
19396       pdynamic,
19397       psystem,
19398       ptuning_parms,
19399       pzone_cfg);
19400 
19401 
19402 
19403   if (status == VL53LX_ERROR_NONE) {
19404 
19405 
19406 
19407 
19408 
19409     VL53LX_init_histogram_config_structure(
19410       7,   0,   1, 2, 3, 4,
19411       8 + 0, 8 + 1, 8 + 2, 3, 4, 5,
19412       phistogram);
19413 
19414 
19415     VL53LX_init_histogram_multizone_config_structure(
19416       7,   0,   1, 2, 3, 4,
19417       8 + 0, 8 + 1, 8 + 2, 3, 4, 5,
19418       &(pzone_cfg->multizone_hist_cfg));
19419 
19420 
19421 
19422     VL53LX_copy_hist_cfg_to_static_cfg(
19423       phistogram,
19424       pstatic,
19425       pgeneral,
19426       ptiming,
19427       pdynamic);
19428 
19429 
19430 
19431     pdynamic->system__sequence_config =
19432       VL53LX_SEQUENCE_VHV_EN |
19433       VL53LX_SEQUENCE_PHASECAL_EN |
19434       VL53LX_SEQUENCE_DSS1_EN |
19435       VL53LX_SEQUENCE_DSS2_EN |
19436       VL53LX_SEQUENCE_MM1_EN |
19437       VL53LX_SEQUENCE_RANGE_EN;
19438   }
19439 
19440   return status;
19441 }
19442 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_long_range_mm2(
19443   VL53LX_hist_post_process_config_t  *phistpostprocess,
19444   VL53LX_static_config_t             *pstatic,
19445   VL53LX_histogram_config_t          *phistogram,
19446   VL53LX_general_config_t            *pgeneral,
19447   VL53LX_timing_config_t             *ptiming,
19448   VL53LX_dynamic_config_t            *pdynamic,
19449   VL53LX_system_control_t            *psystem,
19450   VL53LX_tuning_parm_storage_t      *ptuning_parms,
19451   VL53LX_zone_config_t               *pzone_cfg)
19452 {
19453 
19454 
19455   VL53LX_Error  status = VL53LX_ERROR_NONE;
19456 
19457 
19458   status =
19459     VL53LX_preset_mode_histogram_long_range_mm1(
19460       phistpostprocess,
19461       pstatic,
19462       phistogram,
19463       pgeneral,
19464       ptiming,
19465       pdynamic,
19466       psystem,
19467       ptuning_parms,
19468       pzone_cfg);
19469 
19470 
19471 
19472   if (status == VL53LX_ERROR_NONE) {
19473 
19474 
19475 
19476     pdynamic->system__sequence_config =
19477       VL53LX_SEQUENCE_VHV_EN |
19478       VL53LX_SEQUENCE_PHASECAL_EN |
19479       VL53LX_SEQUENCE_DSS1_EN |
19480       VL53LX_SEQUENCE_DSS2_EN |
19481       VL53LX_SEQUENCE_MM2_EN |
19482       VL53LX_SEQUENCE_RANGE_EN;
19483   }
19484 
19485   return status;
19486 }
19487 
19488 
19489 
19490 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_medium_range(
19491   VL53LX_hist_post_process_config_t  *phistpostprocess,
19492   VL53LX_static_config_t             *pstatic,
19493   VL53LX_histogram_config_t          *phistogram,
19494   VL53LX_general_config_t            *pgeneral,
19495   VL53LX_timing_config_t             *ptiming,
19496   VL53LX_dynamic_config_t            *pdynamic,
19497   VL53LX_system_control_t            *psystem,
19498   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19499   VL53LX_zone_config_t               *pzone_cfg)
19500 {
19501 
19502 
19503   VL53LX_Error  status = VL53LX_ERROR_NONE;
19504 
19505   status =
19506     VL53LX_preset_mode_histogram_ranging(
19507       phistpostprocess,
19508       pstatic,
19509       phistogram,
19510       pgeneral,
19511       ptiming,
19512       pdynamic,
19513       psystem,
19514       ptuning_parms,
19515       pzone_cfg);
19516 
19517 
19518 
19519   if (status == VL53LX_ERROR_NONE) {
19520 
19521 
19522 
19523 
19524 
19525     VL53LX_init_histogram_config_structure(
19526       7, 0, 1, 1, 2, 2,
19527       0, 1, 2, 1, 2, 3,
19528       phistogram);
19529 
19530 
19531     VL53LX_init_histogram_multizone_config_structure(
19532       7, 0, 1, 1, 2, 2,
19533       0, 1, 2, 1, 2, 3,
19534       &(pzone_cfg->multizone_hist_cfg));
19535 
19536 
19537 
19538     VL53LX_copy_hist_cfg_to_static_cfg(
19539       phistogram,
19540       pstatic,
19541       pgeneral,
19542       ptiming,
19543       pdynamic);
19544 
19545 
19546 
19547     ptiming->range_config__vcsel_period_a = 0x05;
19548     ptiming->range_config__vcsel_period_b = 0x07;
19549 
19550 
19551 
19552     ptiming->mm_config__timeout_macrop_a_hi = 0x00;
19553     ptiming->mm_config__timeout_macrop_a_lo = 0x36;
19554     ptiming->mm_config__timeout_macrop_b_hi = 0x00;
19555     ptiming->mm_config__timeout_macrop_b_lo = 0x28;
19556 
19557 
19558 
19559     ptiming->range_config__timeout_macrop_a_hi = 0x00;
19560     ptiming->range_config__timeout_macrop_a_lo = 0x44;
19561     ptiming->range_config__timeout_macrop_b_hi = 0x00;
19562     ptiming->range_config__timeout_macrop_b_lo = 0x33;
19563 
19564 
19565 
19566     pgeneral->cal_config__vcsel_start = 0x05;
19567 
19568 
19569 
19570     pgeneral->phasecal_config__timeout_macrop = 0xF5;
19571 
19572 
19573 
19574     pdynamic->sd_config__woi_sd0 = 0x05;
19575     pdynamic->sd_config__woi_sd1 = 0x07;
19576     pdynamic->sd_config__initial_phase_sd0            =
19577       ptuning_parms->tp_init_phase_rtn_hist_med;
19578     pdynamic->sd_config__initial_phase_sd1            =
19579       ptuning_parms->tp_init_phase_ref_hist_med;
19580 
19581 
19582 
19583     phistpostprocess->valid_phase_low = 0x08;
19584     phistpostprocess->valid_phase_high = 0x48;
19585 
19586     pdynamic->system__sequence_config =
19587       VL53LX_SEQUENCE_VHV_EN |
19588       VL53LX_SEQUENCE_PHASECAL_EN |
19589       VL53LX_SEQUENCE_DSS1_EN |
19590       VL53LX_SEQUENCE_DSS2_EN |
19591       VL53LX_SEQUENCE_RANGE_EN;
19592 
19593 
19594 
19595 
19596     psystem->system__mode_start =
19597       VL53LX_DEVICESCHEDULERMODE_HISTOGRAM |
19598       VL53LX_DEVICEREADOUTMODE_DUAL_SD |
19599       VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
19600   }
19601 
19602   return status;
19603 }
19604 
19605 
19606 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_medium_range_mm1(
19607   VL53LX_hist_post_process_config_t  *phistpostprocess,
19608   VL53LX_static_config_t             *pstatic,
19609   VL53LX_histogram_config_t          *phistogram,
19610   VL53LX_general_config_t            *pgeneral,
19611   VL53LX_timing_config_t             *ptiming,
19612   VL53LX_dynamic_config_t            *pdynamic,
19613   VL53LX_system_control_t            *psystem,
19614   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19615   VL53LX_zone_config_t               *pzone_cfg)
19616 {
19617 
19618 
19619   VL53LX_Error  status = VL53LX_ERROR_NONE;
19620 
19621   status =
19622     VL53LX_preset_mode_histogram_medium_range(
19623       phistpostprocess,
19624       pstatic,
19625       phistogram,
19626       pgeneral,
19627       ptiming,
19628       pdynamic,
19629       psystem,
19630       ptuning_parms,
19631       pzone_cfg);
19632 
19633 
19634 
19635   if (status == VL53LX_ERROR_NONE) {
19636 
19637 
19638 
19639     VL53LX_init_histogram_config_structure(
19640       7,   0,   1, 1, 2, 2,
19641       8 + 0, 8 + 1, 8 + 2, 1, 2, 3,
19642       phistogram);
19643 
19644 
19645     VL53LX_init_histogram_multizone_config_structure(
19646       7,   0,   1, 1, 2, 2,
19647       8 + 0, 8 + 1, 8 + 2, 1, 2, 3,
19648       &(pzone_cfg->multizone_hist_cfg));
19649 
19650 
19651 
19652     VL53LX_copy_hist_cfg_to_static_cfg(
19653       phistogram,
19654       pstatic,
19655       pgeneral,
19656       ptiming,
19657       pdynamic);
19658 
19659 
19660 
19661     pdynamic->system__sequence_config =
19662       VL53LX_SEQUENCE_VHV_EN |
19663       VL53LX_SEQUENCE_PHASECAL_EN |
19664       VL53LX_SEQUENCE_DSS1_EN |
19665       VL53LX_SEQUENCE_DSS2_EN |
19666       VL53LX_SEQUENCE_MM1_EN  |
19667       VL53LX_SEQUENCE_RANGE_EN;
19668   }
19669 
19670   return status;
19671 }
19672 
19673 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_medium_range_mm2(
19674   VL53LX_hist_post_process_config_t  *phistpostprocess,
19675   VL53LX_static_config_t             *pstatic,
19676   VL53LX_histogram_config_t          *phistogram,
19677   VL53LX_general_config_t            *pgeneral,
19678   VL53LX_timing_config_t             *ptiming,
19679   VL53LX_dynamic_config_t            *pdynamic,
19680   VL53LX_system_control_t            *psystem,
19681   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19682   VL53LX_zone_config_t               *pzone_cfg)
19683 {
19684 
19685 
19686   VL53LX_Error  status = VL53LX_ERROR_NONE;
19687 
19688   status =
19689     VL53LX_preset_mode_histogram_medium_range_mm1(
19690       phistpostprocess,
19691       pstatic,
19692       phistogram,
19693       pgeneral,
19694       ptiming,
19695       pdynamic,
19696       psystem,
19697       ptuning_parms,
19698       pzone_cfg);
19699 
19700 
19701 
19702   if (status == VL53LX_ERROR_NONE) {
19703 
19704 
19705 
19706     pdynamic->system__sequence_config =
19707       VL53LX_SEQUENCE_VHV_EN |
19708       VL53LX_SEQUENCE_PHASECAL_EN |
19709       VL53LX_SEQUENCE_DSS1_EN |
19710       VL53LX_SEQUENCE_DSS2_EN |
19711       VL53LX_SEQUENCE_MM2_EN |
19712       VL53LX_SEQUENCE_RANGE_EN;
19713   }
19714 
19715   return status;
19716 }
19717 
19718 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_short_range(
19719   VL53LX_hist_post_process_config_t  *phistpostprocess,
19720   VL53LX_static_config_t             *pstatic,
19721   VL53LX_histogram_config_t          *phistogram,
19722   VL53LX_general_config_t            *pgeneral,
19723   VL53LX_timing_config_t             *ptiming,
19724   VL53LX_dynamic_config_t            *pdynamic,
19725   VL53LX_system_control_t            *psystem,
19726   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19727   VL53LX_zone_config_t               *pzone_cfg)
19728 {
19729 
19730 
19731   VL53LX_Error  status = VL53LX_ERROR_NONE;
19732 
19733   status =
19734     VL53LX_preset_mode_histogram_ranging(
19735       phistpostprocess,
19736       pstatic,
19737       phistogram,
19738       pgeneral,
19739       ptiming,
19740       pdynamic,
19741       psystem,
19742       ptuning_parms,
19743       pzone_cfg);
19744 
19745 
19746 
19747   if (status == VL53LX_ERROR_NONE) {
19748 
19749 
19750 
19751 
19752 
19753     VL53LX_init_histogram_config_structure(
19754       7, 7, 0, 1, 1, 1,
19755       0, 1, 1, 1, 2, 2,
19756       phistogram);
19757 
19758 
19759     VL53LX_init_histogram_multizone_config_structure(
19760       7, 7, 0, 1, 1, 1,
19761       0, 1, 1, 1, 2, 2,
19762       &(pzone_cfg->multizone_hist_cfg));
19763 
19764 
19765 
19766     VL53LX_copy_hist_cfg_to_static_cfg(
19767       phistogram,
19768       pstatic,
19769       pgeneral,
19770       ptiming,
19771       pdynamic);
19772 
19773 
19774 
19775     ptiming->range_config__vcsel_period_a = 0x03;
19776     ptiming->range_config__vcsel_period_b = 0x05;
19777 
19778 
19779 
19780     ptiming->mm_config__timeout_macrop_a_hi = 0x00;
19781     ptiming->mm_config__timeout_macrop_a_lo = 0x52;
19782     ptiming->mm_config__timeout_macrop_b_hi = 0x00;
19783     ptiming->mm_config__timeout_macrop_b_lo = 0x37;
19784 
19785 
19786 
19787     ptiming->range_config__timeout_macrop_a_hi = 0x00;
19788     ptiming->range_config__timeout_macrop_a_lo = 0x66;
19789     ptiming->range_config__timeout_macrop_b_hi = 0x00;
19790     ptiming->range_config__timeout_macrop_b_lo = 0x44;
19791 
19792 
19793 
19794     pgeneral->cal_config__vcsel_start = 0x03;
19795 
19796 
19797 
19798     pgeneral->phasecal_config__timeout_macrop = 0xF5;
19799 
19800 
19801 
19802     pdynamic->sd_config__woi_sd0 = 0x03;
19803     pdynamic->sd_config__woi_sd1 = 0x05;
19804     pdynamic->sd_config__initial_phase_sd0            =
19805       ptuning_parms->tp_init_phase_rtn_hist_short;
19806     pdynamic->sd_config__initial_phase_sd1            =
19807       ptuning_parms->tp_init_phase_ref_hist_short;
19808 
19809 
19810     phistpostprocess->valid_phase_low = 0x08;
19811     phistpostprocess->valid_phase_high = 0x28;
19812 
19813     pdynamic->system__sequence_config =
19814       VL53LX_SEQUENCE_VHV_EN |
19815       VL53LX_SEQUENCE_PHASECAL_EN |
19816       VL53LX_SEQUENCE_DSS1_EN |
19817       VL53LX_SEQUENCE_DSS2_EN |
19818       VL53LX_SEQUENCE_MM1_EN  |
19819 
19820       VL53LX_SEQUENCE_RANGE_EN;
19821 
19822 
19823 
19824 
19825     psystem->system__mode_start =
19826       VL53LX_DEVICESCHEDULERMODE_HISTOGRAM |
19827       VL53LX_DEVICEREADOUTMODE_DUAL_SD |
19828       VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
19829   }
19830 
19831   return status;
19832 }
19833 
19834 
19835 
19836 VL53LX_Error VL53LX::VL53LX_preset_mode_special_histogram_short_range(
19837   VL53LX_hist_post_process_config_t  *phistpostprocess,
19838   VL53LX_static_config_t             *pstatic,
19839   VL53LX_histogram_config_t          *phistogram,
19840   VL53LX_general_config_t            *pgeneral,
19841   VL53LX_timing_config_t             *ptiming,
19842   VL53LX_dynamic_config_t            *pdynamic,
19843   VL53LX_system_control_t            *psystem,
19844   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19845   VL53LX_zone_config_t               *pzone_cfg)
19846 {
19847 
19848 
19849   VL53LX_Error  status = VL53LX_ERROR_NONE;
19850 
19851 
19852   status =
19853     VL53LX_preset_mode_histogram_short_range(
19854       phistpostprocess,
19855       pstatic,
19856       phistogram,
19857       pgeneral,
19858       ptiming,
19859       pdynamic,
19860       psystem,
19861       ptuning_parms,
19862       pzone_cfg);
19863 
19864 
19865 
19866   if (status == VL53LX_ERROR_NONE) {
19867 
19868 
19869 
19870 
19871 
19872     VL53LX_init_histogram_config_structure(
19873       7, 7, 0, 0, 1, 1,
19874       0, 0, 0, 1, 1, 1,
19875       phistogram);
19876 
19877 
19878     VL53LX_init_histogram_multizone_config_structure(
19879       7, 7, 0, 0, 1, 1,
19880       0, 0, 0, 1, 1, 1,
19881       &(pzone_cfg->multizone_hist_cfg));
19882 
19883 
19884 
19885     VL53LX_copy_hist_cfg_to_static_cfg(
19886       phistogram,
19887       pstatic,
19888       pgeneral,
19889       ptiming,
19890       pdynamic);
19891 
19892 
19893 
19894     ptiming->range_config__vcsel_period_a = 0x02;
19895     ptiming->range_config__vcsel_period_b = 0x03;
19896 
19897 
19898 
19899     pgeneral->cal_config__vcsel_start = 0x00;
19900 
19901 
19902 
19903     pgeneral->phasecal_config__target = 0x31;
19904 
19905 
19906 
19907     pdynamic->sd_config__woi_sd0 = 0x02;
19908     pdynamic->sd_config__woi_sd1 = 0x03;
19909     pdynamic->sd_config__initial_phase_sd0            =
19910       ptuning_parms->tp_init_phase_rtn_hist_short;
19911     pdynamic->sd_config__initial_phase_sd1            =
19912       ptuning_parms->tp_init_phase_ref_hist_short;
19913 
19914 
19915 
19916     phistpostprocess->valid_phase_low = 0x10;
19917     phistpostprocess->valid_phase_high = 0x18;
19918 
19919   }
19920 
19921   return status;
19922 }
19923 
19924 
19925 
19926 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_short_range_mm1(
19927   VL53LX_hist_post_process_config_t  *phistpostprocess,
19928   VL53LX_static_config_t             *pstatic,
19929   VL53LX_histogram_config_t          *phistogram,
19930   VL53LX_general_config_t            *pgeneral,
19931   VL53LX_timing_config_t             *ptiming,
19932   VL53LX_dynamic_config_t            *pdynamic,
19933   VL53LX_system_control_t            *psystem,
19934   VL53LX_tuning_parm_storage_t       *ptuning_parms,
19935   VL53LX_zone_config_t               *pzone_cfg)
19936 {
19937 
19938 
19939   VL53LX_Error  status = VL53LX_ERROR_NONE;
19940 
19941   status =
19942     VL53LX_preset_mode_histogram_short_range(
19943       phistpostprocess,
19944       pstatic,
19945       phistogram,
19946       pgeneral,
19947       ptiming,
19948       pdynamic,
19949       psystem,
19950       ptuning_parms,
19951       pzone_cfg);
19952 
19953 
19954 
19955   if (status == VL53LX_ERROR_NONE) {
19956 
19957 
19958 
19959 
19960 
19961     VL53LX_init_histogram_config_structure(
19962       7,   7, 0, 1, 1, 1,
19963       8 + 0, 8 + 1, 1, 1, 2, 2,
19964       phistogram);
19965 
19966 
19967     VL53LX_init_histogram_multizone_config_structure(
19968       7,   7, 0, 1, 1, 1,
19969       8 + 0, 8 + 1, 1, 1, 2, 2,
19970       &(pzone_cfg->multizone_hist_cfg));
19971 
19972 
19973 
19974     VL53LX_copy_hist_cfg_to_static_cfg(
19975       phistogram,
19976       pstatic,
19977       pgeneral,
19978       ptiming,
19979       pdynamic);
19980 
19981 
19982 
19983     pdynamic->system__sequence_config =
19984       VL53LX_SEQUENCE_VHV_EN |
19985       VL53LX_SEQUENCE_PHASECAL_EN |
19986       VL53LX_SEQUENCE_DSS1_EN |
19987       VL53LX_SEQUENCE_DSS2_EN |
19988       VL53LX_SEQUENCE_MM1_EN  |
19989       VL53LX_SEQUENCE_RANGE_EN;
19990 
19991   }
19992 
19993   return status;
19994 }
19995 
19996 
19997 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_short_range_mm2(
19998   VL53LX_hist_post_process_config_t  *phistpostprocess,
19999   VL53LX_static_config_t             *pstatic,
20000   VL53LX_histogram_config_t          *phistogram,
20001   VL53LX_general_config_t            *pgeneral,
20002   VL53LX_timing_config_t             *ptiming,
20003   VL53LX_dynamic_config_t            *pdynamic,
20004   VL53LX_system_control_t            *psystem,
20005   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20006   VL53LX_zone_config_t               *pzone_cfg)
20007 {
20008 
20009 
20010   VL53LX_Error  status = VL53LX_ERROR_NONE;
20011 
20012   status =
20013     VL53LX_preset_mode_histogram_short_range_mm1(
20014       phistpostprocess,
20015       pstatic,
20016       phistogram,
20017       pgeneral,
20018       ptiming,
20019       pdynamic,
20020       psystem,
20021       ptuning_parms,
20022       pzone_cfg);
20023 
20024 
20025 
20026   if (status == VL53LX_ERROR_NONE) {
20027 
20028 
20029 
20030     pdynamic->system__sequence_config =
20031       VL53LX_SEQUENCE_VHV_EN |
20032       VL53LX_SEQUENCE_PHASECAL_EN |
20033       VL53LX_SEQUENCE_DSS1_EN |
20034       VL53LX_SEQUENCE_DSS2_EN |
20035       VL53LX_SEQUENCE_MM2_EN |
20036       VL53LX_SEQUENCE_RANGE_EN;
20037   }
20038 
20039 
20040   return status;
20041 }
20042 
20043 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_characterisation(
20044   VL53LX_hist_post_process_config_t  *phistpostprocess,
20045   VL53LX_static_config_t             *pstatic,
20046   VL53LX_histogram_config_t          *phistogram,
20047   VL53LX_general_config_t            *pgeneral,
20048   VL53LX_timing_config_t             *ptiming,
20049   VL53LX_dynamic_config_t            *pdynamic,
20050   VL53LX_system_control_t            *psystem,
20051   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20052   VL53LX_zone_config_t               *pzone_cfg)
20053 {
20054 
20055 
20056   VL53LX_Error  status = VL53LX_ERROR_NONE;
20057 
20058   status =
20059     VL53LX_preset_mode_histogram_ranging(
20060       phistpostprocess,
20061       pstatic,
20062       phistogram,
20063       pgeneral,
20064       ptiming,
20065       pdynamic,
20066       psystem,
20067       ptuning_parms,
20068       pzone_cfg);
20069 
20070 
20071 
20072   if (status == VL53LX_ERROR_NONE) {
20073 
20074 
20075 
20076     pstatic->debug__ctrl = 0x01;
20077     psystem->power_management__go1_power_force = 0x01;
20078 
20079     pdynamic->system__sequence_config               =
20080       VL53LX_SEQUENCE_VHV_EN |
20081       VL53LX_SEQUENCE_PHASECAL_EN |
20082       VL53LX_SEQUENCE_RANGE_EN;
20083 
20084     psystem->system__mode_start                     =
20085       VL53LX_DEVICESCHEDULERMODE_HISTOGRAM    |
20086       VL53LX_DEVICEREADOUTMODE_SPLIT_MANUAL   |
20087       VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
20088   }
20089 
20090 
20091   return status;
20092 }
20093 
20094 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_xtalk_planar(
20095   VL53LX_hist_post_process_config_t  *phistpostprocess,
20096   VL53LX_static_config_t             *pstatic,
20097   VL53LX_histogram_config_t          *phistogram,
20098   VL53LX_general_config_t            *pgeneral,
20099   VL53LX_timing_config_t             *ptiming,
20100   VL53LX_dynamic_config_t            *pdynamic,
20101   VL53LX_system_control_t            *psystem,
20102   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20103   VL53LX_zone_config_t               *pzone_cfg)
20104 {
20105 
20106 
20107   VL53LX_Error  status = VL53LX_ERROR_NONE;
20108 
20109 
20110   status =
20111     VL53LX_preset_mode_histogram_multizone_long_range(
20112       phistpostprocess,
20113       pstatic,
20114       phistogram,
20115       pgeneral,
20116       ptiming,
20117       pdynamic,
20118       psystem,
20119       ptuning_parms,
20120       pzone_cfg);
20121 
20122 
20123 
20124   if (status == VL53LX_ERROR_NONE) {
20125 
20126 
20127 
20128     status =
20129       VL53LX_zone_preset_xtalk_planar(
20130         pgeneral,
20131         pzone_cfg);
20132 
20133 
20134 
20135     ptiming->range_config__vcsel_period_a = 0x09;
20136     ptiming->range_config__vcsel_period_b = 0x09;
20137 
20138 
20139 
20140     VL53LX_init_histogram_config_structure(
20141       7, 0, 1, 2, 3, 4,
20142       7, 0, 1, 2, 3, 4,
20143       phistogram);
20144 
20145 
20146 
20147     VL53LX_init_histogram_multizone_config_structure(
20148       7, 0, 1, 2, 3, 4,
20149       7, 0, 1, 2, 3, 4,
20150       &(pzone_cfg->multizone_hist_cfg));
20151 
20152 
20153 
20154 
20155     if (status == VL53LX_ERROR_NONE) {
20156       status =
20157         VL53LX_set_histogram_multizone_initial_bin_config(
20158           pzone_cfg,
20159           phistogram,
20160           &(pzone_cfg->multizone_hist_cfg));
20161     }
20162 
20163 
20164 
20165     VL53LX_copy_hist_cfg_to_static_cfg(
20166       phistogram,
20167       pstatic,
20168       pgeneral,
20169       ptiming,
20170       pdynamic);
20171 
20172   }
20173 
20174 
20175   return status;
20176 }
20177 
20178 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_xtalk_mm1(
20179   VL53LX_hist_post_process_config_t  *phistpostprocess,
20180   VL53LX_static_config_t             *pstatic,
20181   VL53LX_histogram_config_t          *phistogram,
20182   VL53LX_general_config_t            *pgeneral,
20183   VL53LX_timing_config_t             *ptiming,
20184   VL53LX_dynamic_config_t            *pdynamic,
20185   VL53LX_system_control_t            *psystem,
20186   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20187   VL53LX_zone_config_t               *pzone_cfg)
20188 {
20189 
20190 
20191   VL53LX_Error  status = VL53LX_ERROR_NONE;
20192 
20193 
20194   status =
20195     VL53LX_preset_mode_histogram_ranging(
20196       phistpostprocess,
20197       pstatic,
20198       phistogram,
20199       pgeneral,
20200       ptiming,
20201       pdynamic,
20202       psystem,
20203       ptuning_parms,
20204       pzone_cfg);
20205 
20206 
20207 
20208 
20209   if (status == VL53LX_ERROR_NONE) {
20210 
20211 
20212 
20213 
20214 
20215     VL53LX_init_histogram_config_structure(
20216       8 + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4,
20217       8 + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4,
20218       phistogram);
20219 
20220 
20221     VL53LX_init_histogram_multizone_config_structure(
20222       8 + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4,
20223       8 + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4,
20224       &(pzone_cfg->multizone_hist_cfg));
20225 
20226 
20227 
20228     VL53LX_copy_hist_cfg_to_static_cfg(
20229       phistogram,
20230       pstatic,
20231       pgeneral,
20232       ptiming,
20233       pdynamic);
20234 
20235 
20236 
20237     ptiming->range_config__vcsel_period_a = 0x09;
20238     ptiming->range_config__vcsel_period_b = 0x09;
20239 
20240 
20241 
20242     ptiming->mm_config__timeout_macrop_a_hi = 0x00;
20243     ptiming->mm_config__timeout_macrop_a_lo = 0x21;
20244     ptiming->mm_config__timeout_macrop_b_hi = 0x00;
20245     ptiming->mm_config__timeout_macrop_b_lo = 0x21;
20246 
20247 
20248 
20249     ptiming->range_config__timeout_macrop_a_hi = 0x00;
20250     ptiming->range_config__timeout_macrop_a_lo = 0x29;
20251     ptiming->range_config__timeout_macrop_b_hi = 0x00;
20252     ptiming->range_config__timeout_macrop_b_lo = 0x29;
20253 
20254 
20255 
20256     pgeneral->cal_config__vcsel_start = 0x09;
20257 
20258 
20259 
20260     pgeneral->phasecal_config__timeout_macrop = 0xF5;
20261 
20262 
20263 
20264     pdynamic->sd_config__woi_sd0 = 0x09;
20265     pdynamic->sd_config__woi_sd1 = 0x09;
20266     pdynamic->sd_config__initial_phase_sd0 = 0x09;
20267     pdynamic->sd_config__initial_phase_sd1 = 0x06;
20268 
20269     pdynamic->system__sequence_config =
20270       VL53LX_SEQUENCE_VHV_EN |
20271       VL53LX_SEQUENCE_PHASECAL_EN |
20272       VL53LX_SEQUENCE_DSS1_EN |
20273       VL53LX_SEQUENCE_DSS2_EN |
20274       VL53LX_SEQUENCE_MM1_EN |
20275       VL53LX_SEQUENCE_RANGE_EN;
20276 
20277 
20278 
20279 
20280     psystem->system__mode_start =
20281       VL53LX_DEVICESCHEDULERMODE_HISTOGRAM |
20282       VL53LX_DEVICEREADOUTMODE_DUAL_SD |
20283       VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
20284   }
20285 
20286   return status;
20287 }
20288 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_xtalk_mm2(
20289   VL53LX_hist_post_process_config_t  *phistpostprocess,
20290   VL53LX_static_config_t             *pstatic,
20291   VL53LX_histogram_config_t          *phistogram,
20292   VL53LX_general_config_t            *pgeneral,
20293   VL53LX_timing_config_t             *ptiming,
20294   VL53LX_dynamic_config_t            *pdynamic,
20295   VL53LX_system_control_t            *psystem,
20296   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20297   VL53LX_zone_config_t               *pzone_cfg)
20298 {
20299 
20300 
20301   VL53LX_Error  status = VL53LX_ERROR_NONE;
20302 
20303   status =
20304     VL53LX_preset_mode_histogram_xtalk_mm1(
20305       phistpostprocess,
20306       pstatic,
20307       phistogram,
20308       pgeneral,
20309       ptiming,
20310       pdynamic,
20311       psystem,
20312       ptuning_parms,
20313       pzone_cfg);
20314 
20315 
20316   pdynamic->system__sequence_config =
20317     VL53LX_SEQUENCE_VHV_EN |
20318     VL53LX_SEQUENCE_PHASECAL_EN |
20319     VL53LX_SEQUENCE_DSS1_EN |
20320     VL53LX_SEQUENCE_DSS2_EN |
20321     VL53LX_SEQUENCE_MM2_EN |
20322     VL53LX_SEQUENCE_RANGE_EN;
20323 
20324 
20325   return status;
20326 }
20327 
20328 
20329 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_multizone(
20330   VL53LX_hist_post_process_config_t  *phistpostprocess,
20331   VL53LX_static_config_t             *pstatic,
20332   VL53LX_histogram_config_t          *phistogram,
20333   VL53LX_general_config_t            *pgeneral,
20334   VL53LX_timing_config_t             *ptiming,
20335   VL53LX_dynamic_config_t            *pdynamic,
20336   VL53LX_system_control_t            *psystem,
20337   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20338   VL53LX_zone_config_t               *pzone_cfg)
20339 {
20340 
20341 
20342   VL53LX_Error  status = VL53LX_ERROR_NONE;
20343 
20344   status =
20345     VL53LX_preset_mode_histogram_medium_range(
20346       phistpostprocess,
20347       pstatic,
20348       phistogram,
20349       pgeneral,
20350       ptiming,
20351       pdynamic,
20352       psystem,
20353       ptuning_parms,
20354       pzone_cfg);
20355 
20356 
20357 
20358   if (status == VL53LX_ERROR_NONE) {
20359 
20360 
20361 
20362     status =
20363       VL53LX_init_zone_config_structure(
20364         4, 8, 2,
20365         4, 8, 2,
20366         7, 7,
20367         pzone_cfg);
20368 
20369     pgeneral->global_config__stream_divider =
20370       pzone_cfg->active_zones + 1;
20371 
20372 
20373 
20374     if (status == VL53LX_ERROR_NONE) {
20375       status =
20376         VL53LX_set_histogram_multizone_initial_bin_config(
20377           pzone_cfg,
20378           phistogram,
20379           &(pzone_cfg->multizone_hist_cfg));
20380     }
20381 
20382     VL53LX_copy_hist_cfg_to_static_cfg(
20383       phistogram,
20384       pstatic,
20385       pgeneral,
20386       ptiming,
20387       pdynamic);
20388   }
20389 
20390   return status;
20391 }
20392 
20393 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_multizone_short_range(
20394   VL53LX_hist_post_process_config_t  *phistpostprocess,
20395   VL53LX_static_config_t             *pstatic,
20396   VL53LX_histogram_config_t          *phistogram,
20397   VL53LX_general_config_t            *pgeneral,
20398   VL53LX_timing_config_t             *ptiming,
20399   VL53LX_dynamic_config_t            *pdynamic,
20400   VL53LX_system_control_t            *psystem,
20401   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20402   VL53LX_zone_config_t               *pzone_cfg)
20403 {
20404 
20405 
20406   VL53LX_Error  status = VL53LX_ERROR_NONE;
20407 
20408   status =
20409     VL53LX_preset_mode_histogram_short_range(
20410       phistpostprocess,
20411       pstatic,
20412       phistogram,
20413       pgeneral,
20414       ptiming,
20415       pdynamic,
20416       psystem,
20417       ptuning_parms,
20418       pzone_cfg);
20419 
20420 
20421 
20422   if (status == VL53LX_ERROR_NONE) {
20423 
20424 
20425 
20426     status =
20427       VL53LX_init_zone_config_structure(
20428         4, 8, 2,
20429         4, 8, 2,
20430         7, 7,
20431         pzone_cfg);
20432 
20433     pgeneral->global_config__stream_divider =
20434       pzone_cfg->active_zones + 1;
20435 
20436 
20437 
20438     if (status == VL53LX_ERROR_NONE) {
20439       status =
20440         VL53LX_set_histogram_multizone_initial_bin_config(
20441           pzone_cfg,
20442           phistogram,
20443           &(pzone_cfg->multizone_hist_cfg)
20444         );
20445     }
20446 
20447 
20448 
20449     VL53LX_copy_hist_cfg_to_static_cfg(
20450       phistogram,
20451       pstatic,
20452       pgeneral,
20453       ptiming,
20454       pdynamic);
20455   }
20456 
20457 
20458   return status;
20459 }
20460 
20461 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_multizone_long_range(
20462   VL53LX_hist_post_process_config_t  *phistpostprocess,
20463   VL53LX_static_config_t             *pstatic,
20464   VL53LX_histogram_config_t          *phistogram,
20465   VL53LX_general_config_t            *pgeneral,
20466   VL53LX_timing_config_t             *ptiming,
20467   VL53LX_dynamic_config_t            *pdynamic,
20468   VL53LX_system_control_t            *psystem,
20469   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20470   VL53LX_zone_config_t               *pzone_cfg)
20471 {
20472 
20473 
20474   VL53LX_Error  status = VL53LX_ERROR_NONE;
20475 
20476   status =
20477     VL53LX_preset_mode_histogram_long_range(
20478       phistpostprocess,
20479       pstatic,
20480       phistogram,
20481       pgeneral,
20482       ptiming,
20483       pdynamic,
20484       psystem,
20485       ptuning_parms,
20486       pzone_cfg);
20487 
20488 
20489 
20490   if (status == VL53LX_ERROR_NONE) {
20491 
20492 
20493 
20494     status =
20495       VL53LX_init_zone_config_structure(
20496         4, 8, 2,
20497         4, 8, 2,
20498         7, 7,
20499         pzone_cfg);
20500 
20501     pgeneral->global_config__stream_divider =
20502       pzone_cfg->active_zones + 1;
20503 
20504 
20505 
20506     if (status == VL53LX_ERROR_NONE) {
20507       status =
20508         VL53LX_set_histogram_multizone_initial_bin_config(
20509           pzone_cfg,
20510           phistogram,
20511           &(pzone_cfg->multizone_hist_cfg));
20512     }
20513 
20514 
20515 
20516     VL53LX_copy_hist_cfg_to_static_cfg(
20517       phistogram,
20518       pstatic,
20519       pgeneral,
20520       ptiming,
20521       pdynamic);
20522   }
20523 
20524   return status;
20525 }
20526 
20527 VL53LX_Error VL53LX::VL53LX_preset_mode_olt(
20528   VL53LX_static_config_t    *pstatic,
20529   VL53LX_histogram_config_t *phistogram,
20530   VL53LX_general_config_t   *pgeneral,
20531   VL53LX_timing_config_t    *ptiming,
20532   VL53LX_dynamic_config_t   *pdynamic,
20533   VL53LX_system_control_t   *psystem,
20534   VL53LX_tuning_parm_storage_t *ptuning_parms,
20535   VL53LX_zone_config_t      *pzone_cfg)
20536 {
20537 
20538 
20539   VL53LX_Error  status = VL53LX_ERROR_NONE;
20540 
20541   status = VL53LX_preset_mode_standard_ranging(
20542              pstatic,
20543              phistogram,
20544              pgeneral,
20545              ptiming,
20546              pdynamic,
20547              psystem,
20548              ptuning_parms,
20549              pzone_cfg);
20550 
20551 
20552 
20553   if (status == VL53LX_ERROR_NONE)
20554 
20555   {
20556     psystem->system__stream_count_ctrl = 0x01;
20557   }
20558 
20559 
20560   return status;
20561 }
20562 
20563 void VL53LX::VL53LX_copy_hist_cfg_to_static_cfg(
20564   VL53LX_histogram_config_t *phistogram,
20565   VL53LX_static_config_t    *pstatic,
20566   VL53LX_general_config_t   *pgeneral,
20567   VL53LX_timing_config_t    *ptiming,
20568   VL53LX_dynamic_config_t   *pdynamic)
20569 {
20570 
20571   SUPPRESS_UNUSED_WARNING(pgeneral);
20572 
20573   pstatic->sigma_estimator__effective_pulse_width_ns =
20574     phistogram->histogram_config__high_amb_even_bin_0_1;
20575   pstatic->sigma_estimator__effective_ambient_width_ns =
20576     phistogram->histogram_config__high_amb_even_bin_2_3;
20577   pstatic->sigma_estimator__sigma_ref_mm =
20578     phistogram->histogram_config__high_amb_even_bin_4_5;
20579 
20580   pstatic->algo__crosstalk_compensation_valid_height_mm =
20581     phistogram->histogram_config__high_amb_odd_bin_0_1;
20582 
20583   pstatic->spare_host_config__static_config_spare_0 =
20584     phistogram->histogram_config__high_amb_odd_bin_2_3;
20585   pstatic->spare_host_config__static_config_spare_1 =
20586     phistogram->histogram_config__high_amb_odd_bin_4_5;
20587 
20588   pstatic->algo__range_ignore_threshold_mcps =
20589     (((uint16_t)phistogram->histogram_config__mid_amb_even_bin_0_1)
20590      << 8)
20591     + (uint16_t)phistogram->histogram_config__mid_amb_even_bin_2_3;
20592 
20593   pstatic->algo__range_ignore_valid_height_mm =
20594     phistogram->histogram_config__mid_amb_even_bin_4_5;
20595   pstatic->algo__range_min_clip =
20596     phistogram->histogram_config__mid_amb_odd_bin_0_1;
20597   pstatic->algo__consistency_check__tolerance =
20598     phistogram->histogram_config__mid_amb_odd_bin_2;
20599 
20600   pstatic->spare_host_config__static_config_spare_2 =
20601     phistogram->histogram_config__mid_amb_odd_bin_3_4;
20602   pstatic->sd_config__reset_stages_msb =
20603     phistogram->histogram_config__mid_amb_odd_bin_5;
20604 
20605   pstatic->sd_config__reset_stages_lsb =
20606     phistogram->histogram_config__user_bin_offset;
20607 
20608   ptiming->range_config__sigma_thresh =
20609     (((uint16_t)phistogram->histogram_config__low_amb_even_bin_0_1)
20610      << 8)
20611     + (uint16_t)phistogram->histogram_config__low_amb_even_bin_2_3;
20612 
20613   ptiming->range_config__min_count_rate_rtn_limit_mcps =
20614     (((uint16_t)phistogram->histogram_config__low_amb_even_bin_4_5)
20615      << 8)
20616     + (uint16_t)phistogram->histogram_config__low_amb_odd_bin_0_1;
20617 
20618   ptiming->range_config__valid_phase_low =
20619     phistogram->histogram_config__low_amb_odd_bin_2_3;
20620   ptiming->range_config__valid_phase_high =
20621     phistogram->histogram_config__low_amb_odd_bin_4_5;
20622 
20623   pdynamic->system__thresh_high =
20624     phistogram->histogram_config__amb_thresh_low;
20625 
20626   pdynamic->system__thresh_low =
20627     phistogram->histogram_config__amb_thresh_high;
20628 
20629   pdynamic->system__enable_xtalk_per_quadrant =
20630     phistogram->histogram_config__spad_array_selection;
20631 
20632 
20633 }
20634 
20635 void VL53LX::VL53LX_copy_hist_bins_to_static_cfg(
20636   VL53LX_histogram_config_t *phistogram,
20637   VL53LX_static_config_t    *pstatic,
20638   VL53LX_timing_config_t    *ptiming)
20639 {
20640 
20641   pstatic->sigma_estimator__effective_pulse_width_ns =
20642     phistogram->histogram_config__high_amb_even_bin_0_1;
20643   pstatic->sigma_estimator__effective_ambient_width_ns =
20644     phistogram->histogram_config__high_amb_even_bin_2_3;
20645   pstatic->sigma_estimator__sigma_ref_mm =
20646     phistogram->histogram_config__high_amb_even_bin_4_5;
20647 
20648   pstatic->algo__crosstalk_compensation_valid_height_mm =
20649     phistogram->histogram_config__high_amb_odd_bin_0_1;
20650 
20651   pstatic->spare_host_config__static_config_spare_0 =
20652     phistogram->histogram_config__high_amb_odd_bin_2_3;
20653   pstatic->spare_host_config__static_config_spare_1 =
20654     phistogram->histogram_config__high_amb_odd_bin_4_5;
20655 
20656   pstatic->algo__range_ignore_threshold_mcps =
20657     (((uint16_t)phistogram->histogram_config__mid_amb_even_bin_0_1)
20658      << 8)
20659     + (uint16_t)phistogram->histogram_config__mid_amb_even_bin_2_3;
20660 
20661   pstatic->algo__range_ignore_valid_height_mm =
20662     phistogram->histogram_config__mid_amb_even_bin_4_5;
20663   pstatic->algo__range_min_clip =
20664     phistogram->histogram_config__mid_amb_odd_bin_0_1;
20665   pstatic->algo__consistency_check__tolerance =
20666     phistogram->histogram_config__mid_amb_odd_bin_2;
20667 
20668   pstatic->spare_host_config__static_config_spare_2 =
20669     phistogram->histogram_config__mid_amb_odd_bin_3_4;
20670   pstatic->sd_config__reset_stages_msb =
20671     phistogram->histogram_config__mid_amb_odd_bin_5;
20672 
20673   ptiming->range_config__sigma_thresh =
20674     (((uint16_t)phistogram->histogram_config__low_amb_even_bin_0_1)
20675      << 8)
20676     + (uint16_t)phistogram->histogram_config__low_amb_even_bin_2_3;
20677 
20678   ptiming->range_config__min_count_rate_rtn_limit_mcps =
20679     (((uint16_t)phistogram->histogram_config__low_amb_even_bin_4_5)
20680      << 8)
20681     + (uint16_t)phistogram->histogram_config__low_amb_odd_bin_0_1;
20682 
20683   ptiming->range_config__valid_phase_low =
20684     phistogram->histogram_config__low_amb_odd_bin_2_3;
20685   ptiming->range_config__valid_phase_high =
20686     phistogram->histogram_config__low_amb_odd_bin_4_5;
20687 
20688 
20689 }
20690 
20691 VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_ref(
20692   VL53LX_hist_post_process_config_t  *phistpostprocess,
20693   VL53LX_static_config_t             *pstatic,
20694   VL53LX_histogram_config_t          *phistogram,
20695   VL53LX_general_config_t            *pgeneral,
20696   VL53LX_timing_config_t             *ptiming,
20697   VL53LX_dynamic_config_t            *pdynamic,
20698   VL53LX_system_control_t            *psystem,
20699   VL53LX_tuning_parm_storage_t       *ptuning_parms,
20700   VL53LX_zone_config_t               *pzone_cfg)
20701 {
20702 
20703 
20704   VL53LX_Error  status = VL53LX_ERROR_NONE;
20705 
20706   status =
20707     VL53LX_preset_mode_histogram_ranging(
20708       phistpostprocess,
20709       pstatic,
20710       phistogram,
20711       pgeneral,
20712       ptiming,
20713       pdynamic,
20714       psystem,
20715       ptuning_parms,
20716       pzone_cfg);
20717 
20718 
20719 
20720   if (status == VL53LX_ERROR_NONE) {
20721 
20722     phistogram->histogram_config__spad_array_selection = 0x01;
20723 
20724 
20725 
20726     VL53LX_copy_hist_cfg_to_static_cfg(
20727       phistogram,
20728       pstatic,
20729       pgeneral,
20730       ptiming,
20731       pdynamic);
20732   }
20733 
20734   return status;
20735 }
20736 
20737 /* vl53lx_silicon_core.c */
20738 
20739 VL53LX_Error VL53LX::VL53LX_is_firmware_ready_silicon(
20740   uint8_t       *pready)
20741 {
20742 
20743 
20744   VL53LX_Error status = VL53LX_ERROR_NONE;
20745   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
20746 
20747   uint8_t  comms_buffer[5];
20748 
20749   status = VL53LX_ReadMulti(
20750              Dev,
20751              VL53LX_INTERRUPT_MANAGER__ENABLES,
20752              comms_buffer,
20753              5);
20754 
20755   if (status != VL53LX_ERROR_NONE) {
20756     goto ENDFUNC;
20757   }
20758 
20759   pdev->dbg_results.interrupt_manager__enables =
20760     comms_buffer[0];
20761   pdev->dbg_results.interrupt_manager__clear =
20762     comms_buffer[1];
20763   pdev->dbg_results.interrupt_manager__status =
20764     comms_buffer[2];
20765   pdev->dbg_results.mcu_to_host_bank__wr_access_en =
20766     comms_buffer[3];
20767   pdev->dbg_results.power_management__go1_reset_status =
20768     comms_buffer[4];
20769 
20770   if ((pdev->sys_ctrl.power_management__go1_power_force & 0x01)
20771       == 0x01) {
20772 
20773     if (((pdev->dbg_results.interrupt_manager__enables &
20774           0x1F) == 0x1F) &&
20775         ((pdev->dbg_results.interrupt_manager__clear
20776           & 0x1F) == 0x1F)) {
20777       *pready = 0x01;
20778     } else {
20779       *pready = 0x00;
20780     }
20781 
20782   } else {
20783 
20784 
20785     if ((pdev->dbg_results.power_management__go1_reset_status
20786          & 0x01) == 0x00) {
20787       *pready = 0x01;
20788     } else {
20789       *pready = 0x00;
20790     }
20791   }
20792 ENDFUNC:
20793   return status;
20794 }
20795 
20796 /* vl53lx_hist_core.c */
20797 void VL53LX::VL53LX_f_022(
20798   uint8_t                         VL53LX_p_032,
20799   uint8_t                         filter_woi,
20800   VL53LX_histogram_bin_data_t    *pbins,
20801   int32_t                        *pa,
20802   int32_t                        *pb,
20803   int32_t                        *pc)
20804 {
20805 
20806 
20807   uint8_t w = 0;
20808   uint8_t j = 0;
20809 
20810   *pa = 0;
20811   *pb = pbins->bin_data[VL53LX_p_032];
20812   *pc = 0;
20813 
20814   for (w = 0 ; w < ((filter_woi << 1) + 1) ; w++) {
20815 
20816 
20817     j = ((VL53LX_p_032 + w + pbins->VL53LX_p_021) -
20818          filter_woi) % pbins->VL53LX_p_021;
20819 
20820     if (w < filter_woi) {
20821       *pa += pbins->bin_data[j];
20822     } else if (w > filter_woi) {
20823       *pc += pbins->bin_data[j];
20824     }
20825   }
20826 }
20827 
20828 
20829 VL53LX_Error VL53LX::VL53LX_f_018(
20830   uint16_t           vcsel_width,
20831   uint16_t           fast_osc_frequency,
20832   uint32_t           total_periods_elapsed,
20833   uint16_t           VL53LX_p_004,
20834   VL53LX_range_data_t  *pdata)
20835 {
20836   VL53LX_Error     status = VL53LX_ERROR_NONE;
20837 
20838   uint32_t    pll_period_us       = 0;
20839   uint32_t    periods_elapsed     = 0;
20840   uint32_t    count_rate_total    = 0;
20841 
20842 
20843   pdata->width                  = vcsel_width;
20844   pdata->fast_osc_frequency     = fast_osc_frequency;
20845   pdata->total_periods_elapsed  = total_periods_elapsed;
20846   pdata->VL53LX_p_004 = VL53LX_p_004;
20847 
20848 
20849 
20850 
20851   if (pdata->fast_osc_frequency == 0) {
20852     status = VL53LX_ERROR_DIVISION_BY_ZERO;
20853   }
20854 
20855   if (pdata->total_periods_elapsed == 0) {
20856     status = VL53LX_ERROR_DIVISION_BY_ZERO;
20857   }
20858 
20859   if (status == VL53LX_ERROR_NONE) {
20860 
20861 
20862 
20863 
20864     pll_period_us =
20865       VL53LX_calc_pll_period_us(pdata->fast_osc_frequency);
20866 
20867     periods_elapsed      = pdata->total_periods_elapsed + 1;
20868 
20869     pdata->peak_duration_us    = VL53LX_duration_maths(
20870                                    pll_period_us,
20871                                    (uint32_t)pdata->width,
20872                                    VL53LX_RANGING_WINDOW_VCSEL_PERIODS,
20873                                    periods_elapsed);
20874 
20875     pdata->woi_duration_us     = VL53LX_duration_maths(
20876                                    pll_period_us,
20877                                    ((uint32_t)pdata->VL53LX_p_029) << 4,
20878                                    VL53LX_RANGING_WINDOW_VCSEL_PERIODS,
20879                                    periods_elapsed);
20880 
20881 
20882 
20883 
20884     pdata->peak_signal_count_rate_mcps = VL53LX_rate_maths(
20885                                            (int32_t)pdata->VL53LX_p_010,
20886                                            pdata->peak_duration_us);
20887 
20888     pdata->avg_signal_count_rate_mcps = VL53LX_rate_maths(
20889                                           (int32_t)pdata->VL53LX_p_010,
20890                                           pdata->woi_duration_us);
20891 
20892     pdata->ambient_count_rate_mcps    = VL53LX_rate_maths(
20893                                           (int32_t)pdata->VL53LX_p_016,
20894                                           pdata->woi_duration_us);
20895 
20896 
20897 
20898 
20899     count_rate_total =
20900       (uint32_t)pdata->peak_signal_count_rate_mcps +
20901       (uint32_t)pdata->ambient_count_rate_mcps;
20902 
20903     pdata->total_rate_per_spad_mcps   =
20904       VL53LX_rate_per_spad_maths(
20905         0x06,
20906         count_rate_total,
20907         pdata->VL53LX_p_004,
20908         0xFFFF);
20909 
20910 
20911 
20912 
20913     pdata->VL53LX_p_009   =
20914       VL53LX_events_per_spad_maths(
20915         pdata->VL53LX_p_010,
20916         pdata->VL53LX_p_004,
20917         pdata->peak_duration_us);
20918 
20919 
20920 
20921   }
20922 
20923   return status;
20924 }
20925 
20926 
20927 void VL53LX::VL53LX_f_019(
20928   uint16_t             gain_factor,
20929   int16_t              range_offset_mm,
20930   VL53LX_range_data_t *pdata)
20931 {
20932 
20933   pdata->min_range_mm =
20934     (int16_t)VL53LX_range_maths(
20935       pdata->fast_osc_frequency,
20936       pdata->VL53LX_p_026,
20937       pdata->zero_distance_phase,
20938       0,
20939 
20940       (int32_t)gain_factor,
20941       (int32_t)range_offset_mm);
20942 
20943   pdata->median_range_mm =
20944     (int16_t)VL53LX_range_maths(
20945       pdata->fast_osc_frequency,
20946       pdata->VL53LX_p_011,
20947       pdata->zero_distance_phase,
20948       0,
20949 
20950       (int32_t)gain_factor,
20951       (int32_t)range_offset_mm);
20952 
20953   pdata->max_range_mm =
20954     (int16_t)VL53LX_range_maths(
20955       pdata->fast_osc_frequency,
20956       pdata->VL53LX_p_027,
20957       pdata->zero_distance_phase,
20958       0,
20959 
20960       (int32_t)gain_factor,
20961       (int32_t)range_offset_mm);
20962 
20963 }
20964 
20965 void  VL53LX::VL53LX_f_029(
20966   VL53LX_histogram_bin_data_t   *pdata,
20967   int32_t                        ambient_estimate_counts_per_bin)
20968 {
20969   uint8_t i = 0;
20970 
20971   for (i = 0 ; i <  pdata->VL53LX_p_021 ; i++)
20972     pdata->bin_data[i] = pdata->bin_data[i] -
20973                          ambient_estimate_counts_per_bin;
20974 }
20975 
20976 
20977 
20978 
20979 void  VL53LX::VL53LX_f_005(
20980   VL53LX_histogram_bin_data_t   *pxtalk,
20981   VL53LX_histogram_bin_data_t   *pbins,
20982   VL53LX_histogram_bin_data_t   *pxtalk_realigned)
20983 {
20984 
20985 
20986   uint8_t i          = 0;
20987   uint8_t min_bins   = 0;
20988   int8_t  bin_offset = 0;
20989   int8_t  bin_access = 0;
20990 
20991 
20992   memcpy(
20993     pxtalk_realigned,
20994     pbins,
20995     sizeof(VL53LX_histogram_bin_data_t));
20996 
20997   for (i = 0 ; i < pxtalk_realigned->VL53LX_p_020 ; i++) {
20998     pxtalk_realigned->bin_data[i] = 0;
20999   }
21000 
21001 
21002   bin_offset =  VL53LX_f_030(
21003                   pbins,
21004                   pxtalk);
21005 
21006 
21007   if (pxtalk->VL53LX_p_021 < pbins->VL53LX_p_021) {
21008     min_bins = pxtalk->VL53LX_p_021;
21009   } else {
21010     min_bins = pbins->VL53LX_p_021;
21011   }
21012 
21013 
21014   for (i = 0 ; i <  min_bins ; i++) {
21015 
21016 
21017 
21018 
21019     if (bin_offset >= 0)
21020       bin_access = ((int8_t)i + (int8_t)bin_offset)
21021                    % (int8_t)pbins->VL53LX_p_021;
21022     else
21023       bin_access = ((int8_t)pbins->VL53LX_p_021 +
21024                     ((int8_t)i + (int8_t)bin_offset))
21025                    % (int8_t)pbins->VL53LX_p_021;
21026 
21027     if (pbins->bin_data[(uint8_t)bin_access] >
21028         pxtalk->bin_data[i]) {
21029 
21030       pbins->bin_data[(uint8_t)bin_access] =
21031         pbins->bin_data[(uint8_t)bin_access]
21032         - pxtalk->bin_data[i];
21033 
21034     } else {
21035       pbins->bin_data[(uint8_t)bin_access] = 0;
21036     }
21037 
21038 
21039     pxtalk_realigned->bin_data[(uint8_t)bin_access] =
21040       pxtalk->bin_data[i];
21041 
21042 
21043   }
21044 
21045 
21046 }
21047 
21048 
21049 
21050 
21051 int8_t  VL53LX::VL53LX_f_030(
21052   VL53LX_histogram_bin_data_t   *pdata1,
21053   VL53LX_histogram_bin_data_t   *pdata2)
21054 {
21055 
21056 
21057   int32_t  phase_delta      = 0;
21058   int8_t   bin_offset       = 0;
21059   uint32_t period           = 0;
21060   uint32_t remapped_phase   = 0;
21061 
21062   period = 2048 *
21063            (uint32_t)VL53LX_decode_vcsel_period(pdata1->VL53LX_p_005);
21064 
21065   remapped_phase = (uint32_t)pdata2->zero_distance_phase % period;
21066 
21067 
21068   phase_delta = (int32_t)pdata1->zero_distance_phase
21069                 - (int32_t)remapped_phase;
21070 
21071 
21072   if (phase_delta > 0) {
21073     bin_offset = (int8_t)((phase_delta + 1024) / 2048);
21074   } else {
21075     bin_offset = (int8_t)((phase_delta - 1024) / 2048);
21076   }
21077 
21078 
21079   return bin_offset;
21080 }
21081 
21082 
21083 VL53LX_Error  VL53LX::VL53LX_f_031(
21084   VL53LX_histogram_bin_data_t   *pidata,
21085   VL53LX_histogram_bin_data_t   *podata)
21086 {
21087   VL53LX_Error status = VL53LX_ERROR_NONE;
21088 
21089   uint8_t  bin_initial_index[VL53LX_MAX_BIN_SEQUENCE_CODE + 1];
21090   uint8_t  bin_repeat_count[VL53LX_MAX_BIN_SEQUENCE_CODE + 1];
21091 
21092   uint8_t  bin_cfg        = 0;
21093   uint8_t  bin_seq_length = 0;
21094   int32_t  repeat_count   = 0;
21095 
21096   uint8_t  VL53LX_p_032       = 0;
21097   uint8_t  lc       = 0;
21098   uint8_t  i       = 0;
21099 
21100   memcpy(podata, pidata, sizeof(VL53LX_histogram_bin_data_t));
21101 
21102   podata->VL53LX_p_021 = 0;
21103 
21104   for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) {
21105     podata->bin_seq[lc] = VL53LX_MAX_BIN_SEQUENCE_CODE + 1;
21106   }
21107 
21108   for (lc = 0 ; lc < podata->VL53LX_p_020 ; lc++) {
21109     podata->bin_data[lc] = 0;
21110   }
21111 
21112 
21113 
21114 
21115   for (lc = 0 ; lc <= VL53LX_MAX_BIN_SEQUENCE_CODE ; lc++) {
21116     bin_initial_index[lc] = 0x00;
21117     bin_repeat_count[lc]  = 0x00;
21118   }
21119 
21120 
21121 
21122 
21123 
21124   bin_seq_length = 0x00;
21125 
21126   for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) {
21127 
21128     bin_cfg = pidata->bin_seq[lc];
21129 
21130 
21131     if (bin_repeat_count[bin_cfg] == 0) {
21132       bin_initial_index[bin_cfg]      = bin_seq_length * 4;
21133       podata->bin_seq[bin_seq_length] = bin_cfg;
21134       bin_seq_length++;
21135     }
21136 
21137     bin_repeat_count[bin_cfg]++;
21138 
21139 
21140     VL53LX_p_032 = bin_initial_index[bin_cfg];
21141 
21142     for (i = 0 ; i < 4 ; i++)
21143       podata->bin_data[VL53LX_p_032 + i] +=
21144         pidata->bin_data[lc * 4 + i];
21145 
21146   }
21147 
21148 
21149 
21150 
21151   for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) {
21152 
21153     bin_cfg = podata->bin_seq[lc];
21154 
21155     if (bin_cfg <= VL53LX_MAX_BIN_SEQUENCE_CODE)
21156       podata->bin_rep[lc] =
21157         bin_repeat_count[bin_cfg];
21158     else {
21159       podata->bin_rep[lc] = 0;
21160     }
21161   }
21162 
21163   podata->VL53LX_p_021 = bin_seq_length * 4;
21164 
21165 
21166   for (lc = 0 ; lc <= VL53LX_MAX_BIN_SEQUENCE_CODE ; lc++) {
21167 
21168     repeat_count = (int32_t)bin_repeat_count[lc];
21169 
21170     if (repeat_count > 0) {
21171 
21172       VL53LX_p_032 = bin_initial_index[lc];
21173 
21174       for (i = 0 ; i < 4 ; i++) {
21175         podata->bin_data[VL53LX_p_032 + i] +=
21176           (repeat_count / 2);
21177         podata->bin_data[VL53LX_p_032 + i] /=
21178           repeat_count;
21179       }
21180     }
21181   }
21182 
21183   podata->number_of_ambient_bins = 0;
21184   if ((bin_repeat_count[7] > 0) ||
21185       (bin_repeat_count[15] > 0)) {
21186     podata->number_of_ambient_bins = 4;
21187   }
21188 
21189   return status;
21190 }
21191 
21192 
21193 /* vl53lx_xtalk.c */
21194 
21195 
21196 VL53LX_Error VL53LX::VL53LX_xtalk_calibration_process_data(
21197   VL53LX_xtalk_range_results_t    *pxtalk_results,
21198   VL53LX_xtalk_histogram_data_t   *pxtalk_shape,
21199   VL53LX_xtalk_calibration_results_t  *pxtalk_cal)
21200 {
21201 
21202   VL53LX_Error status = VL53LX_ERROR_NONE;
21203 
21204   VL53LX_xtalk_algo_data_t xtalk_debug;
21205   VL53LX_xtalk_algo_data_t *pdebug      = &xtalk_debug;
21206   VL53LX_xtalk_range_data_t *pxtalk_data = NULL;
21207 
21208   VL53LX_histogram_bin_data_t avg_bins;
21209   VL53LX_histogram_bin_data_t *pavg_bins   = &avg_bins;
21210 
21211   memcpy(pavg_bins, &(pxtalk_results->central_histogram_avg),
21212          sizeof(VL53LX_histogram_bin_data_t));
21213 
21214 
21215 
21216 
21217   if (status == VL53LX_ERROR_NONE)
21218 
21219     VL53LX_init_histogram_bin_data_struct(
21220       0, 0, &(pdebug->VL53LX_p_056));
21221 
21222   if (status == VL53LX_ERROR_NONE)
21223 
21224     VL53LX_init_histogram_bin_data_struct(
21225       0, 0, &(pdebug->VL53LX_p_057));
21226 
21227 
21228 
21229 
21230 
21231 
21232   if (status == VL53LX_ERROR_NONE)
21233 
21234     status = VL53LX_f_039(
21235                pxtalk_results,
21236                pdebug,
21237                &(pxtalk_cal->algo__crosstalk_compensation_x_plane_gradient_kcps
21238                 ),
21239                &(pxtalk_cal->algo__crosstalk_compensation_y_plane_gradient_kcps
21240                 ));
21241 
21242 
21243 
21244 
21245 
21246 
21247 
21248   if (status != VL53LX_ERROR_NONE) {
21249     goto ENDFUNC;
21250   }
21251 
21252   pxtalk_data = &(pxtalk_results->VL53LX_p_003[4]);
21253 
21254   if (pxtalk_data->no_of_samples >  0) {
21255 
21256 
21257 
21258 
21259     if (status == VL53LX_ERROR_NONE) {
21260 
21261       memcpy(&(pdebug->VL53LX_p_056),
21262              pavg_bins,
21263              sizeof(VL53LX_histogram_bin_data_t));
21264     }
21265 
21266 
21267 
21268 
21269     status = VL53LX_f_040(
21270                pxtalk_data,
21271                pdebug,
21272                &(pxtalk_cal->algo__crosstalk_compensation_plane_offset_kcps));
21273 
21274 
21275 
21276 
21277     if (status == VL53LX_ERROR_NONE)
21278       status = VL53LX_f_041(
21279                  pavg_bins,
21280                  pdebug,
21281                  pxtalk_data,
21282                  pxtalk_results->central_histogram__window_start,
21283                  pxtalk_results->central_histogram__window_end,
21284                  &(pxtalk_shape->xtalk_shape));
21285 
21286   } else {
21287 
21288 
21289 
21290 
21291     pxtalk_cal->algo__crosstalk_compensation_plane_offset_kcps = 0;
21292 
21293 
21294 
21295 
21296     pdebug->VL53LX_p_058 = 0;
21297 
21298 
21299 
21300   }
21301 ENDFUNC:
21302   return status;
21303 }
21304 
21305 
21306 VL53LX_Error VL53LX::VL53LX_generate_dual_reflectance_xtalk_samples(
21307   VL53LX_xtalk_range_results_t  *pxtalk_results,
21308   uint16_t      expected_target_distance_mm,
21309   uint8_t         higher_reflectance,
21310   VL53LX_histogram_bin_data_t *pxtalk_avg_samples
21311 )
21312 {
21313 
21314   VL53LX_Error status        = VL53LX_ERROR_NONE;
21315 
21316   VL53LX_histogram_bin_data_t *pzone_avg_1   =
21317     &(pxtalk_results->histogram_avg_1[0]);
21318   VL53LX_histogram_bin_data_t *pzone_avg_2   =
21319     &(pxtalk_results->histogram_avg_2[0]);
21320 
21321   VL53LX_histogram_bin_data_t *pxtalk_output = pxtalk_avg_samples;
21322 
21323 
21324 
21325 
21326   int i = 0;
21327 
21328 
21329 
21330 
21331   for (i = 0 ; i < 5 ; i++) {
21332 
21333     if (status == VL53LX_ERROR_NONE)
21334 
21335       VL53LX_init_histogram_bin_data_struct(
21336         0, 0, pzone_avg_1);
21337 
21338     if (status == VL53LX_ERROR_NONE)
21339 
21340       VL53LX_init_histogram_bin_data_struct(
21341         0, 0, pzone_avg_2);
21342 
21343     pzone_avg_1++;
21344     pzone_avg_2++;
21345   }
21346 
21347 
21348 
21349 
21350 
21351   pzone_avg_1 = &(pxtalk_results->histogram_avg_1[0]);
21352   pzone_avg_2 = &(pxtalk_results->histogram_avg_2[0]);
21353 
21354   for (i = 0 ; i < 5 ; i++) {
21355 
21356     if (status == VL53LX_ERROR_NONE) {
21357 
21358       status = VL53LX_f_042(
21359                  pzone_avg_1,
21360                  pzone_avg_2,
21361                  expected_target_distance_mm,
21362                  0x01,
21363 
21364                  higher_reflectance,
21365                  pxtalk_output
21366                );
21367 
21368 
21369 
21370 
21371       pzone_avg_1++;
21372       pzone_avg_2++;
21373       pxtalk_output++;
21374 
21375     }
21376   }
21377 
21378   return status;
21379 }
21380 
21381 
21382 VL53LX_Error VL53LX::VL53LX_f_042(
21383   VL53LX_histogram_bin_data_t *pzone_avg_1,
21384   VL53LX_histogram_bin_data_t *pzone_avg_2,
21385   uint16_t      expected_target_distance,
21386   uint8_t       subtract_amb,
21387   uint8_t       higher_reflectance,
21388   VL53LX_histogram_bin_data_t *pxtalk_output
21389 )
21390 {
21391 
21392   VL53LX_Error status = VL53LX_ERROR_NONE;
21393 
21394   VL53LX_histogram_bin_data_t  zone_avg_realigned;
21395 
21396 
21397 
21398   SUPPRESS_UNUSED_WARNING(pxtalk_output);
21399   SUPPRESS_UNUSED_WARNING(expected_target_distance);
21400 
21401 
21402 
21403 
21404   if ((status == VL53LX_ERROR_NONE) && (subtract_amb == 0x01)) {
21405     VL53LX_f_029(
21406       pzone_avg_1,
21407       pzone_avg_1->VL53LX_p_028);
21408 
21409 
21410 
21411     pzone_avg_1->VL53LX_p_028 = 0x0;
21412   }
21413 
21414   if ((status == VL53LX_ERROR_NONE) && (subtract_amb == 0x01)) {
21415     VL53LX_f_029(
21416       pzone_avg_2,
21417       pzone_avg_2->VL53LX_p_028);
21418 
21419 
21420 
21421     pzone_avg_2->VL53LX_p_028 = 0x0;
21422   }
21423 
21424 
21425 
21426 
21427 
21428 
21429 
21430   if (status == VL53LX_ERROR_NONE) {
21431     if (higher_reflectance == 0x01) {
21432       VL53LX_f_005(
21433         pzone_avg_2,
21434         pzone_avg_1,
21435         &zone_avg_realigned);
21436     } else {
21437 
21438 
21439 
21440 
21441       VL53LX_f_005(
21442         pzone_avg_1,
21443         pzone_avg_2,
21444         &zone_avg_realigned);
21445 
21446 
21447 
21448 
21449 
21450     }
21451   }
21452 
21453   return status;
21454 }
21455 
21456 
21457 VL53LX_Error VL53LX::VL53LX_f_041(
21458   VL53LX_histogram_bin_data_t        *pavg_bins,
21459   VL53LX_xtalk_algo_data_t           *pdebug,
21460   VL53LX_xtalk_range_data_t          *pxtalk_data,
21461   uint8_t                             histogram__window_start,
21462   uint8_t                             histogram__window_end,
21463   VL53LX_xtalk_histogram_shape_t     *pxtalk_shape)
21464 {
21465 
21466   VL53LX_Error status        = VL53LX_ERROR_NONE;
21467 
21468 
21469 
21470 
21471   uint32_t ambient_thresh         = 0;
21472 
21473 
21474 
21475 
21476   if (status == VL53LX_ERROR_NONE)
21477 
21478     VL53LX_f_029(
21479       pavg_bins,
21480       pavg_bins->VL53LX_p_028);
21481 
21482 
21483 
21484 
21485   if (status == VL53LX_ERROR_NONE)
21486 
21487     VL53LX_f_043(
21488       6,
21489       pavg_bins->VL53LX_p_028,
21490       &ambient_thresh);
21491 
21492 
21493 
21494 
21495 
21496 
21497 
21498 
21499   if (status == VL53LX_ERROR_NONE)
21500 
21501     status = VL53LX_f_044(
21502                pavg_bins,
21503                ambient_thresh,
21504                histogram__window_start,
21505                histogram__window_end);
21506 
21507 
21508 
21509 
21510   if (status == VL53LX_ERROR_NONE)
21511     status =  VL53LX_f_045(
21512                 pavg_bins,
21513                 pxtalk_data,
21514                 pdebug,
21515                 pxtalk_shape);
21516 
21517 
21518   return status;
21519 
21520 }
21521 
21522 
21523 VL53LX_Error VL53LX::VL53LX_f_039(
21524   VL53LX_xtalk_range_results_t   *pxtalk_results,
21525   VL53LX_xtalk_algo_data_t       *pdebug,
21526   int16_t                        *xgradient,
21527   int16_t                        *ygradient
21528 )
21529 {
21530 
21531 
21532   VL53LX_Error status        = VL53LX_ERROR_NONE;
21533 
21534   VL53LX_xtalk_range_data_t  *presults_int = NULL;
21535 
21536   int          i                   = 0;
21537 
21538   uint32_t xtalk_per_spad[4];
21539   int32_t  VL53LX_p_059         = 0;
21540   int32_t  VL53LX_p_060         = 0;
21541 
21542   uint8_t  result_invalid          = 0;
21543 
21544 
21545 
21546   *xgradient = 0;
21547   *ygradient = 0;
21548 
21549 
21550 
21551 
21552 
21553   for (i = 0; i < 4; i++) {
21554     xtalk_per_spad[i] = 0;
21555   }
21556 
21557 
21558 
21559 
21560   for (i = 0; i < 4; i++) {
21561 
21562     if (status == VL53LX_ERROR_NONE) {
21563 
21564       presults_int = &(pxtalk_results->VL53LX_p_003[i]);
21565 
21566 
21567 
21568 
21569 
21570 
21571       if (presults_int->no_of_samples == 0) {
21572 
21573 
21574 
21575         result_invalid = 1;
21576         pdebug->VL53LX_p_061[i] = 0;
21577 
21578 
21579       } else {
21580 
21581         xtalk_per_spad[i] =
21582           presults_int->rate_per_spad_kcps_avg;
21583 
21584 
21585 
21586 
21587         pdebug->VL53LX_p_061[i] =
21588           (uint32_t)xtalk_per_spad[i];
21589 
21590       }
21591     }
21592 
21593   }
21594 
21595 
21596 
21597 
21598 
21599 
21600 
21601 
21602   if ((status == VL53LX_ERROR_NONE) && (result_invalid == 0)) {
21603 
21604 
21605 
21606 
21607     if (status == VL53LX_ERROR_NONE) {
21608 
21609       VL53LX_p_059 = ((int32_t)xtalk_per_spad[1]
21610                       - (int32_t)xtalk_per_spad[0]) / (8);
21611       VL53LX_p_060 = ((int32_t)xtalk_per_spad[3]
21612                       - (int32_t)xtalk_per_spad[2]) / (8);
21613     }
21614 
21615 
21616 
21617 
21618 
21619 
21620     if (status == VL53LX_ERROR_NONE) {
21621 
21622       if (VL53LX_p_059 < -32767) {
21623         VL53LX_p_059 = -32767;
21624       } else {
21625         if (VL53LX_p_059 > 32767) {
21626           VL53LX_p_059 = 32767;
21627         }
21628       }
21629 
21630       if (VL53LX_p_060 < -32767) {
21631         VL53LX_p_060 = -32767;
21632       } else {
21633         if (VL53LX_p_060 > 32767) {
21634           VL53LX_p_060 = 32767;
21635         }
21636       }
21637 
21638 
21639 
21640 
21641       pdebug->VL53LX_p_059 = (int16_t)VL53LX_p_059;
21642       pdebug->VL53LX_p_060 = (int16_t)VL53LX_p_060;
21643     }
21644 
21645   } else {
21646 
21647 
21648 
21649 
21650     VL53LX_p_059 = 0;
21651     VL53LX_p_060 = 0;
21652 
21653     pdebug->VL53LX_p_059 = 0;
21654     pdebug->VL53LX_p_060 = 0;
21655   }
21656 
21657 
21658 
21659 
21660   if (status == VL53LX_ERROR_NONE) {
21661     *xgradient = (int16_t)VL53LX_p_059;
21662     *ygradient = (int16_t)VL53LX_p_060;
21663   }
21664 
21665   return status;
21666 }
21667 
21668 
21669 VL53LX_Error VL53LX::VL53LX_f_040(
21670   VL53LX_xtalk_range_data_t *pxtalk_data,
21671   VL53LX_xtalk_algo_data_t  *pdebug,
21672   uint32_t                 *xtalk_mean_offset_kcps
21673 )
21674 {
21675 
21676   VL53LX_Error status        = VL53LX_ERROR_NONE;
21677 
21678   uint32_t xtalk_per_spad          = 0;
21679   uint8_t  result_invalid          = 0;
21680 
21681 
21682   *xtalk_mean_offset_kcps          = 0;
21683 
21684 
21685 
21686   if (pxtalk_data->no_of_samples == 0) {
21687 
21688 
21689 
21690 
21691     result_invalid = 1;
21692 
21693 
21694 
21695 
21696     pdebug->VL53LX_p_058 = 0;
21697 
21698   }
21699 
21700 
21701 
21702 
21703 
21704   if ((status == VL53LX_ERROR_NONE) && (result_invalid == 0)) {
21705 
21706 
21707 
21708 
21709 
21710     xtalk_per_spad = pxtalk_data->rate_per_spad_kcps_avg >> 2;
21711 
21712 
21713 
21714 
21715     pdebug->VL53LX_p_058 = xtalk_per_spad;
21716 
21717 
21718 
21719     if (xtalk_per_spad < 0x3FFFF) {
21720       *xtalk_mean_offset_kcps     = (uint32_t)xtalk_per_spad;
21721     } else {
21722       *xtalk_mean_offset_kcps     = 0x3FFFF;
21723     }
21724 
21725   } else {
21726 
21727 
21728 
21729 
21730     *xtalk_mean_offset_kcps     = 0;
21731   }
21732 
21733 
21734   return status;
21735 
21736 }
21737 
21738 
21739 
21740 VL53LX_Error VL53LX::VL53LX_f_045(
21741   VL53LX_histogram_bin_data_t *phist_data,
21742   VL53LX_xtalk_range_data_t      *pxtalk_data,
21743   VL53LX_xtalk_algo_data_t       *pdebug,
21744   VL53LX_xtalk_histogram_shape_t *pxtalk_histo
21745 )
21746 {
21747 
21748   VL53LX_Error status            = VL53LX_ERROR_NONE;
21749 
21750   int          i                 = 0;
21751   uint64_t     bin_data[VL53LX_XTALK_HISTO_BINS];
21752 
21753   pxtalk_histo->VL53LX_p_020             =
21754     phist_data->VL53LX_p_020;
21755   pxtalk_histo->cal_config__vcsel_start =
21756     phist_data->cal_config__vcsel_start;
21757   pxtalk_histo->VL53LX_p_015     =
21758     phist_data->VL53LX_p_015;
21759   pxtalk_histo->VL53LX_p_019               =
21760     phist_data->VL53LX_p_019;
21761   pxtalk_histo->time_stamp              =
21762     phist_data->time_stamp;
21763   pxtalk_histo->vcsel_width             =
21764     phist_data->vcsel_width;
21765   pxtalk_histo->zero_distance_phase     =
21766     phist_data->zero_distance_phase;
21767   pxtalk_histo->zone_id                 =
21768     phist_data->zone_id;
21769   pxtalk_histo->VL53LX_p_021          =
21770     VL53LX_XTALK_HISTO_BINS;
21771   pxtalk_histo->phasecal_result__reference_phase =
21772     phist_data->phasecal_result__reference_phase;
21773   pxtalk_histo->phasecal_result__vcsel_start     =
21774     phist_data->phasecal_result__vcsel_start;
21775 
21776 
21777 
21778 
21779 
21780   memcpy(&(pdebug->VL53LX_p_057),
21781          phist_data, sizeof(VL53LX_histogram_bin_data_t));
21782 
21783 
21784 
21785 
21786 
21787 
21788 
21789 
21790 
21791 
21792   for (i = 0; i < pxtalk_histo->VL53LX_p_021; i++) {
21793     if (phist_data->bin_data[i +
21794                                phist_data->number_of_ambient_bins] > 0) {
21795       bin_data[i] =
21796         (((uint64_t)phist_data->bin_data[i +
21797                                            phist_data->number_of_ambient_bins] << 10)
21798          + ((uint64_t)pxtalk_data->signal_total_events_avg
21799             / 2))
21800         / (uint64_t)pxtalk_data->signal_total_events_avg;
21801     } else {
21802       bin_data[i] = 0;
21803     }
21804   }
21805 
21806 
21807 
21808 
21809 
21810   for (i = 0; i < VL53LX_XTALK_HISTO_BINS; i++) {
21811     pxtalk_histo->bin_data[i] = (uint32_t)bin_data[i];
21812   }
21813 
21814 
21815 
21816 
21817   for (i = 0; i < pxtalk_histo->VL53LX_p_021; i++) {
21818     pdebug->VL53LX_p_062[i] = pxtalk_histo->bin_data[i];
21819   }
21820 
21821 
21822 
21823   return status;
21824 
21825 }
21826 
21827 
21828 
21829 VL53LX_Error VL53LX::VL53LX_f_046(
21830   VL53LX_customer_nvm_managed_t *pcustomer,
21831   VL53LX_dynamic_config_t       *pdyn_cfg,
21832   VL53LX_xtalk_histogram_data_t *pxtalk_shape,
21833   VL53LX_histogram_bin_data_t   *pip_hist_data,
21834   VL53LX_histogram_bin_data_t   *pop_hist_data,
21835   VL53LX_histogram_bin_data_t   *pxtalk_count_data)
21836 {
21837 
21838 
21839 
21840 
21841 
21842 
21843 
21844   VL53LX_Error status = VL53LX_ERROR_NONE;
21845 
21846 
21847 
21848 
21849   uint32_t xtalk_rate_kcps = 0;
21850 
21851 
21852 
21853   memcpy(pop_hist_data, pip_hist_data,
21854          sizeof(VL53LX_histogram_bin_data_t));
21855 
21856 
21857 
21858 
21859   status =
21860     VL53LX_f_032(
21861       pcustomer->algo__crosstalk_compensation_plane_offset_kcps,
21862       pcustomer->algo__crosstalk_compensation_x_plane_gradient_kcps,
21863       pcustomer->algo__crosstalk_compensation_y_plane_gradient_kcps,
21864       0,
21865 
21866       0,
21867 
21868       pip_hist_data->result__dss_actual_effective_spads,
21869 
21870 
21871       pdyn_cfg->roi_config__user_roi_centre_spad,
21872       pdyn_cfg->roi_config__user_roi_requested_global_xy_size,
21873       &(xtalk_rate_kcps));
21874 
21875 
21876 
21877 
21878   if (status == VL53LX_ERROR_NONE)
21879     status =
21880       VL53LX_f_033(
21881         pip_hist_data,
21882         &(pxtalk_shape->xtalk_shape),
21883         xtalk_rate_kcps,
21884         pxtalk_count_data);
21885 
21886 
21887 
21888 
21889   if (status == VL53LX_ERROR_NONE)
21890     status =
21891       VL53LX_f_047(
21892         pop_hist_data,
21893         pxtalk_count_data,
21894         pip_hist_data->number_of_ambient_bins);
21895 
21896   return status;
21897 }
21898 
21899 
21900 VL53LX_Error VL53LX::VL53LX_f_032(
21901   uint32_t                       mean_offset,
21902   int16_t                        xgradient,
21903   int16_t                        ygradient,
21904   int8_t                         centre_offset_x,
21905   int8_t                         centre_offset_y,
21906   uint16_t                       roi_effective_spads,
21907   uint8_t                        roi_centre_spad,
21908   uint8_t                        roi_xy_size,
21909   uint32_t                      *xtalk_rate_kcps
21910 )
21911 {
21912 
21913 
21914 
21915 
21916 
21917 
21918 
21919   VL53LX_Error status = VL53LX_ERROR_NONE;
21920 
21921   uint8_t row = 0;
21922   uint8_t col = 0;
21923 
21924 
21925 
21926 
21927   int16_t  bound_l_x = 0;
21928 
21929   int16_t  bound_r_x = 0;
21930 
21931   int16_t  bound_u_y = 0;
21932 
21933   int16_t  bound_d_y = 0;
21934 
21935 
21936   int64_t xtalk_rate_ll = 0;
21937 
21938   int64_t xtalk_rate_ur = 0;
21939 
21940 
21941   int64_t xtalk_avg = 0;
21942 
21943   SUPPRESS_UNUSED_WARNING(roi_effective_spads);
21944 
21945 
21946 
21947   if (status == VL53LX_ERROR_NONE) {
21948 
21949     VL53LX_decode_row_col(
21950       roi_centre_spad,
21951       &row,
21952       &col);
21953   }
21954 
21955 
21956   if (status == VL53LX_ERROR_NONE) {
21957 
21958     if ((((int16_t)roi_xy_size / 16) & 0x01) == 1)
21959       bound_l_x = (int16_t) col -
21960                   (((int16_t)roi_xy_size / 32) + 1);
21961     else
21962       bound_l_x = (int16_t) col -
21963                   ((int16_t)roi_xy_size / 32);
21964 
21965     bound_r_x = (int16_t) col + ((int16_t)roi_xy_size / 32);
21966 
21967     if ((((int16_t)roi_xy_size) & 0x01) == 1)
21968       bound_d_y = (int16_t) row -
21969                   ((((int16_t)roi_xy_size & 0x0f) / 2) + 1);
21970     else
21971       bound_d_y = (int16_t) row -
21972                   (((int16_t)roi_xy_size & 0x0f) / 2);
21973 
21974     bound_u_y = (int16_t) row +
21975                 (((int16_t)roi_xy_size & 0xf) / 2);
21976   }
21977 
21978 
21979   if (status == VL53LX_ERROR_NONE) {
21980 
21981     bound_l_x = (2 * bound_l_x) - 15 +
21982                 (2 * (int16_t)centre_offset_x);
21983     bound_r_x = (2 * bound_r_x) - 15 +
21984                 (2 * (int16_t)centre_offset_x);
21985     bound_u_y = (2 * bound_u_y) - 15 +
21986                 (2 * (int16_t)centre_offset_y);
21987     bound_d_y = (2 * bound_d_y) - 15 +
21988                 (2 * (int16_t)centre_offset_y);
21989   }
21990 
21991 
21992 
21993 
21994   if (status == VL53LX_ERROR_NONE) {
21995 
21996     xtalk_rate_ll  = ((int64_t)bound_l_x *
21997                       ((int64_t)xgradient)) + ((int64_t)bound_d_y *
21998                                                ((int64_t)ygradient));
21999     xtalk_rate_ll  = (xtalk_rate_ll + 1) / 2;
22000 
22001     xtalk_rate_ll += ((int64_t)mean_offset * 4);
22002 
22003     xtalk_rate_ur  = ((int64_t)bound_r_x *
22004                       ((int64_t)xgradient)) + ((int64_t)bound_u_y *
22005                                                ((int64_t)ygradient));
22006     xtalk_rate_ur  = (xtalk_rate_ur + 1) / 2;
22007 
22008     xtalk_rate_ur += ((int64_t)mean_offset * 4);
22009   }
22010 
22011 
22012   if (status == VL53LX_ERROR_NONE)
22013 
22014   {
22015     xtalk_avg = ((xtalk_rate_ll + xtalk_rate_ur) + 1) / 2;
22016   }
22017 
22018 
22019 
22020   if (status == VL53LX_ERROR_NONE)
22021 
22022     if (xtalk_avg < 0) {
22023       xtalk_avg = 0;
22024     }
22025 
22026   *xtalk_rate_kcps = (uint32_t) xtalk_avg;
22027 
22028   return status;
22029 }
22030 
22031 
22032 
22033 VL53LX_Error VL53LX::VL53LX_f_033(
22034   VL53LX_histogram_bin_data_t    *phist_data,
22035   VL53LX_xtalk_histogram_shape_t *pxtalk_data,
22036   uint32_t                        xtalk_rate_kcps,
22037   VL53LX_histogram_bin_data_t    *pxtalkcount_data
22038 )
22039 {
22040 
22041   VL53LX_Error status              = VL53LX_ERROR_NONE;
22042 
22043   uint64_t xtalk_events_per_spad = 0;
22044   uint64_t xtalk_total_events = 0;
22045   uint64_t xtalk_temp_bin = 0;
22046 
22047   uint8_t  i = 0;
22048 
22049   xtalk_events_per_spad = ((((uint64_t)xtalk_rate_kcps *
22050                              (uint64_t)phist_data->peak_duration_us) + 500) / 1000);
22051 
22052   xtalk_total_events = xtalk_events_per_spad *
22053                        (uint64_t)phist_data->result__dss_actual_effective_spads;
22054 
22055 
22056   xtalk_total_events = (xtalk_total_events)  / 256;
22057 
22058 
22059   xtalk_total_events = (xtalk_total_events + 1024) / 2048;
22060 
22061 
22062   if (xtalk_total_events > 0xFFFFFFFF) {
22063     xtalk_total_events = 0xFFFFFFFF;
22064   }
22065 
22066   for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) {
22067     xtalk_temp_bin = (uint64_t)pxtalk_data->bin_data[i] *
22068                      (uint64_t)xtalk_total_events;
22069     xtalk_temp_bin = (xtalk_temp_bin + 512) / 1024;
22070 
22071     pxtalkcount_data->bin_data[i] = (uint32_t)xtalk_temp_bin;
22072 
22073   }
22074 
22075 
22076   return status;
22077 }
22078 
22079 
22080 VL53LX_Error VL53LX::VL53LX_f_047(
22081   VL53LX_histogram_bin_data_t *phist_data,
22082   VL53LX_histogram_bin_data_t *pxtalk_data,
22083   uint8_t         xtalk_bin_offset)
22084 {
22085 
22086   VL53LX_Error status = VL53LX_ERROR_NONE;
22087 
22088   uint8_t  i = 0;
22089 
22090   int32_t  temp_bin;
22091 
22092   if (status == VL53LX_ERROR_NONE)
22093 
22094     for (i = xtalk_bin_offset;
22095          i < pxtalk_data->VL53LX_p_021; i++) {
22096 
22097 
22098       temp_bin = (int32_t)phist_data->bin_data[i] -
22099                  (int32_t)pxtalk_data->bin_data[i - xtalk_bin_offset];
22100 
22101       if (temp_bin < 0) {
22102         temp_bin = 0;
22103       }
22104 
22105       phist_data->bin_data[i] = (uint32_t)temp_bin;
22106     }
22107 
22108 
22109   return status;
22110 }
22111 
22112 
22113 VL53LX_Error VL53LX::VL53LX_f_044(
22114   VL53LX_histogram_bin_data_t   *pxtalk_data,
22115   uint32_t            amb_threshold,
22116   uint8_t           VL53LX_p_019,
22117   uint8_t           VL53LX_p_024)
22118 {
22119 
22120   VL53LX_Error status = VL53LX_ERROR_NONE;
22121 
22122   uint8_t i = 0;
22123   uint8_t first_bin_int = 0;
22124   uint8_t first_bin_inc = 0;
22125   uint8_t last_bin_int  = 0;
22126   uint8_t realign_bin   = 0;
22127   uint8_t realign_index = 0;
22128   int32_t realign_bin_data[VL53LX_HISTOGRAM_BUFFER_SIZE];
22129 
22130 
22131   for (i = 0 ; i < VL53LX_HISTOGRAM_BUFFER_SIZE ; i++) {
22132     realign_bin_data[i] = 0;
22133   }
22134 
22135   first_bin_int = VL53LX_p_019;
22136   last_bin_int  = VL53LX_p_024;
22137 
22138   VL53LX_hist_remove_ambient_bins(pxtalk_data);
22139 
22140   first_bin_int = (first_bin_int) %
22141                   pxtalk_data->VL53LX_p_021;
22142 
22143   last_bin_int = (last_bin_int) %
22144                  pxtalk_data->VL53LX_p_021;
22145 
22146   first_bin_inc = (first_bin_int + 1) % pxtalk_data->VL53LX_p_021;
22147 
22148   if (first_bin_inc > last_bin_int) {
22149 
22150 
22151 
22152     realign_bin = pxtalk_data->VL53LX_p_021 - first_bin_inc;
22153 
22154 
22155 
22156     first_bin_int = (first_bin_int + realign_bin) %
22157                     pxtalk_data->VL53LX_p_021;
22158     last_bin_int = (last_bin_int + realign_bin) %
22159                    pxtalk_data->VL53LX_p_021;
22160 
22161 
22162 
22163     pxtalk_data->zero_distance_phase =
22164       pxtalk_data->zero_distance_phase +
22165       ((uint16_t)realign_bin * 2048);
22166   }
22167 
22168   if (realign_bin > 0) {
22169 
22170 
22171     for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) {
22172       realign_bin_data[i] = pxtalk_data->bin_data[i];
22173     }
22174 
22175 
22176 
22177     for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) {
22178       realign_index = (pxtalk_data->VL53LX_p_021 -
22179                        realign_bin + i)
22180                       % pxtalk_data->VL53LX_p_021;
22181 
22182       pxtalk_data->bin_data[i] =
22183         realign_bin_data[realign_index];
22184     }
22185   }
22186 
22187 
22188   for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) {
22189 
22190 
22191     if (first_bin_int <= last_bin_int) {
22192       if ((i >= first_bin_int) && (i <= last_bin_int)) {
22193         if (pxtalk_data->bin_data[i] <
22194             (int32_t)amb_threshold) {
22195           pxtalk_data->bin_data[i] = 0;
22196         }
22197       } else {
22198         pxtalk_data->bin_data[i] = 0;
22199       }
22200     } else {
22201       if ((i >= first_bin_int) || (i <= last_bin_int)) {
22202         if (pxtalk_data->bin_data[i] <
22203             (int32_t)amb_threshold) {
22204           pxtalk_data->bin_data[i] = 0;
22205         }
22206       } else {
22207         pxtalk_data->bin_data[i] = 0;
22208       }
22209     }
22210   }
22211 
22212 
22213   return status;
22214 }
22215 
22216 VL53LX_Error VL53LX::VL53LX_f_043(
22217   uint8_t                      sigma_mult,
22218   int32_t                      VL53LX_p_028,
22219   uint32_t                    *ambient_noise)
22220 {
22221 
22222   VL53LX_Error status              = VL53LX_ERROR_NONE;
22223 
22224   uint32_t ambient_events_per_bin_int = 0;
22225 
22226   if (VL53LX_p_028 <= 0) {
22227     ambient_events_per_bin_int = 1;
22228   } else {
22229     ambient_events_per_bin_int = (uint32_t)VL53LX_p_028;
22230   }
22231 
22232   *ambient_noise =  VL53LX_isqrt(ambient_events_per_bin_int);
22233 
22234   *ambient_noise = *ambient_noise * (uint32_t)sigma_mult;
22235 
22236   return status;
22237 }
22238 
22239 /* vl53lx_sigma_estimate.c */
22240 
22241 
22242 uint16_t  VL53LX::VL53LX_f_034(
22243   uint8_t  sigma_estimator__effective_pulse_width_ns,
22244   uint8_t  sigma_estimator__effective_ambient_width_ns,
22245   uint8_t  sigma_estimator__sigma_ref_mm,
22246   VL53LX_range_data_t *pdata)
22247 {
22248   uint16_t    sigma_est  = VL53LX_D_002;
22249 
22250   uint32_t    tmp0 = 0;
22251   uint32_t    tmp1 = 0;
22252   uint32_t    tmp2 = 0;
22253 
22254   uint32_t    sigma_est__rtn_array  = 0;
22255   uint32_t    sigma_est__ref_array  = 0;
22256 
22257   if (pdata->peak_signal_count_rate_mcps  > 0 &&
22258       pdata->VL53LX_p_010 > 0) {
22259 
22260     tmp0 =  100 *
22261             (uint32_t)sigma_estimator__effective_pulse_width_ns;
22262 
22263     tmp1 = ((uint32_t)sigma_estimator__effective_pulse_width_ns *
22264             100 *
22265             (uint32_t)sigma_estimator__effective_ambient_width_ns);
22266 
22267     tmp1 = (tmp1 +
22268             (uint32_t)pdata->peak_signal_count_rate_mcps / 2) /
22269            (uint32_t)pdata->peak_signal_count_rate_mcps;
22270 
22271     sigma_est__rtn_array =
22272       VL53LX_f_035(tmp0, tmp1);
22273 
22274     sigma_est__rtn_array =
22275       ((VL53LX_SPEED_OF_LIGHT_IN_AIR + 1000) / 2000) *
22276       sigma_est__rtn_array;
22277 
22278 
22279 
22280     tmp2 =
22281       VL53LX_isqrt(12 * (uint32_t)pdata->VL53LX_p_010);
22282 
22283     if (tmp2 > 0) {
22284 
22285       sigma_est__rtn_array =
22286         (sigma_est__rtn_array + tmp2 / 2) / tmp2;
22287 
22288 
22289 
22290       sigma_est__ref_array =
22291         100 * (uint32_t)sigma_estimator__sigma_ref_mm;
22292 
22293       sigma_est =
22294         (uint16_t)VL53LX_f_035(
22295           (uint32_t)sigma_est__ref_array,
22296           sigma_est__rtn_array);
22297 
22298     } else {
22299       sigma_est = VL53LX_D_002;
22300     }
22301 
22302   }
22303 
22304   pdata->VL53LX_p_002  = sigma_est;
22305 
22306   return sigma_est;
22307 
22308 }
22309 
22310 
22311 uint16_t VL53LX::VL53LX_f_036(
22312   uint8_t  sigma_estimator__effective_pulse_width_ns,
22313   uint8_t  sigma_estimator__effective_ambient_width_ns,
22314   uint8_t  sigma_estimator__sigma_ref_mm,
22315   VL53LX_range_data_t *pdata)
22316 {
22317 
22318 
22319   uint16_t    sigma_est  = VL53LX_D_002;
22320 
22321   uint32_t    eqn7 = 0;
22322   uint32_t    sigma_est__ref_sq  = 0;
22323   uint32_t    sigma_est__rtn_sq  = 0;
22324 
22325   uint64_t    tmp0 = 0;
22326   uint64_t    tmp1 = 0;
22327 
22328 
22329   if (pdata->peak_signal_count_rate_mcps > 0 &&
22330       pdata->VL53LX_p_010         > 0) {
22331 
22332 
22333     eqn7 =  4573 * 4573;
22334     eqn7 =  eqn7 / (3 * (uint32_t)pdata->VL53LX_p_010);
22335 
22336 
22337     tmp0 = ((uint64_t)sigma_estimator__effective_pulse_width_ns)
22338            << 8;
22339 
22340 
22341 
22342     tmp1 = ((uint64_t)pdata->ambient_count_rate_mcps *
22343             (uint64_t)sigma_estimator__effective_ambient_width_ns)
22344            << 8;
22345 
22346     tmp1 = tmp1 / (uint64_t)pdata->peak_signal_count_rate_mcps;
22347 
22348 
22349     tmp1 = 16 * (uint64_t)eqn7 * (tmp0 * tmp0 + tmp1 * tmp1);
22350     tmp1 = tmp1 / (15625 * 15625);
22351     sigma_est__rtn_sq = (uint32_t)tmp1;
22352 
22353 
22354 
22355 
22356     sigma_est__ref_sq = ((uint32_t)sigma_estimator__sigma_ref_mm)
22357                         << 2;
22358 
22359     sigma_est__ref_sq = sigma_est__ref_sq * sigma_est__ref_sq;
22360 
22361 
22362 
22363 
22364     sigma_est = (uint16_t)VL53LX_isqrt(sigma_est__ref_sq +
22365                                        sigma_est__rtn_sq);
22366 
22367   }
22368 
22369   pdata->VL53LX_p_002  = sigma_est;
22370 
22371   return sigma_est;
22372 
22373 }
22374 
22375 
22376 
22377 VL53LX_Error VL53LX::VL53LX_f_037(
22378   uint8_t  sigma_estimator__sigma_ref_mm,
22379   uint32_t VL53LX_p_007,
22380   uint32_t VL53LX_p_032,
22381   uint32_t VL53LX_p_001,
22382   uint32_t a_zp,
22383   uint32_t c_zp,
22384   uint32_t bx,
22385   uint32_t ax_zp,
22386   uint32_t cx_zp,
22387   uint32_t VL53LX_p_028,
22388   uint16_t fast_osc_frequency,
22389   uint16_t *psigma_est)
22390 {
22391 
22392 
22393 
22394   VL53LX_Error status = VL53LX_ERROR_DIVISION_BY_ZERO;
22395   uint32_t sigma_int  = VL53LX_D_002;
22396 
22397   uint32_t pll_period_mm  = 0;
22398 
22399   uint64_t tmp0        = 0;
22400   uint64_t tmp1        = 0;
22401   uint64_t b_minus_amb = 0;
22402   uint64_t VL53LX_p_055   = 0;
22403 
22404   *psigma_est  = VL53LX_D_002;
22405 
22406   if (fast_osc_frequency != 0) {
22407 
22408 
22409 
22410 
22411 
22412     pll_period_mm = VL53LX_calc_pll_period_mm(fast_osc_frequency);
22413 
22414 
22415 
22416     pll_period_mm = (pll_period_mm + 0x02) >> 2;
22417 
22418 
22419 
22420 
22421     if (VL53LX_p_028 > VL53LX_p_032)
22422       b_minus_amb = (uint64_t)VL53LX_p_028 -
22423                     (uint64_t)VL53LX_p_032;
22424     else
22425       b_minus_amb = (uint64_t)VL53LX_p_032 -
22426                     (uint64_t)VL53LX_p_028;
22427 
22428 
22429 
22430 
22431     if (VL53LX_p_007 > VL53LX_p_001)
22432       VL53LX_p_055 = (uint64_t)VL53LX_p_007 -
22433                      (uint64_t)VL53LX_p_001;
22434     else
22435       VL53LX_p_055 = (uint64_t)VL53LX_p_001 -
22436                      (uint64_t)VL53LX_p_007;
22437 
22438 
22439     if (b_minus_amb != 0) {
22440 
22441 
22442 
22443       tmp0 = (uint64_t)pll_period_mm *
22444              (uint64_t)pll_period_mm;
22445       tmp0 = tmp0 * ((uint64_t)c_zp +
22446                      (uint64_t)cx_zp + (uint64_t)a_zp +
22447                      (uint64_t)ax_zp);
22448       tmp0 = (tmp0 + (b_minus_amb >> 1)) / b_minus_amb;
22449 
22450       tmp1 = (uint64_t)pll_period_mm *
22451              (uint64_t)pll_period_mm * VL53LX_p_055;
22452       tmp1 = (tmp1 + (b_minus_amb >> 1)) / b_minus_amb;
22453 
22454       tmp1 =  tmp1 * VL53LX_p_055;
22455       tmp1 = (tmp1 + (b_minus_amb >> 1)) / b_minus_amb;
22456 
22457       tmp1 =  tmp1 * ((uint64_t)VL53LX_p_032 + (uint64_t)bx +
22458                       (uint64_t)VL53LX_p_028);
22459       tmp1 = (tmp1 + (b_minus_amb >> 1)) / b_minus_amb;
22460 
22461 
22462 
22463       tmp0 = tmp0 + tmp1;
22464       tmp0 = (tmp0 + (b_minus_amb >> 1)) / b_minus_amb;
22465       tmp0 = (tmp0 + 0x01) >> 2;
22466 
22467 
22468 
22469 
22470 
22471 
22472       tmp1 = (uint64_t)sigma_estimator__sigma_ref_mm << 2;
22473       tmp1 = tmp1 * tmp1;
22474       tmp0 = tmp0 + tmp1;
22475 
22476 
22477 
22478 
22479 
22480 
22481       if (tmp0 > 0xFFFFFFFF) {
22482         tmp0 =  0xFFFFFFFF;
22483       }
22484 
22485       sigma_int = VL53LX_isqrt((uint32_t)tmp0);
22486 
22487 
22488 
22489 
22490 
22491 
22492       if (sigma_int > VL53LX_D_002)
22493         *psigma_est =
22494           (uint16_t)VL53LX_D_002;
22495       else {
22496         *psigma_est = (uint16_t)sigma_int;
22497       }
22498 
22499       status = VL53LX_ERROR_NONE;
22500     }
22501 
22502   }
22503 
22504   return status;
22505 }
22506 
22507 
22508 VL53LX_Error VL53LX::VL53LX_f_023(
22509   uint8_t  sigma_estimator__sigma_ref_mm,
22510   uint32_t VL53LX_p_007,
22511   uint32_t VL53LX_p_032,
22512   uint32_t VL53LX_p_001,
22513   uint32_t a_zp,
22514   uint32_t c_zp,
22515   uint32_t bx,
22516   uint32_t ax_zp,
22517   uint32_t cx_zp,
22518   uint32_t VL53LX_p_028,
22519   uint16_t fast_osc_frequency,
22520   uint16_t *psigma_est)
22521 {
22522 
22523   VL53LX_Error status = VL53LX_ERROR_DIVISION_BY_ZERO;
22524   uint32_t sigma_int  = VL53LX_D_002;
22525 
22526   uint32_t pll_period_mm  = 0;
22527 
22528   uint64_t tmp0        = 0;
22529   uint64_t tmp1        = 0;
22530   uint64_t b_minus_amb = 0;
22531   uint64_t VL53LX_p_055   = 0;
22532 
22533   *psigma_est  = VL53LX_D_002;
22534 
22535 
22536 
22537   if (fast_osc_frequency != 0) {
22538 
22539 
22540     pll_period_mm = VL53LX_calc_pll_period_mm(fast_osc_frequency);
22541 
22542 
22543 
22544 
22545     if (VL53LX_p_028 > VL53LX_p_032)
22546       b_minus_amb = (uint64_t)VL53LX_p_028 -
22547                     (uint64_t)VL53LX_p_032;
22548     else
22549       b_minus_amb = (uint64_t)VL53LX_p_032 -
22550                     (uint64_t)VL53LX_p_028;
22551 
22552 
22553 
22554 
22555     if (VL53LX_p_007 > VL53LX_p_001)
22556       VL53LX_p_055 = (uint64_t)VL53LX_p_007 -
22557                      (uint64_t)VL53LX_p_001;
22558     else
22559       VL53LX_p_055 = (uint64_t)VL53LX_p_001 -
22560                      (uint64_t)VL53LX_p_007;
22561 
22562 
22563 
22564 
22565     if (b_minus_amb != 0) {
22566 
22567 
22568       tmp0 = (uint64_t)VL53LX_p_032 + (uint64_t)bx +
22569              (uint64_t)VL53LX_p_028;
22570       if (tmp0 > VL53LX_D_003) {
22571         tmp0 = VL53LX_D_003;
22572       }
22573 
22574 
22575 
22576 
22577       tmp1 = (uint64_t)VL53LX_p_055 * (uint64_t)VL53LX_p_055;
22578       tmp1 = tmp1 << 8;
22579 
22580 
22581 
22582       if (tmp1 > VL53LX_D_004) {
22583         tmp1 = VL53LX_D_004;
22584       }
22585 
22586 
22587 
22588       tmp1 = tmp1 / b_minus_amb;
22589       tmp1 = tmp1 / b_minus_amb;
22590 
22591 
22592 
22593       if (tmp1 > (uint64_t)VL53LX_D_005) {
22594         tmp1 = (uint64_t)VL53LX_D_005;
22595       }
22596 
22597 
22598 
22599       tmp0 = tmp1 * tmp0;
22600 
22601 
22602 
22603 
22604 
22605       tmp1 = (uint64_t)c_zp + (uint64_t)cx_zp +
22606              (uint64_t)a_zp + (uint64_t)ax_zp;
22607 
22608 
22609 
22610       if (tmp1 > (uint64_t)VL53LX_D_003) {
22611         tmp1 = (uint64_t)VL53LX_D_003;
22612       }
22613 
22614       tmp1 = tmp1 << 8;
22615 
22616 
22617 
22618 
22619       tmp0 = tmp1 + tmp0;
22620       if (tmp0 > (uint64_t)VL53LX_D_006) {
22621         tmp0 = (uint64_t)VL53LX_D_006;
22622       }
22623 
22624       if (tmp0 > (uint64_t)VL53LX_D_007) {
22625         tmp0 = tmp0 / b_minus_amb;
22626         tmp0 = tmp0 * pll_period_mm;
22627       } else {
22628         tmp0 = tmp0 * pll_period_mm;
22629         tmp0 = tmp0 / b_minus_amb;
22630       }
22631 
22632 
22633 
22634       if (tmp0 > (uint64_t)VL53LX_D_006) {
22635         tmp0 = (uint64_t)VL53LX_D_006;
22636       }
22637 
22638 
22639 
22640 
22641       if (tmp0 > (uint64_t)VL53LX_D_007) {
22642         tmp0 = tmp0 / b_minus_amb;
22643         tmp0 = tmp0 / 4;
22644         tmp0 = tmp0 * pll_period_mm;
22645       } else {
22646         tmp0 = tmp0 * pll_period_mm;
22647         tmp0 = tmp0 / b_minus_amb;
22648         tmp0 = tmp0 / 4;
22649       }
22650 
22651 
22652 
22653       if (tmp0 > (uint64_t)VL53LX_D_006) {
22654         tmp0 = (uint64_t)VL53LX_D_006;
22655       }
22656 
22657 
22658 
22659       tmp0 = tmp0 >> 2;
22660 
22661 
22662 
22663       if (tmp0 > (uint64_t)VL53LX_D_007) {
22664         tmp0 = (uint64_t)VL53LX_D_007;
22665       }
22666 
22667 
22668 
22669       tmp1 = (uint64_t)sigma_estimator__sigma_ref_mm << 7;
22670       tmp1 = tmp1 * tmp1;
22671       tmp0 = tmp0 + tmp1;
22672 
22673 
22674 
22675       if (tmp0 > (uint64_t)VL53LX_D_007) {
22676         tmp0 = (uint64_t)VL53LX_D_007;
22677       }
22678 
22679 
22680 
22681       sigma_int = VL53LX_isqrt((uint32_t)tmp0);
22682 
22683       *psigma_est = (uint16_t)sigma_int;
22684 
22685       status = VL53LX_ERROR_NONE;
22686     }
22687 
22688   }
22689 
22690   return status;
22691 }
22692 
22693 
22694 uint32_t VL53LX::VL53LX_f_038(
22695   uint64_t VL53LX_p_007,
22696   uint32_t size
22697 )
22698 {
22699 
22700   uint64_t next;
22701   uint64_t upper;
22702   uint64_t lower;
22703   uint32_t stepsize;
22704   uint32_t count;
22705 
22706 
22707   next = VL53LX_p_007;
22708   upper = 0;
22709   lower = 0;
22710   stepsize = size / 2;
22711   count = 0;
22712 
22713   while (1) {
22714     upper = next >> stepsize;
22715     lower = next & ((1 << stepsize) - 1);
22716 
22717     if (upper != 0) {
22718       count += stepsize;
22719       next = upper;
22720     } else {
22721       next = lower;
22722     }
22723 
22724     stepsize = stepsize / 2;
22725     if (stepsize == 0) {
22726       break;
22727     }
22728   }
22729 
22730   return count;
22731 }
22732 
22733 
22734 uint32_t VL53LX::VL53LX_f_035(
22735   uint32_t VL53LX_p_007,
22736   uint32_t VL53LX_p_032)
22737 {
22738 
22739   uint32_t  res = 0;
22740 
22741   if (VL53LX_p_007 > 65535 || VL53LX_p_032 > 65535) {
22742     res = 65535;
22743   } else
22744     res = VL53LX_isqrt(VL53LX_p_007 * VL53LX_p_007 +
22745                        VL53LX_p_032 * VL53LX_p_032);
22746 
22747   return res;
22748 }
22749 
22750 /* vl53lx_hist_algos_gen3.c */
22751 
22752 void VL53LX::VL53LX_f_003(
22753   VL53LX_hist_gen3_algo_private_data_t   *palgo)
22754 {
22755   uint8_t  lb                 = 0;
22756 
22757   palgo->VL53LX_p_020              = VL53LX_HISTOGRAM_BUFFER_SIZE;
22758   palgo->VL53LX_p_019                = 0;
22759   palgo->VL53LX_p_021           = 0;
22760   palgo->VL53LX_p_039         = 0;
22761   palgo->VL53LX_p_028   = 0;
22762   palgo->VL53LX_p_031 = 0;
22763 
22764   for (lb = palgo->VL53LX_p_019; lb < palgo->VL53LX_p_020; lb++) {
22765     palgo->VL53LX_p_040[lb]      = 0;
22766     palgo->VL53LX_p_041[lb] = 0;
22767     palgo->VL53LX_p_042[lb]     = 0;
22768     palgo->VL53LX_p_043[lb]      = 0;
22769     palgo->VL53LX_p_018[lb]     = 0;
22770   }
22771 
22772   palgo->VL53LX_p_044 = 0;
22773   palgo->VL53LX_p_045               = VL53LX_D_001;
22774   palgo->VL53LX_p_046             = 0;
22775 
22776 
22777 
22778 
22779   VL53LX_init_histogram_bin_data_struct(
22780     0,
22781     VL53LX_HISTOGRAM_BUFFER_SIZE,
22782     &(palgo->VL53LX_p_006));
22783   VL53LX_init_histogram_bin_data_struct(
22784     0,
22785     VL53LX_HISTOGRAM_BUFFER_SIZE,
22786     &(palgo->VL53LX_p_047));
22787   VL53LX_init_histogram_bin_data_struct(
22788     0,
22789     VL53LX_HISTOGRAM_BUFFER_SIZE,
22790     &(palgo->VL53LX_p_048));
22791   VL53LX_init_histogram_bin_data_struct(
22792     0,
22793     VL53LX_HISTOGRAM_BUFFER_SIZE,
22794     &(palgo->VL53LX_p_049));
22795   VL53LX_init_histogram_bin_data_struct(
22796     0,
22797     VL53LX_HISTOGRAM_BUFFER_SIZE,
22798     &(palgo->VL53LX_p_050));
22799 }
22800 
22801 
22802 VL53LX_Error VL53LX::VL53LX_f_004(
22803   VL53LX_dmax_calibration_data_t         *pdmax_cal,
22804   VL53LX_hist_gen3_dmax_config_t         *pdmax_cfg,
22805   VL53LX_hist_post_process_config_t      *ppost_cfg,
22806   VL53LX_histogram_bin_data_t            *pbins_input,
22807   VL53LX_histogram_bin_data_t            *pxtalk,
22808   VL53LX_hist_gen3_algo_private_data_t   *palgo,
22809   VL53LX_hist_gen3_dmax_private_data_t   *pdmax_algo,
22810   VL53LX_range_results_t                 *presults)
22811 {
22812 
22813 
22814 
22815 
22816 
22817   VL53LX_Error  status  = VL53LX_ERROR_NONE;
22818 
22819   VL53LX_hist_pulse_data_t     *ppulse_data;
22820   VL53LX_range_data_t          *prange_data;
22821 
22822   uint8_t                       p = 0;
22823 
22824   VL53LX_f_003(palgo);
22825 
22826 
22827 
22828 
22829 
22830 
22831   memcpy(
22832     &(palgo->VL53LX_p_006),
22833     pbins_input,
22834     sizeof(VL53LX_histogram_bin_data_t));
22835 
22836 
22837 
22838 
22839 
22840 
22841   presults->cfg_device_state = pbins_input->cfg_device_state;
22842   presults->rd_device_state  = pbins_input->rd_device_state;
22843   presults->zone_id          = pbins_input->zone_id;
22844   presults->stream_count     = pbins_input->result__stream_count;
22845   presults->wrap_dmax_mm     = 0;
22846   presults->max_results      = VL53LX_MAX_RANGE_RESULTS;
22847   presults->active_results   = 0;
22848 
22849   for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) {
22850     presults->VL53LX_p_022[p] = 0;
22851   }
22852 
22853 
22854 
22855 
22856   VL53LX_hist_calc_zero_distance_phase(&(palgo->VL53LX_p_006));
22857 
22858 
22859 
22860 
22861 
22862 
22863   if (ppost_cfg->hist_amb_est_method ==
22864       VL53LX_HIST_AMB_EST_METHOD__THRESHOLDED_BINS) {
22865     VL53LX_hist_estimate_ambient_from_thresholded_bins(
22866       (int32_t)ppost_cfg->ambient_thresh_sigma0,
22867       &(palgo->VL53LX_p_006));
22868   } else {
22869     VL53LX_hist_estimate_ambient_from_ambient_bins(
22870       &(palgo->VL53LX_p_006));
22871   }
22872 
22873 
22874 
22875 
22876 
22877   VL53LX_hist_remove_ambient_bins(&(palgo->VL53LX_p_006));
22878 
22879 
22880 
22881 
22882 
22883   if (ppost_cfg->algo__crosstalk_compensation_enable > 0) {
22884     VL53LX_f_005(
22885       pxtalk,
22886       &(palgo->VL53LX_p_006),
22887       &(palgo->VL53LX_p_047));
22888   }
22889 
22890 
22891 
22892 
22893 
22894 
22895   pdmax_cfg->ambient_thresh_sigma =
22896     ppost_cfg->ambient_thresh_sigma1;
22897 
22898   for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) {
22899     if (status == VL53LX_ERROR_NONE) {
22900 
22901       status =
22902         VL53LX_f_001(
22903           pdmax_cfg->target_reflectance_for_dmax_calc[p],
22904           pdmax_cal,
22905           pdmax_cfg,
22906           &(palgo->VL53LX_p_006),
22907           pdmax_algo,
22908           &(presults->VL53LX_p_022[p]));
22909     }
22910   }
22911 
22912 
22913 
22914 
22915 
22916 
22917 
22918 
22919 
22920   if (status == VL53LX_ERROR_NONE)
22921     status =
22922       VL53LX_f_006(
22923         ppost_cfg->ambient_thresh_events_scaler,
22924         (int32_t)ppost_cfg->ambient_thresh_sigma1,
22925         (int32_t)ppost_cfg->min_ambient_thresh_events,
22926         ppost_cfg->algo__crosstalk_compensation_enable,
22927         &(palgo->VL53LX_p_006),
22928         &(palgo->VL53LX_p_047),
22929         palgo);
22930 
22931 
22932 
22933 
22934 
22935 
22936 
22937 
22938 
22939   if (status == VL53LX_ERROR_NONE)
22940     status =
22941       VL53LX_f_007(palgo);
22942 
22943 
22944 
22945 
22946 
22947 
22948   if (status == VL53LX_ERROR_NONE)
22949     status =
22950       VL53LX_f_008(palgo);
22951 
22952 
22953 
22954 
22955 
22956 
22957   if (status == VL53LX_ERROR_NONE)
22958     status =
22959       VL53LX_f_009(palgo);
22960 
22961 
22962 
22963 
22964 
22965 
22966 
22967   for (p = 0; p < palgo->VL53LX_p_046; p++) {
22968 
22969     ppulse_data = &(palgo->VL53LX_p_003[p]);
22970 
22971 
22972 
22973 
22974     if (status == VL53LX_ERROR_NONE) {
22975       status =
22976         VL53LX_f_010(
22977           p,
22978           &(palgo->VL53LX_p_006),
22979           palgo);
22980     }
22981 
22982 
22983 
22984 
22985     if (status == VL53LX_ERROR_NONE) {
22986       status =
22987         VL53LX_f_011(
22988           p,
22989           &(palgo->VL53LX_p_006),
22990           palgo,
22991           palgo->VL53LX_p_006.VL53LX_p_028,
22992           &(palgo->VL53LX_p_048));
22993     }
22994 
22995 
22996 
22997 
22998     if (status == VL53LX_ERROR_NONE) {
22999       status =
23000         VL53LX_f_011(
23001           p,
23002           &(palgo->VL53LX_p_006),
23003           palgo,
23004           0,
23005           &(palgo->VL53LX_p_049));
23006     }
23007 
23008 
23009 
23010 
23011     if (status == VL53LX_ERROR_NONE) {
23012       status =
23013         VL53LX_f_011(
23014           p,
23015           &(palgo->VL53LX_p_047),
23016           palgo,
23017           0,
23018           &(palgo->VL53LX_p_050));
23019     }
23020 
23021 
23022 
23023 
23024     if (status == VL53LX_ERROR_NONE) {
23025       status =
23026         VL53LX_f_012(
23027           p,
23028           &(palgo->VL53LX_p_048),
23029           palgo);
23030     }
23031 
23032 
23033 
23034 
23035     if (status == VL53LX_ERROR_NONE) {
23036       status =
23037         VL53LX_f_013(
23038           p,
23039           ppost_cfg->noise_threshold,
23040           palgo);
23041     }
23042 
23043     if (status == VL53LX_ERROR_NONE) {
23044       status =
23045         VL53LX_f_014(
23046           ppulse_data->VL53LX_p_023,
23047           ppost_cfg->sigma_estimator__sigma_ref_mm,
23048           palgo->VL53LX_p_030,
23049           ppulse_data->VL53LX_p_051,
23050           ppost_cfg->algo__crosstalk_compensation_enable,
23051           &(palgo->VL53LX_p_048),
23052           &(palgo->VL53LX_p_049),
23053           &(palgo->VL53LX_p_050),
23054           &(ppulse_data->VL53LX_p_002));
23055     }
23056 
23057 
23058 
23059 
23060 
23061 
23062 
23063 
23064 
23065     if (status == VL53LX_ERROR_NONE)
23066       status =
23067         VL53LX_f_015(
23068           p,
23069           1,
23070           &(palgo->VL53LX_p_006),
23071           palgo);
23072 
23073   }
23074 
23075 
23076 
23077 
23078 
23079 
23080   if (status == VL53LX_ERROR_NONE)
23081     status =
23082       VL53LX_f_016(
23083         ppost_cfg->hist_target_order,
23084         palgo);
23085 
23086 
23087 
23088 
23089 
23090 
23091   for (p = 0; p < palgo->VL53LX_p_046; p++) {
23092 
23093     ppulse_data = &(palgo->VL53LX_p_003[p]);
23094 
23095 
23096 
23097     if (!(presults->active_results < presults->max_results)) {
23098       continue;
23099     }
23100 
23101 
23102 
23103 
23104 
23105 
23106     if (!(ppulse_data->VL53LX_p_010 >
23107           ppost_cfg->signal_total_events_limit &&
23108           ppulse_data->VL53LX_p_023 < 0xFF)) {
23109       continue;
23110     }
23111 
23112     prange_data =
23113       &(presults->VL53LX_p_003[presults->active_results]);
23114 
23115     if (status == VL53LX_ERROR_NONE)
23116       VL53LX_f_017(
23117         presults->active_results,
23118         ppost_cfg->valid_phase_low,
23119         ppost_cfg->valid_phase_high,
23120         ppost_cfg->sigma_thresh,
23121         &(palgo->VL53LX_p_006),
23122         ppulse_data,
23123         prange_data);
23124 
23125 
23126     if (status == VL53LX_ERROR_NONE)
23127       status =
23128         VL53LX_f_018(
23129           palgo->VL53LX_p_006.vcsel_width,
23130           palgo->VL53LX_p_006.VL53LX_p_015,
23131           palgo->VL53LX_p_006.total_periods_elapsed,
23132           palgo->VL53LX_p_006.result__dss_actual_effective_spads,
23133           prange_data);
23134 
23135 
23136     if (status == VL53LX_ERROR_NONE)
23137       VL53LX_f_019(
23138         ppost_cfg->gain_factor,
23139         ppost_cfg->range_offset_mm,
23140         prange_data);
23141 
23142     presults->active_results++;
23143 
23144 
23145   }
23146 
23147 
23148   return status;
23149 }
23150 
23151 
23152 VL53LX_Error VL53LX::VL53LX_f_006(
23153   uint16_t                          ambient_threshold_events_scaler,
23154   int32_t                           ambient_threshold_sigma,
23155   int32_t                           min_ambient_threshold_events,
23156   uint8_t                           algo__crosstalk_compensation_enable,
23157   VL53LX_histogram_bin_data_t           *pbins,
23158   VL53LX_histogram_bin_data_t           *pxtalk,
23159   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23160 {
23161 
23162 
23163 
23164   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23165   uint8_t  lb            = 0;
23166   uint8_t  VL53LX_p_001            = 0;
23167   int64_t  tmp          = 0;
23168   int32_t  amb_events   = 0;
23169   int32_t  VL53LX_p_018       = 0;
23170   int32_t  samples      = 0;
23171 
23172   palgo->VL53LX_p_020            = pbins->VL53LX_p_020;
23173   palgo->VL53LX_p_019              = pbins->VL53LX_p_019;
23174   palgo->VL53LX_p_021         = pbins->VL53LX_p_021;
23175   palgo->VL53LX_p_028 = pbins->VL53LX_p_028;
23176 
23177 
23178 
23179 
23180 
23181 
23182   palgo->VL53LX_p_030 =
23183     VL53LX_decode_vcsel_period(pbins->VL53LX_p_005);
23184 
23185   tmp  = (int64_t)pbins->VL53LX_p_028;
23186   tmp *= (int64_t)ambient_threshold_events_scaler;
23187   tmp += 2048;
23188   tmp = do_division_s(tmp, 4096);
23189   amb_events = (int32_t)tmp;
23190 
23191 
23192   for (lb = 0; lb < pbins->VL53LX_p_021; lb++) {
23193 
23194     VL53LX_p_001 = lb >> 2;
23195     samples = (int32_t)pbins->bin_rep[VL53LX_p_001];
23196 
23197     if (samples > 0) {
23198 
23199       if (lb < pxtalk->VL53LX_p_021 &&
23200           algo__crosstalk_compensation_enable > 0)
23201         VL53LX_p_018 = samples * (amb_events +
23202                                   pxtalk->bin_data[lb]);
23203       else {
23204         VL53LX_p_018 = samples *  amb_events;
23205       }
23206 
23207       VL53LX_p_018  = VL53LX_isqrt(VL53LX_p_018);
23208 
23209       VL53LX_p_018 += (samples / 2);
23210       VL53LX_p_018 /= samples;
23211       VL53LX_p_018 *= ambient_threshold_sigma;
23212       VL53LX_p_018 += 8;
23213       VL53LX_p_018 /= 16;
23214       VL53LX_p_018 += amb_events;
23215 
23216       if (VL53LX_p_018 < min_ambient_threshold_events) {
23217         VL53LX_p_018 = min_ambient_threshold_events;
23218       }
23219 
23220       palgo->VL53LX_p_052[lb]             = VL53LX_p_018;
23221       palgo->VL53LX_p_031 = VL53LX_p_018;
23222     }
23223 
23224   }
23225 
23226   palgo->VL53LX_p_039 = 0;
23227 
23228   for (lb = pbins->VL53LX_p_019; lb < pbins->VL53LX_p_021; lb++) {
23229 
23230     if (pbins->bin_data[lb] > palgo->VL53LX_p_052[lb]) {
23231       palgo->VL53LX_p_040[lb]      = 1;
23232       palgo->VL53LX_p_041[lb] = 1;
23233       palgo->VL53LX_p_039++;
23234     } else {
23235       palgo->VL53LX_p_040[lb]      = 0;
23236       palgo->VL53LX_p_041[lb] = 0;
23237     }
23238   }
23239 
23240 
23241 
23242   return status;
23243 
23244 }
23245 
23246 
23247 
23248 VL53LX_Error VL53LX::VL53LX_f_007(
23249   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23250 {
23251 
23252 
23253   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23254 
23255   uint8_t  i            = 0;
23256   uint8_t  j            = 0;
23257   uint8_t  found        = 0;
23258 
23259 
23260   palgo->VL53LX_p_044 = 0;
23261 
23262   for (i = 0; i < palgo->VL53LX_p_030; i++) {
23263 
23264     j = (i + 1) % palgo->VL53LX_p_030;
23265 
23266 
23267 
23268     if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) {
23269       if (palgo->VL53LX_p_041[i] == 0 &&
23270           palgo->VL53LX_p_041[j] == 1 &&
23271           found == 0) {
23272         palgo->VL53LX_p_044 = i;
23273         found = 1;
23274       }
23275     }
23276   }
23277 
23278 
23279   return status;
23280 }
23281 
23282 
23283 VL53LX_Error VL53LX::VL53LX_f_008(
23284   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23285 {
23286 
23287   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23288   uint8_t  i            = 0;
23289   uint8_t  j            = 0;
23290   uint8_t  lb            = 0;
23291 
23292 
23293 
23294   for (lb = palgo->VL53LX_p_044;
23295        lb < (palgo->VL53LX_p_044 +
23296              palgo->VL53LX_p_030);
23297        lb++) {
23298 
23299 
23300 
23301 
23302 
23303 
23304     i =  lb      % palgo->VL53LX_p_030;
23305     j = (lb + 1) % palgo->VL53LX_p_030;
23306 
23307 
23308 
23309 
23310 
23311 
23312     if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) {
23313 
23314       if (palgo->VL53LX_p_041[i] == 0 &&
23315           palgo->VL53LX_p_041[j] == 1) {
23316         palgo->VL53LX_p_046++;
23317       }
23318 
23319       if (palgo->VL53LX_p_041[i] > 0) {
23320         palgo->VL53LX_p_042[i] = palgo->VL53LX_p_046;
23321       } else {
23322         palgo->VL53LX_p_042[i] = 0;
23323       }
23324     }
23325 
23326   }
23327 
23328 
23329 
23330   if (palgo->VL53LX_p_046 > palgo->VL53LX_p_045) {
23331     palgo->VL53LX_p_046 = palgo->VL53LX_p_045;
23332   }
23333 
23334   return status;
23335 
23336 }
23337 
23338 VL53LX_Error VL53LX::VL53LX_f_009(
23339   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23340 {
23341 
23342 
23343   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23344 
23345   uint8_t  i            = 0;
23346   uint8_t  j            = 0;
23347   uint8_t  blb            = 0;
23348   uint8_t  pulse_no     = 0;
23349 
23350   uint8_t  max_filter_half_width = 0;
23351 
23352   VL53LX_hist_pulse_data_t *pdata;
23353 
23354 
23355 
23356   max_filter_half_width = palgo->VL53LX_p_030 - 1;
23357   max_filter_half_width = max_filter_half_width >> 1;
23358 
23359   for (blb = palgo->VL53LX_p_044;
23360        blb < (palgo->VL53LX_p_044 +
23361               palgo->VL53LX_p_030);
23362        blb++) {
23363 
23364 
23365 
23366 
23367 
23368 
23369     i =  blb      % palgo->VL53LX_p_030;
23370     j = (blb + 1) % palgo->VL53LX_p_030;
23371 
23372 
23373 
23374 
23375 
23376 
23377     if (i < palgo->VL53LX_p_021 &&
23378         j < palgo->VL53LX_p_021) {
23379 
23380 
23381 
23382 
23383       if (palgo->VL53LX_p_042[i] == 0 &&
23384           palgo->VL53LX_p_042[j] > 0) {
23385 
23386         pulse_no = palgo->VL53LX_p_042[j] - 1;
23387         pdata   = &(palgo->VL53LX_p_003[pulse_no]);
23388 
23389         if (pulse_no < palgo->VL53LX_p_045) {
23390           pdata->VL53LX_p_012 = blb;
23391           pdata->VL53LX_p_019    = blb + 1;
23392           pdata->VL53LX_p_023   = 0xFF;
23393 
23394           pdata->VL53LX_p_024     = 0;
23395           pdata->VL53LX_p_013   = 0;
23396         }
23397       }
23398 
23399 
23400 
23401 
23402       if (palgo->VL53LX_p_042[i] > 0
23403           && palgo->VL53LX_p_042[j] == 0) {
23404 
23405         pulse_no = palgo->VL53LX_p_042[i] - 1;
23406         pdata   = &(palgo->VL53LX_p_003[pulse_no]);
23407 
23408         if (pulse_no < palgo->VL53LX_p_045) {
23409 
23410           pdata->VL53LX_p_024    = blb;
23411           pdata->VL53LX_p_013  = blb + 1;
23412 
23413           pdata->VL53LX_p_025 =
23414             (pdata->VL53LX_p_024 + 1) -
23415             pdata->VL53LX_p_019;
23416           pdata->VL53LX_p_051 =
23417             (pdata->VL53LX_p_013 + 1) -
23418             pdata->VL53LX_p_012;
23419 
23420           if (pdata->VL53LX_p_051 >
23421               max_filter_half_width)
23422             pdata->VL53LX_p_051 =
23423               max_filter_half_width;
23424         }
23425 
23426       }
23427     }
23428   }
23429   return status;
23430 
23431 }
23432 
23433 
23434 VL53LX_Error VL53LX::VL53LX_f_016(
23435   VL53LX_HistTargetOrder                target_order,
23436   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23437 {
23438 
23439 
23440   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23441 
23442   VL53LX_hist_pulse_data_t  tmp;
23443   VL53LX_hist_pulse_data_t *ptmp = &tmp;
23444   VL53LX_hist_pulse_data_t *p0;
23445   VL53LX_hist_pulse_data_t *p1;
23446 
23447   uint8_t i       = 0;
23448   uint8_t swapped = 1;
23449 
23450   if (!(palgo->VL53LX_p_046 > 1)) {
23451     goto ENDFUNC;
23452   }
23453 
23454   while (swapped > 0) {
23455 
23456     swapped = 0;
23457 
23458     for (i = 1; i < palgo->VL53LX_p_046; i++) {
23459 
23460       p0 = &(palgo->VL53LX_p_003[i - 1]);
23461       p1 = &(palgo->VL53LX_p_003[i]);
23462 
23463 
23464 
23465 
23466       if (target_order
23467           == VL53LX_HIST_TARGET_ORDER__STRONGEST_FIRST) {
23468 
23469         if (p0->VL53LX_p_010 <
23470             p1->VL53LX_p_010) {
23471 
23472 
23473 
23474 
23475           memcpy(ptmp,
23476                  p1, sizeof(VL53LX_hist_pulse_data_t));
23477           memcpy(p1,
23478                  p0, sizeof(VL53LX_hist_pulse_data_t));
23479           memcpy(p0,
23480                  ptmp, sizeof(VL53LX_hist_pulse_data_t));
23481 
23482           swapped = 1;
23483         }
23484 
23485       } else {
23486 
23487         if (p0->VL53LX_p_011 > p1->VL53LX_p_011) {
23488 
23489 
23490 
23491 
23492           memcpy(ptmp,
23493                  p1, sizeof(VL53LX_hist_pulse_data_t));
23494           memcpy(p1,
23495                  p0,   sizeof(VL53LX_hist_pulse_data_t));
23496           memcpy(p0,
23497                  ptmp, sizeof(VL53LX_hist_pulse_data_t));
23498 
23499           swapped = 1;
23500         }
23501 
23502       }
23503     }
23504   }
23505 ENDFUNC:
23506   return status;
23507 
23508 }
23509 
23510 
23511 VL53LX_Error VL53LX::VL53LX_f_010(
23512   uint8_t                                pulse_no,
23513   VL53LX_histogram_bin_data_t           *pbins,
23514   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23515 {
23516 
23517 
23518   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23519 
23520   uint8_t  i            = 0;
23521   uint8_t  lb            = 0;
23522 
23523   VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]);
23524 
23525 
23526   pdata->VL53LX_p_017  = 0;
23527   pdata->VL53LX_p_016 = 0;
23528 
23529   for (lb = pdata->VL53LX_p_012; lb <= pdata->VL53LX_p_013; lb++) {
23530     i =  lb % palgo->VL53LX_p_030;
23531     pdata->VL53LX_p_017  += pbins->bin_data[i];
23532     pdata->VL53LX_p_016 += palgo->VL53LX_p_028;
23533   }
23534 
23535 
23536   pdata->VL53LX_p_010 =
23537     pdata->VL53LX_p_017 - pdata->VL53LX_p_016;
23538 
23539   return status;
23540 }
23541 
23542 
23543 VL53LX_Error VL53LX::VL53LX_f_015(
23544   uint8_t                                pulse_no,
23545   uint8_t                                clip_events,
23546   VL53LX_histogram_bin_data_t           *pbins,
23547   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23548 {
23549 
23550 
23551   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23552 
23553   uint8_t   i            = 0;
23554   int16_t   VL53LX_p_012 = 0;
23555   int16_t   VL53LX_p_013   = 0;
23556   int16_t   window_width = 0;
23557   uint32_t  tmp_phase    = 0;
23558 
23559   VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]);
23560 
23561   i = pdata->VL53LX_p_023 % palgo->VL53LX_p_030;
23562 
23563   VL53LX_p_012  = (int16_t)i;
23564   VL53LX_p_012 += (int16_t)pdata->VL53LX_p_012;
23565   VL53LX_p_012 -= (int16_t)pdata->VL53LX_p_023;
23566 
23567   VL53LX_p_013    = (int16_t)i;
23568   VL53LX_p_013   += (int16_t)pdata->VL53LX_p_013;
23569   VL53LX_p_013   -= (int16_t)pdata->VL53LX_p_023;
23570 
23571 
23572 
23573 
23574   window_width = VL53LX_p_013 - VL53LX_p_012;
23575   if (window_width > 3) {
23576     window_width = 3;
23577   }
23578 
23579   status =
23580     VL53LX_f_020(
23581       VL53LX_p_012,
23582       VL53LX_p_012 + window_width,
23583       palgo->VL53LX_p_030,
23584       clip_events,
23585       pbins,
23586       &(pdata->VL53LX_p_026));
23587 
23588 
23589   if (status == VL53LX_ERROR_NONE)
23590     status =
23591       VL53LX_f_020(
23592         VL53LX_p_013 - window_width,
23593         VL53LX_p_013,
23594         palgo->VL53LX_p_030,
23595         clip_events,
23596         pbins,
23597         &(pdata->VL53LX_p_027));
23598 
23599 
23600 
23601 
23602 
23603   if (pdata->VL53LX_p_026 > pdata->VL53LX_p_027) {
23604     tmp_phase        = pdata->VL53LX_p_026;
23605     pdata->VL53LX_p_026 = pdata->VL53LX_p_027;
23606     pdata->VL53LX_p_027 = tmp_phase;
23607   }
23608 
23609 
23610   if (pdata->VL53LX_p_011 < pdata->VL53LX_p_026) {
23611     pdata->VL53LX_p_026 = pdata->VL53LX_p_011;
23612   }
23613 
23614   if (pdata->VL53LX_p_011 > pdata->VL53LX_p_027) {
23615     pdata->VL53LX_p_027 = pdata->VL53LX_p_011;
23616   }
23617 
23618   return status;
23619 }
23620 
23621 
23622 VL53LX_Error VL53LX::VL53LX_f_020(
23623   int16_t                            VL53LX_p_019,
23624   int16_t                            VL53LX_p_024,
23625   uint8_t                            VL53LX_p_030,
23626   uint8_t                            clip_events,
23627   VL53LX_histogram_bin_data_t       *pbins,
23628   uint32_t                          *pphase)
23629 {
23630 
23631 
23632   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23633 
23634   int16_t  i            = 0;
23635   int16_t  lb            = 0;
23636 
23637   int64_t VL53LX_p_018        = 0;
23638   int64_t event_sum     = 0;
23639   int64_t weighted_sum  = 0;
23640 
23641 
23642   *pphase = VL53LX_MAX_ALLOWED_PHASE;
23643 
23644   for (lb = VL53LX_p_019; lb <= VL53LX_p_024; lb++) {
23645 
23646 
23647 
23648     if (lb < 0) {
23649       i =  lb + (int16_t)VL53LX_p_030;
23650     } else {
23651       i =  lb % (int16_t)VL53LX_p_030;
23652     }
23653 
23654     VL53LX_p_018 =
23655       (int64_t)pbins->bin_data[i] -
23656       (int64_t)pbins->VL53LX_p_028;
23657 
23658 
23659 
23660 
23661 
23662 
23663     if (clip_events > 0 && VL53LX_p_018 < 0) {
23664       VL53LX_p_018 = 0;
23665     }
23666 
23667     event_sum += VL53LX_p_018;
23668 
23669     weighted_sum +=
23670       (VL53LX_p_018 * (1024 + (2048 * (int64_t)lb)));
23671 
23672 
23673   }
23674 
23675   if (event_sum  > 0) {
23676 
23677     weighted_sum += (event_sum / 2);
23678     weighted_sum /= event_sum;
23679 
23680     if (weighted_sum < 0) {
23681       weighted_sum = 0;
23682     }
23683 
23684     *pphase = (uint32_t)weighted_sum;
23685   }
23686 
23687   return status;
23688 }
23689 
23690 
23691 VL53LX_Error VL53LX::VL53LX_f_011(
23692   uint8_t                                pulse_no,
23693   VL53LX_histogram_bin_data_t           *pbins,
23694   VL53LX_hist_gen3_algo_private_data_t  *palgo,
23695   int32_t                                pad_value,
23696   VL53LX_histogram_bin_data_t           *ppulse)
23697 {
23698 
23699 
23700   VL53LX_Error  status  = VL53LX_ERROR_NONE;
23701 
23702   uint8_t  i            = 0;
23703   uint8_t  lb            = 0;
23704 
23705   VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]);
23706 
23707   memcpy(ppulse, pbins, sizeof(VL53LX_histogram_bin_data_t));
23708 
23709   for (lb = palgo->VL53LX_p_044;
23710        lb < (palgo->VL53LX_p_044 +
23711              palgo->VL53LX_p_030);
23712        lb++) {
23713 
23714     if (lb < pdata->VL53LX_p_012 || lb > pdata->VL53LX_p_013) {
23715       i =  lb % palgo->VL53LX_p_030;
23716       if (i < ppulse->VL53LX_p_021) {
23717         ppulse->bin_data[i] = pad_value;
23718       }
23719     }
23720   }
23721 
23722 
23723   return status;
23724 }
23725 
23726 
23727 VL53LX_Error VL53LX::VL53LX_f_012(
23728   uint8_t                                pulse_no,
23729   VL53LX_histogram_bin_data_t           *ppulse,
23730   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23731 {
23732   VL53LX_Error  status       = VL53LX_ERROR_NONE;
23733 
23734   VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]);
23735 
23736   uint8_t  lb            = 0;
23737   uint8_t  i            = 0;
23738   uint8_t  j            = 0;
23739   uint8_t  w            = 0;
23740 
23741 
23742 
23743   for (lb = pdata->VL53LX_p_012; lb <= pdata->VL53LX_p_013; lb++) {
23744 
23745     i =  lb  % palgo->VL53LX_p_030;
23746 
23747 
23748 
23749     palgo->VL53LX_p_043[i]  = 0;
23750     palgo->VL53LX_p_018[i] = 0;
23751 
23752     for (w = 0; w < (pdata->VL53LX_p_051 << 1); w++) {
23753 
23754 
23755 
23756 
23757 
23758       j = lb + w + palgo->VL53LX_p_030;
23759       j = j - pdata->VL53LX_p_051;
23760       j = j % palgo->VL53LX_p_030;
23761 
23762 
23763 
23764 
23765 
23766 
23767       if (i < ppulse->VL53LX_p_021 && j <
23768           ppulse->VL53LX_p_021) {
23769         if (w < pdata->VL53LX_p_051)
23770           palgo->VL53LX_p_043[i] +=
23771             ppulse->bin_data[j];
23772         else
23773           palgo->VL53LX_p_043[i] -=
23774             ppulse->bin_data[j];
23775       }
23776     }
23777   }
23778 
23779   return status;
23780 }
23781 
23782 
23783 VL53LX_Error VL53LX::VL53LX_f_013(
23784   uint8_t                                pulse_no,
23785   uint16_t                               noise_threshold,
23786   VL53LX_hist_gen3_algo_private_data_t  *palgo)
23787 {
23788 
23789   VL53LX_Error  status       = VL53LX_ERROR_NONE;
23790 
23791   VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]);
23792 
23793   uint8_t  lb            = 0;
23794   uint8_t  i            = 0;
23795   uint8_t  j            = 0;
23796   int32_t  bin_x_delta  = 0;
23797 
23798   for (lb = pdata->VL53LX_p_012; lb < pdata->VL53LX_p_013; lb++) {
23799 
23800     i =  lb    % palgo->VL53LX_p_030;
23801     j = (lb + 1) % palgo->VL53LX_p_030;
23802 
23803     if (i < palgo->VL53LX_p_021 &&
23804         j < palgo->VL53LX_p_021) {
23805 
23806       if (palgo->VL53LX_p_043[i] <= 0 &&
23807           palgo->VL53LX_p_043[j] > 0) {
23808 
23809 
23810 
23811 
23812 
23813         bin_x_delta = palgo->VL53LX_p_043[j] -
23814                       palgo->VL53LX_p_043[i];
23815 
23816 
23817 
23818         if (bin_x_delta >
23819             (int32_t)noise_threshold) {
23820 
23821           pdata->VL53LX_p_023 = lb;
23822 
23823           VL53LX_f_021(
23824             lb,
23825             palgo->VL53LX_p_043[i],
23826             palgo->VL53LX_p_043[j],
23827             palgo->VL53LX_p_030,
23828             &(pdata->VL53LX_p_011));
23829         }
23830       }
23831     }
23832   }
23833 
23834   return status;
23835 }
23836 
23837 
23838 VL53LX_Error VL53LX::VL53LX_f_021(
23839   uint8_t   bin,
23840   int32_t   filta0,
23841   int32_t   filta1,
23842   uint8_t   VL53LX_p_030,
23843   uint32_t *pmean_phase)
23844 {
23845 
23846   VL53LX_Error  status = VL53LX_ERROR_NONE;
23847   int32_t  mean_phase  = VL53LX_MAX_ALLOWED_PHASE;
23848   int32_t  bin_x_phase  = abs(filta0);
23849   int32_t  bin_x_delta  = filta1 - filta0;
23850 
23851 
23852   if (bin_x_delta == 0) {
23853     mean_phase = 1024;
23854   } else
23855     mean_phase  = ((bin_x_phase  * 2048) +
23856                    (bin_x_delta >> 1)) / bin_x_delta;
23857 
23858   mean_phase += (2048 * (int64_t)bin);
23859 
23860 
23861 
23862   if (mean_phase  < 0) {
23863     mean_phase = 0;
23864   }
23865 
23866   if (mean_phase > VL53LX_MAX_ALLOWED_PHASE) {
23867     mean_phase = VL53LX_MAX_ALLOWED_PHASE;
23868   }
23869 
23870 
23871 
23872   mean_phase = mean_phase % ((int32_t)VL53LX_p_030 * 2048);
23873 
23874   *pmean_phase = (uint32_t)mean_phase;
23875 
23876 
23877   return status;
23878 }
23879 
23880 
23881 VL53LX_Error VL53LX::VL53LX_f_014(
23882   uint8_t                       bin,
23883   uint8_t                       sigma_estimator__sigma_ref_mm,
23884   uint8_t                       VL53LX_p_030,
23885   uint8_t                       VL53LX_p_051,
23886   uint8_t                       crosstalk_compensation_enable,
23887   VL53LX_histogram_bin_data_t  *phist_data_ap,
23888   VL53LX_histogram_bin_data_t  *phist_data_zp,
23889   VL53LX_histogram_bin_data_t  *pxtalk_hist,
23890   uint16_t                     *psigma_est)
23891 {
23892 
23893   VL53LX_Error status      = VL53LX_ERROR_NONE;
23894   VL53LX_Error func_status = VL53LX_ERROR_NONE;
23895 
23896   uint8_t  i    = 0;
23897   int32_t  VL53LX_p_007    = 0;
23898   int32_t  VL53LX_p_032    = 0;
23899   int32_t  VL53LX_p_001    = 0;
23900   int32_t  a_zp = 0;
23901   int32_t  c_zp = 0;
23902   int32_t  ax   = 0;
23903   int32_t  bx   = 0;
23904   int32_t  cx   = 0;
23905 
23906 
23907 
23908 
23909   i = bin % VL53LX_p_030;
23910 
23911 
23912 
23913 
23914   VL53LX_f_022(
23915     i,
23916     VL53LX_p_051,
23917     phist_data_zp,
23918     &a_zp,
23919     &VL53LX_p_032,
23920     &c_zp);
23921 
23922 
23923 
23924 
23925   VL53LX_f_022(
23926     i,
23927     VL53LX_p_051,
23928     phist_data_ap,
23929     &VL53LX_p_007,
23930     &VL53LX_p_032,
23931     &VL53LX_p_001);
23932 
23933   if (crosstalk_compensation_enable > 0)
23934     VL53LX_f_022(
23935       i,
23936       VL53LX_p_051,
23937       pxtalk_hist,
23938       &ax,
23939       &bx,
23940       &cx);
23941 
23942 
23943   func_status =
23944     VL53LX_f_023(
23945       sigma_estimator__sigma_ref_mm,
23946       (uint32_t)VL53LX_p_007,
23947 
23948       (uint32_t)VL53LX_p_032,
23949 
23950       (uint32_t)VL53LX_p_001,
23951 
23952       (uint32_t)a_zp,
23953 
23954       (uint32_t)c_zp,
23955 
23956       (uint32_t)bx,
23957       (uint32_t)ax,
23958       (uint32_t)cx,
23959       (uint32_t)phist_data_ap->VL53LX_p_028,
23960       phist_data_ap->VL53LX_p_015,
23961       psigma_est);
23962 
23963 
23964   if (func_status == VL53LX_ERROR_DIVISION_BY_ZERO) {
23965     *psigma_est = 0xFFFF;
23966   }
23967 
23968 
23969   return status;
23970 }
23971 
23972 
23973 void VL53LX::VL53LX_f_017(
23974   uint8_t                      range_id,
23975   uint8_t                      valid_phase_low,
23976   uint8_t                      valid_phase_high,
23977   uint16_t                     sigma_thres,
23978   VL53LX_histogram_bin_data_t *pbins,
23979   VL53LX_hist_pulse_data_t    *ppulse,
23980   VL53LX_range_data_t         *pdata)
23981 {
23982 
23983   uint16_t  lower_phase_limit = 0;
23984   uint16_t  upper_phase_limit = 0;
23985 
23986 
23987 
23988 
23989   pdata->range_id              = range_id;
23990   pdata->time_stamp            = 0;
23991 
23992   pdata->VL53LX_p_012          = ppulse->VL53LX_p_012;
23993   pdata->VL53LX_p_019             = ppulse->VL53LX_p_019;
23994   pdata->VL53LX_p_023            = ppulse->VL53LX_p_023;
23995   pdata->VL53LX_p_024              = ppulse->VL53LX_p_024;
23996   pdata->VL53LX_p_013            = ppulse->VL53LX_p_013;
23997   pdata->VL53LX_p_025             = ppulse->VL53LX_p_025;
23998 
23999 
24000 
24001 
24002   pdata->VL53LX_p_029  =
24003     (ppulse->VL53LX_p_013 + 1) - ppulse->VL53LX_p_012;
24004 
24005 
24006 
24007 
24008   pdata->zero_distance_phase   = pbins->zero_distance_phase;
24009   pdata->VL53LX_p_002              = ppulse->VL53LX_p_002;
24010   pdata->VL53LX_p_026             = (uint16_t)ppulse->VL53LX_p_026;
24011   pdata->VL53LX_p_011          = (uint16_t)ppulse->VL53LX_p_011;
24012   pdata->VL53LX_p_027             = (uint16_t)ppulse->VL53LX_p_027;
24013   pdata->VL53LX_p_017  = (uint32_t)ppulse->VL53LX_p_017;
24014   pdata->VL53LX_p_010   = ppulse->VL53LX_p_010;
24015   pdata->VL53LX_p_016 = (uint32_t)ppulse->VL53LX_p_016;
24016   pdata->total_periods_elapsed = pbins->total_periods_elapsed;
24017 
24018 
24019 
24020 
24021   pdata->range_status = VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK;
24022 
24023 
24024 
24025   if (sigma_thres > 0 &&
24026       (uint32_t)ppulse->VL53LX_p_002 > ((uint32_t)sigma_thres << 5)) {
24027     pdata->range_status = VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK;
24028   }
24029 
24030 
24031 
24032 
24033   lower_phase_limit  = (uint8_t)valid_phase_low << 8;
24034   if (lower_phase_limit < pdata->zero_distance_phase)
24035     lower_phase_limit =
24036       pdata->zero_distance_phase -
24037       lower_phase_limit;
24038   else {
24039     lower_phase_limit  = 0;
24040   }
24041 
24042   upper_phase_limit  = (uint8_t)valid_phase_high << 8;
24043   upper_phase_limit += pbins->zero_distance_phase;
24044 
24045   if (pdata->VL53LX_p_011 < lower_phase_limit ||
24046       pdata->VL53LX_p_011 > upper_phase_limit) {
24047     pdata->range_status = VL53LX_DEVICEERROR_RANGEPHASECHECK;
24048   }
24049 
24050 }
24051 
24052 
24053 
24054 /* vl53lx_hist_algos_gen4.c */
24055 
24056 void VL53LX::VL53LX_f_024(
24057   VL53LX_hist_gen4_algo_filtered_data_t   *palgo)
24058 {
24059 
24060   uint8_t  lb                 = 0;
24061 
24062   palgo->VL53LX_p_020              = VL53LX_HISTOGRAM_BUFFER_SIZE;
24063   palgo->VL53LX_p_019                = 0;
24064   palgo->VL53LX_p_021           = 0;
24065 
24066   for (lb = palgo->VL53LX_p_019; lb < palgo->VL53LX_p_020; lb++) {
24067     palgo->VL53LX_p_007[lb]      = 0;
24068     palgo->VL53LX_p_032[lb]      = 0;
24069     palgo->VL53LX_p_001[lb]      = 0;
24070     palgo->VL53LX_p_053[lb] = 0;
24071     palgo->VL53LX_p_054[lb] = 0;
24072     palgo->VL53LX_p_040[lb]  = 0;
24073   }
24074 }
24075 VL53LX_Error VL53LX::VL53LX_f_025(
24076   VL53LX_dmax_calibration_data_t         *pdmax_cal,
24077   VL53LX_hist_gen3_dmax_config_t         *pdmax_cfg,
24078   VL53LX_hist_post_process_config_t      *ppost_cfg,
24079   VL53LX_histogram_bin_data_t            *pbins_input,
24080   VL53LX_histogram_bin_data_t            *pxtalk,
24081   VL53LX_hist_gen3_algo_private_data_t   *palgo3,
24082   VL53LX_hist_gen4_algo_filtered_data_t  *pfiltered,
24083   VL53LX_hist_gen3_dmax_private_data_t   *pdmax_algo,
24084   VL53LX_range_results_t                 *presults)
24085 {
24086   VL53LX_Error  status  = VL53LX_ERROR_NONE;
24087 
24088   VL53LX_hist_pulse_data_t     *ppulse_data;
24089   VL53LX_range_data_t          *prange_data;
24090 
24091   uint8_t                       p = 0;
24092   VL53LX_histogram_bin_data_t *pB = &(palgo3->VL53LX_p_006);
24093 
24094   VL53LX_f_003(palgo3);
24095 
24096   memcpy(
24097     &(palgo3->VL53LX_p_006),
24098     pbins_input,
24099     sizeof(VL53LX_histogram_bin_data_t));
24100 
24101   presults->cfg_device_state = pbins_input->cfg_device_state;
24102   presults->rd_device_state  = pbins_input->rd_device_state;
24103   presults->zone_id          = pbins_input->zone_id;
24104   presults->stream_count     = pbins_input->result__stream_count;
24105   presults->wrap_dmax_mm     = 0;
24106   presults->max_results      = VL53LX_MAX_RANGE_RESULTS;
24107   presults->active_results   = 0;
24108 
24109   for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) {
24110     presults->VL53LX_p_022[p] = 0;
24111   }
24112 
24113 
24114 
24115 
24116   VL53LX_hist_calc_zero_distance_phase(&(palgo3->VL53LX_p_006));
24117 
24118 
24119 
24120 
24121 
24122 
24123   if (ppost_cfg->hist_amb_est_method ==
24124       VL53LX_HIST_AMB_EST_METHOD__THRESHOLDED_BINS)
24125     VL53LX_hist_estimate_ambient_from_thresholded_bins(
24126       (int32_t)ppost_cfg->ambient_thresh_sigma0,
24127       &(palgo3->VL53LX_p_006));
24128   else
24129     VL53LX_hist_estimate_ambient_from_ambient_bins(
24130       &(palgo3->VL53LX_p_006));
24131 
24132 
24133 
24134 
24135 
24136   VL53LX_hist_remove_ambient_bins(&(palgo3->VL53LX_p_006));
24137 
24138 
24139 
24140 
24141 
24142   if (ppost_cfg->algo__crosstalk_compensation_enable > 0)
24143     VL53LX_f_005(
24144       pxtalk,
24145       &(palgo3->VL53LX_p_006),
24146       &(palgo3->VL53LX_p_047));
24147 
24148 
24149 
24150 
24151 
24152 
24153   pdmax_cfg->ambient_thresh_sigma =
24154     ppost_cfg->ambient_thresh_sigma1;
24155 
24156   for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) {
24157     if (status == VL53LX_ERROR_NONE) {
24158 
24159       status =
24160         VL53LX_f_001(
24161           pdmax_cfg->target_reflectance_for_dmax_calc[p],
24162           pdmax_cal,
24163           pdmax_cfg,
24164           &(palgo3->VL53LX_p_006),
24165           pdmax_algo,
24166           &(presults->VL53LX_p_022[p]));
24167     }
24168   }
24169 
24170 
24171 
24172 
24173 
24174 
24175 
24176 
24177 
24178   if (status == VL53LX_ERROR_NONE)
24179     status =
24180       VL53LX_f_006(
24181         ppost_cfg->ambient_thresh_events_scaler,
24182         (int32_t)ppost_cfg->ambient_thresh_sigma1,
24183         (int32_t)ppost_cfg->min_ambient_thresh_events,
24184         ppost_cfg->algo__crosstalk_compensation_enable,
24185         &(palgo3->VL53LX_p_006),
24186         &(palgo3->VL53LX_p_047),
24187         palgo3);
24188 
24189 
24190 
24191 
24192 
24193 
24194 
24195 
24196 
24197   if (status == VL53LX_ERROR_NONE)
24198     status =
24199       VL53LX_f_007(palgo3);
24200 
24201 
24202 
24203 
24204 
24205 
24206   if (status == VL53LX_ERROR_NONE)
24207     status =
24208       VL53LX_f_008(palgo3);
24209 
24210 
24211 
24212 
24213 
24214 
24215   if (status == VL53LX_ERROR_NONE)
24216     status =
24217       VL53LX_f_009(palgo3);
24218 
24219 
24220 
24221 
24222 
24223 
24224   for (p = 0; p < palgo3->VL53LX_p_046; p++) {
24225 
24226     ppulse_data = &(palgo3->VL53LX_p_003[p]);
24227 
24228 
24229 
24230 
24231     if (status == VL53LX_ERROR_NONE)
24232       status =
24233         VL53LX_f_010(
24234           p,
24235           &(palgo3->VL53LX_p_006),
24236           palgo3);
24237 
24238 
24239 
24240 
24241     if (status == VL53LX_ERROR_NONE)
24242       status =
24243         VL53LX_f_011(
24244           p,
24245           &(palgo3->VL53LX_p_006),
24246           palgo3,
24247           pB->VL53LX_p_028,
24248           &(palgo3->VL53LX_p_048));
24249 
24250 
24251 
24252 
24253     if (status == VL53LX_ERROR_NONE) {
24254       status =
24255         VL53LX_f_011(
24256           p,
24257           &(palgo3->VL53LX_p_006),
24258           palgo3,
24259           0,
24260           &(palgo3->VL53LX_p_049));
24261     }
24262 
24263 
24264 
24265 
24266     if (status == VL53LX_ERROR_NONE) {
24267       status =
24268         VL53LX_f_011(
24269           p,
24270           &(palgo3->VL53LX_p_047),
24271           palgo3,
24272           0,
24273           &(palgo3->VL53LX_p_050));
24274     }
24275 
24276 
24277 
24278 
24279     if (status == VL53LX_ERROR_NONE)
24280       status =
24281         VL53LX_f_026(
24282           p,
24283           &(palgo3->VL53LX_p_048),
24284           palgo3,
24285           pfiltered);
24286 
24287 
24288 
24289 
24290     if (status == VL53LX_ERROR_NONE)
24291       status =
24292         VL53LX_f_027(
24293           p,
24294           ppost_cfg->noise_threshold,
24295           pfiltered,
24296           palgo3);
24297 
24298     if (status == VL53LX_ERROR_NONE)
24299       status =
24300         VL53LX_f_014(
24301           ppulse_data->VL53LX_p_023,
24302           ppost_cfg->sigma_estimator__sigma_ref_mm,
24303           palgo3->VL53LX_p_030,
24304           ppulse_data->VL53LX_p_051,
24305           ppost_cfg->algo__crosstalk_compensation_enable,
24306           &(palgo3->VL53LX_p_048),
24307           &(palgo3->VL53LX_p_049),
24308           &(palgo3->VL53LX_p_050),
24309           &(ppulse_data->VL53LX_p_002));
24310 
24311 
24312 
24313 
24314 
24315 
24316 
24317 
24318 
24319     if (status == VL53LX_ERROR_NONE)
24320       status =
24321         VL53LX_f_015(
24322           p,
24323           1,
24324           &(palgo3->VL53LX_p_006),
24325           palgo3);
24326 
24327   }
24328 
24329 
24330 
24331 
24332 
24333 
24334   if (status == VL53LX_ERROR_NONE)
24335     status =
24336       VL53LX_f_016(
24337         ppost_cfg->hist_target_order,
24338         palgo3);
24339 
24340 
24341 
24342 
24343 
24344 
24345   for (p = 0; p < palgo3->VL53LX_p_046; p++) {
24346 
24347     ppulse_data = &(palgo3->VL53LX_p_003[p]);
24348 
24349 
24350 
24351     if (!(presults->active_results < presults->max_results)) {
24352       continue;
24353     }
24354 
24355 
24356 
24357 
24358 
24359 
24360 
24361 
24362     if (ppulse_data->VL53LX_p_010 >
24363         ppost_cfg->signal_total_events_limit &&
24364         ppulse_data->VL53LX_p_023 < 0xFF) {
24365 
24366       prange_data =
24367         &(presults->VL53LX_p_003[presults->active_results]);
24368 
24369       if (status == VL53LX_ERROR_NONE)
24370         VL53LX_f_017(
24371           presults->active_results,
24372           ppost_cfg->valid_phase_low,
24373           ppost_cfg->valid_phase_high,
24374           ppost_cfg->sigma_thresh,
24375           &(palgo3->VL53LX_p_006),
24376           ppulse_data,
24377           prange_data);
24378 
24379       if (status == VL53LX_ERROR_NONE)
24380         status =
24381           VL53LX_f_018(
24382             pB->vcsel_width,
24383             pB->VL53LX_p_015,
24384             pB->total_periods_elapsed,
24385             pB->result__dss_actual_effective_spads,
24386             prange_data);
24387 
24388       if (status == VL53LX_ERROR_NONE)
24389         VL53LX_f_019(
24390           ppost_cfg->gain_factor,
24391           ppost_cfg->range_offset_mm,
24392           prange_data);
24393 
24394       presults->active_results++;
24395     }
24396 
24397   }
24398 
24399 
24400 
24401   return status;
24402 }
24403 
24404 
24405 
24406 VL53LX_Error VL53LX::VL53LX_f_026(
24407   uint8_t                                pulse_no,
24408   VL53LX_histogram_bin_data_t           *ppulse,
24409   VL53LX_hist_gen3_algo_private_data_t  *palgo3,
24410   VL53LX_hist_gen4_algo_filtered_data_t *pfiltered)
24411 {
24412 
24413   VL53LX_Error  status       = VL53LX_ERROR_NONE;
24414 
24415   VL53LX_hist_pulse_data_t *pdata = &(palgo3->VL53LX_p_003[pulse_no]);
24416 
24417   uint8_t  lb     = 0;
24418   uint8_t  i     = 0;
24419   int32_t  suma  = 0;
24420   int32_t  sumb  = 0;
24421   int32_t  sumc  = 0;
24422 
24423 
24424   pfiltered->VL53LX_p_020    = palgo3->VL53LX_p_020;
24425   pfiltered->VL53LX_p_019      = palgo3->VL53LX_p_019;
24426   pfiltered->VL53LX_p_021 = palgo3->VL53LX_p_021;
24427 
24428   for (lb = pdata->VL53LX_p_012; lb <= pdata->VL53LX_p_013; lb++) {
24429 
24430     i =  lb  % palgo3->VL53LX_p_030;
24431 
24432 
24433 
24434     VL53LX_f_022(
24435       i,
24436       pdata->VL53LX_p_051,
24437       ppulse,
24438       &suma,
24439       &sumb,
24440       &sumc);
24441 
24442 
24443 
24444     pfiltered->VL53LX_p_007[i] = suma;
24445     pfiltered->VL53LX_p_032[i] = sumb;
24446     pfiltered->VL53LX_p_001[i] = sumc;
24447 
24448 
24449 
24450 
24451     pfiltered->VL53LX_p_053[i] =
24452       (suma + sumb) -
24453       (sumc + palgo3->VL53LX_p_028);
24454 
24455 
24456 
24457 
24458     pfiltered->VL53LX_p_054[i] =
24459       (sumb + sumc) -
24460       (suma + palgo3->VL53LX_p_028);
24461   }
24462 
24463   return status;
24464 }
24465 
24466 
24467 VL53LX_Error VL53LX::VL53LX_f_027(
24468   uint8_t                                pulse_no,
24469   uint16_t                               noise_threshold,
24470   VL53LX_hist_gen4_algo_filtered_data_t *pfiltered,
24471   VL53LX_hist_gen3_algo_private_data_t  *palgo3)
24472 {
24473 
24474   VL53LX_Error  status       = VL53LX_ERROR_NONE;
24475   VL53LX_Error  func_status  = VL53LX_ERROR_NONE;
24476 
24477   VL53LX_hist_pulse_data_t *pdata = &(palgo3->VL53LX_p_003[pulse_no]);
24478 
24479   uint8_t  lb            = 0;
24480   uint8_t  i            = 0;
24481   uint8_t  j            = 0;
24482 
24483   SUPPRESS_UNUSED_WARNING(noise_threshold);
24484 
24485   for (lb = pdata->VL53LX_p_012; lb < pdata->VL53LX_p_013; lb++) {
24486 
24487     i =  lb    % palgo3->VL53LX_p_030;
24488     j = (lb + 1) % palgo3->VL53LX_p_030;
24489 
24490     if (i < palgo3->VL53LX_p_021 &&
24491         j < palgo3->VL53LX_p_021) {
24492 
24493       if (pfiltered->VL53LX_p_053[i] == 0 &&
24494           pfiltered->VL53LX_p_054[i] == 0)
24495 
24496 
24497       {
24498         pfiltered->VL53LX_p_040[i] = 0;
24499       }
24500 
24501       else if (pfiltered->VL53LX_p_053[i] >= 0 &&
24502                pfiltered->VL53LX_p_054[i] >= 0) {
24503         pfiltered->VL53LX_p_040[i] = 1;
24504       }
24505 
24506       else if (pfiltered->VL53LX_p_053[i] <  0 &&
24507                pfiltered->VL53LX_p_054[i] >= 0 &&
24508                pfiltered->VL53LX_p_053[j] >= 0 &&
24509                pfiltered->VL53LX_p_054[j] <  0) {
24510         pfiltered->VL53LX_p_040[i] = 1;
24511       }
24512 
24513       else {
24514         pfiltered->VL53LX_p_040[i] = 0;
24515       }
24516 
24517 
24518 
24519       if (pfiltered->VL53LX_p_040[i] > 0) {
24520 
24521         pdata->VL53LX_p_023 = lb;
24522 
24523         func_status =
24524           VL53LX_f_028(
24525             lb,
24526             pfiltered->VL53LX_p_007[i],
24527             pfiltered->VL53LX_p_032[i],
24528             pfiltered->VL53LX_p_001[i],
24529             0,
24530 
24531             0,
24532 
24533             0,
24534 
24535             palgo3->VL53LX_p_028,
24536             palgo3->VL53LX_p_030,
24537             &(pdata->VL53LX_p_011));
24538 
24539         if (func_status ==
24540             VL53LX_ERROR_DIVISION_BY_ZERO) {
24541           pfiltered->VL53LX_p_040[i] = 0;
24542         }
24543 
24544       }
24545     }
24546   }
24547 
24548   return status;
24549 }
24550 
24551 
24552 VL53LX_Error VL53LX::VL53LX_f_028(
24553   uint8_t   bin,
24554   int32_t   VL53LX_p_007,
24555   int32_t   VL53LX_p_032,
24556   int32_t   VL53LX_p_001,
24557   int32_t   ax,
24558   int32_t   bx,
24559   int32_t   cx,
24560   int32_t   VL53LX_p_028,
24561   uint8_t   VL53LX_p_030,
24562   uint32_t *pmean_phase)
24563 {
24564 
24565 
24566 
24567 
24568 
24569   VL53LX_Error  status = VL53LX_ERROR_DIVISION_BY_ZERO;
24570 
24571   int64_t  mean_phase  = VL53LX_MAX_ALLOWED_PHASE;
24572   int64_t  VL53LX_p_055   = 0;
24573   int64_t  b_minus_amb = 0;
24574 
24575 
24576 
24577 
24578 
24579 
24580 
24581 
24582   VL53LX_p_055    =     4096 * ((int64_t)VL53LX_p_001 -
24583                                 (int64_t)cx - (int64_t)VL53LX_p_007 - (int64_t)ax);
24584   b_minus_amb  = 2 * 4096 * ((int64_t)VL53LX_p_032 -
24585                              (int64_t)bx - (int64_t)VL53LX_p_028);
24586 
24587   if (b_minus_amb != 0) {
24588 
24589     mean_phase   = ((4096 * VL53LX_p_055) +
24590                     (b_minus_amb / 2)) / b_minus_amb;
24591     mean_phase  +=  2048;
24592     mean_phase  += (4096 * (int64_t)bin);
24593 
24594 
24595 
24596     mean_phase  = (mean_phase + 1) / 2;
24597 
24598 
24599 
24600     if (mean_phase  < 0) {
24601       mean_phase = 0;
24602     }
24603     if (mean_phase > VL53LX_MAX_ALLOWED_PHASE) {
24604       mean_phase = VL53LX_MAX_ALLOWED_PHASE;
24605     }
24606 
24607 
24608 
24609     mean_phase = mean_phase %
24610                  ((int64_t)VL53LX_p_030 * 2048);
24611 
24612     status = VL53LX_ERROR_NONE;
24613 
24614   }
24615 
24616   *pmean_phase = (uint32_t)mean_phase;
24617 
24618   return status;
24619 }
24620 
24621 /* vl53lx_dmax.c */
24622 VL53LX_Error VL53LX::VL53LX_f_001(
24623   uint16_t                              target_reflectance,
24624   VL53LX_dmax_calibration_data_t       *pcal,
24625   VL53LX_hist_gen3_dmax_config_t       *pcfg,
24626   VL53LX_histogram_bin_data_t          *pbins,
24627   VL53LX_hist_gen3_dmax_private_data_t *pdata,
24628   int16_t                              *pambient_dmax_mm)
24629 {
24630 
24631   VL53LX_Error status  = VL53LX_ERROR_NONE;
24632 
24633   uint32_t    pll_period_us       = 0;
24634   uint32_t    periods_elapsed     = 0;
24635 
24636   uint32_t    tmp32               = 0;
24637   uint64_t    tmp64               = 0;
24638 
24639   uint32_t    amb_thres_delta     = 0;
24640 
24641   pdata->VL53LX_p_004     = 0x0000;
24642   pdata->VL53LX_p_033 = 0x0000;
24643   pdata->VL53LX_p_034          = 0x0000;
24644   pdata->VL53LX_p_009    = 0x0000;
24645   pdata->VL53LX_p_028     = 0x0000;
24646   pdata->VL53LX_p_035 = 0x0000;
24647   pdata->VL53LX_p_036             = 0;
24648   pdata->VL53LX_p_022            = 0;
24649 
24650   *pambient_dmax_mm  = 0;
24651 
24652 
24653 
24654 
24655 
24656   if ((pbins->VL53LX_p_015        != 0) &&
24657       (pbins->total_periods_elapsed      != 0)) {
24658 
24659 
24660 
24661 
24662     pll_period_us   =
24663       VL53LX_calc_pll_period_us(pbins->VL53LX_p_015);
24664 
24665 
24666 
24667 
24668     periods_elapsed = pbins->total_periods_elapsed + 1;
24669 
24670 
24671 
24672 
24673 
24674 
24675     pdata->VL53LX_p_037  =
24676       VL53LX_duration_maths(
24677         pll_period_us,
24678         1 << 4,
24679         VL53LX_RANGING_WINDOW_VCSEL_PERIODS,
24680         periods_elapsed);
24681 
24682 
24683 
24684     pdata->VL53LX_p_034 =
24685       VL53LX_rate_maths(
24686         pbins->VL53LX_p_028,
24687         pdata->VL53LX_p_037);
24688 
24689 
24690 
24691 
24692     pdata->VL53LX_p_033   =
24693       VL53LX_events_per_spad_maths(
24694         pbins->VL53LX_p_028,
24695         pbins->result__dss_actual_effective_spads,
24696         pdata->VL53LX_p_037);
24697 
24698 
24699 
24700 
24701 
24702 
24703 
24704 
24705 
24706 
24707 
24708 
24709 
24710 
24711 
24712     pdata->VL53LX_p_038 = pcfg->max_effective_spads;
24713     pdata->VL53LX_p_004  = pcfg->max_effective_spads;
24714 
24715     if (pdata->VL53LX_p_033 > 0) {
24716       tmp64   =
24717         (uint64_t)pcfg->dss_config__target_total_rate_mcps;
24718       tmp64  *= 1000;
24719       tmp64 <<= (11 + 1);
24720       tmp64  +=
24721         ((uint64_t)pdata->VL53LX_p_033 / 2);
24722       tmp64  /= (uint64_t)pdata->VL53LX_p_033;
24723 
24724       if (tmp64 < (uint64_t)pcfg->max_effective_spads) {
24725         pdata->VL53LX_p_004 = (uint16_t)tmp64;
24726       }
24727     }
24728   }
24729 
24730 
24731 
24732 
24733   if ((pcal->ref__actual_effective_spads != 0) &&
24734       (pbins->VL53LX_p_015        != 0) &&
24735       (pcal->ref_reflectance_pc          != 0) &&
24736       (pbins->total_periods_elapsed      != 0)) {
24737 
24738 
24739 
24740 
24741 
24742 
24743 
24744 
24745 
24746 
24747 
24748 
24749 
24750     tmp64  = (uint64_t)pcal->ref__peak_signal_count_rate_mcps;
24751     tmp64 *= (1000 * 256);
24752     tmp64 += ((uint64_t)pcal->ref__actual_effective_spads / 2);
24753     tmp64 /= (uint64_t)pcal->ref__actual_effective_spads;
24754 
24755     pdata->VL53LX_p_009   = (uint32_t)tmp64;
24756     pdata->VL53LX_p_009 <<= 4;
24757 
24758 
24759 
24760 
24761 
24762 
24763     tmp64   = (uint64_t)pdata->VL53LX_p_037;
24764     tmp64  *= (uint64_t)pdata->VL53LX_p_033;
24765     tmp64  *= (uint64_t)pdata->VL53LX_p_004;
24766     tmp64  += (1 << (11 + 7));
24767     tmp64 >>= (11 + 8);
24768     tmp64  +=  500;
24769     tmp64  /= 1000;
24770 
24771 
24772 
24773     if (tmp64 > 0x00FFFFFF) {
24774       tmp64 = 0x00FFFFFF;
24775     }
24776 
24777     pdata->VL53LX_p_028     = (uint32_t)tmp64;
24778 
24779 
24780 
24781 
24782 
24783 
24784     tmp64   = (uint64_t)pdata->VL53LX_p_037;
24785     tmp64  *= (uint64_t)pdata->VL53LX_p_009;
24786     tmp64  *= (uint64_t)pdata->VL53LX_p_004;
24787     tmp64  += (1 << (11 + 7));
24788     tmp64 >>= (11 + 8);
24789 
24790 
24791 
24792 
24793 
24794 
24795 
24796     tmp64  *= ((uint64_t)target_reflectance *
24797                (uint64_t)pcal->coverglass_transmission);
24798 
24799     tmp64  += (((uint64_t)pcal->ref_reflectance_pc * 256) / 2);
24800     tmp64  /= ((uint64_t)pcal->ref_reflectance_pc * 256);
24801 
24802     tmp64  +=  500;
24803     tmp64  /= 1000;
24804 
24805 
24806 
24807     if (tmp64 > 0x00FFFFFF) {
24808       tmp64 = 0x00FFFFFF;
24809     }
24810 
24811     pdata->VL53LX_p_035 = (uint32_t)tmp64;
24812 
24813 
24814 
24815 
24816 
24817 
24818 
24819 
24820 
24821 
24822 
24823 
24824 
24825 
24826 
24827     tmp32  = VL53LX_isqrt(pdata->VL53LX_p_028 << 8);
24828     tmp32 *= (uint32_t)pcfg->ambient_thresh_sigma;
24829 
24830 
24831 
24832 
24833 
24834 
24835 
24836     if (pdata->VL53LX_p_028 <
24837         (uint32_t)pcfg->min_ambient_thresh_events) {
24838 
24839       amb_thres_delta =
24840         pcfg->min_ambient_thresh_events -
24841         (uint32_t)pdata->VL53LX_p_028;
24842 
24843 
24844 
24845       amb_thres_delta <<= 8;
24846 
24847       if (tmp32 < amb_thres_delta) {
24848         tmp32 = amb_thres_delta;
24849       }
24850     }
24851 
24852 
24853 
24854 
24855     pdata->VL53LX_p_022 =
24856       (int16_t)VL53LX_f_002(
24857         tmp32,
24858 
24859         pdata->VL53LX_p_035,
24860         (uint32_t)pcal->ref__distance_mm,
24861         (uint32_t)pcfg->signal_thresh_sigma);
24862 
24863 
24864 
24865 
24866 
24867 
24868 
24869 
24870     tmp32  = (uint32_t)pdata->VL53LX_p_035;
24871     tmp32 *= (uint32_t)pbins->vcsel_width;
24872     tmp32 += (1 << 3);
24873     tmp32 /= (1 << 4);
24874 
24875     pdata->VL53LX_p_036 =
24876       (int16_t)VL53LX_f_002(
24877         256 * (uint32_t)pcfg->signal_total_events_limit,
24878         tmp32,
24879         (uint32_t)pcal->ref__distance_mm,
24880         (uint32_t)pcfg->signal_thresh_sigma);
24881 
24882 
24883 
24884 
24885 
24886 
24887 
24888     if (pdata->VL53LX_p_036 < pdata->VL53LX_p_022) {
24889       *pambient_dmax_mm = pdata->VL53LX_p_036;
24890     } else {
24891       *pambient_dmax_mm = pdata->VL53LX_p_022;
24892     }
24893 
24894   }
24895 
24896   return status;
24897 
24898 }
24899 
24900 
24901 uint32_t VL53LX::VL53LX_f_002(
24902   uint32_t     events_threshold,
24903   uint32_t     ref_signal_events,
24904   uint32_t   ref_distance_mm,
24905   uint32_t     signal_thresh_sigma)
24906 {
24907 
24908   uint32_t    tmp32               = 0;
24909   uint32_t    range_mm            = 0;
24910 
24911   tmp32 = 4 * events_threshold;
24912 
24913 
24914 
24915 
24916 
24917 
24918   tmp32 += ((uint32_t)signal_thresh_sigma *
24919             (uint32_t)signal_thresh_sigma);
24920 
24921 
24922 
24923 
24924 
24925 
24926   tmp32  = VL53LX_isqrt(tmp32);
24927   tmp32 += (uint32_t)signal_thresh_sigma;
24928 
24929 
24930 
24931 
24932 
24933 
24934 
24935   range_mm =
24936     (uint32_t)VL53LX_isqrt(ref_signal_events << 4);
24937   range_mm *= ref_distance_mm;
24938 
24939   range_mm += (tmp32);
24940   range_mm /= (2 * tmp32);
24941 
24942   return range_mm;
24943 
24944 }
24945 
24946 /* vl53lx_api_calibration.c */
24947 
24948 
24949 VL53LX_Error VL53LX::VL53LX_run_ref_spad_char(
24950   VL53LX_Error     *pcal_status)
24951 {
24952 
24953 
24954   VL53LX_Error status = VL53LX_ERROR_NONE;
24955   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
24956 
24957   uint8_t comms_buffer[6];
24958 
24959   VL53LX_refspadchar_config_t *prefspadchar  = &(pdev->refspadchar);
24960 
24961 
24962   if (status == VL53LX_ERROR_NONE) {
24963     status = VL53LX_enable_powerforce();
24964   }
24965 
24966 
24967 
24968   if (status == VL53LX_ERROR_NONE)
24969     status =
24970       VL53LX_set_ref_spad_char_config(
24971         prefspadchar->VL53LX_p_005,
24972         prefspadchar->timeout_us,
24973         prefspadchar->target_count_rate_mcps,
24974         prefspadchar->max_count_rate_limit_mcps,
24975         prefspadchar->min_count_rate_limit_mcps,
24976         pdev->stat_nvm.osc_measured__fast_osc__frequency);
24977 
24978 
24979 
24980   if (status == VL53LX_ERROR_NONE)
24981     status = VL53LX_run_device_test(
24982                prefspadchar->device_test_mode);
24983 
24984 
24985 
24986   if (status == VL53LX_ERROR_NONE)
24987     status =
24988       VL53LX_ReadMulti(
24989         Dev,
24990         VL53LX_REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS,
24991         comms_buffer,
24992         2);
24993 
24994   if (status == VL53LX_ERROR_NONE) {
24995     pdev->dbg_results.ref_spad_char_result__num_actual_ref_spads =
24996       comms_buffer[0];
24997     pdev->dbg_results.ref_spad_char_result__ref_location =
24998       comms_buffer[1];
24999   }
25000 
25001 
25002 
25003   if (status == VL53LX_ERROR_NONE)
25004     status =
25005       VL53LX_WriteMulti(
25006         Dev,
25007         VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS,
25008         comms_buffer,
25009         2);
25010 
25011   if (status == VL53LX_ERROR_NONE) {
25012     pdev->customer.ref_spad_man__num_requested_ref_spads =
25013       comms_buffer[0];
25014     pdev->customer.ref_spad_man__ref_location =
25015       comms_buffer[1];
25016   }
25017 
25018 
25019 
25020   if (status == VL53LX_ERROR_NONE)
25021     status =
25022       VL53LX_ReadMulti(
25023         Dev,
25024         VL53LX_RESULT__SPARE_0_SD1,
25025         comms_buffer,
25026         6);
25027 
25028 
25029 
25030   if (status == VL53LX_ERROR_NONE)
25031     status =
25032       VL53LX_WriteMulti(
25033         Dev,
25034         VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
25035         comms_buffer,
25036         6);
25037 
25038   if (status == VL53LX_ERROR_NONE) {
25039     pdev->customer.global_config__spad_enables_ref_0 =
25040       comms_buffer[0];
25041     pdev->customer.global_config__spad_enables_ref_1 =
25042       comms_buffer[1];
25043     pdev->customer.global_config__spad_enables_ref_2 =
25044       comms_buffer[2];
25045     pdev->customer.global_config__spad_enables_ref_3 =
25046       comms_buffer[3];
25047     pdev->customer.global_config__spad_enables_ref_4 =
25048       comms_buffer[4];
25049     pdev->customer.global_config__spad_enables_ref_5 =
25050       comms_buffer[5];
25051   }
25052   /*
25053       if (status == VL53LX_ERROR_NONE)
25054       VL53LX_print_customer_nvm_managed(
25055         &(pdev->customer),
25056         "run_ref_spad_char():pdev->lldata.customer.",
25057         VL53LX_TRACE_MODULE_REF_SPAD_CHAR);
25058   */
25059   if (status == VL53LX_ERROR_NONE) {
25060 
25061     switch (pdev->sys_results.result__range_status) {
25062 
25063       case VL53LX_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS:
25064         status = VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS;
25065         break;
25066 
25067       case VL53LX_DEVICEERROR_REFSPADCHARMORETHANTARGET:
25068         status = VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH;
25069         break;
25070 
25071       case VL53LX_DEVICEERROR_REFSPADCHARLESSTHANTARGET:
25072         status = VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW;
25073         break;
25074     }
25075   }
25076 
25077 
25078 
25079   *pcal_status = status;
25080 
25081 
25082   /*
25083     IGNORE_STATUS(
25084       IGNORE_REF_SPAD_CHAR_NOT_ENOUGH_SPADS,
25085       VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS,
25086       status);
25087 
25088     IGNORE_STATUS(
25089       IGNORE_REF_SPAD_CHAR_RATE_TOO_HIGH,
25090       VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH,
25091       status);
25092 
25093     IGNORE_STATUS(
25094       IGNORE_REF_SPAD_CHAR_RATE_TOO_LOW,
25095       VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW,
25096       status);
25097 
25098   */
25099 
25100   return status;
25101 }
25102 
25103 
25104 VL53LX_Error VL53LX::VL53LX_run_xtalk_extraction(
25105   VL53LX_Error                       *pcal_status)
25106 {
25107 
25108 
25109   VL53LX_Error status        = VL53LX_ERROR_NONE;
25110   VL53LX_LLDriverData_t *pdev =
25111     VL53LXDevStructGetLLDriverHandle(Dev);
25112 
25113 
25114 
25115   VL53LX_xtalkextract_config_t *pX = &(pdev->xtalk_extract_cfg);
25116   VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
25117   VL53LX_xtalk_calibration_results_t *pXC = &(pdev->xtalk_cal);
25118 
25119   uint8_t results_invalid  = 0;
25120 
25121   uint8_t i                = 0;
25122   uint16_t tmp16 = 0;
25123 
25124   uint8_t measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
25125 
25126   VL53LX_init_histogram_bin_data_struct(
25127     0,
25128     (uint16_t)VL53LX_HISTOGRAM_BUFFER_SIZE,
25129     &(pdev->xtalk_results.central_histogram_avg));
25130 
25131   VL53LX_init_histogram_bin_data_struct(
25132     0,
25133     (uint16_t)VL53LX_HISTOGRAM_BUFFER_SIZE,
25134     &(pdev->xtalk_results.central_histogram_sum));
25135 
25136 
25137 
25138   if (status == VL53LX_ERROR_NONE)
25139     status =
25140       VL53LX_set_preset_mode(
25141         VL53LX_DEVICEPRESETMODE_HISTOGRAM_XTALK_PLANAR,
25142 
25143         pX->dss_config__target_total_rate_mcps,
25144         pX->phasecal_config_timeout_us,
25145         pX->mm_config_timeout_us,
25146         pX->range_config_timeout_us,
25147 
25148         100);
25149 
25150 
25151 
25152   if (status == VL53LX_ERROR_NONE) {
25153     status = VL53LX_disable_xtalk_compensation();
25154   }
25155 
25156 
25157 
25158   pdev->xtalk_results.max_results    = VL53LX_MAX_XTALK_RANGE_RESULTS;
25159   pdev->xtalk_results.active_results = pdev->zone_cfg.active_zones + 1;
25160 
25161 
25162 
25163   pdev->xtalk_results.central_histogram__window_start = 0xFF;
25164   pdev->xtalk_results.central_histogram__window_end   = 0x00;
25165 
25166   pdev->xtalk_results.num_of_samples_status = 0x00;
25167   pdev->xtalk_results.zero_samples_status   = 0x00;
25168   pdev->xtalk_results.max_sigma_status      = 0x00;
25169 
25170   for (i = 0; i < pdev->xtalk_results.max_results; i++) {
25171     pdev->xtalk_results.VL53LX_p_003[i].no_of_samples           = 0;
25172     pdev->xtalk_results.VL53LX_p_003[i].signal_total_events_avg = 0;
25173     pdev->xtalk_results.VL53LX_p_003[i].signal_total_events_sum = 0;
25174     pdev->xtalk_results.VL53LX_p_003[i].rate_per_spad_kcps_sum  = 0;
25175     pdev->xtalk_results.VL53LX_p_003[i].rate_per_spad_kcps_avg  = 0;
25176     pdev->xtalk_results.VL53LX_p_003[i].sigma_mm_sum            = 0;
25177     pdev->xtalk_results.VL53LX_p_003[i].sigma_mm_avg            = 0;
25178 
25179     pdev->xtalk_results.VL53LX_p_003[i].median_phase_sum        = 0;
25180     pdev->xtalk_results.VL53LX_p_003[i].median_phase_avg        = 0;
25181 
25182   }
25183 
25184 
25185   if (status == VL53LX_ERROR_NONE) {
25186 
25187     status =
25188       VL53LX_get_and_avg_xtalk_samples(
25189         pX->num_of_samples,
25190 
25191         measurement_mode,
25192 
25193         pX->algo__crosstalk_extract_max_valid_range_mm,
25194         pX->algo__crosstalk_extract_min_valid_range_mm,
25195         pX->algo__crosstalk_extract_max_valid_rate_kcps,
25196 
25197         0x0,
25198         0x4,
25199         &(pdev->xtalk_results),
25200         &(pdev->xtalk_results.central_histogram_sum),
25201         &(pdev->xtalk_results.central_histogram_avg));
25202   }
25203 
25204 
25205 
25206 
25207 
25208 
25209 
25210   if (status == VL53LX_ERROR_NONE)
25211     if ((pdev->xtalk_results.VL53LX_p_003[4].no_of_samples == 0) ||
25212         (pdev->xtalk_results.VL53LX_p_003[4].sigma_mm_avg >
25213          ((uint32_t)pX->algo__crosstalk_extract_max_sigma_mm
25214           << 5))) {
25215       results_invalid = 0x01;
25216     }
25217 
25218   /*
25219       if (status == VL53LX_ERROR_NONE)
25220       VL53LX_print_xtalk_range_results(
25221         &(pdev->xtalk_results),
25222         "pdev->xtalk_results",
25223         VL53LX_TRACE_MODULE_CORE);
25224   */
25225   if ((status == VL53LX_ERROR_NONE) && (results_invalid == 0)) {
25226     status =
25227       VL53LX_ipp_xtalk_calibration_process_data(
25228         &(pdev->xtalk_results),
25229         &(pdev->xtalk_shapes),
25230         &(pdev->xtalk_cal));
25231   }
25232   if ((status == VL53LX_ERROR_NONE) && (results_invalid == 0)) {
25233     for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
25234       pXC->algo__xtalk_cpo_HistoMerge_kcps[i] =
25235         pXC->algo__crosstalk_compensation_plane_offset_kcps;
25236     pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
25237       pXC->algo__crosstalk_compensation_x_plane_gradient_kcps;
25238     pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
25239       pXC->algo__crosstalk_compensation_y_plane_gradient_kcps;
25240     pC->algo__crosstalk_compensation_plane_offset_kcps =
25241       pXC->algo__crosstalk_compensation_plane_offset_kcps;
25242   }
25243 
25244   if (status == VL53LX_ERROR_NONE) {
25245     status = VL53LX_enable_xtalk_compensation();
25246   }
25247 
25248   if (status == VL53LX_ERROR_NONE) {
25249     for (i = 0; i < pdev->xtalk_results.max_results; i++) {
25250 
25251       if (pdev->xtalk_results.VL53LX_p_003[i].no_of_samples !=
25252 
25253           pX->num_of_samples) {
25254 
25255         pdev->xtalk_results.num_of_samples_status =
25256           pdev->xtalk_results.num_of_samples_status |
25257           (1 << i);
25258       }
25259 
25260       if (pdev->xtalk_results.VL53LX_p_003[i].no_of_samples ==
25261           0x00) {
25262         pdev->xtalk_results.zero_samples_status =
25263           pdev->xtalk_results.zero_samples_status |
25264           (1 << i);
25265       }
25266 
25267 
25268 
25269 
25270       tmp16 = pX->algo__crosstalk_extract_max_sigma_mm;
25271       if (pdev->xtalk_results.VL53LX_p_003[i].sigma_mm_avg >
25272           ((uint32_t)tmp16 << 5)) {
25273         pdev->xtalk_results.max_sigma_status =
25274           pdev->xtalk_results.max_sigma_status |
25275           (1 << i);
25276       }
25277 
25278     }
25279   }
25280 
25281 
25282   if (results_invalid > 0) {
25283 
25284     if (pdev->xtalk_results.VL53LX_p_003[4].no_of_samples == 0) {
25285       status = VL53LX_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL;
25286     } else {
25287 
25288 
25289       if (pdev->xtalk_results.VL53LX_p_003[4].sigma_mm_avg >
25290           (((uint32_t)pX->algo__crosstalk_extract_max_sigma_mm)
25291            << 5)) {
25292         status =
25293           VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
25294       }
25295 
25296     }
25297   } else {
25298 
25299     if (pdev->xtalk_results.zero_samples_status != 0x00) {
25300       status = VL53LX_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT;
25301     } else {
25302       if (pdev->xtalk_results.max_sigma_status != 0x00) {
25303         status =
25304           VL53LX_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT;
25305       } else {
25306         if (pdev->xtalk_results.num_of_samples_status !=
25307             0x00)
25308           status =
25309             VL53LX_WARNING_XTALK_MISSING_SAMPLES;
25310       }
25311     }
25312   }
25313 
25314 
25315 
25316   pdev->xtalk_results.cal_status = status;
25317   *pcal_status = pdev->xtalk_results.cal_status;
25318 
25319 
25320 
25321   /*IGNORE_STATUS(
25322     IGNORE_XTALK_EXTRACTION_NO_SAMPLE_FAIL,
25323     VL53LX_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL,
25324     status);
25325 
25326   IGNORE_STATUS(
25327     IGNORE_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL,
25328     VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL,
25329     status);
25330 
25331   IGNORE_STATUS(
25332     IGNORE_XTALK_EXTRACTION_NO_SAMPLE_FOR_GRADIENT_WARN,
25333     VL53LX_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT,
25334     status);
25335 
25336   IGNORE_STATUS(
25337     IGNORE_XTALK_EXTRACTION_SIGMA_LIMIT_FOR_GRADIENT_WARN,
25338     VL53LX_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT,
25339     status);
25340 
25341   IGNORE_STATUS(
25342     IGNORE_XTALK_EXTRACTION_MISSING_SAMPLES_WARN,
25343     VL53LX_WARNING_XTALK_MISSING_SAMPLES,
25344     status);
25345     */
25346   /*
25347 
25348     VL53LX_print_customer_nvm_managed(
25349       &(pdev->customer),
25350       "run_xtalk_extraction():pdev->lldata.customer.",
25351       VL53LX_TRACE_MODULE_XTALK_DATA);
25352 
25353     VL53LX_print_xtalk_config(
25354       &(pdev->xtalk_cfg),
25355       "run_xtalk_extraction():pdev->lldata.xtalk_cfg.",
25356       VL53LX_TRACE_MODULE_XTALK_DATA);
25357 
25358     VL53LX_print_xtalk_extract_config(
25359       &(pdev->xtalk_extract_cfg),
25360       "run_xtalk_extraction():pdev->lldata.xtalk_extract_cfg.",
25361       VL53LX_TRACE_MODULE_XTALK_DATA);
25362 
25363     VL53LX_print_histogram_bin_data(
25364       &(pdev->hist_data),
25365       "run_xtalk_extraction():pdev->lldata.hist_data.",
25366       VL53LX_TRACE_MODULE_XTALK_DATA);
25367 
25368     VL53LX_print_xtalk_histogram_data(
25369       &(pdev->xtalk_shapes),
25370       "pdev->lldata.xtalk_shapes.",
25371       VL53LX_TRACE_MODULE_XTALK_DATA);
25372 
25373     VL53LX_print_xtalk_range_results(
25374       &(pdev->xtalk_results),
25375       "run_xtalk_extraction():pdev->lldata.xtalk_results.",
25376       VL53LX_TRACE_MODULE_XTALK_DATA);
25377 
25378   #endif
25379   */
25380 
25381   return status;
25382 
25383 }
25384 
25385 
25386 VL53LX_Error VL53LX::VL53LX_get_and_avg_xtalk_samples(
25387   uint8_t                       num_of_samples,
25388   uint8_t                       measurement_mode,
25389   int16_t                       xtalk_filter_thresh_max_mm,
25390   int16_t                       xtalk_filter_thresh_min_mm,
25391   uint16_t                      xtalk_max_valid_rate_kcps,
25392   uint8_t                       xtalk_result_id,
25393   uint8_t                       xtalk_histo_id,
25394   VL53LX_xtalk_range_results_t *pXR,
25395   VL53LX_histogram_bin_data_t  *psum_histo,
25396   VL53LX_histogram_bin_data_t  *pavg_histo)
25397 {
25398 
25399 
25400 
25401   VL53LX_Error status        = VL53LX_ERROR_NONE;
25402   VL53LX_LLDriverData_t *pdev =
25403     VL53LXDevStructGetLLDriverHandle(Dev);
25404 
25405 
25406   VL53LX_range_results_t      *prs =
25407     (VL53LX_range_results_t *) pdev->wArea1;
25408 
25409   VL53LX_range_data_t         *prange_data;
25410   VL53LX_xtalk_range_data_t   *pxtalk_range_data;
25411 
25412   uint8_t i                = 0;
25413   uint8_t j                = 0;
25414   uint8_t zone_id          = 0;
25415   uint8_t final_zone       = pdev->zone_cfg.active_zones + 1;
25416   uint8_t valid_result;
25417 
25418   uint8_t smudge_corr_en   = 0;
25419 
25420 
25421 
25422 
25423   smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
25424 
25425   status = VL53LX_dynamic_xtalk_correction_disable();
25426 
25427 
25428   VL53LX_load_patch();
25429 
25430 
25431 
25432   if (status == VL53LX_ERROR_NONE)
25433     status =
25434       VL53LX_init_and_start_range(
25435         measurement_mode,
25436         VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
25437 
25438 
25439   for (i = 0; i <= (final_zone * num_of_samples); i++) {
25440 
25441 
25442 
25443     if (status == VL53LX_ERROR_NONE) {
25444       status = VL53LX_wait_for_range_completion();
25445     }
25446 
25447 
25448 
25449     if (status == VL53LX_ERROR_NONE)
25450       status =
25451         VL53LX_get_device_results(
25452           VL53LX_DEVICERESULTSLEVEL_FULL,
25453           prs);
25454 
25455 
25456 
25457     if (status == VL53LX_ERROR_NONE &&
25458         pdev->ll_state.rd_device_state !=
25459         VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) {
25460 
25461       zone_id = pdev->ll_state.rd_zone_id + xtalk_result_id;
25462       prange_data       = &(prs->VL53LX_p_003[0]);
25463 
25464 
25465       if (prs->active_results > 1) {
25466         for (j = 1;
25467              j < prs->active_results; j++) {
25468           if (prs->VL53LX_p_003[j].median_range_mm
25469               <
25470               prange_data->median_range_mm)
25471             prange_data =
25472               &(prs->VL53LX_p_003[j]);
25473 
25474         }
25475       }
25476 
25477       pxtalk_range_data = &(pXR->VL53LX_p_003[zone_id]);
25478 
25479 
25480 
25481       if ((prs->active_results > 0) &&
25482           (prange_data->median_range_mm <
25483            xtalk_filter_thresh_max_mm) &&
25484           (prange_data->median_range_mm >
25485            xtalk_filter_thresh_min_mm) &&
25486           (prange_data->VL53LX_p_009 <
25487            (uint32_t)(xtalk_max_valid_rate_kcps * 16))) {
25488         valid_result = 1;
25489       } else {
25490         valid_result = 0;
25491       }
25492 
25493       if (valid_result == 1) {
25494 
25495         pxtalk_range_data->no_of_samples++;
25496 
25497         pxtalk_range_data->rate_per_spad_kcps_sum +=
25498           prange_data->VL53LX_p_009;
25499 
25500         pxtalk_range_data->signal_total_events_sum +=
25501           prange_data->VL53LX_p_010;
25502 
25503         pxtalk_range_data->sigma_mm_sum +=
25504           (uint32_t)prange_data->VL53LX_p_002;
25505 
25506 
25507 
25508         pxtalk_range_data->median_phase_sum +=
25509           (uint32_t)prange_data->VL53LX_p_011;
25510 
25511 
25512 
25513 
25514       }
25515 
25516       if ((valid_result == 1) && (zone_id >= 4)) {
25517         status = VL53LX_sum_histogram_data(
25518                    &(pdev->hist_data),
25519                    psum_histo);
25520 
25521 
25522 
25523         if (prange_data->VL53LX_p_012 <
25524             pXR->central_histogram__window_start)
25525           pXR->central_histogram__window_start =
25526             prange_data->VL53LX_p_012;
25527 
25528 
25529         if (prange_data->VL53LX_p_013 >
25530             pXR->central_histogram__window_end)
25531           pXR->central_histogram__window_end =
25532             prange_data->VL53LX_p_013;
25533 
25534       }
25535 
25536     }
25537 
25538 
25539     if (status == VL53LX_ERROR_NONE) {
25540       status = VL53LX_wait_for_firmware_ready();
25541     }
25542 
25543 
25544 
25545     if (status == VL53LX_ERROR_NONE)
25546       status =
25547         VL53LX_clear_interrupt_and_enable_next_range(
25548           measurement_mode);
25549 
25550 
25551   }
25552 
25553 
25554 
25555 
25556   if (status == VL53LX_ERROR_NONE) {
25557     status = VL53LX_stop_range();
25558   }
25559 
25560   VL53LX_unload_patch();
25561 
25562 
25563 
25564   for (i = 0; i < (pdev->zone_cfg.active_zones + 1); i++) {
25565 
25566     pxtalk_range_data = &(pXR->VL53LX_p_003[i + xtalk_result_id]);
25567 
25568     if (pxtalk_range_data->no_of_samples > 0) {
25569       pxtalk_range_data->rate_per_spad_kcps_avg =
25570         pxtalk_range_data->rate_per_spad_kcps_sum /
25571         (uint32_t)pxtalk_range_data->no_of_samples;
25572 
25573       pxtalk_range_data->signal_total_events_avg =
25574         pxtalk_range_data->signal_total_events_sum /
25575         (int32_t)pxtalk_range_data->no_of_samples;
25576 
25577       pxtalk_range_data->sigma_mm_avg =
25578         pxtalk_range_data->sigma_mm_sum /
25579         (uint32_t)pxtalk_range_data->no_of_samples;
25580 
25581 
25582 
25583       pxtalk_range_data->median_phase_avg =
25584         pxtalk_range_data->median_phase_sum /
25585         (uint32_t)pxtalk_range_data->no_of_samples;
25586 
25587 
25588 
25589     } else {
25590       pxtalk_range_data->rate_per_spad_kcps_avg =
25591         pxtalk_range_data->rate_per_spad_kcps_sum;
25592       pxtalk_range_data->signal_total_events_avg =
25593         pxtalk_range_data->signal_total_events_sum;
25594       pxtalk_range_data->sigma_mm_avg =
25595         pxtalk_range_data->sigma_mm_sum;
25596 
25597 
25598 
25599       pxtalk_range_data->median_phase_avg =
25600         pxtalk_range_data->median_phase_sum;
25601 
25602 
25603     }
25604   }
25605 
25606 
25607 
25608   memcpy(pavg_histo, &(pdev->hist_data),
25609          sizeof(VL53LX_histogram_bin_data_t));
25610 
25611 
25612 
25613   if (status == VL53LX_ERROR_NONE) {
25614 
25615     pxtalk_range_data = &(pXR->VL53LX_p_003[xtalk_histo_id]);
25616 
25617     status = VL53LX_avg_histogram_data(
25618                pxtalk_range_data->no_of_samples,
25619                psum_histo,
25620                pavg_histo);
25621   }
25622 
25623 
25624 
25625 
25626   if (status == VL53LX_ERROR_NONE) {
25627     if (smudge_corr_en == 1) {
25628       status = VL53LX_dynamic_xtalk_correction_enable();
25629     }
25630   }
25631 
25632 
25633   return status;
25634 
25635 }
25636 
25637 
25638 VL53LX_Error VL53LX::VL53LX_run_offset_calibration(
25639   int16_t                       cal_distance_mm,
25640   uint16_t                      cal_reflectance_pc,
25641   VL53LX_Error                 *pcal_status)
25642 {
25643 
25644 
25645   VL53LX_Error status        = VL53LX_ERROR_NONE;
25646   VL53LX_LLDriverData_t *pdev =
25647     VL53LXDevStructGetLLDriverHandle(Dev);
25648 
25649   VL53LX_DevicePresetModes device_preset_modes[
25650    VL53LX_MAX_OFFSET_RANGE_RESULTS];
25651 
25652   VL53LX_range_results_t     *prange_results =
25653     (VL53LX_range_results_t *) pdev->wArea1;
25654 
25655   VL53LX_range_data_t        *pRData = NULL;
25656   VL53LX_offset_range_data_t *pfs     = NULL;
25657   VL53LX_general_config_t *pG = &(pdev->gen_cfg);
25658   VL53LX_additional_offset_cal_data_t *pAO = &(pdev->add_off_cal_data);
25659 
25660   uint8_t  i                      = 0;
25661   uint8_t  m                      = 0;
25662   uint8_t  measurement_mode       =
25663     VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
25664   uint16_t manual_effective_spads =
25665     pG->dss_config__manual_effective_spads_select;
25666 
25667   uint8_t num_of_samples[VL53LX_MAX_OFFSET_RANGE_RESULTS];
25668 
25669   uint8_t smudge_corr_en   = 0;
25670 
25671 
25672 
25673 
25674   switch (pdev->offset_calibration_mode) {
25675 
25676     case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM:
25677     case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY:
25678       device_preset_modes[0] =
25679         VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING;
25680       device_preset_modes[1] =
25681         VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM1_CAL;
25682       device_preset_modes[2] =
25683         VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM2_CAL;
25684       break;
25685 
25686     default:
25687       device_preset_modes[0] =
25688         VL53LX_DEVICEPRESETMODE_STANDARD_RANGING;
25689       device_preset_modes[1] =
25690         VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL;
25691       device_preset_modes[2] =
25692         VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL;
25693       break;
25694   }
25695 
25696 
25697 
25698   num_of_samples[0] = pdev->offsetcal_cfg.pre_num_of_samples;
25699   num_of_samples[1] = pdev->offsetcal_cfg.mm1_num_of_samples;
25700   num_of_samples[2] = pdev->offsetcal_cfg.mm2_num_of_samples;
25701 
25702 
25703 
25704 
25705   switch (pdev->offset_calibration_mode) {
25706 
25707     case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY:
25708     case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY:
25709 
25710       pdev->offset_results.active_results  = 1;
25711 
25712       break;
25713 
25714     default:
25715 
25716       pdev->customer.mm_config__inner_offset_mm  = 0;
25717       pdev->customer.mm_config__outer_offset_mm  = 0;
25718       pdev->offset_results.active_results  =
25719         VL53LX_MAX_OFFSET_RANGE_RESULTS;
25720 
25721       break;
25722   }
25723 
25724   pdev->customer.algo__part_to_part_range_offset_mm = 0;
25725 
25726 
25727 
25728   pdev->offset_results.max_results   = VL53LX_MAX_OFFSET_RANGE_RESULTS;
25729   pdev->offset_results.cal_distance_mm       = cal_distance_mm;
25730   pdev->offset_results.cal_reflectance_pc    = cal_reflectance_pc;
25731 
25732   for (m = 0; m <  VL53LX_MAX_OFFSET_RANGE_RESULTS; m++) {
25733 
25734     pfs = &(pdev->offset_results.VL53LX_p_003[m]);
25735     pfs->preset_mode         = 0;
25736     pfs->no_of_samples       = 0;
25737     pfs->effective_spads     = 0;
25738     pfs->peak_rate_mcps      = 0;
25739     pfs->VL53LX_p_002            = 0;
25740     pfs->median_range_mm     = 0;
25741   }
25742 
25743 
25744 
25745 
25746   smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
25747 
25748   status = VL53LX_dynamic_xtalk_correction_disable();
25749 
25750 
25751 
25752   for (m = 0; m < pdev->offset_results.active_results; m++) {
25753 
25754     pfs = &(pdev->offset_results.VL53LX_p_003[m]);
25755 
25756     pfs->preset_mode         = device_preset_modes[m];
25757 
25758 
25759 
25760     if (status == VL53LX_ERROR_NONE)
25761       status =
25762         VL53LX_set_preset_mode(
25763           device_preset_modes[m],
25764 
25765           pdev->offsetcal_cfg.dss_config__target_total_rate_mcps,
25766           pdev->offsetcal_cfg.phasecal_config_timeout_us,
25767           pdev->offsetcal_cfg.mm_config_timeout_us,
25768           pdev->offsetcal_cfg.range_config_timeout_us,
25769 
25770           100);
25771 
25772     pG->dss_config__manual_effective_spads_select =
25773       manual_effective_spads;
25774 
25775 
25776     VL53LX_load_patch();
25777 
25778     if (status == VL53LX_ERROR_NONE)
25779       status =
25780         VL53LX_init_and_start_range(
25781           measurement_mode,
25782           VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
25783 
25784     for (i = 0; i <= (num_of_samples[m] + 2); i++) {
25785 
25786 
25787 
25788       if (status == VL53LX_ERROR_NONE)
25789         status =
25790           VL53LX_wait_for_range_completion();
25791 
25792 
25793 
25794       if (status == VL53LX_ERROR_NONE)
25795         status =
25796           VL53LX_get_device_results(
25797             VL53LX_DEVICERESULTSLEVEL_FULL,
25798             prange_results);
25799 
25800 
25801 
25802       pRData  = &(prange_results->VL53LX_p_003[0]);
25803 
25804       if ((prange_results->active_results > 0 &&
25805            prange_results->stream_count   > 1) &&
25806           (pRData->range_status ==
25807            VL53LX_DEVICEERROR_RANGECOMPLETE)) {
25808 
25809         pfs->no_of_samples++;
25810         pfs->effective_spads +=
25811           (uint32_t)pRData->VL53LX_p_004;
25812         pfs->peak_rate_mcps  +=
25813           (uint32_t)pRData->peak_signal_count_rate_mcps;
25814         pfs->VL53LX_p_002        +=
25815           (uint32_t)pRData->VL53LX_p_002;
25816         pfs->median_range_mm +=
25817           (int32_t)pRData->median_range_mm;
25818 
25819         pfs->dss_config__roi_mode_control =
25820           pG->dss_config__roi_mode_control;
25821         pfs->dss_config__manual_effective_spads_select =
25822           pG->dss_config__manual_effective_spads_select;
25823 
25824       }
25825 
25826 
25827 
25828       if (status == VL53LX_ERROR_NONE)
25829         status =
25830           VL53LX_wait_for_firmware_ready();
25831 
25832 
25833 
25834       if (status == VL53LX_ERROR_NONE)
25835         status =
25836           VL53LX_clear_interrupt_and_enable_next_range(
25837             measurement_mode);
25838     }
25839 
25840 
25841 
25842     if (status == VL53LX_ERROR_NONE) {
25843       status = VL53LX_stop_range();
25844     }
25845 
25846 
25847 
25848     if (status == VL53LX_ERROR_NONE) {
25849       status = VL53LX_WaitUs(Dev, 1000);
25850     }
25851     VL53LX_unload_patch();
25852 
25853 
25854     if (pfs->no_of_samples > 0) {
25855 
25856       pfs->effective_spads += (pfs->no_of_samples / 2);
25857       pfs->effective_spads /= pfs->no_of_samples;
25858 
25859       pfs->peak_rate_mcps  += (pfs->no_of_samples / 2);
25860       pfs->peak_rate_mcps  /= pfs->no_of_samples;
25861 
25862       pfs->VL53LX_p_002        += (pfs->no_of_samples / 2);
25863       pfs->VL53LX_p_002        /= pfs->no_of_samples;
25864 
25865       pfs->median_range_mm += (pfs->no_of_samples / 2);
25866       pfs->median_range_mm /= pfs->no_of_samples;
25867 
25868       pfs->range_mm_offset  = (int32_t)cal_distance_mm;
25869       pfs->range_mm_offset -= pfs->median_range_mm;
25870 
25871 
25872       if (pfs->preset_mode ==
25873           VL53LX_DEVICEPRESETMODE_STANDARD_RANGING)
25874         manual_effective_spads =
25875           (uint16_t)pfs->effective_spads;
25876     }
25877   }
25878 
25879 
25880 
25881   switch (pdev->offset_calibration_mode) {
25882 
25883     case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY:
25884     case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY:
25885 
25886 
25887       pdev->customer.mm_config__inner_offset_mm +=
25888         (int16_t)pdev->offset_results.VL53LX_p_003[0].range_mm_offset;
25889       pdev->customer.mm_config__outer_offset_mm +=
25890         (int16_t)pdev->offset_results.VL53LX_p_003[0].range_mm_offset;
25891       break;
25892 
25893     default:
25894 
25895       pdev->customer.mm_config__inner_offset_mm =
25896         (int16_t)pdev->offset_results.VL53LX_p_003[1].range_mm_offset;
25897       pdev->customer.mm_config__outer_offset_mm =
25898         (int16_t)pdev->offset_results.VL53LX_p_003[2].range_mm_offset;
25899       pdev->customer.algo__part_to_part_range_offset_mm = 0;
25900 
25901 
25902 
25903       pAO->result__mm_inner_actual_effective_spads =
25904         (uint16_t)pdev->offset_results.VL53LX_p_003[1].effective_spads;
25905       pAO->result__mm_outer_actual_effective_spads =
25906         (uint16_t)pdev->offset_results.VL53LX_p_003[2].effective_spads;
25907 
25908       pAO->result__mm_inner_peak_signal_count_rtn_mcps =
25909         (uint16_t)pdev->offset_results.VL53LX_p_003[1].peak_rate_mcps;
25910       pAO->result__mm_outer_peak_signal_count_rtn_mcps =
25911         (uint16_t)pdev->offset_results.VL53LX_p_003[2].peak_rate_mcps;
25912 
25913       break;
25914   }
25915 
25916 
25917 
25918   pdev->cust_dmax_cal.ref__actual_effective_spads =
25919     (uint16_t)pdev->offset_results.VL53LX_p_003[0].effective_spads;
25920   pdev->cust_dmax_cal.ref__peak_signal_count_rate_mcps =
25921     (uint16_t)pdev->offset_results.VL53LX_p_003[0].peak_rate_mcps;
25922 
25923 
25924   pdev->cust_dmax_cal.ref__distance_mm = cal_distance_mm * 16;
25925 
25926   pdev->cust_dmax_cal.ref_reflectance_pc = cal_reflectance_pc;
25927   pdev->cust_dmax_cal.coverglass_transmission = 0x0100;
25928 
25929 
25930 
25931   if (status == VL53LX_ERROR_NONE)
25932     status =
25933       VL53LX_set_customer_nvm_managed(
25934         &(pdev->customer));
25935 
25936 
25937 
25938 
25939   if (status == VL53LX_ERROR_NONE) {
25940     if (smudge_corr_en == 1) {
25941       status = VL53LX_dynamic_xtalk_correction_enable();
25942     }
25943   }
25944 
25945 
25946 
25947 
25948   for (m = 0; m < pdev->offset_results.active_results; m++) {
25949 
25950     pfs = &(pdev->offset_results.VL53LX_p_003[m]);
25951 
25952     if (status == VL53LX_ERROR_NONE) {
25953 
25954       pdev->offset_results.cal_report = m;
25955 
25956       if (pfs->no_of_samples < num_of_samples[m])
25957         status =
25958           VL53LX_WARNING_OFFSET_CAL_MISSING_SAMPLES;
25959 
25960 
25961       if (m == 0 && pfs->VL53LX_p_002 >
25962           ((uint32_t)VL53LX_OFFSET_CAL_MAX_SIGMA_MM << 5))
25963         status =
25964           VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
25965 
25966       if (pfs->peak_rate_mcps >
25967           VL53LX_OFFSET_CAL_MAX_PRE_PEAK_RATE_MCPS)
25968         status =
25969           VL53LX_WARNING_OFFSET_CAL_RATE_TOO_HIGH;
25970 
25971       if (pfs->dss_config__manual_effective_spads_select <
25972           VL53LX_OFFSET_CAL_MIN_EFFECTIVE_SPADS)
25973         status =
25974           VL53LX_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW;
25975 
25976       if (pfs->dss_config__manual_effective_spads_select == 0)
25977         status =
25978           VL53LX_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL;
25979 
25980       if (pfs->no_of_samples == 0) {
25981         status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
25982       }
25983     }
25984   }
25985 
25986 
25987 
25988   pdev->offset_results.cal_status = status;
25989   *pcal_status = pdev->offset_results.cal_status;
25990 
25991 
25992   /*
25993     IGNORE_STATUS(
25994       IGNORE_OFFSET_CAL_MISSING_SAMPLES,
25995       VL53LX_WARNING_OFFSET_CAL_MISSING_SAMPLES,
25996       status);
25997 
25998     IGNORE_STATUS(
25999       IGNORE_OFFSET_CAL_SIGMA_TOO_HIGH,
26000       VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH,
26001       status);
26002 
26003     IGNORE_STATUS(
26004       IGNORE_OFFSET_CAL_RATE_TOO_HIGH,
26005       VL53LX_WARNING_OFFSET_CAL_RATE_TOO_HIGH,
26006       status);
26007 
26008     IGNORE_STATUS(
26009       IGNORE_OFFSET_CAL_SPAD_COUNT_TOO_LOW,
26010       VL53LX_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW,
26011       status);
26012   */
26013 
26014   /*
26015   #ifdef VL53LX_LOG_ENABLE
26016 
26017 
26018 
26019     VL53LX_print_customer_nvm_managed(
26020       &(pdev->customer),
26021       "run_offset_calibration():pdev->lldata.customer.",
26022       VL53LX_TRACE_MODULE_OFFSET_DATA);
26023 
26024     VL53LX_print_dmax_calibration_data(
26025       &(pdev->fmt_dmax_cal),
26026       "run_offset_calibration():pdev->lldata.fmt_dmax_cal.",
26027       VL53LX_TRACE_MODULE_OFFSET_DATA);
26028 
26029     VL53LX_print_dmax_calibration_data(
26030       &(pdev->cust_dmax_cal),
26031       "run_offset_calibration():pdev->lldata.cust_dmax_cal.",
26032       VL53LX_TRACE_MODULE_OFFSET_DATA);
26033 
26034     VL53LX_print_additional_offset_cal_data(
26035       &(pdev->add_off_cal_data),
26036       "run_offset_calibration():pdev->lldata.add_off_cal_data.",
26037       VL53LX_TRACE_MODULE_OFFSET_DATA);
26038 
26039     VL53LX_print_offset_range_results(
26040       &(pdev->offset_results),
26041       "run_offset_calibration():pdev->lldata.offset_results.",
26042       VL53LX_TRACE_MODULE_OFFSET_DATA);
26043   #endif
26044   */
26045 
26046   return status;
26047 }
26048 
26049 
26050 VL53LX_Error VL53LX::VL53LX_run_phasecal_average(
26051   uint8_t                 measurement_mode,
26052   uint8_t                 phasecal_result__vcsel_start,
26053   uint16_t                phasecal_num_of_samples,
26054   VL53LX_range_results_t *prange_results,
26055   uint16_t               *pphasecal_result__reference_phase,
26056   uint16_t               *pzero_distance_phase)
26057 {
26058 
26059 
26060   VL53LX_Error status        = VL53LX_ERROR_NONE;
26061   VL53LX_LLDriverData_t *pdev =
26062     VL53LXDevStructGetLLDriverHandle(Dev);
26063 
26064   uint16_t  i                                = 0;
26065   uint16_t  m                                = 0;
26066   uint32_t  samples                          = 0;
26067 
26068   uint32_t  period                           = 0;
26069   uint32_t  VL53LX_p_014                            = 0;
26070   uint32_t  phasecal_result__reference_phase = 0;
26071   uint32_t  zero_distance_phase              = 0;
26072 
26073 
26074   VL53LX_load_patch();
26075 
26076   for (m = 0; m < phasecal_num_of_samples; m++) {
26077 
26078 
26079 
26080     if (status == VL53LX_ERROR_NONE)
26081       status =
26082         VL53LX_init_and_start_range(
26083           measurement_mode,
26084           VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
26085 
26086     for (i = 0; i <= 1; i++) {
26087 
26088 
26089 
26090       if (status == VL53LX_ERROR_NONE)
26091         status =
26092           VL53LX_wait_for_range_completion();
26093 
26094 
26095 
26096       if (status == VL53LX_ERROR_NONE)
26097         status =
26098           VL53LX_get_device_results(
26099             VL53LX_DEVICERESULTSLEVEL_FULL,
26100             prange_results);
26101 
26102 
26103 
26104       if (status == VL53LX_ERROR_NONE)
26105         status =
26106           VL53LX_wait_for_firmware_ready();
26107 
26108 
26109 
26110       if (status == VL53LX_ERROR_NONE)
26111         status =
26112           VL53LX_clear_interrupt_and_enable_next_range(
26113             measurement_mode);
26114     }
26115 
26116 
26117 
26118     if (status == VL53LX_ERROR_NONE) {
26119       status = VL53LX_stop_range();
26120     }
26121 
26122 
26123 
26124     if (status == VL53LX_ERROR_NONE) {
26125       status = VL53LX_WaitUs(Dev, 1000);
26126     }
26127 
26128 
26129 
26130     if (status == VL53LX_ERROR_NONE) {
26131 
26132       samples++;
26133 
26134 
26135       period = 2048 *
26136                (uint32_t)VL53LX_decode_vcsel_period(
26137                  pdev->hist_data.VL53LX_p_005);
26138 
26139       VL53LX_p_014  = period;
26140       VL53LX_p_014 += (uint32_t)(
26141                         pdev->hist_data.phasecal_result__reference_phase);
26142       VL53LX_p_014 +=
26143         (2048 *
26144          (uint32_t)phasecal_result__vcsel_start);
26145       VL53LX_p_014 -= (2048 *
26146                        (uint32_t)pdev->hist_data.cal_config__vcsel_start);
26147 
26148       VL53LX_p_014  = VL53LX_p_014 % period;
26149 
26150       phasecal_result__reference_phase += (uint32_t)(
26151                                             pdev->hist_data.phasecal_result__reference_phase);
26152 
26153       zero_distance_phase += (uint32_t)VL53LX_p_014;
26154     }
26155   }
26156   VL53LX_unload_patch();
26157 
26158 
26159 
26160   if (status == VL53LX_ERROR_NONE && samples > 0) {
26161 
26162     phasecal_result__reference_phase += (samples >> 1);
26163     phasecal_result__reference_phase /= samples;
26164 
26165     zero_distance_phase += (samples >> 1);
26166     zero_distance_phase /= samples;
26167 
26168     *pphasecal_result__reference_phase =
26169       (uint16_t)phasecal_result__reference_phase;
26170     *pzero_distance_phase =
26171       (uint16_t)zero_distance_phase;
26172   }
26173 
26174   return status;
26175 }
26176 
26177 VL53LX_Error VL53LX::VL53LX_run_zone_calibration(
26178   VL53LX_DevicePresetModes      device_preset_mode,
26179   VL53LX_DeviceZonePreset       zone_preset,
26180   VL53LX_zone_config_t         *pzone_cfg,
26181   int16_t                       cal_distance_mm,
26182   uint16_t                      cal_reflectance_pc,
26183   VL53LX_Error                 *pcal_status)
26184 {
26185 
26186 
26187   VL53LX_Error status        = VL53LX_ERROR_NONE;
26188   VL53LX_LLDriverData_t *pdev =
26189     VL53LXDevStructGetLLDriverHandle(Dev);
26190 
26191   VL53LX_LLDriverResults_t *pres =
26192     VL53LXDevStructGetLLResultsHandle(Dev);
26193 
26194   VL53LX_range_results_t         *pRR =
26195     (VL53LX_range_results_t *) pdev->wArea1;
26196   VL53LX_range_data_t            *prange_data = NULL;
26197   VL53LX_zone_calibration_data_t *pzone_data  = NULL;
26198 
26199   uint16_t  i                      = 0;
26200   uint16_t  m                      = 0;
26201 
26202   uint8_t   z                      = 0;
26203   uint8_t   measurement_mode       =
26204     VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
26205 
26206   VL53LX_OffsetCorrectionMode  offset_cor_mode =
26207     VL53LX_OFFSETCORRECTIONMODE__NONE;
26208 
26209   if (status == VL53LX_ERROR_NONE)
26210     status =
26211       VL53LX_set_preset_mode(
26212         device_preset_mode,
26213 
26214         pdev->zonecal_cfg.dss_config__target_total_rate_mcps,
26215         pdev->zonecal_cfg.phasecal_config_timeout_us,
26216         pdev->zonecal_cfg.mm_config_timeout_us,
26217         pdev->zonecal_cfg.range_config_timeout_us,
26218 
26219         100);
26220 
26221 
26222 
26223   if (zone_preset == VL53LX_DEVICEZONEPRESET_CUSTOM) {
26224 
26225     if (status == VL53LX_ERROR_NONE)
26226       status =
26227         VL53LX_set_zone_config(
26228           pzone_cfg);
26229 
26230   } else if (zone_preset != VL53LX_DEVICEZONEPRESET_NONE) {
26231 
26232     if (status == VL53LX_ERROR_NONE)
26233       status =
26234         VL53LX_set_zone_preset(
26235           zone_preset);
26236   }
26237 
26238 
26239 
26240   pres->zone_cal.preset_mode        = device_preset_mode;
26241   pres->zone_cal.zone_preset        = zone_preset;
26242 
26243   pres->zone_cal.cal_distance_mm    = cal_distance_mm * 16;
26244   pres->zone_cal.cal_reflectance_pc = cal_reflectance_pc;
26245   pres->zone_cal.max_zones          = VL53LX_MAX_USER_ZONES;
26246   pres->zone_cal.active_zones       = pdev->zone_cfg.active_zones + 1;
26247 
26248   for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) {
26249     pres->zone_cal.VL53LX_p_003[i].no_of_samples   = 0;
26250     pres->zone_cal.VL53LX_p_003[i].effective_spads = 0;
26251     pres->zone_cal.VL53LX_p_003[i].peak_rate_mcps  = 0;
26252     pres->zone_cal.VL53LX_p_003[i].VL53LX_p_011    = 0;
26253     pres->zone_cal.VL53LX_p_003[i].VL53LX_p_002        = 0;
26254     pres->zone_cal.VL53LX_p_003[i].median_range_mm = 0;
26255     pres->zone_cal.VL53LX_p_003[i].range_mm_offset = 0;
26256   }
26257 
26258   pres->zone_cal.phasecal_result__reference_phase = 0;
26259   pres->zone_cal.zero_distance_phase              = 0;
26260 
26261 
26262 
26263   status =
26264     VL53LX_get_offset_correction_mode(
26265       &offset_cor_mode);
26266 
26267   if (status == VL53LX_ERROR_NONE)
26268     status =
26269       VL53LX_set_offset_correction_mode(
26270         VL53LX_OFFSETCORRECTIONMODE__NONE);
26271 
26272 
26273   VL53LX_load_patch();
26274 
26275   if (status == VL53LX_ERROR_NONE)
26276     status =
26277       VL53LX_init_and_start_range(
26278         measurement_mode,
26279         VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
26280 
26281 
26282 
26283 
26284   m = (pdev->zonecal_cfg.zone_num_of_samples + 2) *
26285       (uint16_t)pres->zone_cal.active_zones;
26286 
26287 
26288   for (i = 0; i <= m; i++) {
26289 
26290 
26291 
26292     if (status == VL53LX_ERROR_NONE)
26293       status =
26294         VL53LX_wait_for_range_completion();
26295 
26296 
26297 
26298     if (status == VL53LX_ERROR_NONE)
26299       status =
26300         VL53LX_get_device_results(
26301           VL53LX_DEVICERESULTSLEVEL_FULL,
26302           pRR);
26303 
26304 
26305 
26306     prange_data  = &(pRR->VL53LX_p_003[0]);
26307 
26308     if (pRR->active_results > 0 &&
26309         i > (uint16_t)pres->zone_cal.active_zones) {
26310 
26311       if (prange_data->range_status ==
26312           VL53LX_DEVICEERROR_RANGECOMPLETE) {
26313 
26314         pres->zone_cal.phasecal_result__reference_phase
26315           =
26316             pdev->hist_data.phasecal_result__reference_phase
26317             ;
26318         pres->zone_cal.zero_distance_phase =
26319           pdev->hist_data.zero_distance_phase;
26320 
26321         pzone_data =
26322           &(pres->zone_cal.VL53LX_p_003[pRR->zone_id]);
26323         pzone_data->no_of_samples++;
26324         pzone_data->effective_spads +=
26325           (uint32_t)prange_data->VL53LX_p_004;
26326         pzone_data->peak_rate_mcps  += (uint32_t)(
26327                                          prange_data->peak_signal_count_rate_mcps);
26328         pzone_data->VL53LX_p_011  +=
26329           (uint32_t)prange_data->VL53LX_p_011;
26330         pzone_data->VL53LX_p_002        +=
26331           (uint32_t)prange_data->VL53LX_p_002;
26332         pzone_data->median_range_mm +=
26333           (int32_t)prange_data->median_range_mm;
26334 
26335       }
26336     }
26337 
26338 
26339 
26340     if (status == VL53LX_ERROR_NONE)
26341       status =
26342         VL53LX_wait_for_firmware_ready();
26343 
26344 
26345 
26346     if (status == VL53LX_ERROR_NONE)
26347       status =
26348         VL53LX_clear_interrupt_and_enable_next_range(
26349           measurement_mode);
26350   }
26351 
26352 
26353 
26354   if (status == VL53LX_ERROR_NONE) {
26355     status = VL53LX_stop_range();
26356   }
26357 
26358 
26359   if (status == VL53LX_ERROR_NONE) {
26360     status = VL53LX_WaitUs(Dev, 1000);
26361   }
26362   VL53LX_unload_patch();
26363 
26364 
26365   if (status == VL53LX_ERROR_NONE)
26366     status =
26367       VL53LX_run_phasecal_average(
26368         measurement_mode,
26369         pdev->hist_data.phasecal_result__vcsel_start,
26370 
26371         pdev->zonecal_cfg.phasecal_num_of_samples,
26372 
26373         pRR,
26374         &(pres->zone_cal.phasecal_result__reference_phase),
26375         &(pres->zone_cal.zero_distance_phase));
26376 
26377 
26378 
26379   if (status == VL53LX_ERROR_NONE)
26380     status =
26381       VL53LX_set_offset_correction_mode(
26382         offset_cor_mode);
26383 
26384 
26385 
26386   if (status == VL53LX_ERROR_NONE) {
26387 
26388     for (z = 0; z < pres->zone_cal.active_zones; z++) {
26389 
26390       pzone_data = &(pres->zone_cal.VL53LX_p_003[z]);
26391 
26392 
26393       if (pzone_data->no_of_samples > 0) {
26394 
26395         pzone_data->effective_spads +=
26396           (pzone_data->no_of_samples / 2);
26397         pzone_data->effective_spads /=
26398           pzone_data->no_of_samples;
26399 
26400         pzone_data->peak_rate_mcps  +=
26401           (pzone_data->no_of_samples / 2);
26402         pzone_data->peak_rate_mcps  /=
26403           pzone_data->no_of_samples;
26404 
26405         pzone_data->VL53LX_p_011    +=
26406           (pzone_data->no_of_samples / 2);
26407         pzone_data->VL53LX_p_011    /=
26408           pzone_data->no_of_samples;
26409 
26410         pzone_data->VL53LX_p_002        +=
26411           (pzone_data->no_of_samples / 2);
26412         pzone_data->VL53LX_p_002        /=
26413           pzone_data->no_of_samples;
26414 
26415 
26416 
26417         pzone_data->median_range_mm =
26418           VL53LX_range_maths(
26419             pdev->stat_nvm.osc_measured__fast_osc__frequency
26420             , (uint16_t)pzone_data->VL53LX_p_011,
26421             pres->zone_cal.zero_distance_phase,
26422             2,
26423             0x0800,
26424             0);
26425 
26426         pzone_data->range_mm_offset  =
26427           ((int32_t)cal_distance_mm) * 4;
26428         pzone_data->range_mm_offset -=
26429           pzone_data->median_range_mm;
26430 
26431 
26432         if (pzone_data->no_of_samples <
26433             pdev->zonecal_cfg.zone_num_of_samples)
26434           status =
26435             VL53LX_WARNING_ZONE_CAL_MISSING_SAMPLES;
26436 
26437 
26438         if (pzone_data->VL53LX_p_002 >
26439             ((uint32_t)VL53LX_ZONE_CAL_MAX_SIGMA_MM
26440              << 5))
26441           status =
26442             VL53LX_WARNING_ZONE_CAL_SIGMA_TOO_HIGH;
26443 
26444         if (pzone_data->peak_rate_mcps >
26445             VL53LX_ZONE_CAL_MAX_PRE_PEAK_RATE_MCPS)
26446           status =
26447             VL53LX_WARNING_ZONE_CAL_RATE_TOO_HIGH;
26448 
26449       } else {
26450         status = VL53LX_ERROR_ZONE_CAL_NO_SAMPLE_FAIL;
26451       }
26452     }
26453   }
26454 
26455 
26456 
26457   pres->zone_cal.cal_status = status;
26458   *pcal_status = pres->zone_cal.cal_status;
26459 
26460   /*
26461 
26462     IGNORE_STATUS(
26463       IGNORE_ZONE_CAL_MISSING_SAMPLES,
26464       VL53LX_WARNING_ZONE_CAL_MISSING_SAMPLES,
26465       status);
26466 
26467     IGNORE_STATUS(
26468       IGNORE_ZONE_CAL_SIGMA_TOO_HIGH,
26469       VL53LX_WARNING_ZONE_CAL_SIGMA_TOO_HIGH,
26470       status);
26471 
26472     IGNORE_STATUS(
26473       IGNORE_ZONE_CAL_RATE_TOO_HIGH,
26474       VL53LX_WARNING_ZONE_CAL_RATE_TOO_HIGH,
26475       status);
26476   */
26477   /*
26478   #ifdef VL53LX_LOG_ENABLE
26479 
26480 
26481 
26482     VL53LX_print_zone_calibration_results(
26483       &(pres->zone_cal),
26484       "run_zone_calibration():pdev->llresults.zone_cal.",
26485       VL53LX_TRACE_MODULE_OFFSET_DATA);
26486 
26487   #endif
26488   */
26489 
26490 
26491   return status;
26492 }
26493 
26494 
26495 VL53LX_Error VL53LX::VL53LX_run_spad_rate_map(
26496   VL53LX_DeviceTestMode      device_test_mode,
26497   VL53LX_DeviceSscArray      array_select,
26498   uint32_t                   ssc_config_timeout_us,
26499   VL53LX_spad_rate_data_t   *pspad_rate_data)
26500 {
26501 
26502 
26503 
26504   VL53LX_Error status = VL53LX_ERROR_NONE;
26505 
26506   VL53LX_LLDriverData_t *pdev =
26507     VL53LXDevStructGetLLDriverHandle(Dev);
26508 
26509   if (status == VL53LX_ERROR_NONE) {
26510     status = VL53LX_enable_powerforce();
26511   }
26512 
26513 
26514 
26515   if (status == VL53LX_ERROR_NONE) {
26516     pdev->ssc_cfg.array_select = array_select;
26517     pdev->ssc_cfg.timeout_us   = ssc_config_timeout_us;
26518     status =
26519       VL53LX_set_ssc_config(
26520         &(pdev->ssc_cfg),
26521         pdev->stat_nvm.osc_measured__fast_osc__frequency);
26522   }
26523 
26524 
26525 
26526   if (status == VL53LX_ERROR_NONE)
26527     status =
26528       VL53LX_run_device_test(
26529         device_test_mode);
26530 
26531 
26532 
26533   if (status == VL53LX_ERROR_NONE)
26534     status =
26535       VL53LX_get_spad_rate_data(
26536         pspad_rate_data);
26537 
26538   if (device_test_mode == VL53LX_DEVICETESTMODE_LCR_VCSEL_ON) {
26539     pspad_rate_data->fractional_bits =  7;
26540   } else {
26541     pspad_rate_data->fractional_bits = 15;
26542   }
26543 
26544 
26545 
26546   if (status == VL53LX_ERROR_NONE) {
26547     status = VL53LX_disable_powerforce();
26548   }
26549   /*
26550   #ifdef VL53LX_LOG_ENABLE
26551 
26552 
26553     if (status == VL53LX_ERROR_NONE) {
26554       VL53LX_print_spad_rate_data(
26555         pspad_rate_data,
26556         "run_spad_rate_map():",
26557         VL53LX_TRACE_MODULE_SPAD_RATE_MAP);
26558       VL53LX_print_spad_rate_map(
26559         pspad_rate_data,
26560         "run_spad_rate_map():",
26561         VL53LX_TRACE_MODULE_SPAD_RATE_MAP);
26562     }
26563   #endif
26564   */
26565 
26566   return status;
26567 }
26568 
26569 
26570 VL53LX_Error VL53LX::VL53LX_run_device_test(
26571   VL53LX_DeviceTestMode  device_test_mode)
26572 {
26573 
26574 
26575   VL53LX_Error status = VL53LX_ERROR_NONE;
26576   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
26577 
26578   uint8_t      comms_buffer[2];
26579   uint8_t      gpio_hv_mux__ctrl = 0;
26580 
26581 
26582   if (status == VL53LX_ERROR_NONE)
26583     status =
26584       VL53LX_RdByte(
26585         Dev,
26586         VL53LX_GPIO_HV_MUX__CTRL,
26587         &gpio_hv_mux__ctrl);
26588 
26589   if (status == VL53LX_ERROR_NONE) {
26590     pdev->stat_cfg.gpio_hv_mux__ctrl = gpio_hv_mux__ctrl;
26591   }
26592 
26593 
26594   if (status == VL53LX_ERROR_NONE)
26595     status = VL53LX_start_test(
26596                device_test_mode);
26597 
26598 
26599   if (status == VL53LX_ERROR_NONE) {
26600     status = VL53LX_wait_for_test_completion();
26601   }
26602 
26603 
26604   if (status == VL53LX_ERROR_NONE)
26605     status =
26606       VL53LX_ReadMulti(
26607         Dev,
26608         VL53LX_RESULT__RANGE_STATUS,
26609         comms_buffer,
26610         2);
26611 
26612   if (status == VL53LX_ERROR_NONE) {
26613     pdev->sys_results.result__range_status  = comms_buffer[0];
26614     pdev->sys_results.result__report_status = comms_buffer[1];
26615   }
26616 
26617 
26618 
26619   pdev->sys_results.result__range_status &=
26620     VL53LX_RANGE_STATUS__RANGE_STATUS_MASK;
26621 
26622   if (status == VL53LX_ERROR_NONE) {
26623 
26624     if (status == VL53LX_ERROR_NONE) {
26625       status = VL53LX_clear_interrupt();
26626     }
26627   }
26628 
26629 
26630 
26631   if (status == VL53LX_ERROR_NONE)
26632     status =
26633       VL53LX_start_test(0x00);
26634 
26635 
26636   return status;
26637 }
26638 
26639 void VL53LX::VL53LX_hist_xtalk_extract_data_init(
26640   VL53LX_hist_xtalk_extract_data_t *pxtalk_data)
26641 {
26642 
26643 
26644   int32_t lb = 0;
26645 
26646   pxtalk_data->sample_count             = 0U;
26647   pxtalk_data->pll_period_mm            = 0U;
26648   pxtalk_data->peak_duration_us_sum     = 0U;
26649   pxtalk_data->effective_spad_count_sum = 0U;
26650   pxtalk_data->zero_distance_phase_sum  = 0U;
26651   pxtalk_data->zero_distance_phase_avg  = 0U;
26652   pxtalk_data->event_scaler_sum         = 0U;
26653   pxtalk_data->event_scaler_avg         = 4096U;
26654   pxtalk_data->signal_events_sum        = 0;
26655   pxtalk_data->xtalk_rate_kcps_per_spad = 0U;
26656   pxtalk_data->VL53LX_p_012             = 0U;
26657   pxtalk_data->VL53LX_p_013               = 0U;
26658   pxtalk_data->target_start             = 0U;
26659 
26660   for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) {
26661     pxtalk_data->bin_data_sums[lb] = 0;
26662   }
26663 
26664 }
26665 
26666 VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_update(
26667   int16_t                             target_distance_mm,
26668   uint16_t                            target_width_oversize,
26669   VL53LX_histogram_bin_data_t        *phist_bins,
26670   VL53LX_hist_xtalk_extract_data_t   *pxtalk_data)
26671 {
26672   VL53LX_Error  status = VL53LX_ERROR_NONE;
26673 
26674   status =
26675     VL53LX_hist_xtalk_extract_calc_window(
26676       target_distance_mm,
26677       target_width_oversize,
26678       phist_bins,
26679       pxtalk_data);
26680 
26681   if (status == VL53LX_ERROR_NONE) {
26682     status =
26683       VL53LX_hist_xtalk_extract_calc_event_sums(
26684         phist_bins,
26685         pxtalk_data);
26686   }
26687 
26688   return status;
26689 }
26690 
26691 
26692 VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_fini(
26693   VL53LX_histogram_bin_data_t        *phist_bins,
26694   VL53LX_hist_xtalk_extract_data_t   *pxtalk_data,
26695   VL53LX_xtalk_calibration_results_t *pxtalk_cal,
26696   VL53LX_xtalk_histogram_shape_t     *pxtalk_shape)
26697 {
26698 
26699 
26700   VL53LX_Error  status = VL53LX_ERROR_NONE;
26701   VL53LX_xtalk_calibration_results_t *pX = pxtalk_cal;
26702 
26703 
26704   if (pxtalk_data->sample_count > 0) {
26705 
26706 
26707     pxtalk_data->event_scaler_avg  = pxtalk_data->event_scaler_sum;
26708     pxtalk_data->event_scaler_avg +=
26709       (pxtalk_data->sample_count >> 1);
26710     pxtalk_data->event_scaler_avg /=  pxtalk_data->sample_count;
26711 
26712 
26713 
26714     status =
26715       VL53LX_hist_xtalk_extract_calc_rate_per_spad(
26716         pxtalk_data);
26717 
26718 
26719 
26720     if (status == VL53LX_ERROR_NONE) {
26721 
26722 
26723       pxtalk_data->zero_distance_phase_avg =
26724         pxtalk_data->zero_distance_phase_sum;
26725       pxtalk_data->zero_distance_phase_avg +=
26726         (pxtalk_data->sample_count >> 1);
26727       pxtalk_data->zero_distance_phase_avg /=
26728         pxtalk_data->sample_count;
26729 
26730 
26731       status =
26732         VL53LX_hist_xtalk_extract_calc_shape(
26733           pxtalk_data,
26734           pxtalk_shape);
26735 
26736 
26737 
26738 
26739       pxtalk_shape->phasecal_result__vcsel_start =
26740         phist_bins->phasecal_result__vcsel_start;
26741       pxtalk_shape->cal_config__vcsel_start =
26742         phist_bins->cal_config__vcsel_start;
26743       pxtalk_shape->vcsel_width =
26744         phist_bins->vcsel_width;
26745       pxtalk_shape->VL53LX_p_015 =
26746         phist_bins->VL53LX_p_015;
26747     }
26748 
26749 
26750     if (status == VL53LX_ERROR_NONE) {
26751 
26752 
26753       pX->algo__crosstalk_compensation_plane_offset_kcps =
26754         pxtalk_data->xtalk_rate_kcps_per_spad;
26755       pX->algo__crosstalk_compensation_x_plane_gradient_kcps
26756         = 0U;
26757       pX->algo__crosstalk_compensation_y_plane_gradient_kcps
26758         = 0U;
26759 
26760     }
26761   }
26762 
26763 
26764   return status;
26765 }
26766 
26767 
26768 VL53LX_Error   VL53LX::VL53LX_run_hist_xtalk_extraction(
26769   int16_t                             cal_distance_mm,
26770   VL53LX_Error                       *pcal_status)
26771 {
26772 
26773 
26774 #define OVERSIZE 4
26775   VL53LX_Error status = VL53LX_ERROR_NONE;
26776   VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
26777   VL53LX_xtalkextract_config_t *pX = &(pdev->xtalk_extract_cfg);
26778   VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
26779   VL53LX_xtalk_calibration_results_t *pXC = &(pdev->xtalk_cal);
26780 
26781 
26782 
26783   uint8_t smudge_corr_en   = 0;
26784   uint8_t i                = 0;
26785   int8_t k = 0;
26786   uint8_t nbloops;
26787   int32_t initMergeSize = 0;
26788   int32_t MergeEnabled = 0;
26789   uint32_t deltaXtalk;
26790   uint32_t stepXtalk;
26791   uint32_t XtalkMin;
26792   uint32_t XtalkMax;
26793   uint8_t measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
26794   int8_t MaxId;
26795   uint8_t histo_merge_nb;
26796   uint8_t wait_for_accumulation;
26797   VL53LX_range_results_t     *prange_results =
26798     (VL53LX_range_results_t *) pdev->wArea1;
26799   uint8_t Very1stRange = 0;
26800 
26801 
26802 
26803 
26804   if (status == VL53LX_ERROR_NONE)
26805     status =
26806       VL53LX_set_preset_mode(
26807         VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE,
26808         pX->dss_config__target_total_rate_mcps,
26809         pX->phasecal_config_timeout_us,
26810         pX->mm_config_timeout_us,
26811         pX->range_config_timeout_us,
26812         100);
26813 
26814 
26815 
26816   if (status == VL53LX_ERROR_NONE) {
26817     status = VL53LX_disable_xtalk_compensation();
26818   }
26819 
26820 
26821 
26822   smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
26823 
26824   if (status == VL53LX_ERROR_NONE) {
26825     status = VL53LX_dynamic_xtalk_correction_disable();
26826   }
26827 
26828 
26829   VL53LX_load_patch();
26830 
26831   VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE,
26832                          &initMergeSize);
26833   VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE,
26834                          &MergeEnabled);
26835   memset(&pdev->xtalk_cal, 0, sizeof(pdev->xtalk_cal));
26836 
26837   if (status == VL53LX_ERROR_NONE)
26838     status = VL53LX_init_and_start_range(measurement_mode,
26839                                          VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
26840 
26841   MaxId = pdev->tuning_parms.tp_hist_merge_max_size - 1;
26842   nbloops = (MergeEnabled == 0 ? 1 : 2);
26843   for (k = 0; k < nbloops; k++) {
26844 
26845     VL53LX_hist_xtalk_extract_data_init(
26846       &(pdev->xtalk_extract));
26847     VL53LX_set_tuning_parm(
26848       VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE,
26849       k * MaxId + 1);
26850 
26851     for (i = 0; i <= pX->num_of_samples; i++) {
26852       if (status == VL53LX_ERROR_NONE) {
26853         status = VL53LX_wait_for_range_completion();
26854       }
26855       if (status == VL53LX_ERROR_NONE)
26856         status = VL53LX_get_device_results(
26857                    VL53LX_DEVICERESULTSLEVEL_FULL,
26858                    prange_results);
26859       Very1stRange =
26860         (pdev->ll_state.rd_device_state ==
26861          VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC);
26862 
26863       VL53LX_compute_histo_merge_nb(&histo_merge_nb);
26864       wait_for_accumulation = ((k != 0) &&
26865                                (MergeEnabled) &&
26866                                (status == VL53LX_ERROR_NONE) &&
26867                                (histo_merge_nb <
26868                                 pdev->tuning_parms.tp_hist_merge_max_size));
26869       if (wait_for_accumulation) {
26870         i = 0;
26871       } else {
26872         if ((status == VL53LX_ERROR_NONE) &&
26873             (!Very1stRange)) {
26874           status =
26875             VL53LX_hist_xtalk_extract_update(
26876               cal_distance_mm,
26877               OVERSIZE,
26878               &(pdev->hist_data),
26879               &(pdev->xtalk_extract));
26880         }
26881       }
26882 
26883       if (status == VL53LX_ERROR_NONE) {
26884         status = VL53LX_wait_for_firmware_ready();
26885       }
26886       if (status == VL53LX_ERROR_NONE)
26887         status =
26888           VL53LX_clear_interrupt_and_enable_next_range(measurement_mode);
26889 
26890 
26891       if (status == VL53LX_ERROR_NONE)
26892         status =
26893           VL53LX_hist_xtalk_extract_fini(
26894             &(pdev->hist_data),
26895             &(pdev->xtalk_extract),
26896             &(pdev->xtalk_cal),
26897             &(pdev->xtalk_shapes.xtalk_shape));
26898       if (status != VL53LX_ERROR_NONE) {
26899         goto LOOPOUT;
26900       }
26901       pXC->algo__xtalk_cpo_HistoMerge_kcps[k * MaxId] =
26902         pXC->algo__crosstalk_compensation_plane_offset_kcps;
26903     }
26904   }
26905 
26906 LOOPOUT:
26907 
26908   VL53LX_stop_range();
26909 
26910   VL53LX_set_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE,
26911                          initMergeSize);
26912   VL53LX_unload_patch();
26913 
26914   if (status != VL53LX_ERROR_NONE) {
26915     status = VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
26916   } else if ((MergeEnabled == 1) && (MaxId > 0)) {
26917     XtalkMin = pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0];
26918     XtalkMax =
26919       pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[MaxId];
26920     pdev->xtalk_cal.
26921     algo__crosstalk_compensation_plane_offset_kcps = XtalkMin;
26922     if (XtalkMax > XtalkMin) {
26923       deltaXtalk =  XtalkMax - XtalkMin;
26924       stepXtalk = deltaXtalk / MaxId;
26925       for (k = 1; k < MaxId; k++)
26926         pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[k] =
26927           XtalkMin + stepXtalk * k;
26928     } else
26929       status =
26930         VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
26931   }
26932 
26933   if (status == VL53LX_ERROR_NONE) {
26934     pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
26935       pXC->algo__crosstalk_compensation_x_plane_gradient_kcps;
26936     pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
26937       pXC->algo__crosstalk_compensation_y_plane_gradient_kcps;
26938     pC->algo__crosstalk_compensation_plane_offset_kcps =
26939       pXC->algo__crosstalk_compensation_plane_offset_kcps;
26940   }
26941 
26942 
26943   pdev->xtalk_results.cal_status = status;
26944   *pcal_status = pdev->xtalk_results.cal_status;
26945 
26946 
26947   status = VL53LX_enable_xtalk_compensation();
26948   if (smudge_corr_en == 1) {
26949     status = VL53LX_dynamic_xtalk_correction_enable();
26950   }
26951   /*
26952   #ifdef VL53LX_LOG_ENABLE
26953 
26954 
26955 
26956     VL53LX_print_customer_nvm_managed(
26957       &(pdev->customer),
26958       "run_xtalk_extraction():pdev->lldata.customer.",
26959       VL53LX_TRACE_MODULE_XTALK_DATA);
26960 
26961     VL53LX_print_xtalk_config(
26962       &(pdev->xtalk_cfg),
26963       "run_xtalk_extraction():pdev->lldata.xtalk_cfg.",
26964       VL53LX_TRACE_MODULE_XTALK_DATA);
26965 
26966     VL53LX_print_xtalk_histogram_data(
26967       &(pdev->xtalk_shapes),
26968       "pdev->lldata.xtalk_shapes.",
26969       VL53LX_TRACE_MODULE_XTALK_DATA);
26970 
26971   #endif
26972   */
26973 
26974   return status;
26975 }
26976 
26977 /* vl53lx_api.c */
26978 
26979 VL53LX_Error VL53LX::VL53LX_GetVersion(VL53LX_Version_t *pVersion)
26980 {
26981   VL53LX_Error Status = VL53LX_ERROR_NONE;
26982 
26983   pVersion->major  = VL53LX_IMPLEMENTATION_VER_MAJOR;
26984   pVersion->minor  = VL53LX_IMPLEMENTATION_VER_MINOR;
26985   pVersion->build  = VL53LX_IMPLEMENTATION_VER_SUB;
26986 
26987   pVersion->revision  = VL53LX_IMPLEMENTATION_VER_REVISION;
26988 
26989   return Status;
26990 }
26991 
26992 
26993 VL53LX_Error VL53LX::VL53LX_GetProductRevision(
26994   uint8_t *pProductRevisionMajor, uint8_t *pProductRevisionMinor)
26995 {
26996   VL53LX_Error Status = VL53LX_ERROR_NONE;
26997   uint8_t revision_id;
26998   VL53LX_LLDriverData_t   *pLLData;
26999 
27000 
27001   pLLData =  VL53LXDevStructGetLLDriverHandle(Dev);
27002   revision_id = pLLData->nvm_copy_data.identification__revision_id;
27003   *pProductRevisionMajor = 1;
27004   *pProductRevisionMinor = (revision_id & 0xF0) >> 4;
27005 
27006   return Status;
27007 
27008 }
27009 
27010 VL53LX_Error VL53LX::VL53LX_GetDeviceInfo(
27011   VL53LX_DeviceInfo_t *pVL53LX_DeviceInfo)
27012 {
27013   VL53LX_Error Status = VL53LX_ERROR_NONE;
27014   uint8_t revision_id;
27015   VL53LX_LLDriverData_t   *pLLData;
27016 
27017   pLLData =  VL53LXDevStructGetLLDriverHandle(Dev);
27018 
27019   pVL53LX_DeviceInfo->ProductType  =
27020     pLLData->nvm_copy_data.identification__module_type;
27021 
27022   revision_id = pLLData->nvm_copy_data.identification__revision_id;
27023   pVL53LX_DeviceInfo->ProductRevisionMajor  = 1;
27024   pVL53LX_DeviceInfo->ProductRevisionMinor  = (revision_id & 0xF0) >> 4;
27025 
27026   return Status;
27027 }
27028 
27029 VL53LX_Error VL53LX::VL53LX_GetUID(uint64_t *pUid)
27030 {
27031   VL53LX_Error Status = VL53LX_ERROR_NONE;
27032   uint8_t fmtdata[8];
27033 
27034   Status = VL53LX_read_nvm_raw_data(
27035              (uint8_t)(0x1F8 >> 2),
27036              (uint8_t)(8 >> 2),
27037              fmtdata);
27038   memcpy(pUid, fmtdata, sizeof(uint64_t));
27039 
27040   return Status;
27041 }
27042 
27043 VL53LX_Error VL53LX::VL53LX_SetDeviceAddress(uint8_t DeviceAddress)
27044 {
27045 
27046   VL53LX_Error Status = VL53LX_ERROR_NONE;
27047 
27048   Status = VL53LX_WrByte(Dev, VL53LX_I2C_SLAVE__DEVICE_ADDRESS,
27049                          DeviceAddress / 2);
27050 
27051   if (Status == VL53LX_ERROR_NONE) {
27052     Dev->I2cDevAddr = DeviceAddress;
27053   }
27054 
27055   return Status;
27056 }
27057 
27058 
27059 VL53LX_Error VL53LX::VL53LX_DataInit()
27060 {
27061   VL53LX_Error Status = VL53LX_ERROR_NONE;
27062   VL53LX_LLDriverData_t *pdev;
27063   uint8_t  measurement_mode;
27064 
27065 
27066 
27067 #ifdef USE_I2C_2V8
27068   Status = VL53LX_RdByte(Dev, VL53LX_PAD_I2C_HV__EXTSUP_CONFIG, &i);
27069   if (Status == VL53LX_ERROR_NONE) {
27070     i = (i & 0xfe) | 0x01;
27071     Status = VL53LX_WrByte(Dev, VL53LX_PAD_I2C_HV__EXTSUP_CONFIG,
27072                            i);
27073   }
27074 #endif
27075 
27076   if (Status == VL53LX_ERROR_NONE) {
27077     Status = VL53LX_data_init(1);
27078   }
27079 
27080   Status = SetPresetModeL3CX(
27081              VL53LX_DISTANCEMODE_LONG,
27082              1000);
27083 
27084 
27085   if (Status == VL53LX_ERROR_NONE)
27086     Status = VL53LX_SetMeasurementTimingBudgetMicroSeconds(
27087                33333);
27088 
27089   if (Status == VL53LX_ERROR_NONE) {
27090     Status = SetInterMeasurementPeriodMilliSeconds(1000);
27091   }
27092 
27093   if (Status == VL53LX_ERROR_NONE) {
27094     pdev = VL53LXDevStructGetLLDriverHandle(Dev);
27095     memset(&pdev->per_vcsel_cal_data, 0,
27096            sizeof(pdev->per_vcsel_cal_data));
27097   }
27098 
27099   if (Status == VL53LX_ERROR_NONE) {
27100     Status = VL53LX_set_dmax_mode(
27101                VL53LX_DEVICEDMAXMODE__CUST_CAL_DATA);
27102   }
27103 
27104 
27105   measurement_mode  = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
27106   VL53LXDevDataSet(Dev, LLData.measurement_mode, measurement_mode);
27107 
27108   VL53LXDevDataSet(Dev, CurrentParameters.DistanceMode,
27109                    VL53LX_DISTANCEMODE_LONG);
27110 
27111 
27112   return Status;
27113 }
27114 
27115 VL53LX_Error VL53LX::VL53LX_WaitDeviceBooted()
27116 {
27117   VL53LX_Error Status = VL53LX_ERROR_NONE;
27118 
27119   Status = VL53LX_poll_for_boot_completion(
27120              VL53LX_BOOT_COMPLETION_POLLING_TIMEOUT_MS);
27121 
27122   return Status;
27123 }
27124 
27125 VL53LX_Error VL53LX::ComputeDevicePresetMode(
27126   VL53LX_DistanceModes DistanceMode,
27127   VL53LX_DevicePresetModes *pDevicePresetMode)
27128 {
27129   VL53LX_Error Status = VL53LX_ERROR_NONE;
27130 
27131   uint8_t DistIdx;
27132   VL53LX_DevicePresetModes RangingModes[3] = {
27133     VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE,
27134     VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE,
27135     VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE
27136   };
27137 
27138   switch (DistanceMode) {
27139     case VL53LX_DISTANCEMODE_SHORT:
27140       DistIdx = 0;
27141       break;
27142     case VL53LX_DISTANCEMODE_MEDIUM:
27143       DistIdx = 1;
27144       break;
27145     default:
27146       DistIdx = 2;
27147   }
27148 
27149   *pDevicePresetMode = RangingModes[DistIdx];
27150 
27151   return Status;
27152 }
27153 
27154 VL53LX_Error VL53LX::SetPresetModeL3CX(
27155   VL53LX_DistanceModes DistanceMode,
27156   uint32_t inter_measurement_period_ms)
27157 {
27158   VL53LX_Error Status = VL53LX_ERROR_NONE;
27159   VL53LX_DevicePresetModes   device_preset_mode;
27160   uint8_t measurement_mode;
27161   uint16_t dss_config__target_total_rate_mcps;
27162   uint32_t phasecal_config_timeout_us;
27163   uint32_t mm_config_timeout_us;
27164   uint32_t lld_range_config_timeout_us;
27165 
27166 
27167   measurement_mode  = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
27168 
27169   Status = ComputeDevicePresetMode(DistanceMode,
27170                                    &device_preset_mode);
27171 
27172   if (Status == VL53LX_ERROR_NONE)
27173     Status =  VL53LX_get_preset_mode_timing_cfg(
27174                 device_preset_mode,
27175                 &dss_config__target_total_rate_mcps,
27176                 &phasecal_config_timeout_us,
27177                 &mm_config_timeout_us,
27178                 &lld_range_config_timeout_us);
27179 
27180   if (Status == VL53LX_ERROR_NONE)
27181     Status = VL53LX_set_preset_mode(
27182                device_preset_mode,
27183                dss_config__target_total_rate_mcps,
27184                phasecal_config_timeout_us,
27185                mm_config_timeout_us,
27186                lld_range_config_timeout_us,
27187                inter_measurement_period_ms);
27188 
27189   if (Status == VL53LX_ERROR_NONE)
27190     VL53LXDevDataSet(Dev, LLData.measurement_mode,
27191                      measurement_mode);
27192 
27193   return Status;
27194 }
27195 
27196 VL53LX_Error VL53LX::VL53LX_SetDistanceMode(
27197   VL53LX_DistanceModes DistanceMode)
27198 {
27199   VL53LX_Error Status = VL53LX_ERROR_NONE;
27200   uint32_t inter_measurement_period_ms;
27201   uint32_t TimingBudget;
27202   uint32_t MmTimeoutUs;
27203   uint32_t PhaseCalTimeoutUs;
27204 
27205   if ((DistanceMode != VL53LX_DISTANCEMODE_SHORT) &&
27206       (DistanceMode != VL53LX_DISTANCEMODE_MEDIUM) &&
27207       (DistanceMode != VL53LX_DISTANCEMODE_LONG)) {
27208     return VL53LX_ERROR_INVALID_PARAMS;
27209   }
27210 
27211   inter_measurement_period_ms =  VL53LXDevDataGet(Dev,
27212                                                   LLData.inter_measurement_period_ms);
27213 
27214   if (Status == VL53LX_ERROR_NONE)
27215     Status = VL53LX_get_timeouts_us(&PhaseCalTimeoutUs,
27216                                     &MmTimeoutUs, &TimingBudget);
27217 
27218   if (Status == VL53LX_ERROR_NONE)
27219     Status = SetPresetModeL3CX(
27220                DistanceMode,
27221                inter_measurement_period_ms);
27222 
27223   if (Status == VL53LX_ERROR_NONE) {
27224     VL53LXDevDataSet(Dev, CurrentParameters.DistanceMode,
27225                      DistanceMode);
27226   }
27227 
27228   if (Status == VL53LX_ERROR_NONE) {
27229     Status = VL53LX_set_timeouts_us(PhaseCalTimeoutUs,
27230                                     MmTimeoutUs, TimingBudget);
27231 
27232     if (Status == VL53LX_ERROR_NONE)
27233       VL53LXDevDataSet(Dev, LLData.range_config_timeout_us,
27234                        TimingBudget);
27235   }
27236 
27237   return Status;
27238 }
27239 
27240 VL53LX_Error VL53LX::VL53LX_GetDistanceMode(
27241   VL53LX_DistanceModes *pDistanceMode)
27242 {
27243   VL53LX_Error Status = VL53LX_ERROR_NONE;
27244 
27245 
27246   *pDistanceMode = VL53LXDevDataGet(Dev, CurrentParameters.DistanceMode);
27247 
27248   return Status;
27249 }
27250 
27251 
27252 VL53LX_Error VL53LX::VL53LX_SetMeasurementTimingBudgetMicroSeconds(
27253   uint32_t MeasurementTimingBudgetMicroSeconds)
27254 {
27255   VL53LX_Error Status = VL53LX_ERROR_NONE;
27256   uint32_t TimingGuard;
27257   uint32_t divisor;
27258   uint32_t TimingBudget;
27259   uint32_t MmTimeoutUs;
27260   uint32_t PhaseCalTimeoutUs;
27261   uint32_t FDAMaxTimingBudgetUs = FDA_MAX_TIMING_BUDGET_US;
27262 
27263   if (MeasurementTimingBudgetMicroSeconds > 10000000) {
27264     Status = VL53LX_ERROR_INVALID_PARAMS;
27265   }
27266 
27267   if (Status == VL53LX_ERROR_NONE)
27268     Status = VL53LX_get_timeouts_us(
27269                &PhaseCalTimeoutUs,
27270                &MmTimeoutUs,
27271                &TimingBudget);
27272 
27273   TimingGuard = 1700;
27274   divisor = 6;
27275 
27276   if (MeasurementTimingBudgetMicroSeconds <= TimingGuard) {
27277     Status = VL53LX_ERROR_INVALID_PARAMS;
27278   } else {
27279     TimingBudget = (MeasurementTimingBudgetMicroSeconds
27280                     - TimingGuard);
27281   }
27282 
27283   if (Status == VL53LX_ERROR_NONE) {
27284     if (TimingBudget > FDAMaxTimingBudgetUs) {
27285       Status = VL53LX_ERROR_INVALID_PARAMS;
27286     } else {
27287       TimingBudget /= divisor;
27288       Status = VL53LX_set_timeouts_us(
27289                  PhaseCalTimeoutUs,
27290                  MmTimeoutUs,
27291                  TimingBudget);
27292     }
27293 
27294     if (Status == VL53LX_ERROR_NONE)
27295       VL53LXDevDataSet(Dev,
27296                        LLData.range_config_timeout_us,
27297                        TimingBudget);
27298   }
27299 
27300   if (Status == VL53LX_ERROR_NONE) {
27301     VL53LXDevDataSet(Dev,
27302                      CurrentParameters.MeasurementTimingBudgetMicroSeconds,
27303                      MeasurementTimingBudgetMicroSeconds);
27304   }
27305 
27306   return Status;
27307 }
27308 
27309 
27310 VL53LX_Error VL53LX::VL53LX_GetMeasurementTimingBudgetMicroSeconds(
27311   uint32_t *pMeasurementTimingBudgetMicroSeconds)
27312 {
27313   VL53LX_Error Status = VL53LX_ERROR_NONE;
27314   uint32_t MmTimeoutUs = 0;
27315   uint32_t RangeTimeoutUs = 0;
27316   uint32_t PhaseCalTimeoutUs = 0;
27317 
27318   *pMeasurementTimingBudgetMicroSeconds = 0;
27319 
27320   if (Status == VL53LX_ERROR_NONE)
27321     Status = VL53LX_get_timeouts_us(
27322                &PhaseCalTimeoutUs,
27323                &MmTimeoutUs,
27324                &RangeTimeoutUs);
27325 
27326   if (Status == VL53LX_ERROR_NONE)
27327     *pMeasurementTimingBudgetMicroSeconds = (6 * RangeTimeoutUs) +
27328                                             1700;
27329 
27330   return Status;
27331 }
27332 
27333 VL53LX_Error VL53LX::SetInterMeasurementPeriodMilliSeconds(
27334   uint32_t InterMeasurementPeriodMilliSeconds)
27335 {
27336   VL53LX_Error Status = VL53LX_ERROR_NONE;
27337   uint32_t adjustedIMP;
27338 
27339   adjustedIMP = InterMeasurementPeriodMilliSeconds;
27340   adjustedIMP += (adjustedIMP * 64) / 1000;
27341 
27342   Status = VL53LX_set_inter_measurement_period_ms(
27343              adjustedIMP);
27344 
27345   return Status;
27346 }
27347 
27348 VL53LX_Error VL53LX::GetInterMeasurementPeriodMilliSeconds(
27349   uint32_t *pInterMeasurementPeriodMilliSeconds)
27350 {
27351   VL53LX_Error Status = VL53LX_ERROR_NONE;
27352   uint32_t adjustedIMP;
27353 
27354 
27355   Status = VL53LX_get_inter_measurement_period_ms(&adjustedIMP);
27356 
27357   adjustedIMP -= (adjustedIMP * 64) / 1000;
27358   *pInterMeasurementPeriodMilliSeconds = adjustedIMP;
27359 
27360   return Status;
27361 }
27362 
27363 VL53LX_Error VL53LX::VL53LX_StartMeasurement()
27364 {
27365 #define TIMED_MODE_TIMING_GUARD_MILLISECONDS 4
27366   VL53LX_Error Status = VL53LX_ERROR_NONE;
27367   uint8_t DeviceMeasurementMode;
27368   VL53LX_Error lStatus;
27369   uint32_t MTBus, IMPms;
27370 
27371 
27372   VL53LX_load_patch();
27373 
27374   DeviceMeasurementMode = VL53LXDevDataGet(Dev, LLData.measurement_mode);
27375 
27376 
27377   if ((Status == VL53LX_ERROR_NONE) &&
27378       (DeviceMeasurementMode == VL53LX_DEVICEMEASUREMENTMODE_TIMED)) {
27379     lStatus = VL53LX_GetMeasurementTimingBudgetMicroSeconds(
27380                 &MTBus);
27381 
27382     MTBus /= 1000;
27383     lStatus = GetInterMeasurementPeriodMilliSeconds(
27384                 &IMPms);
27385 
27386     SUPPRESS_UNUSED_WARNING(lStatus);
27387     if (IMPms < MTBus + TIMED_MODE_TIMING_GUARD_MILLISECONDS) {
27388       Status = VL53LX_ERROR_INVALID_PARAMS;
27389     }
27390   }
27391 
27392   if (Status == VL53LX_ERROR_NONE)
27393     Status = VL53LX_init_and_start_range(
27394                DeviceMeasurementMode,
27395                VL53LX_DEVICECONFIGLEVEL_FULL);
27396 
27397   return Status;
27398 }
27399 
27400 VL53LX_Error VL53LX::VL53LX_StopMeasurement()
27401 {
27402   VL53LX_Error Status = VL53LX_ERROR_NONE;
27403 
27404   Status = VL53LX_stop_range();
27405 
27406   VL53LX_unload_patch();
27407 
27408   return Status;
27409 }
27410 
27411 VL53LX_Error VL53LX::VL53LX_ClearInterruptAndStartMeasurement()
27412 {
27413   VL53LX_Error Status = VL53LX_ERROR_NONE;
27414   uint8_t DeviceMeasurementMode;
27415 
27416   DeviceMeasurementMode = VL53LXDevDataGet(Dev, LLData.measurement_mode);
27417 
27418   Status = VL53LX_clear_interrupt_and_enable_next_range(
27419              DeviceMeasurementMode);
27420 
27421   return Status;
27422 }
27423 
27424 VL53LX_Error VL53LX::VL53LX_GetMeasurementDataReady(uint8_t *pMeasurementDataReady)
27425 {
27426   VL53LX_Error Status = VL53LX_ERROR_NONE;
27427 
27428   Status = VL53LX_is_new_data_ready(pMeasurementDataReady);
27429 
27430   return Status;
27431 }
27432 
27433 VL53LX_Error VL53LX::VL53LX_WaitMeasurementDataReady()
27434 {
27435   VL53LX_Error Status = VL53LX_ERROR_NONE;
27436 
27437   Status = VL53LX_poll_for_range_completion(
27438              VL53LX_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
27439 
27440   return Status;
27441 }
27442 
27443 uint8_t VL53LX::ConvertStatusHisto(uint8_t FilteredRangeStatus)
27444 {
27445   uint8_t RangeStatus;
27446 
27447   switch (FilteredRangeStatus) {
27448     case VL53LX_DEVICEERROR_RANGEPHASECHECK:
27449       RangeStatus = VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL;
27450       break;
27451     case VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK:
27452       RangeStatus = VL53LX_RANGESTATUS_SIGMA_FAIL;
27453       break;
27454     case VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK:
27455       RangeStatus =
27456         VL53LX_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL;
27457       break;
27458     case VL53LX_DEVICEERROR_PHASECONSISTENCY:
27459       RangeStatus = VL53LX_RANGESTATUS_WRAP_TARGET_FAIL;
27460       break;
27461     case VL53LX_DEVICEERROR_PREV_RANGE_NO_TARGETS:
27462       RangeStatus = VL53LX_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL;
27463       break;
27464     case VL53LX_DEVICEERROR_EVENTCONSISTENCY:
27465       RangeStatus = VL53LX_RANGESTATUS_WRAP_TARGET_FAIL;
27466       break;
27467     case VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE:
27468       RangeStatus = VL53LX_RANGESTATUS_RANGE_VALID_MERGED_PULSE;
27469       break;
27470     case VL53LX_DEVICEERROR_RANGECOMPLETE:
27471       RangeStatus = VL53LX_RANGESTATUS_RANGE_VALID;
27472       break;
27473     default:
27474       RangeStatus = VL53LX_RANGESTATUS_NONE;
27475   }
27476 
27477   return RangeStatus;
27478 }
27479 
27480 VL53LX_Error VL53LX::SetTargetData(
27481   uint8_t active_results, uint8_t device_status,
27482   VL53LX_range_data_t *presults_data,
27483   VL53LX_TargetRangeData_t *pRangeData)
27484 {
27485   VL53LX_Error Status = VL53LX_ERROR_NONE;
27486   uint8_t FilteredRangeStatus;
27487   FixPoint1616_t AmbientRate;
27488   FixPoint1616_t SignalRate;
27489   FixPoint1616_t TempFix1616;
27490   int16_t Range;
27491 
27492   SUPPRESS_UNUSED_WARNING(Dev);
27493 
27494   FilteredRangeStatus = presults_data->range_status & 0x1F;
27495 
27496   SignalRate = VL53LX_FIXPOINT97TOFIXPOINT1616(
27497                  presults_data->peak_signal_count_rate_mcps);
27498   pRangeData->SignalRateRtnMegaCps 
27499     = SignalRate;
27500 
27501   AmbientRate = VL53LX_FIXPOINT97TOFIXPOINT1616(
27502                   presults_data->ambient_count_rate_mcps);
27503   pRangeData->AmbientRateRtnMegaCps  = AmbientRate;
27504 
27505   TempFix1616 = VL53LX_FIXPOINT97TOFIXPOINT1616(
27506                   presults_data->VL53LX_p_002);
27507 
27508   pRangeData->SigmaMilliMeter  = TempFix1616;
27509 
27510   pRangeData->RangeMilliMeter  = presults_data->median_range_mm;
27511   pRangeData->RangeMaxMilliMeter  = presults_data->max_range_mm;
27512   pRangeData->RangeMinMilliMeter  = presults_data->min_range_mm;
27513 
27514 
27515   switch (device_status) {
27516     case VL53LX_DEVICEERROR_MULTCLIPFAIL:
27517     case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
27518     case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
27519     case VL53LX_DEVICEERROR_NOVHVVALUEFOUND:
27520       pRangeData->RangeStatus  =  VL53LX_RANGESTATUS_HARDWARE_FAIL;
27521       break;
27522     case VL53LX_DEVICEERROR_USERROICLIP:
27523       pRangeData->RangeStatus  =  VL53LX_RANGESTATUS_MIN_RANGE_FAIL;
27524       break;
27525     default:
27526       pRangeData->RangeStatus  =  VL53LX_RANGESTATUS_RANGE_VALID;
27527   }
27528 
27529 
27530   if ((pRangeData->RangeStatus  ==  VL53LX_RANGESTATUS_RANGE_VALID) &&
27531       (active_results == 0)) {
27532     pRangeData->RangeStatus  =  VL53LX_RANGESTATUS_NONE;
27533     pRangeData->SignalRateRtnMegaCps  = 0;
27534     pRangeData->SigmaMilliMeter  = 0;
27535     pRangeData->RangeMilliMeter  = 8191;
27536     pRangeData->RangeMaxMilliMeter  = 8191;
27537     pRangeData->RangeMinMilliMeter  = 8191;
27538   }
27539 
27540 
27541   if (pRangeData->RangeStatus  ==  VL53LX_RANGESTATUS_RANGE_VALID)
27542     pRangeData->RangeStatus  =
27543       ConvertStatusHisto(FilteredRangeStatus);
27544 
27545   Range = pRangeData->RangeMilliMeter ;
27546   if ((pRangeData->RangeStatus  ==  VL53LX_RANGESTATUS_RANGE_VALID) &&
27547       (Range < 0)) {
27548     if (Range < BDTable[VL53LX_TUNING_PROXY_MIN])
27549       pRangeData->RangeStatus  =
27550         VL53LX_RANGESTATUS_RANGE_INVALID;
27551     else {
27552       pRangeData->RangeMilliMeter  = 0;
27553     }
27554   }
27555 
27556   return Status;
27557 }
27558 
27559 VL53LX_Error VL53LX::SetMeasurementData(
27560   VL53LX_range_results_t *presults,
27561   VL53LX_MultiRangingData_t *pMultiRangingData)
27562 {
27563   uint8_t i;
27564   uint8_t iteration;
27565   VL53LX_TargetRangeData_t *pRangeData;
27566   VL53LX_range_data_t *presults_data;
27567   VL53LX_Error Status = VL53LX_ERROR_NONE;
27568   uint8_t ActiveResults;
27569 
27570   pMultiRangingData->NumberOfObjectsFound  = presults->active_results;
27571   pMultiRangingData->HasXtalkValueChanged  =
27572     presults->smudge_corrector_data.new_xtalk_applied_flag;
27573 
27574 
27575   pMultiRangingData->TimeStamp  = 0;
27576 
27577   pMultiRangingData->StreamCount  = presults->stream_count;
27578 
27579   ActiveResults = presults->active_results;
27580   if (ActiveResults < 1)
27581 
27582   {
27583     iteration = 1;
27584   } else {
27585     iteration = ActiveResults;
27586   }
27587   for (i = 0; i < iteration; i++) {
27588     pRangeData = &(pMultiRangingData->RangeData [i]);
27589 
27590     presults_data = &(presults->VL53LX_p_003[i]);
27591     if (Status == VL53LX_ERROR_NONE)
27592       Status = SetTargetData(ActiveResults,
27593                              presults->device_status,
27594                              presults_data,
27595                              pRangeData);
27596 
27597     pMultiRangingData->EffectiveSpadRtnCount  =
27598       presults_data->VL53LX_p_004;
27599 
27600   }
27601   return Status;
27602 }
27603 
27604 VL53LX_Error VL53LX::VL53LX_GetMultiRangingData(
27605   VL53LX_MultiRangingData_t *pMultiRangingData)
27606 {
27607   VL53LX_Error Status = VL53LX_ERROR_NONE;
27608   VL53LX_LLDriverData_t *pdev =
27609     VL53LXDevStructGetLLDriverHandle(Dev);
27610   VL53LX_range_results_t *presults =
27611     (VL53LX_range_results_t *) pdev->wArea1;
27612 
27613   memset(pMultiRangingData, 0xFF,
27614          sizeof(VL53LX_MultiRangingData_t));
27615 
27616 
27617   Status = VL53LX_get_device_results(
27618              VL53LX_DEVICERESULTSLEVEL_FULL,
27619              presults);
27620 
27621   Status = SetMeasurementData(
27622              presults,
27623              pMultiRangingData);
27624 
27625   return Status;
27626 }
27627 /*
27628 VL53LX_Error VL53LX::VL53LX_GetAdditionalData()
27629 {
27630   VL53LX_Error Status = VL53LX_ERROR_NONE;
27631 
27632 
27633   return Status;
27634 }
27635 */
27636 VL53LX_Error VL53LX::VL53LX_SetTuningParameter(
27637   uint16_t TuningParameterId, int32_t TuningParameterValue)
27638 {
27639   VL53LX_Error Status = VL53LX_ERROR_NONE;
27640 
27641   if (TuningParameterId ==
27642       VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS) {
27643     return VL53LX_ERROR_INVALID_PARAMS;
27644   }
27645 
27646   if (TuningParameterId >= 32768)
27647     Status = VL53LX_set_tuning_parm(
27648                TuningParameterId,
27649                TuningParameterValue);
27650   else {
27651     if (TuningParameterId < VL53LX_TUNING_MAX_TUNABLE_KEY) {
27652       BDTable[TuningParameterId] = TuningParameterValue;
27653     } else {
27654       Status = VL53LX_ERROR_INVALID_PARAMS;
27655     }
27656   }
27657 
27658   return Status;
27659 }
27660 VL53LX_Error VL53LX::VL53LX_GetTuningParameter(
27661   uint16_t TuningParameterId, int32_t *pTuningParameterValue)
27662 {
27663   VL53LX_Error Status = VL53LX_ERROR_NONE;
27664 
27665 
27666   if (TuningParameterId >= 32768)
27667     Status = VL53LX_get_tuning_parm(
27668                TuningParameterId,
27669                pTuningParameterValue);
27670   else {
27671     if (TuningParameterId < VL53LX_TUNING_MAX_TUNABLE_KEY) {
27672       *pTuningParameterValue = BDTable[TuningParameterId];
27673     } else {
27674       Status = VL53LX_ERROR_INVALID_PARAMS;
27675     }
27676   }
27677 
27678 
27679   return Status;
27680 }
27681 
27682 VL53LX_Error VL53LX::VL53LX_PerformRefSpadManagement()
27683 {
27684   VL53LX_Error Status = VL53LX_ERROR_NONE;
27685   VL53LX_Error RawStatus;
27686   uint8_t dcrbuffer[24];
27687   uint8_t *commbuf;
27688   uint8_t numloc[2] = {5, 3};
27689   VL53LX_LLDriverData_t *pdev;
27690   VL53LX_customer_nvm_managed_t *pc;
27691   VL53LX_DistanceModes DistanceMode;
27692 
27693   pdev = VL53LXDevStructGetLLDriverHandle(Dev);
27694   pc = &pdev->customer;
27695 
27696   if (Status == VL53LX_ERROR_NONE) {
27697     DistanceMode = VL53LXDevDataGet(Dev,
27698                                     CurrentParameters.DistanceMode);
27699     Status = VL53LX_run_ref_spad_char(&RawStatus);
27700 
27701     if (Status == VL53LX_ERROR_NONE) {
27702       Status = VL53LX_SetDistanceMode(DistanceMode);
27703     }
27704   }
27705 
27706   if (Status == VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH) {
27707 
27708     Status = VL53LX_read_nvm_raw_data(
27709                (uint8_t)(0xA0 >> 2),
27710                (uint8_t)(24 >> 2),
27711                dcrbuffer);
27712 
27713     if (Status == VL53LX_ERROR_NONE)
27714       Status = VL53LX_WriteMulti(Dev,
27715                                  VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS,
27716                                  numloc, 2);
27717 
27718     if (Status == VL53LX_ERROR_NONE) {
27719       pc->ref_spad_man__num_requested_ref_spads = numloc[0];
27720       pc->ref_spad_man__ref_location = numloc[1];
27721     }
27722 
27723     if (Status == VL53LX_ERROR_NONE) {
27724       commbuf = &dcrbuffer[16];
27725     }
27726 
27727 
27728 
27729     if (Status == VL53LX_ERROR_NONE)
27730       Status = VL53LX_WriteMulti(Dev,
27731                                  VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
27732                                  commbuf, 6);
27733 
27734     if (Status == VL53LX_ERROR_NONE) {
27735       pc->global_config__spad_enables_ref_0 = commbuf[0];
27736       pc->global_config__spad_enables_ref_1 = commbuf[1];
27737       pc->global_config__spad_enables_ref_2 = commbuf[2];
27738       pc->global_config__spad_enables_ref_3 = commbuf[3];
27739       pc->global_config__spad_enables_ref_4 = commbuf[4];
27740       pc->global_config__spad_enables_ref_5 = commbuf[5];
27741     }
27742 
27743   }
27744 
27745   return Status;
27746 }
27747 
27748 
27749 VL53LX_Error VL53LX::VL53LX_SmudgeCorrectionEnable(
27750   VL53LX_SmudgeCorrectionModes Mode)
27751 {
27752   VL53LX_Error Status = VL53LX_ERROR_NONE;
27753   VL53LX_Error s1 = VL53LX_ERROR_NONE;
27754   VL53LX_Error s2 = VL53LX_ERROR_NONE;
27755   VL53LX_Error s3 = VL53LX_ERROR_NONE;
27756 
27757   switch (Mode) {
27758     case VL53LX_SMUDGE_CORRECTION_NONE:
27759       s1 = VL53LX_dynamic_xtalk_correction_disable();
27760       s2 = VL53LX_dynamic_xtalk_correction_apply_disable();
27761       s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable();
27762       break;
27763     case VL53LX_SMUDGE_CORRECTION_CONTINUOUS:
27764       s1 = VL53LX_dynamic_xtalk_correction_enable();
27765       s2 = VL53LX_dynamic_xtalk_correction_apply_enable();
27766       s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable();
27767       break;
27768     case VL53LX_SMUDGE_CORRECTION_SINGLE:
27769       s1 = VL53LX_dynamic_xtalk_correction_enable();
27770       s2 = VL53LX_dynamic_xtalk_correction_apply_enable();
27771       s3 = VL53LX_dynamic_xtalk_correction_single_apply_enable();
27772       break;
27773     case VL53LX_SMUDGE_CORRECTION_DEBUG:
27774       s1 = VL53LX_dynamic_xtalk_correction_enable();
27775       s2 = VL53LX_dynamic_xtalk_correction_apply_disable();
27776       s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable();
27777       break;
27778     default:
27779       Status = VL53LX_ERROR_INVALID_PARAMS;
27780       break;
27781   }
27782 
27783   if (Status == VL53LX_ERROR_NONE) {
27784     Status = s1;
27785     if (Status == VL53LX_ERROR_NONE) {
27786       Status = s2;
27787     }
27788     if (Status == VL53LX_ERROR_NONE) {
27789       Status = s3;
27790     }
27791   }
27792 
27793   return Status;
27794 }
27795 
27796 VL53LX_Error VL53LX::VL53LX_SetXTalkCompensationEnable(
27797   uint8_t XTalkCompensationEnable)
27798 {
27799   VL53LX_Error Status = VL53LX_ERROR_NONE;
27800 
27801   if (XTalkCompensationEnable == 0) {
27802     Status = VL53LX_disable_xtalk_compensation();
27803   } else {
27804     Status = VL53LX_enable_xtalk_compensation();
27805   }
27806 
27807   return Status;
27808 }
27809 
27810 VL53LX_Error VL53LX::VL53LX_GetXTalkCompensationEnable(
27811   uint8_t *pXTalkCompensationEnable)
27812 {
27813   VL53LX_Error Status = VL53LX_ERROR_NONE;
27814 
27815   VL53LX_get_xtalk_compensation_enable(
27816     pXTalkCompensationEnable);
27817 
27818   return Status;
27819 }
27820 
27821 
27822 VL53LX_Error VL53LX::VL53LX_PerformXTalkCalibration()
27823 {
27824   VL53LX_Error Status = VL53LX_ERROR_NONE;
27825   VL53LX_Error UStatus;
27826   int16_t CalDistanceMm;
27827   VL53LX_xtalk_calibration_results_t xtalk;
27828 
27829   VL53LX_CalibrationData_t caldata;
27830   VL53LX_LLDriverData_t *pLLData;
27831   int i;
27832   uint32_t *pPlaneOffsetKcps;
27833   uint32_t Margin =
27834     BDTable[VL53LX_TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN];
27835   uint32_t DefaultOffset =
27836     BDTable[VL53LX_TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET];
27837   uint32_t *pLLDataPlaneOffsetKcps;
27838   uint32_t sum = 0;
27839   uint8_t binok = 0;
27840 
27841   pPlaneOffsetKcps =
27842     &caldata.customer.algo__crosstalk_compensation_plane_offset_kcps;
27843   pLLData = VL53LXDevStructGetLLDriverHandle(Dev);
27844   pLLDataPlaneOffsetKcps =
27845     &pLLData->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps;
27846 
27847   CalDistanceMm = (int16_t)
27848                   BDTable[VL53LX_TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM];
27849   Status = VL53LX_run_hist_xtalk_extraction(CalDistanceMm,
27850                                             &UStatus);
27851                                             
27852 
27853   VL53LX_GetCalibrationData(&caldata);
27854   for (i = 0; i < VL53LX_XTALK_HISTO_BINS; i++) {
27855     sum += caldata.xtalkhisto.xtalk_shape.bin_data[i];
27856     if (caldata.xtalkhisto.xtalk_shape.bin_data[i] > 0) {
27857       binok++;
27858     }
27859   }
27860 
27861   if ((UStatus ==
27862        VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL) ||
27863       (sum > (1024 + Margin)) || (sum < (1024 - Margin)) ||
27864       (binok < 3)) {
27865     *pPlaneOffsetKcps = DefaultOffset;
27866     *pLLDataPlaneOffsetKcps = DefaultOffset;
27867     caldata.xtalkhisto.xtalk_shape.bin_data[0] = 307;
27868     caldata.xtalkhisto.xtalk_shape.bin_data[1] = 410;
27869     caldata.xtalkhisto.xtalk_shape.bin_data[2] = 410;
27870     caldata.xtalkhisto.xtalk_shape.bin_data[3] = 307;
27871     for (i = 4; i < VL53LX_XTALK_HISTO_BINS; i++) {
27872       caldata.xtalkhisto.xtalk_shape.bin_data[i] = 0;
27873     }
27874     for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
27875       caldata.algo__xtalk_cpo_HistoMerge_kcps[i] =
27876         DefaultOffset + DefaultOffset * i;
27877     VL53LX_SetCalibrationData(&caldata);
27878   }
27879 
27880   if (Status == VL53LX_ERROR_NONE) {
27881     Status = VL53LX_get_current_xtalk_settings(&xtalk);
27882     Status = VL53LX_set_tuning_parm(
27883                VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS,
27884                xtalk.algo__crosstalk_compensation_plane_offset_kcps);
27885   }
27886 
27887   return Status;
27888 }
27889 VL53LX_Error VL53LX::VL53LX_SetOffsetCorrectionMode(
27890   VL53LX_OffsetCorrectionModes OffsetCorrectionMode)
27891 {
27892   VL53LX_Error Status = VL53LX_ERROR_NONE;
27893   VL53LX_OffsetCorrectionMode   offset_cor_mode;
27894 
27895   if (OffsetCorrectionMode == VL53LX_OFFSETCORRECTIONMODE_STANDARD) {
27896     offset_cor_mode =
27897       VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS;
27898   } else if (OffsetCorrectionMode ==
27899              VL53LX_OFFSETCORRECTIONMODE_PERVCSEL) {
27900     offset_cor_mode =
27901       VL53LX_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS;
27902   } else {
27903     Status = VL53LX_ERROR_INVALID_PARAMS;
27904   }
27905 
27906   if (Status == VL53LX_ERROR_NONE)
27907     Status =  VL53LX_set_offset_correction_mode(
27908                 offset_cor_mode);
27909 
27910   return Status;
27911 }
27912 
27913 VL53LX_Error VL53LX::VL53LX_PerformOffsetSimpleCalibration(
27914   int32_t CalDistanceMilliMeter)
27915 {
27916   VL53LX_Error Status = VL53LX_ERROR_NONE;
27917   int32_t sum_ranging;
27918   uint8_t offset_meas;
27919   int16_t Max, UnderMax, OverMax, Repeat;
27920   int32_t total_count, inloopcount;
27921   int32_t IncRounding;
27922   int16_t meanDistance_mm;
27923   int16_t offset;
27924   VL53LX_MultiRangingData_t RangingMeasurementData;
27925   VL53LX_LLDriverData_t *pdev;
27926   uint8_t goodmeas;
27927   VL53LX_Error SmudgeStatus = VL53LX_ERROR_NONE;
27928   uint8_t smudge_corr_en;
27929   VL53LX_TargetRangeData_t *pRange;
27930 
27931   pdev = VL53LXDevStructGetLLDriverHandle(Dev);
27932 
27933   smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
27934   SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable();
27935 
27936   pdev->customer.algo__part_to_part_range_offset_mm = 0;
27937   pdev->customer.mm_config__inner_offset_mm = 0;
27938   pdev->customer.mm_config__outer_offset_mm = 0;
27939   memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
27940   Repeat = BDTable[VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
27941   Max = BDTable[
27942          VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
27943   UnderMax = 1 + (Max / 2);
27944   OverMax = Max + (Max / 2);
27945   sum_ranging = 0;
27946   total_count = 0;
27947 
27948   while ((Repeat > 0) && (Status == VL53LX_ERROR_NONE)) {
27949     Status = VL53LX_StartMeasurement();
27950 
27951     if (Status == VL53LX_ERROR_NONE) {
27952       VL53LX_WaitMeasurementDataReady();
27953       VL53LX_GetMultiRangingData(
27954         &RangingMeasurementData);
27955       VL53LX_ClearInterruptAndStartMeasurement();
27956     }
27957 
27958     inloopcount = 0;
27959     offset_meas = 0;
27960     while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) &&
27961            (offset_meas < OverMax)) {
27962       Status = VL53LX_WaitMeasurementDataReady();
27963       if (Status == VL53LX_ERROR_NONE)
27964         Status = VL53LX_GetMultiRangingData(
27965                    &RangingMeasurementData);
27966       pRange = &(RangingMeasurementData.RangeData [0]);
27967       goodmeas = (pRange->RangeStatus  ==
27968                   VL53LX_RANGESTATUS_RANGE_VALID);
27969       if ((Status == VL53LX_ERROR_NONE) && goodmeas) {
27970         sum_ranging += pRange->RangeMilliMeter ;
27971         inloopcount++;
27972       }
27973       Status = VL53LX_ClearInterruptAndStartMeasurement();
27974       offset_meas++;
27975     }
27976     total_count += inloopcount;
27977 
27978 
27979     if (inloopcount < UnderMax) {
27980       Status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
27981     }
27982 
27983     VL53LX_StopMeasurement();
27984 
27985     Repeat--;
27986 
27987   }
27988 
27989   if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1)) {
27990     SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable();
27991   }
27992 
27993   if ((sum_ranging < 0) ||
27994       (sum_ranging > ((int32_t) total_count * 0xffff))) {
27995     Status = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
27996   }
27997 
27998   if ((Status == VL53LX_ERROR_NONE) && (total_count > 0)) {
27999     IncRounding = total_count / 2;
28000     meanDistance_mm = (int16_t)((sum_ranging + IncRounding)
28001                                 / total_count);
28002     offset = (int16_t)CalDistanceMilliMeter - meanDistance_mm;
28003     pdev->customer.algo__part_to_part_range_offset_mm = 0;
28004     pdev->customer.mm_config__inner_offset_mm = offset;
28005     pdev->customer.mm_config__outer_offset_mm = offset;
28006 
28007     Status = VL53LX_set_customer_nvm_managed(
28008                &(pdev->customer));
28009   }
28010 
28011   return Status;
28012 }
28013 
28014 
28015 VL53LX_Error VL53LX::VL53LX_PerformOffsetZeroDistanceCalibration()
28016 {
28017 #define START_OFFSET 50
28018   VL53LX_Error Status = VL53LX_ERROR_NONE;
28019   int32_t sum_ranging;
28020   uint8_t offset_meas;
28021   int16_t Max, UnderMax, OverMax, Repeat;
28022   int32_t total_count, inloopcount;
28023   int32_t IncRounding;
28024   int16_t meanDistance_mm;
28025   int16_t offset, ZeroDistanceOffset;
28026   VL53LX_MultiRangingData_t RangingMeasurementData;
28027   VL53LX_LLDriverData_t *pdev;
28028   uint8_t goodmeas;
28029   VL53LX_Error SmudgeStatus = VL53LX_ERROR_NONE;
28030   uint8_t smudge_corr_en;
28031   VL53LX_TargetRangeData_t *pRange;
28032 
28033   pdev = VL53LXDevStructGetLLDriverHandle(Dev);
28034   smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
28035   SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable();
28036   pdev->customer.algo__part_to_part_range_offset_mm = 0;
28037   pdev->customer.mm_config__inner_offset_mm = START_OFFSET;
28038   pdev->customer.mm_config__outer_offset_mm = START_OFFSET;
28039   memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
28040   ZeroDistanceOffset = BDTable[
28041                         VL53LX_TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR];
28042   Repeat = BDTable[VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
28043   Max =
28044     BDTable[VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
28045   UnderMax = 1 + (Max / 2);
28046   OverMax = Max + (Max / 2);
28047   sum_ranging = 0;
28048   total_count = 0;
28049 
28050   while ((Repeat > 0) && (Status == VL53LX_ERROR_NONE)) {
28051     Status = VL53LX_StartMeasurement();
28052     if (Status == VL53LX_ERROR_NONE) {
28053       VL53LX_WaitMeasurementDataReady();
28054       VL53LX_GetMultiRangingData(
28055         &RangingMeasurementData);
28056       VL53LX_ClearInterruptAndStartMeasurement();
28057     }
28058     inloopcount = 0;
28059     offset_meas = 0;
28060     while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) &&
28061            (offset_meas < OverMax)) {
28062       Status = VL53LX_WaitMeasurementDataReady();
28063       if (Status == VL53LX_ERROR_NONE)
28064         Status = VL53LX_GetMultiRangingData(
28065                    &RangingMeasurementData);
28066       pRange = &(RangingMeasurementData.RangeData [0]);
28067       goodmeas = (pRange->RangeStatus  ==
28068                   VL53LX_RANGESTATUS_RANGE_VALID);
28069       if ((Status == VL53LX_ERROR_NONE) && goodmeas) {
28070         sum_ranging = sum_ranging +
28071                       pRange->RangeMilliMeter ;
28072         inloopcount++;
28073       }
28074       Status = VL53LX_ClearInterruptAndStartMeasurement();
28075       offset_meas++;
28076     }
28077     total_count += inloopcount;
28078     if (inloopcount < UnderMax) {
28079       Status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
28080     }
28081     VL53LX_StopMeasurement();
28082     Repeat--;
28083   }
28084   if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1)) {
28085     SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable();
28086   }
28087   if ((sum_ranging < 0) ||
28088       (sum_ranging > ((int32_t) total_count * 0xffff))) {
28089     Status = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
28090   }
28091 
28092   if ((Status == VL53LX_ERROR_NONE) && (total_count > 0)) {
28093     IncRounding = total_count / 2;
28094     meanDistance_mm = (int16_t)
28095                       ((sum_ranging + IncRounding) / total_count);
28096     offset = START_OFFSET - meanDistance_mm + ZeroDistanceOffset;
28097     pdev->customer.algo__part_to_part_range_offset_mm = 0;
28098     pdev->customer.mm_config__inner_offset_mm = offset;
28099     pdev->customer.mm_config__outer_offset_mm = offset;
28100     Status = VL53LX_set_customer_nvm_managed(
28101                &(pdev->customer));
28102   }
28103 
28104   return Status;
28105 }
28106 
28107 VL53LX_Error VL53LX::VL53LX_SetCalibrationData(
28108   VL53LX_CalibrationData_t *pCalibrationData)
28109 {
28110   VL53LX_Error Status = VL53LX_ERROR_NONE;
28111   VL53LX_CustomerNvmManaged_t          *pC;
28112   VL53LX_calibration_data_t            cal_data;
28113   uint32_t x;
28114   VL53LX_xtalk_calibration_results_t xtalk;
28115 
28116   cal_data.struct_version = pCalibrationData->struct_version -
28117                             VL53LX_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
28118 
28119 
28120   memcpy(
28121     &(cal_data.add_off_cal_data),
28122     &(pCalibrationData->add_off_cal_data),
28123     sizeof(VL53LX_additional_offset_cal_data_t));
28124 
28125 
28126   memcpy(
28127     &(cal_data.optical_centre),
28128     &(pCalibrationData->optical_centre),
28129     sizeof(VL53LX_optical_centre_t));
28130 
28131 
28132   memcpy(
28133     &(cal_data.xtalkhisto),
28134     &(pCalibrationData->xtalkhisto),
28135     sizeof(VL53LX_xtalk_histogram_data_t));
28136 
28137 
28138   memcpy(
28139     &(cal_data.gain_cal),
28140     &(pCalibrationData->gain_cal),
28141     sizeof(VL53LX_gain_calibration_data_t));
28142 
28143 
28144   memcpy(
28145     &(cal_data.cal_peak_rate_map),
28146     &(pCalibrationData->cal_peak_rate_map),
28147     sizeof(VL53LX_cal_peak_rate_map_t));
28148 
28149 
28150   memcpy(
28151     &(cal_data.per_vcsel_cal_data),
28152     &(pCalibrationData->per_vcsel_cal_data),
28153     sizeof(VL53LX_per_vcsel_period_offset_cal_data_t));
28154 
28155   pC = &pCalibrationData->customer;
28156   x = pC->algo__crosstalk_compensation_plane_offset_kcps;
28157   cal_data.customer.algo__crosstalk_compensation_plane_offset_kcps =
28158     (uint16_t)(x & 0x0000FFFF);
28159 
28160   cal_data.customer.global_config__spad_enables_ref_0 =
28161     pC->global_config__spad_enables_ref_0;
28162   cal_data.customer.global_config__spad_enables_ref_1 =
28163     pC->global_config__spad_enables_ref_1;
28164   cal_data.customer.global_config__spad_enables_ref_2 =
28165     pC->global_config__spad_enables_ref_2;
28166   cal_data.customer.global_config__spad_enables_ref_3 =
28167     pC->global_config__spad_enables_ref_3;
28168   cal_data.customer.global_config__spad_enables_ref_4 =
28169     pC->global_config__spad_enables_ref_4;
28170   cal_data.customer.global_config__spad_enables_ref_5 =
28171     pC->global_config__spad_enables_ref_5;
28172   cal_data.customer.global_config__ref_en_start_select =
28173     pC->global_config__ref_en_start_select;
28174   cal_data.customer.ref_spad_man__num_requested_ref_spads =
28175     pC->ref_spad_man__num_requested_ref_spads;
28176   cal_data.customer.ref_spad_man__ref_location =
28177     pC->ref_spad_man__ref_location;
28178   cal_data.customer.algo__crosstalk_compensation_x_plane_gradient_kcps =
28179     pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
28180   cal_data.customer.algo__crosstalk_compensation_y_plane_gradient_kcps =
28181     pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
28182   cal_data.customer.ref_spad_char__total_rate_target_mcps =
28183     pC->ref_spad_char__total_rate_target_mcps;
28184   cal_data.customer.algo__part_to_part_range_offset_mm =
28185     pC->algo__part_to_part_range_offset_mm;
28186   cal_data.customer.mm_config__inner_offset_mm =
28187     pC->mm_config__inner_offset_mm;
28188   cal_data.customer.mm_config__outer_offset_mm =
28189     pC->mm_config__outer_offset_mm;
28190 
28191   Status = VL53LX_set_part_to_part_data(&cal_data);
28192 
28193   if (Status != VL53LX_ERROR_NONE) {
28194     goto ENDFUNC;
28195   }
28196 
28197   Status = VL53LX_get_current_xtalk_settings(&xtalk);
28198 
28199   if (Status != VL53LX_ERROR_NONE) {
28200     goto ENDFUNC;
28201   }
28202 
28203   xtalk.algo__crosstalk_compensation_plane_offset_kcps = x;
28204 
28205   Status = VL53LX_set_tuning_parm(
28206              VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS,
28207              x);
28208 
28209 
28210   memcpy(
28211     &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]),
28212     &(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]),
28213     sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
28214 
28215   Status = VL53LX_set_current_xtalk_settings(&xtalk);
28216 ENDFUNC:
28217   return Status;
28218 
28219 }
28220 
28221 VL53LX_Error VL53LX::VL53LX_GetCalibrationData(
28222   VL53LX_CalibrationData_t  *pCalibrationData)
28223 {
28224   VL53LX_Error Status = VL53LX_ERROR_NONE;
28225   VL53LX_calibration_data_t      cal_data;
28226   VL53LX_CustomerNvmManaged_t         *pC;
28227   VL53LX_customer_nvm_managed_t       *pC2;
28228   VL53LX_xtalk_calibration_results_t xtalk;
28229   uint32_t                          tmp;
28230 
28231   Status = VL53LX_get_part_to_part_data(&cal_data);
28232 
28233   pCalibrationData->struct_version = cal_data.struct_version +
28234                                      VL53LX_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION;
28235 
28236 
28237   memcpy(
28238     &(pCalibrationData->add_off_cal_data),
28239     &(cal_data.add_off_cal_data),
28240     sizeof(VL53LX_additional_offset_cal_data_t));
28241 
28242 
28243   memcpy(
28244     &(pCalibrationData->optical_centre),
28245     &(cal_data.optical_centre),
28246     sizeof(VL53LX_optical_centre_t));
28247 
28248 
28249   memcpy(
28250     &(pCalibrationData->xtalkhisto),
28251     &(cal_data.xtalkhisto),
28252     sizeof(VL53LX_xtalk_histogram_data_t));
28253 
28254   memcpy(
28255     &(pCalibrationData->gain_cal),
28256     &(cal_data.gain_cal),
28257     sizeof(VL53LX_gain_calibration_data_t));
28258 
28259 
28260   memcpy(
28261     &(pCalibrationData->cal_peak_rate_map),
28262     &(cal_data.cal_peak_rate_map),
28263     sizeof(VL53LX_cal_peak_rate_map_t));
28264 
28265 
28266   memcpy(
28267     &(pCalibrationData->per_vcsel_cal_data),
28268     &(cal_data.per_vcsel_cal_data),
28269     sizeof(VL53LX_per_vcsel_period_offset_cal_data_t));
28270 
28271   pC = &pCalibrationData->customer;
28272   pC2 = &cal_data.customer;
28273   pC->global_config__spad_enables_ref_0 =
28274     pC2->global_config__spad_enables_ref_0;
28275   pC->global_config__spad_enables_ref_1 =
28276     pC2->global_config__spad_enables_ref_1;
28277   pC->global_config__spad_enables_ref_2 =
28278     pC2->global_config__spad_enables_ref_2;
28279   pC->global_config__spad_enables_ref_3 =
28280     pC2->global_config__spad_enables_ref_3;
28281   pC->global_config__spad_enables_ref_4 =
28282     pC2->global_config__spad_enables_ref_4;
28283   pC->global_config__spad_enables_ref_5 =
28284     pC2->global_config__spad_enables_ref_5;
28285   pC->global_config__ref_en_start_select =
28286     pC2->global_config__ref_en_start_select;
28287   pC->ref_spad_man__num_requested_ref_spads =
28288     pC2->ref_spad_man__num_requested_ref_spads;
28289   pC->ref_spad_man__ref_location =
28290     pC2->ref_spad_man__ref_location;
28291   pC->algo__crosstalk_compensation_x_plane_gradient_kcps =
28292     pC2->algo__crosstalk_compensation_x_plane_gradient_kcps;
28293   pC->algo__crosstalk_compensation_y_plane_gradient_kcps =
28294     pC2->algo__crosstalk_compensation_y_plane_gradient_kcps;
28295   pC->ref_spad_char__total_rate_target_mcps =
28296     pC2->ref_spad_char__total_rate_target_mcps;
28297   pC->algo__part_to_part_range_offset_mm =
28298     pC2->algo__part_to_part_range_offset_mm;
28299   pC->mm_config__inner_offset_mm =
28300     pC2->mm_config__inner_offset_mm;
28301   pC->mm_config__outer_offset_mm =
28302     pC2->mm_config__outer_offset_mm;
28303 
28304   pC->algo__crosstalk_compensation_plane_offset_kcps =
28305     (uint32_t)(
28306       pC2->algo__crosstalk_compensation_plane_offset_kcps);
28307 
28308   Status = VL53LX_get_current_xtalk_settings(&xtalk);
28309 
28310   if (Status != VL53LX_ERROR_NONE) {
28311     goto ENDFUNC;
28312   }
28313 
28314   tmp = xtalk.algo__crosstalk_compensation_plane_offset_kcps;
28315   pC->algo__crosstalk_compensation_plane_offset_kcps = tmp;
28316   tmp = xtalk.algo__crosstalk_compensation_x_plane_gradient_kcps;
28317   pC->algo__crosstalk_compensation_x_plane_gradient_kcps = tmp;
28318   tmp = xtalk.algo__crosstalk_compensation_y_plane_gradient_kcps;
28319   pC->algo__crosstalk_compensation_y_plane_gradient_kcps = tmp;
28320 
28321   memcpy(&(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]),
28322          &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]),
28323          sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
28324 ENDFUNC:
28325   return Status;
28326 }
28327 
28328 
28329 VL53LX_Error VL53LX::VL53LX_PerformOffsetPerVcselCalibration(
28330   int32_t CalDistanceMilliMeter)
28331 {
28332   VL53LX_Error Status = VL53LX_ERROR_NONE;
28333   int32_t sum_ranging_range_A, sum_ranging_range_B;
28334   uint8_t offset_meas_range_A, offset_meas_range_B;
28335   int16_t Max, UnderMax, OverMax, Repeat;
28336   int32_t inloopcount;
28337   int32_t IncRounding;
28338   int16_t meanDistance_mm;
28339   VL53LX_MultiRangingData_t RangingMeasurementData;
28340   VL53LX_LLDriverData_t *pdev;
28341   uint8_t goodmeas;
28342   VL53LX_DistanceModes currentDist;
28343   VL53LX_DistanceModes DistMode[3] = {VL53LX_DISTANCEMODE_SHORT,
28344                                       VL53LX_DISTANCEMODE_MEDIUM, VL53LX_DISTANCEMODE_LONG
28345                                      };
28346   int16_t offsetA[3];
28347   int16_t offsetB[3];
28348 
28349   VL53LX_Error SmudgeStatus = VL53LX_ERROR_NONE;
28350   uint8_t smudge_corr_en, ics;
28351   VL53LX_TargetRangeData_t *pRange;
28352 
28353   pdev = VL53LXDevStructGetLLDriverHandle(Dev);
28354 
28355   smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
28356   SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable();
28357 
28358   pdev->customer.algo__part_to_part_range_offset_mm = 0;
28359   pdev->customer.mm_config__inner_offset_mm = 0;
28360   pdev->customer.mm_config__outer_offset_mm = 0;
28361   pdev->customer.mm_config__outer_offset_mm = 0;
28362   memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
28363 
28364   Repeat = 0;
28365   Max = 2 * BDTable[
28366          VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
28367   UnderMax = 1 + (Max / 2);
28368   OverMax = Max + (Max / 2);
28369 
28370   Status = VL53LX_GetDistanceMode(&currentDist);
28371 
28372   while ((Repeat < 3) && (Status == VL53LX_ERROR_NONE)) {
28373     Status = VL53LX_SetDistanceMode(DistMode[Repeat]);
28374     Status = VL53LX_StartMeasurement();
28375 
28376     if (Status == VL53LX_ERROR_NONE) {
28377       VL53LX_WaitMeasurementDataReady();
28378       VL53LX_GetMultiRangingData(
28379         &RangingMeasurementData);
28380       VL53LX_ClearInterruptAndStartMeasurement();
28381     }
28382 
28383     inloopcount = 0;
28384     offset_meas_range_A = 0;
28385     sum_ranging_range_A = 0;
28386     offset_meas_range_B = 0;
28387     sum_ranging_range_B = 0;
28388     while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) &&
28389            (inloopcount < OverMax)) {
28390       Status = VL53LX_WaitMeasurementDataReady();
28391       if (Status == VL53LX_ERROR_NONE)
28392         Status = VL53LX_GetMultiRangingData(
28393                    &RangingMeasurementData);
28394       pRange = &(RangingMeasurementData.RangeData [0]);
28395       goodmeas = (pRange->RangeStatus  ==
28396                   VL53LX_RANGESTATUS_RANGE_VALID);
28397       ics = pdev->ll_state.cfg_internal_stream_count;
28398       if ((Status == VL53LX_ERROR_NONE) && goodmeas) {
28399         if (ics & 0x01) {
28400           sum_ranging_range_A +=
28401             pRange->RangeMilliMeter ;
28402           offset_meas_range_A++;
28403         } else {
28404           sum_ranging_range_B +=
28405             pRange->RangeMilliMeter ;
28406           offset_meas_range_B++;
28407         }
28408         inloopcount = offset_meas_range_A +
28409                       offset_meas_range_B;
28410       }
28411       Status = VL53LX_ClearInterruptAndStartMeasurement();
28412     }
28413 
28414 
28415     if (inloopcount < UnderMax) {
28416       Status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
28417     }
28418 
28419     VL53LX_StopMeasurement();
28420 
28421 
28422     if ((sum_ranging_range_A < 0) ||
28423         (sum_ranging_range_B < 0) ||
28424         (sum_ranging_range_A >
28425          ((int32_t) offset_meas_range_A * 0xffff)) ||
28426         (sum_ranging_range_B >
28427          ((int32_t) offset_meas_range_B * 0xffff))) {
28428       Status = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
28429     }
28430 
28431     if ((Status == VL53LX_ERROR_NONE) &&
28432         (offset_meas_range_A > 0)) {
28433       IncRounding = offset_meas_range_A / 2;
28434       meanDistance_mm = (int16_t)
28435                         ((sum_ranging_range_A + IncRounding)
28436                          / offset_meas_range_A);
28437       offsetA[Repeat] = (int16_t)
28438                         CalDistanceMilliMeter - meanDistance_mm;
28439     }
28440 
28441     if ((Status == VL53LX_ERROR_NONE) &&
28442         (offset_meas_range_B > 0)) {
28443       IncRounding = offset_meas_range_B / 2;
28444       meanDistance_mm = (int16_t)
28445                         ((sum_ranging_range_B + IncRounding)
28446                          / offset_meas_range_B);
28447       offsetB[Repeat] = (int16_t)
28448                         CalDistanceMilliMeter - meanDistance_mm;
28449     }
28450     Repeat++;
28451   }
28452 
28453   if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1)) {
28454     SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable();
28455   }
28456 
28457   if (Status == VL53LX_ERROR_NONE) {
28458     pdev->per_vcsel_cal_data.short_a_offset_mm  = offsetA[0];
28459     pdev->per_vcsel_cal_data.short_b_offset_mm  = offsetB[0];
28460     pdev->per_vcsel_cal_data.medium_a_offset_mm = offsetA[1];
28461     pdev->per_vcsel_cal_data.medium_b_offset_mm = offsetB[1];
28462     pdev->per_vcsel_cal_data.long_a_offset_mm   = offsetA[2];
28463     pdev->per_vcsel_cal_data.long_b_offset_mm   = offsetB[2];
28464   }
28465 
28466   VL53LX_SetDistanceMode(currentDist);
28467 
28468   return Status;
28469 }
28470