Fork Charles's library
Dependencies: X_NUCLEO_COMMON ST_INTERFACES
Dependents: VL53L3ExpansionBoard
Diff: VL53L3SRC/vl53lx_class.cpp
- Revision:
- 0:0be0bd219e72
- Child:
- 2:ad33ff89d2cf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L3SRC/vl53lx_class.cpp Fri Oct 16 15:46:03 2020 +0000 @@ -0,0 +1,28470 @@ +/** + ****************************************************************************** + * @file vl53l3x_class.cpp + * @author IMG + * @version V0.0.1 + * @date 14-December-2018 + * @brief Implementation file for the VL53LX driver class + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2018 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** +*/ + +/* Includes */ +#include <stdlib.h> + +#include "mbed.h" + +#include "pinmap.h" +//#include "Arduino.h" +#include "vl53lx_class.h" +#include "vl53L3_I2c.h" + +#define TEMP_BUF_SIZE 80 + + +/* Write and read functions from I2C */ + +VL53LX_Error VL53LX::VL53LX_WriteMulti(VL53LX_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count) +{ + int status; + + status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, pdata, (uint16_t)count); + return status; +} + +VL53LX_Error VL53LX::VL53LX_ReadMulti(VL53LX_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count) +{ + int status; + + status = VL53LX_I2CRead(Dev->I2cDevAddr, index, pdata, (uint16_t)count); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_WrByte(VL53LX_DEV Dev, uint16_t index, uint8_t data) +{ + int status; + status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, &data, 1); + return status; +} + +VL53LX_Error VL53LX::VL53LX_WrWord(VL53LX_DEV Dev, uint16_t index, uint16_t data) +{ + int status; + uint8_t buffer[2]; + + buffer[0] = data >> 8; + buffer[1] = data & 0x00FF; + status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, (uint8_t *)buffer, 2); + return status; +} + +VL53LX_Error VL53LX::VL53LX_WrDWord(VL53LX_DEV Dev, uint16_t index, uint32_t data) +{ + int status; + uint8_t buffer[4]; + + buffer[0] = (data >> 24) & 0xFF; + buffer[1] = (data >> 16) & 0xFF; + buffer[2] = (data >> 8) & 0xFF; + buffer[3] = (data >> 0) & 0xFF; + status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, (uint8_t *)buffer, 4); + return status; +} + + +VL53LX_Error VL53LX::VL53LX_RdByte(VL53LX_DEV Dev, uint16_t index, uint8_t *data) +{ + int status; + + status = VL53LX_I2CRead(Dev->I2cDevAddr, index, data, 1); + + if (status) { + printf("VL53LX_RdByte fail %d %d %d \n",Dev->I2cDevAddr,index,status); + return -1; + } + + return 0; +} + +VL53LX_Error VL53LX::VL53LX_RdWord(VL53LX_DEV Dev, uint16_t index, uint16_t *data) +{ + int status; + uint8_t buffer[2] = {0, 0}; + + status = VL53LX_I2CRead(Dev->I2cDevAddr, index, buffer, 2); + if (!status) { + *data = (buffer[0] << 8) + buffer[1]; + } + return status; + +} + +VL53LX_Error VL53LX::VL53LX_RdDWord(VL53LX_DEV Dev, uint16_t index, uint32_t *data) +{ + int status; + uint8_t buffer[4] = {0, 0, 0, 0}; + + status = VL53LX_I2CRead(Dev->I2cDevAddr, index, buffer, 4); + if (!status) { + *data = ((uint32_t)buffer[0] << 24) + ((uint32_t)buffer[1] << 16) + ((uint32_t)buffer[2] << 8) + (uint32_t)buffer[3]; + } + return status; + +} + +VL53LX_Error VL53LX::VL53LX_UpdateByte(VL53LX_DEV Dev, uint16_t index, uint8_t AndData, uint8_t OrData) +{ + int status; + uint8_t buffer = 0; + + /* read data direct onto buffer */ + status = VL53LX_I2CRead(Dev->I2cDevAddr, index, &buffer, 1); + if (!status) { + buffer = (buffer & AndData) | OrData; + status = VL53LX_I2CWrite(Dev->I2cDevAddr, index, &buffer, (uint16_t)1); + } + return status; +} +/* + +VL53LX_Error VL53LX::VL53LX_I2CWrite(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToWrite) { + int ret; + uint8_t tmp[TEMP_BUF_SIZE]; + + if(NumByteToWrite >= TEMP_BUF_SIZE) return -2; + + // First, send device address. Then, send data and STOP condition + tmp[0] = RegisterAddr >> 8; + tmp[1] = RegisterAddr & 0x0FF; + memcpy(tmp+2, pBuffer, NumByteToWrite); + + ret = write(DeviceAddr, (const char*)tmp, NumByteToWrite+2, false); + + if(ret) return -1; + return 0; +} +*/ + + +VL53LX_Error VL53LX::VL53LX_I2CWrite(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToWrite) +{ + + return i2c_inst->VL53L3_i2c_write(pBuffer,DeviceAddr,RegisterAddr,NumByteToWrite); +} + + +VL53LX_Error VL53LX::VL53LX_I2CRead(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToRead) +{ + + return i2c_inst->VL53L3_i2c_read(pBuffer,DeviceAddr,RegisterAddr,NumByteToRead); +} + + +VL53LX_Error VL53LX::VL53LX_GetTickCount( + uint32_t *ptick_count_ms) +{ + + /* Returns current tick count in [ms] */ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + *ptick_count_ms = us_ticker_read() / 1000; + // *ptick_count_ms = 0; + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_WaitUs(VL53LX_Dev_t *pdev, int32_t wait_num_us) +{ + (void)pdev; + //delay(wait_us / 1000); + wait_ms(wait_num_us/1000); + return VL53LX_ERROR_NONE; +} + + +VL53LX_Error VL53LX::VL53LX_WaitMs(VL53LX_Dev_t *pdev, int32_t wait_num_ms) +{ + (void)pdev; + wait_ms(wait_num_ms); + return VL53LX_ERROR_NONE; +} + + +VL53LX_Error VL53LX::VL53LX_WaitValueMaskEx( + VL53LX_Dev_t *pdev, + uint32_t timeout_ms, + uint16_t index, + uint8_t value, + uint8_t mask, + uint32_t poll_delay_ms) +{ + + /* + * Platform implementation of WaitValueMaskEx V2WReg script command + * + * WaitValueMaskEx( + * duration_ms, + * index, + * value, + * mask, + * poll_delay_ms); + */ + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint32_t start_time_ms = 0; + uint32_t current_time_ms = 0; + uint32_t polling_time_ms = 0; + uint8_t byte_value = 0; + uint8_t found = 0; + + + + /* calculate time limit in absolute time */ + + VL53LX_GetTickCount(&start_time_ms); + + /* remember current trace functions and temporarily disable + * function logging + */ + + + /* wait until value is found, timeout reached on error occurred */ + + while ((status == VL53LX_ERROR_NONE) && + (polling_time_ms < timeout_ms) && + (found == 0)) { + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_RdByte( + pdev, + index, + &byte_value); + + + if ((byte_value & mask) == value) { + found = 1; + } + + if (status == VL53LX_ERROR_NONE && + found == 0 && + poll_delay_ms > 0) + status = VL53LX_WaitMs( + pdev, + poll_delay_ms); + + /* Update polling time (Compare difference rather than absolute to + negate 32bit wrap around issue) */ + VL53LX_GetTickCount(¤t_time_ms); + polling_time_ms = current_time_ms - start_time_ms; + + } + + + if (found == 0 && status == VL53LX_ERROR_NONE) { + status = VL53LX_ERROR_TIME_OUT; + } + + return status; +} + + + +/* vl53lx_api_core.c */ +VL53LX_Error VL53LX::select_offset_per_vcsel(VL53LX_LLDriverData_t *pdev, int16_t *poffset) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + int16_t tA, tB; + uint8_t isc; + + switch (pdev->preset_mode) { + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE: + tA = pdev->per_vcsel_cal_data.short_a_offset_mm; + tB = pdev->per_vcsel_cal_data.short_b_offset_mm; + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE: + tA = pdev->per_vcsel_cal_data.medium_a_offset_mm; + tB = pdev->per_vcsel_cal_data.medium_b_offset_mm; + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE: + tA = pdev->per_vcsel_cal_data.long_a_offset_mm; + tB = pdev->per_vcsel_cal_data.long_b_offset_mm; + break; + default: + tA = pdev->per_vcsel_cal_data.long_a_offset_mm; + tB = pdev->per_vcsel_cal_data.long_b_offset_mm; + status = VL53LX_ERROR_INVALID_PARAMS; + *poffset = 0; + break; + } + + isc = pdev->ll_state.cfg_internal_stream_count; + if (status == VL53LX_ERROR_NONE) { + *poffset = (isc & 0x01) ? tA : tB; + } + + return status; +} + + +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) +{ + uint16_t bin = 0; + int32_t total_rate_pre = 0; + int32_t total_rate_cur = 0; + int32_t PrevBin, CurrBin; + + total_rate_pre = 0; + total_rate_cur = 0; + + + for (bin = timing * 4; bin < HighIndex; bin++) { + total_rate_pre += + pdev->multi_bins_rec[prev_pos][timing][bin]; + total_rate_cur += pdata->bin_data[bin]; + } + + if ((total_rate_pre != 0) && (total_rate_cur != 0)) + for (bin = timing * 4; bin < HighIndex; bin++) { + PrevBin = pdev->multi_bins_rec[prev_pos][timing][bin]; + PrevBin = (PrevBin * 1000) / total_rate_pre; + CurrBin = pdata->bin_data[bin] * 1000 / total_rate_cur; + *pdiff_histo_stddev += (PrevBin - CurrBin) * + (PrevBin - CurrBin); + } +} + + +void VL53LX::vl53lx_histo_merge(VL53LX_histogram_bin_data_t *pdata) +{ + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + uint16_t bin = 0; + uint8_t i = 0; + int32_t TuningBinRecSize = 0; + uint8_t recom_been_reset = 0; + uint8_t timing = 0; + int32_t rmt = 0; + int32_t diff_histo_stddev = 0; + uint8_t HighIndex, prev_pos; + uint8_t BuffSize = VL53LX_HISTOGRAM_BUFFER_SIZE; + uint8_t pos; + + VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, + &TuningBinRecSize); + + VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD, + &rmt); + + + if (pdev->pos_before_next_recom == 0) { + + timing = 1 - pdata->result__stream_count % 2; + + diff_histo_stddev = 0; + HighIndex = BuffSize - timing * 4; + if (pdev->bin_rec_pos > 0) { + prev_pos = pdev->bin_rec_pos - 1; + } else { + prev_pos = (TuningBinRecSize - 1); + } + + if (pdev->multi_bins_rec[prev_pos][timing][4] > 0) + vl53lx_diff_histo_stddev(pdev, pdata, + timing, HighIndex, prev_pos, + &diff_histo_stddev); + + if (diff_histo_stddev >= rmt) { + memset(pdev->multi_bins_rec, 0, + sizeof(pdev->multi_bins_rec)); + pdev->bin_rec_pos = 0; + + recom_been_reset = 1; + + if (timing == 0) + pdev->pos_before_next_recom = + VL53LX_FRAME_WAIT_EVENT; + else + pdev->pos_before_next_recom = + VL53LX_FRAME_WAIT_EVENT + 1; + } else { + + pos = pdev->bin_rec_pos; + for (i = 0; i < BuffSize; i++) + pdev->multi_bins_rec[pos][timing][i] = + pdata->bin_data[i]; + } + + if (pdev->bin_rec_pos == (TuningBinRecSize - 1) && timing == 1) { + pdev->bin_rec_pos = 0; + } else if (timing == 1) { + pdev->bin_rec_pos++; + } + + if (!((recom_been_reset == 1) && (timing == 0)) && + (pdev->pos_before_next_recom == 0)) { + + for (bin = 0; bin < BuffSize; bin++) { + pdata->bin_data[bin] = 0; + } + + for (bin = 0; bin < BuffSize; bin++) + for (i = 0; i < TuningBinRecSize; i++) + pdata->bin_data[bin] += + (pdev->multi_bins_rec[i][timing][bin]); + } + } else { + + pdev->pos_before_next_recom--; + if (pdev->pos_before_next_recom == 255) { + pdev->pos_before_next_recom = 0; + } + } +} + +VL53LX_Error VL53LX::VL53LX_load_patch() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + int32_t patch_tuning = 0; + uint8_t comms_buffer[256]; + uint32_t patch_power; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte(Dev, + VL53LX_FIRMWARE__ENABLE, 0x00); + + if (status == VL53LX_ERROR_NONE) { + VL53LX_enable_powerforce(); + } + + VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER, + &patch_tuning); + + switch (patch_tuning) { + case 0: + patch_power = 0x00; + break; + case 1: + patch_power = 0x10; + break; + case 2: + patch_power = 0x20; + break; + case 3: + patch_power = 0x40; + break; + default: + patch_power = 0x00; + } + + if (status == VL53LX_ERROR_NONE) { + + comms_buffer[0] = 0x29; + comms_buffer[1] = 0xC9; + comms_buffer[2] = 0x0E; + comms_buffer[3] = 0x40; + comms_buffer[4] = 0x28; + comms_buffer[5] = patch_power; + + status = VL53LX_WriteMulti(Dev, + VL53LX_PATCH__OFFSET_0, comms_buffer, 6); + } + + if (status == VL53LX_ERROR_NONE) { + comms_buffer[0] = 0x03; + comms_buffer[1] = 0x6D; + comms_buffer[2] = 0x03; + comms_buffer[3] = 0x6F; + comms_buffer[4] = 0x07; + comms_buffer[5] = 0x29; + status = VL53LX_WriteMulti(Dev, + VL53LX_PATCH__ADDRESS_0, comms_buffer, 6); + } + + if (status == VL53LX_ERROR_NONE) { + comms_buffer[0] = 0x00; + comms_buffer[1] = 0x07; + status = VL53LX_WriteMulti(Dev, VL53LX_PATCH__JMP_ENABLES, comms_buffer, 2); + } + + if (status == VL53LX_ERROR_NONE) { + comms_buffer[0] = 0x00; + comms_buffer[1] = 0x07; + status = VL53LX_WriteMulti(Dev, + VL53LX_PATCH__DATA_ENABLES, comms_buffer, 2); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte(Dev, + VL53LX_PATCH__CTRL, 0x01); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte(Dev, + VL53LX_FIRMWARE__ENABLE, 0x01); + + + return status; +} + +VL53LX_Error VL53LX:: VL53LX_unload_patch() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x00); + } + + if (status == VL53LX_ERROR_NONE) { + VL53LX_disable_powerforce(); + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WrByte(Dev, VL53LX_PATCH__CTRL, 0x00); + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x01); + } + + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_version(VL53LX_ll_version_t *pdata) +{ + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_init_version(); + + memcpy(pdata, &(pdev->version), sizeof(VL53LX_ll_version_t)); + + return VL53LX_ERROR_NONE; +} + +VL53LX_Error VL53LX::VL53LX_get_device_firmware_version(uint16_t *pfw_version) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_RdWord( + Dev, + VL53LX_MCU_GENERAL_PURPOSE__GP_0, + pfw_version); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_data_init(uint8_t read_p2p_data) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + + + VL53LX_zone_objects_t *pobjects; + + uint8_t i = 0; + + VL53LX_init_ll_driver_state(VL53LX_DEVICESTATE_UNKNOWN); + + pres->range_results.max_results = VL53LX_MAX_RANGE_RESULTS; + pres->range_results.active_results = 0; + pres->zone_results.max_zones = VL53LX_MAX_USER_ZONES; + pres->zone_results.active_zones = 0; + + for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) { + pobjects = &(pres->zone_results.VL53LX_p_003[i]); + pobjects->xmonitor.VL53LX_p_016 = 0; + pobjects->xmonitor.VL53LX_p_017 = 0; + pobjects->xmonitor.VL53LX_p_011 = 0; + pobjects->xmonitor.range_status = + VL53LX_DEVICEERROR_NOUPDATE; + } + + + + pres->zone_hists.max_zones = VL53LX_MAX_USER_ZONES; + pres->zone_hists.active_zones = 0; + + + + pres->zone_cal.max_zones = VL53LX_MAX_USER_ZONES; + pres->zone_cal.active_zones = 0; + for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) { + pres->zone_cal.VL53LX_p_003[i].no_of_samples = 0; + pres->zone_cal.VL53LX_p_003[i].effective_spads = 0; + pres->zone_cal.VL53LX_p_003[i].peak_rate_mcps = 0; + pres->zone_cal.VL53LX_p_003[i].median_range_mm = 0; + pres->zone_cal.VL53LX_p_003[i].range_mm_offset = 0; + } + + pdev->wait_method = VL53LX_WAIT_METHOD_BLOCKING; + pdev->preset_mode = VL53LX_DEVICEPRESETMODE_STANDARD_RANGING; + pdev->zone_preset = VL53LX_DEVICEZONEPRESET_NONE; + pdev->measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_STOP; + + pdev->offset_calibration_mode = + VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD; + pdev->offset_correction_mode = + VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS; + pdev->dmax_mode = + VL53LX_DEVICEDMAXMODE__FMT_CAL_DATA; + + pdev->phasecal_config_timeout_us = 1000; + pdev->mm_config_timeout_us = 2000; + pdev->range_config_timeout_us = 13000; + pdev->inter_measurement_period_ms = 100; + pdev->dss_config__target_total_rate_mcps = 0x0A00; + pdev->debug_mode = 0x00; + + pdev->offset_results.max_results = VL53LX_MAX_OFFSET_RANGE_RESULTS; + pdev->offset_results.active_results = 0; + + + + pdev->gain_cal.standard_ranging_gain_factor = + VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR_DEFAULT; + pdev->gain_cal.histogram_ranging_gain_factor = + VL53LX_TUNINGPARM_HIST_GAIN_FACTOR_DEFAULT; + + + VL53LX_init_version(); + + + memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec)); + pdev->bin_rec_pos = 0; + pdev->pos_before_next_recom = 0; + + + + if (read_p2p_data > 0 && status == VL53LX_ERROR_NONE) { + status = VL53LX_read_p2p_data(); + } + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_refspadchar_config_struct( + &(pdev->refspadchar)); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_ssc_config_struct( + &(pdev->ssc_cfg)); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_xtalk_config_struct( + &(pdev->customer), + &(pdev->xtalk_cfg)); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_xtalk_extract_config_struct( + &(pdev->xtalk_extract_cfg)); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_offset_cal_config_struct( + &(pdev->offsetcal_cfg)); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_zone_cal_config_struct( + &(pdev->zonecal_cfg)); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_hist_post_process_config_struct( + pdev->xtalk_cfg.global_crosstalk_compensation_enable, + &(pdev->histpostprocess)); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_hist_gen3_dmax_config_struct( + &(pdev->dmax_cfg)); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_tuning_parm_storage_struct( + &(pdev->tuning_parms)); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_set_preset_mode( + pdev->preset_mode, + pdev->dss_config__target_total_rate_mcps, + pdev->phasecal_config_timeout_us, + pdev->mm_config_timeout_us, + pdev->range_config_timeout_us, + pdev->inter_measurement_period_ms); + + + VL53LX_init_histogram_bin_data_struct( + 0, + VL53LX_HISTOGRAM_BUFFER_SIZE, + &(pdev->hist_data)); + + VL53LX_init_histogram_bin_data_struct( + 0, + VL53LX_HISTOGRAM_BUFFER_SIZE, + &(pdev->hist_xtalk)); + + + VL53LX_init_xtalk_bin_data_struct( + 0, + VL53LX_XTALK_HISTO_BINS, + &(pdev->xtalk_shapes.xtalk_shape)); + + + + VL53LX_xtalk_cal_data_init(); + + + + VL53LX_dynamic_xtalk_correction_data_init(); + + + + VL53LX_low_power_auto_data_init(); + /* + #ifdef VL53LX_LOG_ENABLE + + + + VL53LX_print_static_nvm_managed( + &(pdev->stat_nvm), + "data_init():pdev->lldata.stat_nvm.", + VL53LX_TRACE_MODULE_DATA_INIT); + + VL53LX_print_customer_nvm_managed( + &(pdev->customer), + "data_init():pdev->lldata.customer.", + VL53LX_TRACE_MODULE_DATA_INIT); + + VL53LX_print_nvm_copy_data( + &(pdev->nvm_copy_data), + "data_init():pdev->lldata.nvm_copy_data.", + VL53LX_TRACE_MODULE_DATA_INIT); + + VL53LX_print_dmax_calibration_data( + &(pdev->fmt_dmax_cal), + "data_init():pdev->lldata.fmt_dmax_cal.", + VL53LX_TRACE_MODULE_DATA_INIT); + + VL53LX_print_dmax_calibration_data( + &(pdev->cust_dmax_cal), + "data_init():pdev->lldata.cust_dmax_cal.", + VL53LX_TRACE_MODULE_DATA_INIT); + + VL53LX_print_additional_offset_cal_data( + &(pdev->add_off_cal_data), + "data_init():pdev->lldata.add_off_cal_data.", + VL53LX_TRACE_MODULE_DATA_INIT); + + VL53LX_print_user_zone( + &(pdev->mm_roi), + "data_init():pdev->lldata.mm_roi.", + VL53LX_TRACE_MODULE_DATA_INIT); + + VL53LX_print_optical_centre( + &(pdev->optical_centre), + "data_init():pdev->lldata.optical_centre.", + VL53LX_TRACE_MODULE_DATA_INIT); + + VL53LX_print_cal_peak_rate_map( + &(pdev->cal_peak_rate_map), + "data_init():pdev->lldata.cal_peak_rate_map.", + VL53LX_TRACE_MODULE_DATA_INIT); + + #endif + + LOG_FUNCTION_END(status); + */ + return status; +} + +VL53LX_Error VL53LX::VL53LX_read_p2p_data() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + VL53LX_customer_nvm_managed_t *pN = &(pdev->customer); + VL53LX_additional_offset_cal_data_t *pCD = &(pdev->add_off_cal_data); + + VL53LX_decoded_nvm_fmt_range_data_t fmt_rrd; + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_get_static_nvm_managed(&(pdev->stat_nvm)); + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_get_customer_nvm_managed(&(pdev->customer)); + } + + if (status == VL53LX_ERROR_NONE) { + + status = VL53LX_get_nvm_copy_data(&(pdev->nvm_copy_data)); + + + if (status == VL53LX_ERROR_NONE) + VL53LX_copy_rtn_good_spads_to_buffer( + &(pdev->nvm_copy_data), + &(pdev->rtn_good_spads[0])); + } + + + + if (status == VL53LX_ERROR_NONE) { + pHP->algo__crosstalk_compensation_plane_offset_kcps = + pN->algo__crosstalk_compensation_plane_offset_kcps; + pHP->algo__crosstalk_compensation_x_plane_gradient_kcps = + pN->algo__crosstalk_compensation_x_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_y_plane_gradient_kcps = + pN->algo__crosstalk_compensation_y_plane_gradient_kcps; + } + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_read_nvm_optical_centre(&(pdev->optical_centre)); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_read_nvm_cal_peak_rate_map(&(pdev->cal_peak_rate_map)); + + + + if (status == VL53LX_ERROR_NONE) { + + status = + VL53LX_read_nvm_additional_offset_cal_data(&(pdev->add_off_cal_data)); + + + + if (pCD->result__mm_inner_peak_signal_count_rtn_mcps == 0 && + pCD->result__mm_outer_peak_signal_count_rtn_mcps == 0) { + + pCD->result__mm_inner_peak_signal_count_rtn_mcps + = 0x0080; + pCD->result__mm_outer_peak_signal_count_rtn_mcps + = 0x0180; + + + + VL53LX_calc_mm_effective_spads( + pdev->nvm_copy_data.roi_config__mode_roi_centre_spad, + pdev->nvm_copy_data.roi_config__mode_roi_xy_size, + 0xC7, + 0xFF, + &(pdev->rtn_good_spads[0]), + VL53LX_RTN_SPAD_APERTURE_TRANSMISSION, + &(pCD->result__mm_inner_actual_effective_spads), + &(pCD->result__mm_outer_actual_effective_spads)); + } + } + + + if (status == VL53LX_ERROR_NONE) { + + status = + VL53LX_read_nvm_fmt_range_results_data(VL53LX_NVM__FMT__RANGE_RESULTS__140MM_DARK, + &fmt_rrd); + + if (status == VL53LX_ERROR_NONE) { + pdev->fmt_dmax_cal.ref__actual_effective_spads = + fmt_rrd.result__actual_effective_rtn_spads; + pdev->fmt_dmax_cal.ref__peak_signal_count_rate_mcps = + fmt_rrd.result__peak_signal_count_rate_rtn_mcps; + pdev->fmt_dmax_cal.ref__distance_mm = + fmt_rrd.measured_distance_mm; + + + if (pdev->cal_peak_rate_map.cal_reflectance_pc != 0) { + pdev->fmt_dmax_cal.ref_reflectance_pc = + pdev->cal_peak_rate_map.cal_reflectance_pc; + } else { + pdev->fmt_dmax_cal.ref_reflectance_pc = 0x0014; + } + + + pdev->fmt_dmax_cal.coverglass_transmission = 0x0100; + } + } + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_RdWord( + Dev, + VL53LX_RESULT__OSC_CALIBRATE_VAL, + &(pdev->dbg_results.result__osc_calibrate_val)); + + + + if (pdev->stat_nvm.osc_measured__fast_osc__frequency < 0x1000) { + + pdev->stat_nvm.osc_measured__fast_osc__frequency = 0xBCCC; + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_get_mode_mitigation_roi(&(pdev->mm_roi)); + + + + if (pdev->optical_centre.x_centre == 0 && + pdev->optical_centre.y_centre == 0) { + pdev->optical_centre.x_centre = + pdev->mm_roi.x_centre << 4; + pdev->optical_centre.y_centre = + pdev->mm_roi.y_centre << 4; + } + + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_software_reset() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_SOFT_RESET, + 0x00); + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WaitUs( + Dev, + VL53LX_SOFTWARE_RESET_DURATION_US); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_SOFT_RESET, + 0x01); + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_wait_for_boot_completion(); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_part_to_part_data(VL53LX_calibration_data_t *pcal_data) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg); + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + VL53LX_customer_nvm_managed_t *pN = &(pdev->customer); + + uint32_t tempu32; + + + if (pcal_data->struct_version != + VL53LX_LL_CALIBRATION_DATA_STRUCT_VERSION) { + status = VL53LX_ERROR_INVALID_PARAMS; + } + + if (status == VL53LX_ERROR_NONE) { + + + memcpy( + &(pdev->customer), + &(pcal_data->customer), + sizeof(VL53LX_customer_nvm_managed_t)); + + + memcpy( + &(pdev->add_off_cal_data), + &(pcal_data->add_off_cal_data), + sizeof(VL53LX_additional_offset_cal_data_t)); + + + memcpy( + &(pdev->fmt_dmax_cal), + &(pcal_data->fmt_dmax_cal), + sizeof(VL53LX_dmax_calibration_data_t)); + + + memcpy( + &(pdev->cust_dmax_cal), + &(pcal_data->cust_dmax_cal), + sizeof(VL53LX_dmax_calibration_data_t)); + + + memcpy( + &(pdev->xtalk_shapes), + &(pcal_data->xtalkhisto), + sizeof(VL53LX_xtalk_histogram_data_t)); + + + memcpy( + &(pdev->gain_cal), + &(pcal_data->gain_cal), + sizeof(VL53LX_gain_calibration_data_t)); + + + memcpy( + &(pdev->cal_peak_rate_map), + &(pcal_data->cal_peak_rate_map), + sizeof(VL53LX_cal_peak_rate_map_t)); + + + memcpy( + &(pdev->per_vcsel_cal_data), + &(pcal_data->per_vcsel_cal_data), + sizeof(VL53LX_per_vcsel_period_offset_cal_data_t)); + + + + pC->algo__crosstalk_compensation_plane_offset_kcps = + pN->algo__crosstalk_compensation_plane_offset_kcps; + pC->algo__crosstalk_compensation_x_plane_gradient_kcps = + pN->algo__crosstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps = + pN->algo__crosstalk_compensation_y_plane_gradient_kcps; + + pHP->algo__crosstalk_compensation_plane_offset_kcps = + VL53LX_calc_crosstalk_plane_offset_with_margin( + pC->algo__crosstalk_compensation_plane_offset_kcps, + pC->histogram_mode_crosstalk_margin_kcps); + + pHP->algo__crosstalk_compensation_x_plane_gradient_kcps = + pC->algo__crosstalk_compensation_x_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_y_plane_gradient_kcps = + pC->algo__crosstalk_compensation_y_plane_gradient_kcps; + + + + if (pC->global_crosstalk_compensation_enable == 0x00) { + pN->algo__crosstalk_compensation_plane_offset_kcps = + 0x00; + pN->algo__crosstalk_compensation_x_plane_gradient_kcps = + 0x00; + pN->algo__crosstalk_compensation_y_plane_gradient_kcps = + 0x00; + } else { + tempu32 = + VL53LX_calc_crosstalk_plane_offset_with_margin( + pC->algo__crosstalk_compensation_plane_offset_kcps, + pC->lite_mode_crosstalk_margin_kcps); + + + if (tempu32 > 0xFFFF) { + tempu32 = 0xFFFF; + } + + pN->algo__crosstalk_compensation_plane_offset_kcps = + (uint16_t)tempu32; + } + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_part_to_part_data(VL53LX_calibration_data_t *pcal_data) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg); + VL53LX_customer_nvm_managed_t *pCN = &(pcal_data->customer); + + pcal_data->struct_version = + VL53LX_LL_CALIBRATION_DATA_STRUCT_VERSION; + + + memcpy( + &(pcal_data->customer), + &(pdev->customer), + sizeof(VL53LX_customer_nvm_managed_t)); + + + + + if (pC->algo__crosstalk_compensation_plane_offset_kcps > 0xFFFF) { + pCN->algo__crosstalk_compensation_plane_offset_kcps = + 0xFFFF; + } else { + pCN->algo__crosstalk_compensation_plane_offset_kcps = + (uint16_t)pC->algo__crosstalk_compensation_plane_offset_kcps; + } + pCN->algo__crosstalk_compensation_x_plane_gradient_kcps = + pC->algo__crosstalk_compensation_x_plane_gradient_kcps; + pCN->algo__crosstalk_compensation_y_plane_gradient_kcps = + pC->algo__crosstalk_compensation_y_plane_gradient_kcps; + + + memcpy( + &(pcal_data->fmt_dmax_cal), + &(pdev->fmt_dmax_cal), + sizeof(VL53LX_dmax_calibration_data_t)); + + + memcpy( + &(pcal_data->cust_dmax_cal), + &(pdev->cust_dmax_cal), + sizeof(VL53LX_dmax_calibration_data_t)); + + + memcpy( + &(pcal_data->add_off_cal_data), + &(pdev->add_off_cal_data), + sizeof(VL53LX_additional_offset_cal_data_t)); + + + memcpy( + &(pcal_data->optical_centre), + &(pdev->optical_centre), + sizeof(VL53LX_optical_centre_t)); + + + memcpy( + &(pcal_data->xtalkhisto), + &(pdev->xtalk_shapes), + sizeof(VL53LX_xtalk_histogram_data_t)); + + + memcpy( + &(pcal_data->gain_cal), + &(pdev->gain_cal), + sizeof(VL53LX_gain_calibration_data_t)); + + + memcpy( + &(pcal_data->cal_peak_rate_map), + &(pdev->cal_peak_rate_map), + sizeof(VL53LX_cal_peak_rate_map_t)); + + + memcpy( + &(pcal_data->per_vcsel_cal_data), + &(pdev->per_vcsel_cal_data), + sizeof(VL53LX_per_vcsel_period_offset_cal_data_t)); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_inter_measurement_period_ms( + uint32_t inter_measurement_period_ms) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + if (pdev->dbg_results.result__osc_calibrate_val == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } + + if (status == VL53LX_ERROR_NONE) { + pdev->inter_measurement_period_ms = inter_measurement_period_ms; + pdev->tim_cfg.system__intermeasurement_period = + inter_measurement_period_ms * + (uint32_t)pdev->dbg_results.result__osc_calibrate_val; + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_inter_measurement_period_ms(uint32_t *pinter_measurement_period_ms) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + if (pdev->dbg_results.result__osc_calibrate_val == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } + + if (status == VL53LX_ERROR_NONE) + *pinter_measurement_period_ms = + pdev->tim_cfg.system__intermeasurement_period / + (uint32_t)pdev->dbg_results.result__osc_calibrate_val; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_timeouts_us( + uint32_t phasecal_config_timeout_us, + uint32_t mm_config_timeout_us, + uint32_t range_config_timeout_us) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + + if (pdev->stat_nvm.osc_measured__fast_osc__frequency == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } + + if (status == VL53LX_ERROR_NONE) { + + pdev->phasecal_config_timeout_us = phasecal_config_timeout_us; + pdev->mm_config_timeout_us = mm_config_timeout_us; + pdev->range_config_timeout_us = range_config_timeout_us; + + status = + VL53LX_calc_timeout_register_values( + phasecal_config_timeout_us, + mm_config_timeout_us, + range_config_timeout_us, + pdev->stat_nvm.osc_measured__fast_osc__frequency, + &(pdev->gen_cfg), + &(pdev->tim_cfg)); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_timeouts_us( + uint32_t *pphasecal_config_timeout_us, + uint32_t *pmm_config_timeout_us, + uint32_t *prange_config_timeout_us) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + uint32_t macro_period_us = 0; + uint16_t timeout_encoded = 0; + + if (pdev->stat_nvm.osc_measured__fast_osc__frequency == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } + + if (status == VL53LX_ERROR_NONE) { + + + macro_period_us = + VL53LX_calc_macro_period_us( + pdev->stat_nvm.osc_measured__fast_osc__frequency, + pdev->tim_cfg.range_config__vcsel_period_a); + + + + *pphasecal_config_timeout_us = + VL53LX_calc_timeout_us( + (uint32_t)pdev->gen_cfg.phasecal_config__timeout_macrop, + macro_period_us); + + + + timeout_encoded = + (uint16_t)pdev->tim_cfg.mm_config__timeout_macrop_a_hi; + timeout_encoded = (timeout_encoded << 8) + + (uint16_t)pdev->tim_cfg.mm_config__timeout_macrop_a_lo; + + *pmm_config_timeout_us = + VL53LX_calc_decoded_timeout_us( + timeout_encoded, + macro_period_us); + + + + timeout_encoded = + (uint16_t)pdev->tim_cfg.range_config__timeout_macrop_a_hi; + timeout_encoded = (timeout_encoded << 8) + + (uint16_t)pdev->tim_cfg.range_config__timeout_macrop_a_lo; + + *prange_config_timeout_us = + VL53LX_calc_decoded_timeout_us( + timeout_encoded, + macro_period_us); + + pdev->phasecal_config_timeout_us = *pphasecal_config_timeout_us; + pdev->mm_config_timeout_us = *pmm_config_timeout_us; + pdev->range_config_timeout_us = *prange_config_timeout_us; + + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_calibration_repeat_period( + uint16_t cal_config__repeat_period) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->gen_cfg.cal_config__repeat_rate = cal_config__repeat_period; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_get_calibration_repeat_period( + uint16_t *pcal_config__repeat_period) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + *pcal_config__repeat_period = pdev->gen_cfg.cal_config__repeat_rate; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_set_sequence_config_bit( + VL53LX_DeviceSequenceConfig bit_id, + uint8_t value) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t bit_mask = 0x01; + uint8_t clr_mask = 0xFF - bit_mask; + uint8_t bit_value = value & bit_mask; + + if (bit_id <= VL53LX_DEVICESEQUENCECONFIG_RANGE) { + + if (bit_id > 0) { + bit_mask = 0x01 << bit_id; + bit_value = bit_value << bit_id; + clr_mask = 0xFF - bit_mask; + } + + pdev->dyn_cfg.system__sequence_config = + (pdev->dyn_cfg.system__sequence_config & clr_mask) | + bit_value; + + } else { + status = VL53LX_ERROR_INVALID_PARAMS; + } + + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_get_sequence_config_bit( + VL53LX_DeviceSequenceConfig bit_id, + uint8_t *pvalue) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t bit_mask = 0x01; + + if (bit_id <= VL53LX_DEVICESEQUENCECONFIG_RANGE) { + + if (bit_id > 0) { + bit_mask = 0x01 << bit_id; + } + + *pvalue = + pdev->dyn_cfg.system__sequence_config & bit_mask; + + if (bit_id > 0) { + *pvalue = *pvalue >> bit_id; + } + + } else { + status = VL53LX_ERROR_INVALID_PARAMS; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_interrupt_polarity( + VL53LX_DeviceInterruptPolarity interrupt_polarity) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->stat_cfg.gpio_hv_mux__ctrl = + (pdev->stat_cfg.gpio_hv_mux__ctrl & + VL53LX_DEVICEINTERRUPTPOLARITY_CLEAR_MASK) | + (interrupt_polarity & + VL53LX_DEVICEINTERRUPTPOLARITY_BIT_MASK); + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_set_refspadchar_config_struct( + VL53LX_refspadchar_config_t *pdata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->refspadchar.device_test_mode = pdata->device_test_mode; + pdev->refspadchar.VL53LX_p_005 = pdata->VL53LX_p_005; + pdev->refspadchar.timeout_us = pdata->timeout_us; + pdev->refspadchar.target_count_rate_mcps = + pdata->target_count_rate_mcps; + pdev->refspadchar.min_count_rate_limit_mcps = + pdata->min_count_rate_limit_mcps; + pdev->refspadchar.max_count_rate_limit_mcps = + pdata->max_count_rate_limit_mcps; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_refspadchar_config_struct( + VL53LX_refspadchar_config_t *pdata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + pdata->device_test_mode = pdev->refspadchar.device_test_mode; + pdata->VL53LX_p_005 = pdev->refspadchar.VL53LX_p_005; + pdata->timeout_us = pdev->refspadchar.timeout_us; + pdata->target_count_rate_mcps = + pdev->refspadchar.target_count_rate_mcps; + pdata->min_count_rate_limit_mcps = + pdev->refspadchar.min_count_rate_limit_mcps; + pdata->max_count_rate_limit_mcps = + pdev->refspadchar.max_count_rate_limit_mcps; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_range_ignore_threshold( + uint8_t range_ignore_thresh_mult, + uint16_t range_ignore_threshold_mcps) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps = + range_ignore_threshold_mcps; + + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult = + range_ignore_thresh_mult; + + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_get_range_ignore_threshold( + uint8_t *prange_ignore_thresh_mult, + uint16_t *prange_ignore_threshold_mcps_internal, + uint16_t *prange_ignore_threshold_mcps_current) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + *prange_ignore_thresh_mult = + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult; + + *prange_ignore_threshold_mcps_current = + pdev->stat_cfg.algo__range_ignore_threshold_mcps; + + *prange_ignore_threshold_mcps_internal = + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_get_interrupt_polarity( + VL53LX_DeviceInterruptPolarity *pinterrupt_polarity) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + *pinterrupt_polarity = + pdev->stat_cfg.gpio_hv_mux__ctrl & + VL53LX_DEVICEINTERRUPTPOLARITY_BIT_MASK; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_set_user_zone( + VL53LX_user_zone_t *puser_zone) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_encode_row_col( + puser_zone->y_centre, + puser_zone->x_centre, + &(pdev->dyn_cfg.roi_config__user_roi_centre_spad)); + + + VL53LX_encode_zone_size( + puser_zone->width, + puser_zone->height, + &(pdev->dyn_cfg.roi_config__user_roi_requested_global_xy_size)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_user_zone( + VL53LX_user_zone_t *puser_zone) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_decode_row_col( + pdev->dyn_cfg.roi_config__user_roi_centre_spad, + &(puser_zone->y_centre), + &(puser_zone->x_centre)); + + + VL53LX_decode_zone_size( + pdev->dyn_cfg.roi_config__user_roi_requested_global_xy_size, + &(puser_zone->width), + &(puser_zone->height)); + + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_mode_mitigation_roi( + VL53LX_user_zone_t *pmm_roi) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t x = 0; + uint8_t y = 0; + uint8_t xy_size = 0; + + + VL53LX_decode_row_col( + pdev->nvm_copy_data.roi_config__mode_roi_centre_spad, + &y, + &x); + + pmm_roi->x_centre = x; + pmm_roi->y_centre = y; + + + xy_size = pdev->nvm_copy_data.roi_config__mode_roi_xy_size; + + pmm_roi->height = xy_size >> 4; + pmm_roi->width = xy_size & 0x0F; + + + return status; +} +VL53LX_Error VL53LX::VL53LX_set_zone_config( + VL53LX_zone_config_t *pzone_cfg) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + memcpy(&(pdev->zone_cfg.user_zones), &(pzone_cfg->user_zones), + sizeof(pdev->zone_cfg.user_zones)); + + + pdev->zone_cfg.max_zones = pzone_cfg->max_zones; + pdev->zone_cfg.active_zones = pzone_cfg->active_zones; + + status = VL53LX_init_zone_config_histogram_bins(&pdev->zone_cfg); + + + + if (pzone_cfg->active_zones == 0) { + pdev->gen_cfg.global_config__stream_divider = 0; + } else if (pzone_cfg->active_zones < VL53LX_MAX_USER_ZONES) + pdev->gen_cfg.global_config__stream_divider = + pzone_cfg->active_zones + 1; + else + pdev->gen_cfg.global_config__stream_divider = + VL53LX_MAX_USER_ZONES + 1; + + return status; + +} + + + +VL53LX_Error VL53LX::VL53LX_get_zone_config( + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + memcpy(pzone_cfg, &(pdev->zone_cfg), sizeof(VL53LX_zone_config_t)); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_preset_mode_timing_cfg( + VL53LX_DevicePresetModes device_preset_mode, + uint16_t *pdss_config__target_total_rate_mcps, + uint32_t *pphasecal_config_timeout_us, + uint32_t *pmm_config_timeout_us, + uint32_t *prange_config_timeout_us) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + switch (device_preset_mode) { + + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING: + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_SHORT_RANGE: + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_LONG_RANGE: + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL: + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL: + case VL53LX_DEVICEPRESETMODE_OLT: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_lite_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_lite_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_lite_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_lite_us; + break; + + case VL53LX_DEVICEPRESETMODE_TIMED_RANGING: + case VL53LX_DEVICEPRESETMODE_TIMED_RANGING_SHORT_RANGE: + case VL53LX_DEVICEPRESETMODE_TIMED_RANGING_LONG_RANGE: + case VL53LX_DEVICEPRESETMODE_SINGLESHOT_RANGING: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_timed_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_timed_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_timed_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_timed_us; + break; + + case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_SHORT_RANGE: + case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_MEDIUM_RANGE: + case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_LONG_RANGE: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_timed_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_timed_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_lpa_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_lpa_us; + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_WITH_MM1: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_WITH_MM2: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM1_CAL: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM2_CAL: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_REF_ARRAY: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE_MM1: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE_MM2: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_CHARACTERISATION: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_hist_long_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_histo_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_histo_us; + + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mz_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_mz_med_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_mz_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_mz_us; + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_SHORT_RANGE: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mz_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_mz_short_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_mz_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_mz_us; + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_LONG_RANGE: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mz_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_mz_long_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_mz_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_mz_us; + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_SHORT_TIMING: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_hist_short_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_histo_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_histo_us; + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE_MM1: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE_MM2: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_hist_med_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_histo_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_histo_us; + break; + + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE_MM1: + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE_MM2: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_hist_short_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_histo_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_histo_us; + break; + + case VL53LX_DEVICEPRESETMODE_SPECIAL_HISTOGRAM_SHORT_RANGE: + *pdss_config__target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_very_short_mcps; + *pphasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_hist_short_us; + *pmm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_histo_us; + *prange_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_histo_us; + break; + + default: + status = VL53LX_ERROR_INVALID_PARAMS; + break; + + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_preset_mode( + VL53LX_DevicePresetModes device_preset_mode, + uint16_t dss_config__target_total_rate_mcps, + uint32_t phasecal_config_timeout_us, + uint32_t mm_config_timeout_us, + uint32_t range_config_timeout_us, + uint32_t inter_measurement_period_ms) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_hist_post_process_config_t *phistpostprocess = + &(pdev->histpostprocess); + + VL53LX_static_config_t *pstatic = &(pdev->stat_cfg); + VL53LX_histogram_config_t *phistogram = &(pdev->hist_cfg); + VL53LX_general_config_t *pgeneral = &(pdev->gen_cfg); + VL53LX_timing_config_t *ptiming = &(pdev->tim_cfg); + VL53LX_dynamic_config_t *pdynamic = &(pdev->dyn_cfg); + VL53LX_system_control_t *psystem = &(pdev->sys_ctrl); + VL53LX_zone_config_t *pzone_cfg = &(pdev->zone_cfg); + VL53LX_tuning_parm_storage_t *ptuning_parms = &(pdev->tuning_parms); + VL53LX_low_power_auto_data_t *plpadata = + &(pdev->low_power_auto_data); + + + pdev->preset_mode = device_preset_mode; + pdev->mm_config_timeout_us = mm_config_timeout_us; + pdev->range_config_timeout_us = range_config_timeout_us; + pdev->inter_measurement_period_ms = inter_measurement_period_ms; + + + + VL53LX_init_ll_driver_state(VL53LX_DEVICESTATE_SW_STANDBY); + + + + switch (device_preset_mode) { + + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING: + status = VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_SHORT_RANGE: + status = VL53LX_preset_mode_standard_ranging_short_range( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_LONG_RANGE: + status = VL53LX_preset_mode_standard_ranging_long_range( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL: + status = VL53LX_preset_mode_standard_ranging_mm1_cal( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL: + status = VL53LX_preset_mode_standard_ranging_mm2_cal( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_TIMED_RANGING: + status = VL53LX_preset_mode_timed_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_TIMED_RANGING_SHORT_RANGE: + status = VL53LX_preset_mode_timed_ranging_short_range( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_TIMED_RANGING_LONG_RANGE: + status = VL53LX_preset_mode_timed_ranging_long_range( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING: + status = VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_WITH_MM1: + status = VL53LX_preset_mode_histogram_ranging_with_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_WITH_MM2: + status = VL53LX_preset_mode_histogram_ranging_with_mm2( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM1_CAL: + status = VL53LX_preset_mode_histogram_ranging_mm1_cal( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM2_CAL: + status = VL53LX_preset_mode_histogram_ranging_mm2_cal( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE: + status = VL53LX_preset_mode_histogram_multizone( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_SHORT_RANGE: + status = VL53LX_preset_mode_histogram_multizone_short_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MULTIZONE_LONG_RANGE: + status = VL53LX_preset_mode_histogram_multizone_long_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_REF_ARRAY: + status = VL53LX_preset_mode_histogram_ranging_ref( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_SHORT_TIMING: + status = VL53LX_preset_mode_histogram_ranging_short_timing( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE: + status = VL53LX_preset_mode_histogram_long_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE_MM1: + status = VL53LX_preset_mode_histogram_long_range_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE_MM2: + status = VL53LX_preset_mode_histogram_long_range_mm2( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE: + status = VL53LX_preset_mode_histogram_medium_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE_MM1: + status = VL53LX_preset_mode_histogram_medium_range_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE_MM2: + status = VL53LX_preset_mode_histogram_medium_range_mm2( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE: + status = VL53LX_preset_mode_histogram_short_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE_MM1: + status = VL53LX_preset_mode_histogram_short_range_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE_MM2: + status = VL53LX_preset_mode_histogram_short_range_mm2( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_CHARACTERISATION: + status = VL53LX_preset_mode_histogram_characterisation( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_XTALK_PLANAR: + status = VL53LX_preset_mode_histogram_xtalk_planar( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_XTALK_MM1: + status = VL53LX_preset_mode_histogram_xtalk_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_XTALK_MM2: + status = VL53LX_preset_mode_histogram_xtalk_mm2( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_OLT: + status = VL53LX_preset_mode_olt( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_SINGLESHOT_RANGING: + status = VL53LX_preset_mode_singleshot_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_SHORT_RANGE: + status = VL53LX_preset_mode_low_power_auto_short_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg, + plpadata); + break; + + case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_MEDIUM_RANGE: + status = VL53LX_preset_mode_low_power_auto_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg, + plpadata); + break; + + case VL53LX_DEVICEPRESETMODE_LOWPOWERAUTO_LONG_RANGE: + status = VL53LX_preset_mode_low_power_auto_long_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg, + plpadata); + break; + + + case VL53LX_DEVICEPRESETMODE_SPECIAL_HISTOGRAM_SHORT_RANGE: + status = VL53LX_preset_mode_special_histogram_short_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + break; + + default: + status = VL53LX_ERROR_INVALID_PARAMS; + break; + + } + + + + if (status == VL53LX_ERROR_NONE) { + + pstatic->dss_config__target_total_rate_mcps = + dss_config__target_total_rate_mcps; + pdev->dss_config__target_total_rate_mcps = + dss_config__target_total_rate_mcps; + + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_timeouts_us( + phasecal_config_timeout_us, + mm_config_timeout_us, + range_config_timeout_us); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_inter_measurement_period_ms(inter_measurement_period_ms); + + + + V53L1_init_zone_results_structure( + pdev->zone_cfg.active_zones + 1, + &(pres->zone_results)); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_zone_preset( + VL53LX_DeviceZonePreset zone_preset) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_general_config_t *pgeneral = &(pdev->gen_cfg); + VL53LX_zone_config_t *pzone_cfg = &(pdev->zone_cfg); + + pdev->zone_preset = zone_preset; + + + + switch (zone_preset) { + + case VL53LX_DEVICEZONEPRESET_XTALK_PLANAR: + status = + VL53LX_zone_preset_xtalk_planar( + pgeneral, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_1X1_SIZE_16X16: + status = + VL53LX_init_zone_config_structure( + 8, 1, 1, + 8, 1, 1, + 15, 15, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_1X2_SIZE_16X8: + status = + VL53LX_init_zone_config_structure( + 8, 1, 1, + 4, 8, 2, + 15, 7, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_2X1_SIZE_8X16: + status = + VL53LX_init_zone_config_structure( + 4, 8, 2, + 8, 1, 1, + 7, 15, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_2X2_SIZE_8X8: + status = + VL53LX_init_zone_config_structure( + 4, 8, 2, + 4, 8, 2, + 7, 7, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_3X3_SIZE_5X5: + status = + VL53LX_init_zone_config_structure( + 2, 5, 3, + 2, 5, 3, + 4, 4, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_4X4_SIZE_4X4: + status = + VL53LX_init_zone_config_structure( + 2, 4, 4, + 2, 4, 4, + 3, 3, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_5X5_SIZE_4X4: + status = + VL53LX_init_zone_config_structure( + 2, 3, 5, + 2, 3, 5, + 3, 3, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_11X11_SIZE_5X5: + status = + VL53LX_init_zone_config_structure( + 3, 1, 11, + 3, 1, 11, + 4, 4, + pzone_cfg); + break; + + case VL53LX_DEVICEZONEPRESET_13X13_SIZE_4X4: + status = + VL53LX_init_zone_config_structure( + 2, 1, 13, + 2, 1, 13, + 3, 3, + pzone_cfg); + + break; + + case VL53LX_DEVICEZONEPRESET_1X1_SIZE_4X4_POS_8X8: + status = + VL53LX_init_zone_config_structure( + 8, 1, 1, + 8, 1, 1, + 3, 3, + pzone_cfg); + break; + + } + + + + if (pzone_cfg->active_zones == 0) { + pdev->gen_cfg.global_config__stream_divider = 0; + } else if (pzone_cfg->active_zones < VL53LX_MAX_USER_ZONES) + pdev->gen_cfg.global_config__stream_divider = + pzone_cfg->active_zones + 1; + else + pdev->gen_cfg.global_config__stream_divider = + VL53LX_MAX_USER_ZONES + 1; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_enable_xtalk_compensation() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + uint32_t tempu32; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg); + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + VL53LX_customer_nvm_managed_t *pN = &(pdev->customer); + + tempu32 = VL53LX_calc_crosstalk_plane_offset_with_margin( + pC->algo__crosstalk_compensation_plane_offset_kcps, + pC->lite_mode_crosstalk_margin_kcps); + if (tempu32 > 0xFFFF) { + tempu32 = 0xFFFF; + } + + pN->algo__crosstalk_compensation_plane_offset_kcps = + (uint16_t)tempu32; + + pN->algo__crosstalk_compensation_x_plane_gradient_kcps = + pC->algo__crosstalk_compensation_x_plane_gradient_kcps; + + pN->algo__crosstalk_compensation_y_plane_gradient_kcps = + pC->algo__crosstalk_compensation_y_plane_gradient_kcps; + + + pHP->algo__crosstalk_compensation_plane_offset_kcps = + VL53LX_calc_crosstalk_plane_offset_with_margin( + pC->algo__crosstalk_compensation_plane_offset_kcps, + pC->histogram_mode_crosstalk_margin_kcps); + + pHP->algo__crosstalk_compensation_x_plane_gradient_kcps + = pC->algo__crosstalk_compensation_x_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_y_plane_gradient_kcps + = pC->algo__crosstalk_compensation_y_plane_gradient_kcps; + + + + pC->global_crosstalk_compensation_enable = 0x01; + + pHP->algo__crosstalk_compensation_enable = + pC->global_crosstalk_compensation_enable; + + + + + if (status == VL53LX_ERROR_NONE) { + pC->crosstalk_range_ignore_threshold_rate_mcps = + VL53LX_calc_range_ignore_threshold( + pC->algo__crosstalk_compensation_plane_offset_kcps, + pC->algo__crosstalk_compensation_x_plane_gradient_kcps, + pC->algo__crosstalk_compensation_y_plane_gradient_kcps, + pC->crosstalk_range_ignore_threshold_mult); + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_customer_nvm_managed(&(pdev->customer)); + + return status; + +} + +void VL53LX::VL53LX_get_xtalk_compensation_enable(uint8_t *pcrosstalk_compensation_enable) +{ + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + *pcrosstalk_compensation_enable = + pdev->xtalk_cfg.global_crosstalk_compensation_enable; + +} + + +VL53LX_Error VL53LX::VL53LX_get_lite_xtalk_margin_kcps( + int16_t *pxtalk_margin) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + *pxtalk_margin = pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps; + + return status; + +} +VL53LX_Error VL53LX::VL53LX_set_lite_xtalk_margin_kcps( + int16_t xtalk_margin) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps = xtalk_margin; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_histogram_xtalk_margin_kcps( + int16_t *pxtalk_margin) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *pxtalk_margin = pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps; + + return status; + +} +VL53LX_Error VL53LX::VL53LX_set_histogram_xtalk_margin_kcps( + int16_t xtalk_margin) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps = xtalk_margin; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_restore_xtalk_nvm_default() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg); + + pC->algo__crosstalk_compensation_plane_offset_kcps = + pC->nvm_default__crosstalk_compensation_plane_offset_kcps; + pC->algo__crosstalk_compensation_x_plane_gradient_kcps = + pC->nvm_default__crosstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps = + pC->nvm_default__crosstalk_compensation_y_plane_gradient_kcps; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_disable_xtalk_compensation() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + VL53LX_customer_nvm_managed_t *pN = &(pdev->customer); + + pN->algo__crosstalk_compensation_plane_offset_kcps = + 0x00; + + pN->algo__crosstalk_compensation_x_plane_gradient_kcps = + 0x00; + + pN->algo__crosstalk_compensation_y_plane_gradient_kcps = + 0x00; + + + + pdev->xtalk_cfg.global_crosstalk_compensation_enable = 0x00; + + pHP->algo__crosstalk_compensation_enable = + pdev->xtalk_cfg.global_crosstalk_compensation_enable; + + + + if (status == VL53LX_ERROR_NONE) { + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps = + 0x0000; + } + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_set_customer_nvm_managed(&(pdev->customer)); + } + + + return status; + +} +VL53LX_Error VL53LX::VL53LX_get_histogram_phase_consistency( + uint8_t *pphase_consistency) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + + *pphase_consistency = + pHP->algo__consistency_check__phase_tolerance; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_set_histogram_phase_consistency( + uint8_t phase_consistency) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->histpostprocess.algo__consistency_check__phase_tolerance = + phase_consistency; + + return status; + +} +VL53LX_Error VL53LX::VL53LX_get_histogram_event_consistency( + uint8_t *pevent_consistency) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *pevent_consistency = + pdev->histpostprocess.algo__consistency_check__event_sigma; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_histogram_event_consistency( + uint8_t event_consistency) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->histpostprocess.algo__consistency_check__event_sigma = + event_consistency; + + return status; + +} +VL53LX_Error VL53LX::VL53LX_get_histogram_ambient_threshold_sigma( + uint8_t *pamb_thresh_sigma) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *pamb_thresh_sigma = + pdev->histpostprocess.ambient_thresh_sigma1; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_set_histogram_ambient_threshold_sigma( + uint8_t amb_thresh_sigma) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->histpostprocess.ambient_thresh_sigma1 = + amb_thresh_sigma; + + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_get_lite_sigma_threshold( + uint16_t *plite_sigma) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *plite_sigma = + pdev->tim_cfg.range_config__sigma_thresh; + + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_set_lite_sigma_threshold( + uint16_t lite_sigma) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->tim_cfg.range_config__sigma_thresh = lite_sigma; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_get_lite_min_count_rate( + uint16_t *plite_mincountrate) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + *plite_mincountrate = + pdev->tim_cfg.range_config__min_count_rate_rtn_limit_mcps; + + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_set_lite_min_count_rate( + uint16_t lite_mincountrate) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->tim_cfg.range_config__min_count_rate_rtn_limit_mcps = + lite_mincountrate; + + return status; + +} +VL53LX_Error VL53LX::VL53LX_get_xtalk_detect_config( + int16_t *pmax_valid_range_mm, + int16_t *pmin_valid_range_mm, + uint16_t *pmax_valid_rate_kcps, + uint16_t *pmax_sigma_mm) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *pmax_valid_range_mm = + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm; + *pmin_valid_range_mm = + pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm; + *pmax_valid_rate_kcps = + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps; + *pmax_sigma_mm = + pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm; + + return status; + +} + + + +VL53LX_Error VL53LX::VL53LX_set_xtalk_detect_config( + int16_t max_valid_range_mm, + int16_t min_valid_range_mm, + uint16_t max_valid_rate_kcps, + uint16_t max_sigma_mm) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm = + max_valid_range_mm; + pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm = + min_valid_range_mm; + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps = + max_valid_rate_kcps; + pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm = + max_sigma_mm; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_get_target_order_mode( + VL53LX_HistTargetOrder *phist_target_order) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *phist_target_order = + pdev->histpostprocess.hist_target_order; + + return status; + +} +VL53LX_Error VL53LX::VL53LX_set_target_order_mode( + VL53LX_HistTargetOrder hist_target_order) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + pdev->histpostprocess.hist_target_order = hist_target_order; + + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_get_dmax_reflectance_values( + VL53LX_dmax_reflectance_array_t *pdmax_reflectances) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + for (i = 0; i < VL53LX_MAX_AMBIENT_DMAX_VALUES; i++) { + pdmax_reflectances->target_reflectance_for_dmax[i] = + pdev->dmax_cfg.target_reflectance_for_dmax_calc[i]; + } + + return status; + +} +VL53LX_Error VL53LX::VL53LX_set_dmax_reflectance_values( + VL53LX_dmax_reflectance_array_t *pdmax_reflectances) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + for (i = 0; i < VL53LX_MAX_AMBIENT_DMAX_VALUES; i++) { + pdev->dmax_cfg.target_reflectance_for_dmax_calc[i] = + pdmax_reflectances->target_reflectance_for_dmax[i]; + } + + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_get_vhv_loopbound( + uint8_t *pvhv_loopbound) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *pvhv_loopbound = + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound / 4; + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_set_vhv_loopbound( + uint8_t vhv_loopbound) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound = + (pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound & 0x03) + + (vhv_loopbound * 4); + + return status; + +} +VL53LX_Error VL53LX::VL53LX_get_vhv_config( + uint8_t *pvhv_init_en, + uint8_t *pvhv_init_value) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + *pvhv_init_en = (pdev->stat_nvm.vhv_config__init & 0x80) >> 7; + *pvhv_init_value = + (pdev->stat_nvm.vhv_config__init & 0x7F); + + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_set_vhv_config( + uint8_t vhv_init_en, + uint8_t vhv_init_value) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->stat_nvm.vhv_config__init = + ((vhv_init_en & 0x01) << 7) + + (vhv_init_value & 0x7F); + + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_init_and_start_range( + uint8_t measurement_mode, + VL53LX_DeviceConfigLevel device_config_level) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE]; + + VL53LX_static_nvm_managed_t *pstatic_nvm = &(pdev->stat_nvm); + VL53LX_customer_nvm_managed_t *pcustomer_nvm = &(pdev->customer); + VL53LX_static_config_t *pstatic = &(pdev->stat_cfg); + VL53LX_general_config_t *pgeneral = &(pdev->gen_cfg); + VL53LX_timing_config_t *ptiming = &(pdev->tim_cfg); + VL53LX_dynamic_config_t *pdynamic = &(pdev->dyn_cfg); + VL53LX_system_control_t *psystem = &(pdev->sys_ctrl); + + VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state); + VL53LX_customer_nvm_managed_t *pN = &(pdev->customer); + + uint8_t *pbuffer = &buffer[0]; + uint16_t i = 0; + uint16_t i2c_index = 0; + uint16_t i2c_buffer_offset_bytes = 0; + uint16_t i2c_buffer_size_bytes = 0; + + + pdev->measurement_mode = measurement_mode; + + + + psystem->system__mode_start = + (psystem->system__mode_start & + VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK) | + measurement_mode; + + + + status = + VL53LX_set_user_zone( + &(pdev->zone_cfg.user_zones[pdev->ll_state.cfg_zone_id])); + + + if (pdev->zone_cfg.active_zones > 0) { + status = + VL53LX_set_zone_dss_config( + &(pres->zone_dyn_cfgs.VL53LX_p_003[pdev->ll_state.cfg_zone_id]) + ); + } + + + + + if (((pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) == 0x00) && + (pdev->xtalk_cfg.global_crosstalk_compensation_enable + == 0x01)) { + pdev->stat_cfg.algo__range_ignore_threshold_mcps = + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps; + } + + + + + + if (pdev->low_power_auto_data.low_power_auto_range_count == 0xFF) { + pdev->low_power_auto_data.low_power_auto_range_count = 0x0; + } + + + if ((pdev->low_power_auto_data.is_low_power_auto_mode == 1) && + (pdev->low_power_auto_data.low_power_auto_range_count == 0)) { + + pdev->low_power_auto_data.saved_interrupt_config = + pdev->gen_cfg.system__interrupt_config_gpio; + + pdev->gen_cfg.system__interrupt_config_gpio = 1 << 5; + + if ((pdev->dyn_cfg.system__sequence_config & ( + VL53LX_SEQUENCE_MM1_EN | VL53LX_SEQUENCE_MM2_EN)) == + 0x0) { + pN->algo__part_to_part_range_offset_mm = + (pN->mm_config__outer_offset_mm << 2); + } else { + pN->algo__part_to_part_range_offset_mm = 0x0; + } + + + if (device_config_level < + VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS) { + device_config_level = + VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS; + } + } + + if ((pdev->low_power_auto_data.is_low_power_auto_mode == 1) && + (pdev->low_power_auto_data.low_power_auto_range_count == 1)) { + + pdev->gen_cfg.system__interrupt_config_gpio = + pdev->low_power_auto_data.saved_interrupt_config; + + + device_config_level = VL53LX_DEVICECONFIGLEVEL_FULL; + } + + + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_save_cfg_data(); + } + + + + switch (device_config_level) { + case VL53LX_DEVICECONFIGLEVEL_FULL: + i2c_index = VL53LX_STATIC_NVM_MANAGED_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS: + i2c_index = VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS: + i2c_index = VL53LX_STATIC_CONFIG_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS: + i2c_index = VL53LX_GENERAL_CONFIG_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS: + i2c_index = VL53LX_TIMING_CONFIG_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS: + i2c_index = VL53LX_DYNAMIC_CONFIG_I2C_INDEX; + break; + default: + i2c_index = VL53LX_SYSTEM_CONTROL_I2C_INDEX; + break; + } + + + + i2c_buffer_size_bytes = + (VL53LX_SYSTEM_CONTROL_I2C_INDEX + + VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES) - + i2c_index; + + + + pbuffer = &buffer[0]; + for (i = 0; i < i2c_buffer_size_bytes; i++) { + *pbuffer++ = 0; + } + + + + if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_FULL && + status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_STATIC_NVM_MANAGED_I2C_INDEX - i2c_index; + + status = + VL53LX_i2c_encode_static_nvm_managed( + pstatic_nvm, + VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes]); + } + + if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS && + status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX - i2c_index; + + status = + VL53LX_i2c_encode_customer_nvm_managed( + pcustomer_nvm, + VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes]); + } + + if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS && + status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_STATIC_CONFIG_I2C_INDEX - i2c_index; + + status = + VL53LX_i2c_encode_static_config( + pstatic, + VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes]); + } + + if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS && + status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_GENERAL_CONFIG_I2C_INDEX - i2c_index; + + status = + VL53LX_i2c_encode_general_config( + pgeneral, + VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes]); + } + + if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS && + status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_TIMING_CONFIG_I2C_INDEX - i2c_index; + + status = + VL53LX_i2c_encode_timing_config( + ptiming, + VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes]); + } + + if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS && + status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_DYNAMIC_CONFIG_I2C_INDEX - i2c_index; + + + if ((psystem->system__mode_start & + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) == + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) { + pdynamic->system__grouped_parameter_hold_0 = + pstate->cfg_gph_id | 0x01; + pdynamic->system__grouped_parameter_hold_1 = + pstate->cfg_gph_id | 0x01; + pdynamic->system__grouped_parameter_hold = + pstate->cfg_gph_id; + } + status = + VL53LX_i2c_encode_dynamic_config( + pdynamic, + VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes]); + } + + if (status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_SYSTEM_CONTROL_I2C_INDEX - i2c_index; + + status = + VL53LX_i2c_encode_system_control( + psystem, + VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes]); + } + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_WriteMulti( + Dev, + i2c_index, + buffer, + (uint32_t)i2c_buffer_size_bytes); + } + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_update_ll_driver_rd_state(); + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_update_ll_driver_cfg_state(); + } + + + return status; +} +VL53LX_Error VL53LX::VL53LX_stop_range() +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + + + pdev->sys_ctrl.system__mode_start = + (pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK) | + VL53LX_DEVICEMEASUREMENTMODE_ABORT; + + status = VL53LX_set_system_control( + &pdev->sys_ctrl); + + + pdev->sys_ctrl.system__mode_start = + (pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK); + + + VL53LX_init_ll_driver_state( + VL53LX_DEVICESTATE_SW_STANDBY); + + + V53L1_init_zone_results_structure( + pdev->zone_cfg.active_zones + 1, + &(pres->zone_results)); + + + V53L1_init_zone_dss_configs(); + + + if (pdev->low_power_auto_data.is_low_power_auto_mode == 1) { + VL53LX_low_power_auto_data_stop_range(); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_measurement_results( + VL53LX_DeviceResultsLevel device_results_level) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE]; + + VL53LX_system_results_t *psystem_results = &(pdev->sys_results); + VL53LX_core_results_t *pcore_results = &(pdev->core_results); + VL53LX_debug_results_t *pdebug_results = &(pdev->dbg_results); + + uint16_t i2c_index = VL53LX_SYSTEM_RESULTS_I2C_INDEX; + uint16_t i2c_buffer_offset_bytes = 0; + uint16_t i2c_buffer_size_bytes = 0; + + switch (device_results_level) { + case VL53LX_DEVICERESULTSLEVEL_FULL: + i2c_buffer_size_bytes = + (VL53LX_DEBUG_RESULTS_I2C_INDEX + + VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES) - + i2c_index; + break; + case VL53LX_DEVICERESULTSLEVEL_UPTO_CORE: + i2c_buffer_size_bytes = + (VL53LX_CORE_RESULTS_I2C_INDEX + + VL53LX_CORE_RESULTS_I2C_SIZE_BYTES) - + i2c_index; + break; + default: + i2c_buffer_size_bytes = + VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES; + break; + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_ReadMulti( + Dev, + i2c_index, + buffer, + (uint32_t)i2c_buffer_size_bytes); + + + + if (device_results_level >= VL53LX_DEVICERESULTSLEVEL_FULL && + status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_DEBUG_RESULTS_I2C_INDEX - i2c_index; + + status = + VL53LX_i2c_decode_debug_results( + VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes], + pdebug_results); + } + + if (device_results_level >= VL53LX_DEVICERESULTSLEVEL_UPTO_CORE && + status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = + VL53LX_CORE_RESULTS_I2C_INDEX - i2c_index; + + status = + VL53LX_i2c_decode_core_results( + VL53LX_CORE_RESULTS_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes], + pcore_results); + } + + if (status == VL53LX_ERROR_NONE) { + + i2c_buffer_offset_bytes = 0; + status = + VL53LX_i2c_decode_system_results( + VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES, + &buffer[i2c_buffer_offset_bytes], + psystem_results); + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_device_results( + VL53LX_DeviceResultsLevel device_results_level, + VL53LX_range_results_t *prange_results) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_range_results_t *presults = + &(pres->range_results); + VL53LX_zone_objects_t *pobjects = + &(pres->zone_results.VL53LX_p_003[0]); + VL53LX_ll_driver_state_t *pstate = + &(pdev->ll_state); + VL53LX_zone_config_t *pzone_cfg = + &(pdev->zone_cfg); + VL53LX_zone_hist_info_t *phist_info = + &(pres->zone_hists.VL53LX_p_003[0]); + + VL53LX_dmax_calibration_data_t dmax_cal; + VL53LX_dmax_calibration_data_t *pdmax_cal = &dmax_cal; + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg); + VL53LX_low_power_auto_data_t *pL = &(pdev->low_power_auto_data); + VL53LX_histogram_bin_data_t *pHD = &(pdev->hist_data); + VL53LX_customer_nvm_managed_t *pN = &(pdev->customer); + VL53LX_zone_histograms_t *pZH = &(pres->zone_hists); + VL53LX_xtalk_calibration_results_t *pXCR = &(pdev->xtalk_cal); + uint8_t tmp8; + uint8_t zid; + uint8_t i; + uint8_t histo_merge_nb, idx; + VL53LX_range_data_t *pdata; + + + if ((pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) + == VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) { + + + + status = VL53LX_get_histogram_bin_data(&(pdev->hist_data)); + + + + + if (status == VL53LX_ERROR_NONE && + pHD->number_of_ambient_bins == 0) { + zid = pdev->ll_state.rd_zone_id; + status = VL53LX_hist_copy_and_scale_ambient_info( + &(pZH->VL53LX_p_003[zid]), + &(pdev->hist_data)); + } + + + if (status != VL53LX_ERROR_NONE) { + goto UPDATE_DYNAMIC_CONFIG; + } + + VL53LX_compute_histo_merge_nb(&histo_merge_nb); + if (histo_merge_nb == 0) { + histo_merge_nb = 1; + } + idx = histo_merge_nb - 1; + if (pdev->tuning_parms.tp_hist_merge == 1) + pC->algo__crosstalk_compensation_plane_offset_kcps = + pXCR->algo__xtalk_cpo_HistoMerge_kcps[idx]; + + pHP->gain_factor = + pdev->gain_cal.histogram_ranging_gain_factor; + + pHP->algo__crosstalk_compensation_plane_offset_kcps = + VL53LX_calc_crosstalk_plane_offset_with_margin( + pC->algo__crosstalk_compensation_plane_offset_kcps, + pC->histogram_mode_crosstalk_margin_kcps); + + pHP->algo__crosstalk_compensation_x_plane_gradient_kcps = + pC->algo__crosstalk_compensation_x_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_y_plane_gradient_kcps = + pC->algo__crosstalk_compensation_y_plane_gradient_kcps; + + pdev->dmax_cfg.ambient_thresh_sigma = + pHP->ambient_thresh_sigma1; + pdev->dmax_cfg.min_ambient_thresh_events = + pHP->min_ambient_thresh_events; + pdev->dmax_cfg.signal_total_events_limit = + pHP->signal_total_events_limit; + pdev->dmax_cfg.dss_config__target_total_rate_mcps = + pdev->stat_cfg.dss_config__target_total_rate_mcps; + pdev->dmax_cfg.dss_config__aperture_attenuation = + pdev->gen_cfg.dss_config__aperture_attenuation; + + pHP->algo__crosstalk_detect_max_valid_range_mm = + pC->algo__crosstalk_detect_max_valid_range_mm; + pHP->algo__crosstalk_detect_min_valid_range_mm = + pC->algo__crosstalk_detect_min_valid_range_mm; + pHP->algo__crosstalk_detect_max_valid_rate_kcps = + pC->algo__crosstalk_detect_max_valid_rate_kcps; + pHP->algo__crosstalk_detect_max_sigma_mm = + pC->algo__crosstalk_detect_max_sigma_mm; + + + + VL53LX_copy_rtn_good_spads_to_buffer( + &(pdev->nvm_copy_data), + &(pdev->rtn_good_spads[0])); + + + + switch (pdev->offset_correction_mode) { + + case VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS: + tmp8 = pdev->gen_cfg.dss_config__aperture_attenuation; + + VL53LX_hist_combine_mm1_mm2_offsets( + pN->mm_config__inner_offset_mm, + pN->mm_config__outer_offset_mm, + pdev->nvm_copy_data.roi_config__mode_roi_centre_spad, + pdev->nvm_copy_data.roi_config__mode_roi_xy_size, + pHD->roi_config__user_roi_centre_spad, + pHD->roi_config__user_roi_requested_global_xy_size, + &(pdev->add_off_cal_data), + &(pdev->rtn_good_spads[0]), + (uint16_t)tmp8, + &(pHP->range_offset_mm)); + break; + case VL53LX_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS: + select_offset_per_vcsel( + pdev, + &(pHP->range_offset_mm)); + pHP->range_offset_mm *= 4; + break; + default: + pHP->range_offset_mm = 0; + break; + + } + + + + if (status != VL53LX_ERROR_NONE) { + goto UPDATE_DYNAMIC_CONFIG; + } + + + VL53LX_calc_max_effective_spads( + pHD->roi_config__user_roi_centre_spad, + pHD->roi_config__user_roi_requested_global_xy_size, + &(pdev->rtn_good_spads[0]), + (uint16_t)pdev->gen_cfg.dss_config__aperture_attenuation, + &(pdev->dmax_cfg.max_effective_spads)); + + status = + VL53LX_get_dmax_calibration_data( + pdev->dmax_mode, + pdmax_cal); + + + if (status != VL53LX_ERROR_NONE) { + goto UPDATE_DYNAMIC_CONFIG; + } + + status = VL53LX_ipp_hist_process_data( + pdmax_cal, + &(pdev->dmax_cfg), + &(pdev->histpostprocess), + &(pdev->hist_data), + &(pdev->xtalk_shapes), + pdev->wArea1, + pdev->wArea2, + &histo_merge_nb, + presults); + + if ((pdev->tuning_parms.tp_hist_merge == 1) && + (histo_merge_nb > 1)) + for (i = 0; i < VL53LX_MAX_RANGE_RESULTS; i++) { + pdata = &(presults->VL53LX_p_003[i]); + pdata->VL53LX_p_016 /= histo_merge_nb; + pdata->VL53LX_p_017 /= histo_merge_nb; + pdata->VL53LX_p_010 /= histo_merge_nb; + pdata->peak_signal_count_rate_mcps /= histo_merge_nb; + pdata->avg_signal_count_rate_mcps /= histo_merge_nb; + pdata->ambient_count_rate_mcps /= histo_merge_nb; + pdata->VL53LX_p_009 /= histo_merge_nb; + } + + + if (status != VL53LX_ERROR_NONE) { + goto UPDATE_DYNAMIC_CONFIG; + } + + status = VL53LX_hist_wrap_dmax( + &(pdev->histpostprocess), + &(pdev->hist_data), + &(presults->wrap_dmax_mm)); + + + if (status != VL53LX_ERROR_NONE) { + goto UPDATE_DYNAMIC_CONFIG; + } + + zid = pdev->ll_state.rd_zone_id; + status = VL53LX_hist_phase_consistency_check( + &(pZH->VL53LX_p_003[zid]), + &(pres->zone_results.VL53LX_p_003[zid]), + presults); + + + if (status != VL53LX_ERROR_NONE) { + goto UPDATE_DYNAMIC_CONFIG; + } + + zid = pdev->ll_state.rd_zone_id; + status = VL53LX_hist_xmonitor_consistency_check( + &(pZH->VL53LX_p_003[zid]), + &(pres->zone_results.VL53LX_p_003[zid]), + &(presults->xmonitor)); + + + if (status != VL53LX_ERROR_NONE) { + goto UPDATE_DYNAMIC_CONFIG; + } + + + zid = pdev->ll_state.rd_zone_id; + pZH->max_zones = VL53LX_MAX_USER_ZONES; + pZH->active_zones = + pdev->zone_cfg.active_zones + 1; + pHD->zone_id = zid; + + if (zid < + pres->zone_results.max_zones) { + + phist_info = + &(pZH->VL53LX_p_003[zid]); + + phist_info->rd_device_state = + pHD->rd_device_state; + + phist_info->number_of_ambient_bins = + pHD->number_of_ambient_bins; + + phist_info->result__dss_actual_effective_spads = + pHD->result__dss_actual_effective_spads; + + phist_info->VL53LX_p_005 = + pHD->VL53LX_p_005; + + phist_info->total_periods_elapsed = + pHD->total_periods_elapsed; + + phist_info->ambient_events_sum = + pHD->ambient_events_sum; + } + + + + if (status != VL53LX_ERROR_NONE) { + goto UPDATE_DYNAMIC_CONFIG; + } + + VL53LX_hist_copy_results_to_sys_and_core( + &(pdev->hist_data), + presults, + &(pdev->sys_results), + &(pdev->core_results)); + + +UPDATE_DYNAMIC_CONFIG: + if (pzone_cfg->active_zones > 0) { + if (pstate->rd_device_state != + VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) { + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_dynamic_zone_update(presults); + } + } + + + for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) { + pzone_cfg->bin_config[i] = + ((pdev->ll_state.cfg_internal_stream_count) + & 0x01) ? + VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB : + VL53LX_ZONECONFIG_BINCONFIG__LOWAMB; + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_multizone_hist_bins_update(); + } + + } + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_dynamic_xtalk_correction_corrector(); + } + /* + #ifdef VL53LX_LOG_ENABLE + if (status == VL53LX_ERROR_NONE) + VL53LX_print_histogram_bin_data( + &(pdev->hist_data), + "get_device_results():pdev->lldata.hist_data.", + VL53LX_TRACE_MODULE_HISTOGRAM_DATA); + #endif + */ + } else { + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_get_measurement_results( + device_results_level); + + if (status == VL53LX_ERROR_NONE) + VL53LX_copy_sys_and_core_results_to_range_results( + (int32_t)pdev->gain_cal.standard_ranging_gain_factor, + &(pdev->sys_results), + &(pdev->core_results), + presults); + + + + if (pL->is_low_power_auto_mode == 1) { + + if ((status == VL53LX_ERROR_NONE) && + (pL->low_power_auto_range_count == 0)) { + + status = + VL53LX_low_power_auto_setup_manual_calibration(); + pL->low_power_auto_range_count = 1; + } else if ((status == VL53LX_ERROR_NONE) && + (pL->low_power_auto_range_count == 1)) { + pL->low_power_auto_range_count = 2; + } + + + if ((pL->low_power_auto_range_count != 0xFF) && + (status == VL53LX_ERROR_NONE)) { + status = VL53LX_low_power_auto_update_DSS(); + } + } + + } + + + presults->cfg_device_state = pdev->ll_state.cfg_device_state; + presults->rd_device_state = pdev->ll_state.rd_device_state; + presults->zone_id = pdev->ll_state.rd_zone_id; + + if (status == VL53LX_ERROR_NONE) { + + + pres->zone_results.max_zones = VL53LX_MAX_USER_ZONES; + pres->zone_results.active_zones = pdev->zone_cfg.active_zones + 1; + zid = pdev->ll_state.rd_zone_id; + + if (zid < pres->zone_results.max_zones) { + + pobjects = + &(pres->zone_results.VL53LX_p_003[zid]); + + pobjects->cfg_device_state = + presults->cfg_device_state; + pobjects->rd_device_state = presults->rd_device_state; + pobjects->zone_id = presults->zone_id; + pobjects->stream_count = presults->stream_count; + + + + pobjects->xmonitor.VL53LX_p_016 = + presults->xmonitor.VL53LX_p_016; + pobjects->xmonitor.VL53LX_p_017 = + presults->xmonitor.VL53LX_p_017; + pobjects->xmonitor.VL53LX_p_011 = + presults->xmonitor.VL53LX_p_011; + pobjects->xmonitor.range_status = + presults->xmonitor.range_status; + + pobjects->max_objects = presults->max_results; + pobjects->active_objects = presults->active_results; + + for (i = 0; i < presults->active_results; i++) { + pobjects->VL53LX_p_003[i].VL53LX_p_016 = + presults->VL53LX_p_003[i].VL53LX_p_016; + pobjects->VL53LX_p_003[i].VL53LX_p_017 = + presults->VL53LX_p_003[i].VL53LX_p_017; + pobjects->VL53LX_p_003[i].VL53LX_p_011 = + presults->VL53LX_p_003[i].VL53LX_p_011; + pobjects->VL53LX_p_003[i].range_status = + presults->VL53LX_p_003[i].range_status; + } + + + } + } + + + + memcpy( + prange_results, + presults, + sizeof(VL53LX_range_results_t)); + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_check_ll_driver_rd_state(); + } + /* + #ifdef VL53LX_LOG_ENABLE + if (status == VL53LX_ERROR_NONE) + VL53LX_print_range_results( + presults, + "get_device_results():pdev->llresults.range_results.", + VL53LX_TRACE_MODULE_RANGE_RESULTS_DATA); + #endif + */ + + return status; +} + +VL53LX_Error VL53LX::VL53LX_clear_interrupt_and_enable_next_range( + uint8_t measurement_mode) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_and_start_range( + measurement_mode, + VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_histogram_bin_data( + VL53LX_histogram_bin_data_t *pdata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg; + + VL53LX_static_nvm_managed_t *pstat_nvm = &(pdev->stat_nvm); + VL53LX_static_config_t *pstat_cfg = &(pdev->stat_cfg); + VL53LX_general_config_t *pgen_cfg = &(pdev->gen_cfg); + VL53LX_timing_config_t *ptim_cfg = &(pdev->tim_cfg); + VL53LX_range_results_t *presults = &(pres->range_results); + + uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE]; + uint8_t *pbuffer = &buffer[0]; + uint8_t bin_23_0 = 0x00; + uint16_t bin = 0; + uint16_t i2c_buffer_offset_bytes = 0; + uint16_t encoded_timeout = 0; + + uint32_t pll_period_us = 0; + uint32_t periods_elapsed_tmp = 0; + + uint8_t i = 0; + + int32_t hist_merge = 0; + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX, + pbuffer, + VL53LX_HISTOGRAM_BIN_DATA_I2C_SIZE_BYTES); + + + + pdata->result__interrupt_status = *(pbuffer + 0); + pdata->result__range_status = *(pbuffer + 1); + pdata->result__report_status = *(pbuffer + 2); + pdata->result__stream_count = *(pbuffer + 3); + pdata->result__dss_actual_effective_spads = + VL53LX_i2c_decode_uint16_t(2, pbuffer + 4); + + + + i2c_buffer_offset_bytes = + VL53LX_PHASECAL_RESULT__REFERENCE_PHASE - + VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX; + + pbuffer = &buffer[i2c_buffer_offset_bytes]; + + pdata->phasecal_result__reference_phase = + VL53LX_i2c_decode_uint16_t(2, pbuffer); + + i2c_buffer_offset_bytes = + VL53LX_PHASECAL_RESULT__VCSEL_START - + VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX; + + pdata->phasecal_result__vcsel_start = buffer[i2c_buffer_offset_bytes]; + + + + pdev->dbg_results.phasecal_result__reference_phase = + pdata->phasecal_result__reference_phase; + pdev->dbg_results.phasecal_result__vcsel_start = + pdata->phasecal_result__vcsel_start; + + + + i2c_buffer_offset_bytes = + VL53LX_RESULT__HISTOGRAM_BIN_23_0_MSB - + VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX; + + bin_23_0 = buffer[i2c_buffer_offset_bytes] << 2; + + i2c_buffer_offset_bytes = + VL53LX_RESULT__HISTOGRAM_BIN_23_0_LSB - + VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX; + + bin_23_0 += buffer[i2c_buffer_offset_bytes]; + + i2c_buffer_offset_bytes = + VL53LX_RESULT__HISTOGRAM_BIN_23_0 - + VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX; + + buffer[i2c_buffer_offset_bytes] = bin_23_0; + + + + i2c_buffer_offset_bytes = + VL53LX_RESULT__HISTOGRAM_BIN_0_2 - + VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX; + + pbuffer = &buffer[i2c_buffer_offset_bytes]; + for (bin = 0; bin < VL53LX_HISTOGRAM_BUFFER_SIZE; bin++) { + pdata->bin_data[bin] = + (int32_t)VL53LX_i2c_decode_uint32_t(3, pbuffer); + pbuffer += 3; + } + + + + + VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE, &hist_merge); + + if (pdata->result__stream_count == 0) { + + memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec)); + pdev->bin_rec_pos = 0; + pdev->pos_before_next_recom = 0; + } + + if (hist_merge == 1) { + vl53lx_histo_merge(pdata); + } + + + pdata->zone_id = pdev->ll_state.rd_zone_id; + pdata->VL53LX_p_019 = 0; + pdata->VL53LX_p_020 = VL53LX_HISTOGRAM_BUFFER_SIZE; + pdata->VL53LX_p_021 = VL53LX_HISTOGRAM_BUFFER_SIZE; + + pdata->cal_config__vcsel_start = pgen_cfg->cal_config__vcsel_start; + + + + pdata->vcsel_width = + ((uint16_t)pgen_cfg->global_config__vcsel_width) << 4; + pdata->vcsel_width += + (uint16_t)pstat_cfg->ana_config__vcsel_pulse_width_offset; + + + pdata->VL53LX_p_015 = + pstat_nvm->osc_measured__fast_osc__frequency; + + + + VL53LX_hist_get_bin_sequence_config(pdata); + + + + if (pdev->ll_state.rd_timing_status == 0) { + + encoded_timeout = + (ptim_cfg->range_config__timeout_macrop_a_hi << 8) + + ptim_cfg->range_config__timeout_macrop_a_lo; + pdata->VL53LX_p_005 = ptim_cfg->range_config__vcsel_period_a; + } else { + + encoded_timeout = + (ptim_cfg->range_config__timeout_macrop_b_hi << 8) + + ptim_cfg->range_config__timeout_macrop_b_lo; + pdata->VL53LX_p_005 = ptim_cfg->range_config__vcsel_period_b; + } + + + + pdata->number_of_ambient_bins = 0; + + for (i = 0; i < 6; i++) { + if ((pdata->bin_seq[i] & 0x07) == 0x07) + pdata->number_of_ambient_bins = + pdata->number_of_ambient_bins + 0x04; + } + + pdata->total_periods_elapsed = + VL53LX_decode_timeout(encoded_timeout); + + + + + pll_period_us = + VL53LX_calc_pll_period_us(pdata->VL53LX_p_015); + + + + periods_elapsed_tmp = pdata->total_periods_elapsed + 1; + + + + pdata->peak_duration_us = + VL53LX_duration_maths( + pll_period_us, + (uint32_t)pdata->vcsel_width, + VL53LX_RANGING_WINDOW_VCSEL_PERIODS, + periods_elapsed_tmp); + + pdata->woi_duration_us = 0; + + + + VL53LX_hist_calc_zero_distance_phase(pdata); + + + + VL53LX_hist_estimate_ambient_from_ambient_bins(pdata); + + + + pdata->cfg_device_state = pdev->ll_state.cfg_device_state; + pdata->rd_device_state = pdev->ll_state.rd_device_state; + + + + pzone_dyn_cfg = &(pres->zone_dyn_cfgs.VL53LX_p_003[pdata->zone_id]); + + pdata->roi_config__user_roi_centre_spad = + pzone_dyn_cfg->roi_config__user_roi_centre_spad; + pdata->roi_config__user_roi_requested_global_xy_size = + pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size; + + + + presults->device_status = VL53LX_DEVICEERROR_NOUPDATE; + + + + switch (pdata->result__range_status & + VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) { + + case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE: + case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE: + case VL53LX_DEVICEERROR_NOVHVVALUEFOUND: + case VL53LX_DEVICEERROR_USERROICLIP: + case VL53LX_DEVICEERROR_MULTCLIPFAIL: + + presults->device_status = (pdata->result__range_status & + VL53LX_RANGE_STATUS__RANGE_STATUS_MASK); + + status = VL53LX_ERROR_RANGE_ERROR; + + break; + + } + + + return status; +} + +void VL53LX::VL53LX_copy_sys_and_core_results_to_range_results( + int32_t gain_factor, + VL53LX_system_results_t *psys, + VL53LX_core_results_t *pcore, + VL53LX_range_results_t *presults) +{ + uint8_t i = 0; + + VL53LX_range_data_t *pdata; + int32_t range_mm = 0; + uint32_t tmpu32 = 0; + uint16_t rpscr_crosstalk_corrected_mcps_sd0; + uint16_t rmmo_effective_spads_sd0; + uint16_t rmmi_effective_spads_sd0; + + + + + presults->zone_id = 0; + presults->stream_count = psys->result__stream_count; + presults->wrap_dmax_mm = 0; + presults->max_results = VL53LX_MAX_RANGE_RESULTS; + presults->active_results = 1; + rpscr_crosstalk_corrected_mcps_sd0 = + psys->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0; + rmmo_effective_spads_sd0 = + psys->result__mm_outer_actual_effective_spads_sd0; + rmmi_effective_spads_sd0 = + psys->result__mm_inner_actual_effective_spads_sd0; + + + for (i = 0; i < VL53LX_MAX_AMBIENT_DMAX_VALUES; i++) { + presults->VL53LX_p_022[i] = 0; + } + + pdata = &(presults->VL53LX_p_003[0]); + + for (i = 0; i < 2; i++) { + + pdata->range_id = i; + pdata->time_stamp = 0; + + if ((psys->result__stream_count == 0) && + ((psys->result__range_status & + VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) == + VL53LX_DEVICEERROR_RANGECOMPLETE)) { + pdata->range_status = + VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK; + } else { + pdata->range_status = + psys->result__range_status & + VL53LX_RANGE_STATUS__RANGE_STATUS_MASK; + } + + pdata->VL53LX_p_012 = 0; + pdata->VL53LX_p_019 = 0; + pdata->VL53LX_p_023 = 0; + pdata->VL53LX_p_024 = 0; + pdata->VL53LX_p_013 = 0; + pdata->VL53LX_p_025 = 0; + + switch (i) { + + case 0: + if (psys->result__report_status == + VL53LX_DEVICEREPORTSTATUS_MM1) + pdata->VL53LX_p_004 = + rmmi_effective_spads_sd0; + else if (psys->result__report_status == + VL53LX_DEVICEREPORTSTATUS_MM2) + pdata->VL53LX_p_004 = + rmmo_effective_spads_sd0; + else + pdata->VL53LX_p_004 = + psys->result__dss_actual_effective_spads_sd0; + + pdata->peak_signal_count_rate_mcps = + rpscr_crosstalk_corrected_mcps_sd0; + pdata->avg_signal_count_rate_mcps = + psys->result__avg_signal_count_rate_mcps_sd0; + pdata->ambient_count_rate_mcps = + psys->result__ambient_count_rate_mcps_sd0; + + + + + tmpu32 = ((uint32_t)psys->result__sigma_sd0 << 5); + if (tmpu32 > 0xFFFF) { + tmpu32 = 0xFFFF; + } + + pdata->VL53LX_p_002 = (uint16_t)tmpu32; + + + + pdata->VL53LX_p_011 = + psys->result__phase_sd0; + + range_mm = (int32_t)( + psys->result__final_crosstalk_corrected_range_mm_sd0); + + + range_mm *= gain_factor; + range_mm += 0x0400; + range_mm /= 0x0800; + + pdata->median_range_mm = (int16_t)range_mm; + + pdata->VL53LX_p_017 = + pcore->result_core__ranging_total_events_sd0; + pdata->VL53LX_p_010 = + pcore->result_core__signal_total_events_sd0; + pdata->total_periods_elapsed = + pcore->result_core__total_periods_elapsed_sd0; + pdata->VL53LX_p_016 = + pcore->result_core__ambient_window_events_sd0; + + break; + case 1: + + pdata->VL53LX_p_004 = + psys->result__dss_actual_effective_spads_sd1; + pdata->peak_signal_count_rate_mcps = + psys->result__peak_signal_count_rate_mcps_sd1; + pdata->avg_signal_count_rate_mcps = + 0xFFFF; + pdata->ambient_count_rate_mcps = + psys->result__ambient_count_rate_mcps_sd1; + + + + + tmpu32 = ((uint32_t)psys->result__sigma_sd1 << 5); + if (tmpu32 > 0xFFFF) { + tmpu32 = 0xFFFF; + } + + pdata->VL53LX_p_002 = (uint16_t)tmpu32; + + + + pdata->VL53LX_p_011 = + psys->result__phase_sd1; + + range_mm = (int32_t)( + psys->result__final_crosstalk_corrected_range_mm_sd1); + + + range_mm *= gain_factor; + range_mm += 0x0400; + range_mm /= 0x0800; + + pdata->median_range_mm = (int16_t)range_mm; + + pdata->VL53LX_p_017 = + pcore->result_core__ranging_total_events_sd1; + pdata->VL53LX_p_010 = + pcore->result_core__signal_total_events_sd1; + pdata->total_periods_elapsed = + pcore->result_core__total_periods_elapsed_sd1; + pdata->VL53LX_p_016 = + pcore->result_core__ambient_window_events_sd1; + + break; + } + + + pdata->VL53LX_p_026 = pdata->VL53LX_p_011; + pdata->VL53LX_p_027 = pdata->VL53LX_p_011; + pdata->min_range_mm = pdata->median_range_mm; + pdata->max_range_mm = pdata->median_range_mm; + + pdata++; + } + + + + presults->device_status = VL53LX_DEVICEERROR_NOUPDATE; + + + + switch (psys->result__range_status & + VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) { + + case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE: + case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE: + case VL53LX_DEVICEERROR_NOVHVVALUEFOUND: + case VL53LX_DEVICEERROR_USERROICLIP: + case VL53LX_DEVICEERROR_MULTCLIPFAIL: + + presults->device_status = (psys->result__range_status & + VL53LX_RANGE_STATUS__RANGE_STATUS_MASK); + + presults->VL53LX_p_003[0].range_status = + VL53LX_DEVICEERROR_NOUPDATE; + break; + + } + +} + +VL53LX_Error VL53LX::VL53LX_set_zone_dss_config( + VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state); + + if (pstate->cfg_device_state == + VL53LX_DEVICESTATE_RANGING_DSS_MANUAL) { + pdev->gen_cfg.dss_config__roi_mode_control = + VL53LX_DSS_CONTROL__MODE_EFFSPADS; + pdev->gen_cfg.dss_config__manual_effective_spads_select = + pzone_dyn_cfg->dss_requested_effective_spad_count; + } else { + pdev->gen_cfg.dss_config__roi_mode_control = + VL53LX_DSS_CONTROL__MODE_TARGET_RATE; + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_calc_ambient_dmax( + uint16_t target_reflectance, + int16_t *pambient_dmax_mm) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_dmax_calibration_data_t dmax_cal; + VL53LX_dmax_calibration_data_t *pdmax_cal = &dmax_cal; + + status = + VL53LX_get_dmax_calibration_data( + pdev->debug_mode, + pdmax_cal); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_ipp_hist_ambient_dmax( + target_reflectance, + &(pdev->fmt_dmax_cal), + &(pdev->dmax_cfg), + &(pdev->hist_data), + pambient_dmax_mm); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_GPIO_interrupt_config( + VL53LX_GPIO_Interrupt_Mode intr_mode_distance, + VL53LX_GPIO_Interrupt_Mode intr_mode_rate, + uint8_t intr_new_measure_ready, + uint8_t intr_no_target, + uint8_t intr_combined_mode, + uint16_t thresh_distance_high, + uint16_t thresh_distance_low, + uint16_t thresh_rate_high, + uint16_t thresh_rate_low +) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_GPIO_interrupt_config_t *pintconf = + &(pdev->gpio_interrupt_config); + + pintconf->intr_mode_distance = intr_mode_distance; + pintconf->intr_mode_rate = intr_mode_rate; + pintconf->intr_new_measure_ready = intr_new_measure_ready; + pintconf->intr_no_target = intr_no_target; + pintconf->intr_combined_mode = intr_combined_mode; + pintconf->threshold_distance_high = thresh_distance_high; + pintconf->threshold_distance_low = thresh_distance_low; + pintconf->threshold_rate_high = thresh_rate_high; + pintconf->threshold_rate_low = thresh_rate_low; + + + pdev->gen_cfg.system__interrupt_config_gpio = + VL53LX_encode_GPIO_interrupt_config(pintconf); + + + + status = VL53LX_set_GPIO_thresholds_from_struct( + pintconf); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_GPIO_interrupt_config_struct( + VL53LX_GPIO_interrupt_config_t intconf) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_GPIO_interrupt_config_t *pintconf = + &(pdev->gpio_interrupt_config); + memcpy(pintconf, &(intconf), sizeof(VL53LX_GPIO_interrupt_config_t)); + + + pdev->gen_cfg.system__interrupt_config_gpio = + VL53LX_encode_GPIO_interrupt_config(pintconf); + + + status = VL53LX_set_GPIO_thresholds_from_struct( + pintconf); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_GPIO_interrupt_config( + VL53LX_GPIO_interrupt_config_t *pintconf) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->gpio_interrupt_config = VL53LX_decode_GPIO_interrupt_config( + pdev->gen_cfg.system__interrupt_config_gpio); + + + pdev->gpio_interrupt_config.threshold_distance_high = + pdev->dyn_cfg.system__thresh_high; + pdev->gpio_interrupt_config.threshold_distance_low = + pdev->dyn_cfg.system__thresh_low; + + pdev->gpio_interrupt_config.threshold_rate_high = + pdev->gen_cfg.system__thresh_rate_high; + pdev->gpio_interrupt_config.threshold_rate_low = + pdev->gen_cfg.system__thresh_rate_low; + + if (pintconf == &(pdev->gpio_interrupt_config)) { + + } else { + + + memcpy(pintconf, &(pdev->gpio_interrupt_config), + sizeof(VL53LX_GPIO_interrupt_config_t)); + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_set_dmax_mode( + VL53LX_DeviceDmaxMode dmax_mode) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->dmax_mode = dmax_mode; + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_dmax_mode( + VL53LX_DeviceDmaxMode *pdmax_mode) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *pdmax_mode = pdev->dmax_mode; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_dmax_calibration_data( + VL53LX_DeviceDmaxMode dmax_mode, + VL53LX_dmax_calibration_data_t *pdmax_cal) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + + switch (dmax_mode) { + + case VL53LX_DEVICEDMAXMODE__CUST_CAL_DATA: + memcpy( + pdmax_cal, + &(pdev->cust_dmax_cal), + sizeof(VL53LX_dmax_calibration_data_t)); + break; + + case VL53LX_DEVICEDMAXMODE__FMT_CAL_DATA: + memcpy( + pdmax_cal, + &(pdev->fmt_dmax_cal), + sizeof(VL53LX_dmax_calibration_data_t)); + break; + + default: + status = VL53LX_ERROR_INVALID_PARAMS; + break; + + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_hist_dmax_config( + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + memcpy( + &(pdev->dmax_cfg), + pdmax_cfg, + sizeof(VL53LX_hist_gen3_dmax_config_t)); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_hist_dmax_config( + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + memcpy( + pdmax_cfg, + &(pdev->dmax_cfg), + sizeof(VL53LX_hist_gen3_dmax_config_t)); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_offset_calibration_mode( + VL53LX_OffsetCalibrationMode offset_cal_mode) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->offset_calibration_mode = offset_cal_mode; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_offset_calibration_mode( + VL53LX_OffsetCalibrationMode *poffset_cal_mode) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + *poffset_cal_mode = pdev->offset_calibration_mode; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_offset_correction_mode( + VL53LX_OffsetCorrectionMode offset_cor_mode) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->offset_correction_mode = offset_cor_mode; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_offset_correction_mode( + VL53LX_OffsetCorrectionMode *poffset_cor_mode) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + *poffset_cor_mode = pdev->offset_correction_mode; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_zone_calibration_data( + VL53LX_zone_calibration_results_t *pzone_cal) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev); + + + if (pzone_cal->struct_version != + VL53LX_LL_ZONE_CALIBRATION_DATA_STRUCT_VERSION) { + status = VL53LX_ERROR_INVALID_PARAMS; + } + + + if (status == VL53LX_ERROR_NONE) + + memcpy( + &(pres->zone_cal), + pzone_cal, + sizeof(VL53LX_zone_calibration_results_t)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_zone_calibration_data( + VL53LX_zone_calibration_results_t *pzone_cal) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev); + + memcpy( + pzone_cal, + &(pres->zone_cal), + sizeof(VL53LX_zone_calibration_results_t)); + + pzone_cal->struct_version = + VL53LX_LL_ZONE_CALIBRATION_DATA_STRUCT_VERSION; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_tuning_debug_data( + VL53LX_tuning_parameters_t *ptun_data) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + VL53LX_xtalkextract_config_t *pXC = &(pdev->xtalk_extract_cfg); + + + ptun_data->vl53lx_tuningparm_version = + pdev->tuning_parms.tp_tuning_parm_version; + + ptun_data->vl53lx_tuningparm_key_table_version = + pdev->tuning_parms.tp_tuning_parm_key_table_version; + + + ptun_data->vl53lx_tuningparm_lld_version = + pdev->tuning_parms.tp_tuning_parm_lld_version; + + ptun_data->vl53lx_tuningparm_hist_algo_select = + pHP->hist_algo_select; + + ptun_data->vl53lx_tuningparm_hist_target_order = + pHP->hist_target_order; + + ptun_data->vl53lx_tuningparm_hist_filter_woi_0 = + pHP->filter_woi0; + + ptun_data->vl53lx_tuningparm_hist_filter_woi_1 = + pHP->filter_woi1; + + ptun_data->vl53lx_tuningparm_hist_amb_est_method = + pHP->hist_amb_est_method; + + ptun_data->vl53lx_tuningparm_hist_amb_thresh_sigma_0 = + pHP->ambient_thresh_sigma0; + + ptun_data->vl53lx_tuningparm_hist_amb_thresh_sigma_1 = + pHP->ambient_thresh_sigma1; + + ptun_data->vl53lx_tuningparm_hist_min_amb_thresh_events = + pHP->min_ambient_thresh_events; + + ptun_data->vl53lx_tuningparm_hist_amb_events_scaler = + pHP->ambient_thresh_events_scaler; + + ptun_data->vl53lx_tuningparm_hist_noise_threshold = + pHP->noise_threshold; + + ptun_data->vl53lx_tuningparm_hist_signal_total_events_limit = + pHP->signal_total_events_limit; + + ptun_data->vl53lx_tuningparm_hist_sigma_est_ref_mm = + pHP->sigma_estimator__sigma_ref_mm; + + ptun_data->vl53lx_tuningparm_hist_sigma_thresh_mm = + pHP->sigma_thresh; + + ptun_data->vl53lx_tuningparm_hist_gain_factor = + pdev->gain_cal.histogram_ranging_gain_factor; + + ptun_data->vl53lx_tuningparm_consistency_hist_phase_tolerance = + pHP->algo__consistency_check__phase_tolerance; + + ptun_data->vl53lx_tuningparm_consistency_hist_min_max_tolerance_mm = + pHP->algo__consistency_check__min_max_tolerance; + + ptun_data->vl53lx_tuningparm_consistency_hist_event_sigma = + pHP->algo__consistency_check__event_sigma; + + ptun_data->vl53lx_tuningparm_consistency_hist_event_sigma_min_spad_limit + = pHP->algo__consistency_check__event_min_spad_count; + + ptun_data->vl53lx_tuningparm_initial_phase_rtn_histo_long_range = + pdev->tuning_parms.tp_init_phase_rtn_hist_long; + + ptun_data->vl53lx_tuningparm_initial_phase_rtn_histo_med_range = + pdev->tuning_parms.tp_init_phase_rtn_hist_med; + + ptun_data->vl53lx_tuningparm_initial_phase_rtn_histo_short_range = + pdev->tuning_parms.tp_init_phase_rtn_hist_short; + + ptun_data->vl53lx_tuningparm_initial_phase_ref_histo_long_range = + pdev->tuning_parms.tp_init_phase_ref_hist_long; + + ptun_data->vl53lx_tuningparm_initial_phase_ref_histo_med_range = + pdev->tuning_parms.tp_init_phase_ref_hist_med; + + ptun_data->vl53lx_tuningparm_initial_phase_ref_histo_short_range = + pdev->tuning_parms.tp_init_phase_ref_hist_short; + + ptun_data->vl53lx_tuningparm_xtalk_detect_min_valid_range_mm = + pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm; + + ptun_data->vl53lx_tuningparm_xtalk_detect_max_valid_range_mm = + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm; + + ptun_data->vl53lx_tuningparm_xtalk_detect_max_sigma_mm = + pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm; + + ptun_data->vl53lx_tuningparm_xtalk_detect_min_max_tolerance = + pHP->algo__crosstalk_detect_min_max_tolerance; + + ptun_data->vl53lx_tuningparm_xtalk_detect_max_valid_rate_kcps = + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps; + + ptun_data->vl53lx_tuningparm_xtalk_detect_event_sigma = + pHP->algo__crosstalk_detect_event_sigma; + + ptun_data->vl53lx_tuningparm_hist_xtalk_margin_kcps = + pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps; + + ptun_data->vl53lx_tuningparm_consistency_lite_phase_tolerance = + pdev->tuning_parms.tp_consistency_lite_phase_tolerance; + + ptun_data->vl53lx_tuningparm_phasecal_target = + pdev->tuning_parms.tp_phasecal_target; + + ptun_data->vl53lx_tuningparm_lite_cal_repeat_rate = + pdev->tuning_parms.tp_cal_repeat_rate; + + ptun_data->vl53lx_tuningparm_lite_ranging_gain_factor = + pdev->gain_cal.standard_ranging_gain_factor; + + ptun_data->vl53lx_tuningparm_lite_min_clip_mm = + pdev->tuning_parms.tp_lite_min_clip; + + ptun_data->vl53lx_tuningparm_lite_long_sigma_thresh_mm = + pdev->tuning_parms.tp_lite_long_sigma_thresh_mm; + + ptun_data->vl53lx_tuningparm_lite_med_sigma_thresh_mm = + pdev->tuning_parms.tp_lite_med_sigma_thresh_mm; + + ptun_data->vl53lx_tuningparm_lite_short_sigma_thresh_mm = + pdev->tuning_parms.tp_lite_short_sigma_thresh_mm; + + ptun_data->vl53lx_tuningparm_lite_long_min_count_rate_rtn_mcps = + pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps; + + ptun_data->vl53lx_tuningparm_lite_med_min_count_rate_rtn_mcps = + pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps; + + ptun_data->vl53lx_tuningparm_lite_short_min_count_rate_rtn_mcps = + pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps; + + ptun_data->vl53lx_tuningparm_lite_sigma_est_pulse_width = + pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns; + + ptun_data->vl53lx_tuningparm_lite_sigma_est_amb_width_ns = + pdev->tuning_parms.tp_lite_sigma_est_amb_width_ns; + + ptun_data->vl53lx_tuningparm_lite_sigma_ref_mm = + pdev->tuning_parms.tp_lite_sigma_ref_mm; + + ptun_data->vl53lx_tuningparm_lite_rit_mult = + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult; + + ptun_data->vl53lx_tuningparm_lite_seed_config = + pdev->tuning_parms.tp_lite_seed_cfg; + + ptun_data->vl53lx_tuningparm_lite_quantifier = + pdev->tuning_parms.tp_lite_quantifier; + + ptun_data->vl53lx_tuningparm_lite_first_order_select = + pdev->tuning_parms.tp_lite_first_order_select; + + ptun_data->vl53lx_tuningparm_lite_xtalk_margin_kcps = + pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps; + + ptun_data->vl53lx_tuningparm_initial_phase_rtn_lite_long_range = + pdev->tuning_parms.tp_init_phase_rtn_lite_long; + + ptun_data->vl53lx_tuningparm_initial_phase_rtn_lite_med_range = + pdev->tuning_parms.tp_init_phase_rtn_lite_med; + + ptun_data->vl53lx_tuningparm_initial_phase_rtn_lite_short_range = + pdev->tuning_parms.tp_init_phase_rtn_lite_short; + + ptun_data->vl53lx_tuningparm_initial_phase_ref_lite_long_range = + pdev->tuning_parms.tp_init_phase_ref_lite_long; + + ptun_data->vl53lx_tuningparm_initial_phase_ref_lite_med_range = + pdev->tuning_parms.tp_init_phase_ref_lite_med; + + ptun_data->vl53lx_tuningparm_initial_phase_ref_lite_short_range = + pdev->tuning_parms.tp_init_phase_ref_lite_short; + + ptun_data->vl53lx_tuningparm_timed_seed_config = + pdev->tuning_parms.tp_timed_seed_cfg; + + ptun_data->vl53lx_tuningparm_dmax_cfg_signal_thresh_sigma = + pdev->dmax_cfg.signal_thresh_sigma; + + ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_0 = + pdev->dmax_cfg.target_reflectance_for_dmax_calc[0]; + + ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_1 = + pdev->dmax_cfg.target_reflectance_for_dmax_calc[1]; + + ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_2 = + pdev->dmax_cfg.target_reflectance_for_dmax_calc[2]; + + ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_3 = + pdev->dmax_cfg.target_reflectance_for_dmax_calc[3]; + + ptun_data->vl53lx_tuningparm_dmax_cfg_reflectance_array_4 = + pdev->dmax_cfg.target_reflectance_for_dmax_calc[4]; + + ptun_data->vl53lx_tuningparm_vhv_loopbound = + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound; + + ptun_data->vl53lx_tuningparm_refspadchar_device_test_mode = + pdev->refspadchar.device_test_mode; + + ptun_data->vl53lx_tuningparm_refspadchar_vcsel_period = + pdev->refspadchar.VL53LX_p_005; + + ptun_data->vl53lx_tuningparm_refspadchar_phasecal_timeout_us = + pdev->refspadchar.timeout_us; + + ptun_data->vl53lx_tuningparm_refspadchar_target_count_rate_mcps = + pdev->refspadchar.target_count_rate_mcps; + + ptun_data->vl53lx_tuningparm_refspadchar_min_countrate_limit_mcps = + pdev->refspadchar.min_count_rate_limit_mcps; + + ptun_data->vl53lx_tuningparm_refspadchar_max_countrate_limit_mcps = + pdev->refspadchar.max_count_rate_limit_mcps; + + ptun_data->vl53lx_tuningparm_xtalk_extract_num_of_samples = + pXC->num_of_samples; + + ptun_data->vl53lx_tuningparm_xtalk_extract_min_filter_thresh_mm = + pXC->algo__crosstalk_extract_min_valid_range_mm; + + ptun_data->vl53lx_tuningparm_xtalk_extract_max_filter_thresh_mm = + pXC->algo__crosstalk_extract_max_valid_range_mm; + + ptun_data->vl53lx_tuningparm_xtalk_extract_dss_rate_mcps = + pXC->dss_config__target_total_rate_mcps; + + ptun_data->vl53lx_tuningparm_xtalk_extract_phasecal_timeout_us = + pXC->phasecal_config_timeout_us; + + ptun_data->vl53lx_tuningparm_xtalk_extract_max_valid_rate_kcps = + pXC->algo__crosstalk_extract_max_valid_rate_kcps; + + ptun_data->vl53lx_tuningparm_xtalk_extract_sigma_threshold_mm = + pXC->algo__crosstalk_extract_max_sigma_mm; + + ptun_data->vl53lx_tuningparm_xtalk_extract_dss_timeout_us = + pXC->mm_config_timeout_us; + + ptun_data->vl53lx_tuningparm_xtalk_extract_bin_timeout_us = + pXC->range_config_timeout_us; + + ptun_data->vl53lx_tuningparm_offset_cal_dss_rate_mcps = + pdev->offsetcal_cfg.dss_config__target_total_rate_mcps; + + ptun_data->vl53lx_tuningparm_offset_cal_phasecal_timeout_us = + pdev->offsetcal_cfg.phasecal_config_timeout_us; + + ptun_data->vl53lx_tuningparm_offset_cal_mm_timeout_us = + pdev->offsetcal_cfg.mm_config_timeout_us; + + ptun_data->vl53lx_tuningparm_offset_cal_range_timeout_us = + pdev->offsetcal_cfg.range_config_timeout_us; + + ptun_data->vl53lx_tuningparm_offset_cal_pre_samples = + pdev->offsetcal_cfg.pre_num_of_samples; + + ptun_data->vl53lx_tuningparm_offset_cal_mm1_samples = + pdev->offsetcal_cfg.mm1_num_of_samples; + + ptun_data->vl53lx_tuningparm_offset_cal_mm2_samples = + pdev->offsetcal_cfg.mm2_num_of_samples; + + ptun_data->vl53lx_tuningparm_zone_cal_dss_rate_mcps = + pdev->zonecal_cfg.dss_config__target_total_rate_mcps; + + ptun_data->vl53lx_tuningparm_zone_cal_phasecal_timeout_us = + pdev->zonecal_cfg.phasecal_config_timeout_us; + + ptun_data->vl53lx_tuningparm_zone_cal_dss_timeout_us = + pdev->zonecal_cfg.mm_config_timeout_us; + + ptun_data->vl53lx_tuningparm_zone_cal_phasecal_num_samples = + pdev->zonecal_cfg.phasecal_num_of_samples; + + ptun_data->vl53lx_tuningparm_zone_cal_range_timeout_us = + pdev->zonecal_cfg.range_config_timeout_us; + + ptun_data->vl53lx_tuningparm_zone_cal_zone_num_samples = + pdev->zonecal_cfg.zone_num_of_samples; + + ptun_data->vl53lx_tuningparm_spadmap_vcsel_period = + pdev->ssc_cfg.VL53LX_p_005; + + ptun_data->vl53lx_tuningparm_spadmap_vcsel_start = + pdev->ssc_cfg.vcsel_start; + + ptun_data->vl53lx_tuningparm_spadmap_rate_limit_mcps = + pdev->ssc_cfg.rate_limit_mcps; + + ptun_data->vl53lx_tuningparm_lite_dss_config_target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_lite_mcps; + + ptun_data->vl53lx_tuningparm_ranging_dss_config_target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mcps; + + ptun_data->vl53lx_tuningparm_mz_dss_config_target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_histo_mz_mcps; + + ptun_data->vl53lx_tuningparm_timed_dss_config_target_total_rate_mcps = + pdev->tuning_parms.tp_dss_target_timed_mcps; + + ptun_data->vl53lx_tuningparm_lite_phasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_lite_us; + + ptun_data->vl53lx_tuningparm_ranging_long_phasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_hist_long_us; + + ptun_data->vl53lx_tuningparm_ranging_med_phasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_hist_med_us; + + ptun_data->vl53lx_tuningparm_ranging_short_phasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_hist_short_us; + + ptun_data->vl53lx_tuningparm_mz_long_phasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_mz_long_us; + + ptun_data->vl53lx_tuningparm_mz_med_phasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_mz_med_us; + + ptun_data->vl53lx_tuningparm_mz_short_phasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_mz_short_us; + + ptun_data->vl53lx_tuningparm_timed_phasecal_config_timeout_us = + pdev->tuning_parms.tp_phasecal_timeout_timed_us; + + ptun_data->vl53lx_tuningparm_lite_mm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_lite_us; + + ptun_data->vl53lx_tuningparm_ranging_mm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_histo_us; + + ptun_data->vl53lx_tuningparm_mz_mm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_mz_us; + + ptun_data->vl53lx_tuningparm_timed_mm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_timed_us; + + ptun_data->vl53lx_tuningparm_lite_range_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_lite_us; + + ptun_data->vl53lx_tuningparm_ranging_range_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_histo_us; + + ptun_data->vl53lx_tuningparm_mz_range_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_mz_us; + + ptun_data->vl53lx_tuningparm_timed_range_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_timed_us; + + ptun_data->vl53lx_tuningparm_dynxtalk_smudge_margin = + pdev->smudge_correct_config.smudge_margin; + + ptun_data->vl53lx_tuningparm_dynxtalk_noise_margin = + pdev->smudge_correct_config.noise_margin; + + ptun_data->vl53lx_tuningparm_dynxtalk_xtalk_offset_limit = + pdev->smudge_correct_config.user_xtalk_offset_limit; + + ptun_data->vl53lx_tuningparm_dynxtalk_xtalk_offset_limit_hi = + pdev->smudge_correct_config.user_xtalk_offset_limit_hi; + + ptun_data->vl53lx_tuningparm_dynxtalk_sample_limit = + pdev->smudge_correct_config.sample_limit; + + ptun_data->vl53lx_tuningparm_dynxtalk_single_xtalk_delta = + pdev->smudge_correct_config.single_xtalk_delta; + + ptun_data->vl53lx_tuningparm_dynxtalk_averaged_xtalk_delta = + pdev->smudge_correct_config.averaged_xtalk_delta; + + ptun_data->vl53lx_tuningparm_dynxtalk_clip_limit = + pdev->smudge_correct_config.smudge_corr_clip_limit; + + ptun_data->vl53lx_tuningparm_dynxtalk_scaler_calc_method = + pdev->smudge_correct_config.scaler_calc_method; + + ptun_data->vl53lx_tuningparm_dynxtalk_xgradient_scaler = + pdev->smudge_correct_config.x_gradient_scaler; + + ptun_data->vl53lx_tuningparm_dynxtalk_ygradient_scaler = + pdev->smudge_correct_config.y_gradient_scaler; + + ptun_data->vl53lx_tuningparm_dynxtalk_user_scaler_set = + pdev->smudge_correct_config.user_scaler_set; + + ptun_data->vl53lx_tuningparm_dynxtalk_smudge_cor_single_apply = + pdev->smudge_correct_config.smudge_corr_single_apply; + + ptun_data->vl53lx_tuningparm_dynxtalk_xtalk_amb_threshold = + pdev->smudge_correct_config.smudge_corr_ambient_threshold; + + ptun_data->vl53lx_tuningparm_dynxtalk_nodetect_amb_threshold_kcps = + pdev->smudge_correct_config.nodetect_ambient_threshold; + + ptun_data->vl53lx_tuningparm_dynxtalk_nodetect_sample_limit = + pdev->smudge_correct_config.nodetect_sample_limit; + + ptun_data->vl53lx_tuningparm_dynxtalk_nodetect_xtalk_offset_kcps = + pdev->smudge_correct_config.nodetect_xtalk_offset; + + ptun_data->vl53lx_tuningparm_dynxtalk_nodetect_min_range_mm = + pdev->smudge_correct_config.nodetect_min_range_mm; + + ptun_data->vl53lx_tuningparm_lowpowerauto_vhv_loop_bound = + pdev->low_power_auto_data.vhv_loop_bound; + + ptun_data->vl53lx_tuningparm_lowpowerauto_mm_config_timeout_us = + pdev->tuning_parms.tp_mm_timeout_lpa_us; + + ptun_data->vl53lx_tuningparm_lowpowerauto_range_config_timeout_us = + pdev->tuning_parms.tp_range_timeout_lpa_us; + + ptun_data->vl53lx_tuningparm_very_short_dss_rate_mcps = + pdev->tuning_parms.tp_dss_target_very_short_mcps; + + ptun_data->vl53lx_tuningparm_phasecal_patch_power = + pdev->tuning_parms.tp_phasecal_patch_power; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_tuning_parm( + VL53LX_TuningParms tuning_parm_key, + int32_t *ptuning_parm_value) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + VL53LX_xtalkextract_config_t *pXC = &(pdev->xtalk_extract_cfg); + + switch (tuning_parm_key) { + + case VL53LX_TUNINGPARM_VERSION: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_tuning_parm_version; + break; + case VL53LX_TUNINGPARM_KEY_TABLE_VERSION: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_tuning_parm_key_table_version; + break; + case VL53LX_TUNINGPARM_LLD_VERSION: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_tuning_parm_lld_version; + break; + case VL53LX_TUNINGPARM_HIST_ALGO_SELECT: + *ptuning_parm_value = + (int32_t)pHP->hist_algo_select; + break; + case VL53LX_TUNINGPARM_HIST_TARGET_ORDER: + *ptuning_parm_value = + (int32_t)pHP->hist_target_order; + break; + case VL53LX_TUNINGPARM_HIST_FILTER_WOI_0: + *ptuning_parm_value = + (int32_t)pHP->filter_woi0; + break; + case VL53LX_TUNINGPARM_HIST_FILTER_WOI_1: + *ptuning_parm_value = + (int32_t)pHP->filter_woi1; + break; + case VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD: + *ptuning_parm_value = + (int32_t)pHP->hist_amb_est_method; + break; + case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0: + *ptuning_parm_value = + (int32_t)pHP->ambient_thresh_sigma0; + break; + case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1: + *ptuning_parm_value = + (int32_t)pHP->ambient_thresh_sigma1; + break; + case VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS: + *ptuning_parm_value = + (int32_t)pHP->min_ambient_thresh_events; + break; + case VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER: + *ptuning_parm_value = + (int32_t)pHP->ambient_thresh_events_scaler; + break; + case VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD: + *ptuning_parm_value = + (int32_t)pHP->noise_threshold; + break; + case VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT: + *ptuning_parm_value = + (int32_t)pHP->signal_total_events_limit; + break; + case VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM: + *ptuning_parm_value = + (int32_t)pHP->sigma_estimator__sigma_ref_mm; + break; + case VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM: + *ptuning_parm_value = + (int32_t)pHP->sigma_thresh; + break; + case VL53LX_TUNINGPARM_HIST_GAIN_FACTOR: + *ptuning_parm_value = + (int32_t)pdev->gain_cal.histogram_ranging_gain_factor; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE: + *ptuning_parm_value = + (int32_t)pHP->algo__consistency_check__phase_tolerance; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM: + *ptuning_parm_value = + (int32_t)pHP->algo__consistency_check__min_max_tolerance; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA: + *ptuning_parm_value = + (int32_t)pHP->algo__consistency_check__event_sigma; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT: + *ptuning_parm_value = + (int32_t)pHP->algo__consistency_check__event_min_spad_count; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_long; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_med; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_short; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_long; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_med; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_short; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM: + *ptuning_parm_value = (int32_t)( + pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm); + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM: + *ptuning_parm_value = (int32_t)( + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm); + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM: + *ptuning_parm_value = + (int32_t)pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE: + *ptuning_parm_value = + (int32_t)pHP->algo__crosstalk_detect_min_max_tolerance; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS: + *ptuning_parm_value = (int32_t)( + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps); + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA: + *ptuning_parm_value = + (int32_t)pHP->algo__crosstalk_detect_event_sigma; + break; + case VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS: + *ptuning_parm_value = + (int32_t)pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_consistency_lite_phase_tolerance; + break; + case VL53LX_TUNINGPARM_PHASECAL_TARGET: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_target; + break; + case VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_cal_repeat_rate; + break; + case VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR: + *ptuning_parm_value = + (int32_t)pdev->gain_cal.standard_ranging_gain_factor; + break; + case VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_min_clip; + break; + case VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_long_sigma_thresh_mm; + break; + case VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_med_sigma_thresh_mm; + break; + case VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_short_sigma_thresh_mm; + break; + case VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS: + *ptuning_parm_value = (int32_t)( + pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps); + break; + case VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps; + break; + case VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS: + *ptuning_parm_value = (int32_t)( + pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps); + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_sigma_est_amb_width_ns; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_sigma_ref_mm; + break; + case VL53LX_TUNINGPARM_LITE_RIT_MULT: + *ptuning_parm_value = + (int32_t)pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult; + break; + case VL53LX_TUNINGPARM_LITE_SEED_CONFIG: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_seed_cfg; + break; + case VL53LX_TUNINGPARM_LITE_QUANTIFIER: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_quantifier; + break; + case VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_lite_first_order_select; + break; + case VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS: + *ptuning_parm_value = + (int32_t)pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_long; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_med; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_short; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_long; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_med; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_short; + break; + case VL53LX_TUNINGPARM_TIMED_SEED_CONFIG: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_timed_seed_cfg; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA: + *ptuning_parm_value = + (int32_t)pdev->dmax_cfg.signal_thresh_sigma; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0: + *ptuning_parm_value = + (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[0]; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1: + *ptuning_parm_value = + (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[1]; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2: + *ptuning_parm_value = + (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[2]; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3: + *ptuning_parm_value = + (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[3]; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4: + *ptuning_parm_value = + (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[4]; + break; + case VL53LX_TUNINGPARM_VHV_LOOPBOUND: + *ptuning_parm_value = + (int32_t)pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE: + *ptuning_parm_value = + (int32_t)pdev->refspadchar.device_test_mode; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD: + *ptuning_parm_value = + (int32_t)pdev->refspadchar.VL53LX_p_005; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->refspadchar.timeout_us; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pdev->refspadchar.target_count_rate_mcps; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS: + *ptuning_parm_value = + (int32_t)pdev->refspadchar.min_count_rate_limit_mcps; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS: + *ptuning_parm_value = + (int32_t)pdev->refspadchar.max_count_rate_limit_mcps; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES: + *ptuning_parm_value = + (int32_t)pXC->num_of_samples; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM: + *ptuning_parm_value = + (int32_t)pXC->algo__crosstalk_extract_min_valid_range_mm; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM: + *ptuning_parm_value = + (int32_t)pXC->algo__crosstalk_extract_max_valid_range_mm; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pXC->dss_config__target_total_rate_mcps; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pXC->phasecal_config_timeout_us; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS: + *ptuning_parm_value = + (int32_t)pXC->algo__crosstalk_extract_max_valid_rate_kcps; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM: + *ptuning_parm_value = + (int32_t)pXC->algo__crosstalk_extract_max_sigma_mm; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pXC->mm_config_timeout_us; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pXC->range_config_timeout_us; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pdev->offsetcal_cfg.dss_config__target_total_rate_mcps; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->offsetcal_cfg.phasecal_config_timeout_us; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->offsetcal_cfg.mm_config_timeout_us; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->offsetcal_cfg.range_config_timeout_us; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES: + *ptuning_parm_value = + (int32_t)pdev->offsetcal_cfg.pre_num_of_samples; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES: + *ptuning_parm_value = + (int32_t)pdev->offsetcal_cfg.mm1_num_of_samples; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES: + *ptuning_parm_value = + (int32_t)pdev->offsetcal_cfg.mm2_num_of_samples; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pdev->zonecal_cfg.dss_config__target_total_rate_mcps; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->zonecal_cfg.phasecal_config_timeout_us; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->zonecal_cfg.mm_config_timeout_us; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES: + *ptuning_parm_value = + (int32_t)pdev->zonecal_cfg.phasecal_num_of_samples; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->zonecal_cfg.range_config_timeout_us; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES: + *ptuning_parm_value = + (int32_t)pdev->zonecal_cfg.zone_num_of_samples; + break; + case VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD: + *ptuning_parm_value = + (int32_t)pdev->ssc_cfg.VL53LX_p_005; + break; + case VL53LX_TUNINGPARM_SPADMAP_VCSEL_START: + *ptuning_parm_value = + (int32_t)pdev->ssc_cfg.vcsel_start; + break; + case VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS: + *ptuning_parm_value = + (int32_t)pdev->ssc_cfg.rate_limit_mcps; + break; + case VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_dss_target_lite_mcps; + break; + case VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_dss_target_histo_mcps; + break; + case VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_dss_target_histo_mz_mcps; + break; + case VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_dss_target_timed_mcps; + break; + case VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_timeout_lite_us; + break; + case VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_long_us; + break; + case VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_med_us; + break; + case VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_short_us; + break; + case VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_long_us; + break; + case VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_med_us; + break; + case VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_short_us; + break; + case VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_phasecal_timeout_timed_us; + break; + case VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_mm_timeout_lite_us; + break; + case VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_mm_timeout_histo_us; + break; + case VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_mm_timeout_mz_us; + break; + case VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_mm_timeout_timed_us; + break; + case VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_range_timeout_lite_us; + break; + case VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_range_timeout_histo_us; + break; + case VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_range_timeout_mz_us; + break; + case VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_range_timeout_timed_us; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.smudge_margin; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.noise_margin; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.user_xtalk_offset_limit; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.user_xtalk_offset_limit_hi; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.sample_limit; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.single_xtalk_delta; + break; + case VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.averaged_xtalk_delta; + break; + case VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.smudge_corr_clip_limit; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.scaler_calc_method; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.x_gradient_scaler; + break; + case VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.y_gradient_scaler; + break; + case VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.user_scaler_set; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.smudge_corr_single_apply; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD: + *ptuning_parm_value = (int32_t)( + pdev->smudge_correct_config.smudge_corr_ambient_threshold); + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.nodetect_ambient_threshold; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.nodetect_sample_limit; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.nodetect_xtalk_offset; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM: + *ptuning_parm_value = + (int32_t)pdev->smudge_correct_config.nodetect_min_range_mm; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND: + *ptuning_parm_value = + (int32_t)pdev->low_power_auto_data.vhv_loop_bound; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_mm_timeout_lpa_us; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_range_timeout_lpa_us; + break; + case VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS: + *ptuning_parm_value = + (int32_t)pdev->tuning_parms.tp_dss_target_very_short_mcps; + break; + case VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER: + *ptuning_parm_value = + (int32_t) pdev->tuning_parms.tp_phasecal_patch_power; + break; + case VL53LX_TUNINGPARM_HIST_MERGE: + *ptuning_parm_value = + (int32_t) pdev->tuning_parms.tp_hist_merge; + break; + case VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD: + *ptuning_parm_value = + (int32_t) pdev->tuning_parms.tp_reset_merge_threshold; + break; + case VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE: + *ptuning_parm_value = + (int32_t) pdev->tuning_parms.tp_hist_merge_max_size; + break; + case VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR: + *ptuning_parm_value = + pdev->smudge_correct_config.max_smudge_factor; + break; + + default: + *ptuning_parm_value = 0x7FFFFFFF; + status = VL53LX_ERROR_INVALID_PARAMS; + break; + + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_tuning_parm( + VL53LX_TuningParms tuning_parm_key, + int32_t tuning_parm_value) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess); + VL53LX_xtalkextract_config_t *pXC = &(pdev->xtalk_extract_cfg); + + switch (tuning_parm_key) { + + case VL53LX_TUNINGPARM_VERSION: + pdev->tuning_parms.tp_tuning_parm_version = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_KEY_TABLE_VERSION: + pdev->tuning_parms.tp_tuning_parm_key_table_version = + (uint16_t)tuning_parm_value; + + + + if ((uint16_t)tuning_parm_value + != VL53LX_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT) { + status = VL53LX_ERROR_TUNING_PARM_KEY_MISMATCH; + } + + break; + case VL53LX_TUNINGPARM_LLD_VERSION: + pdev->tuning_parms.tp_tuning_parm_lld_version = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_ALGO_SELECT: + pHP->hist_algo_select = + (VL53LX_HistAlgoSelect)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_TARGET_ORDER: + pHP->hist_target_order = + (VL53LX_HistTargetOrder)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_FILTER_WOI_0: + pHP->filter_woi0 = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_FILTER_WOI_1: + pHP->filter_woi1 = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD: + pHP->hist_amb_est_method = + (VL53LX_HistAmbEstMethod)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0: + pHP->ambient_thresh_sigma0 = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1: + pHP->ambient_thresh_sigma1 = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS: + pHP->min_ambient_thresh_events = + (int32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER: + pHP->ambient_thresh_events_scaler = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD: + pHP->noise_threshold = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT: + pHP->signal_total_events_limit = + (int32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM: + pHP->sigma_estimator__sigma_ref_mm = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM: + pHP->sigma_thresh = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_GAIN_FACTOR: + pdev->gain_cal.histogram_ranging_gain_factor = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE: + pHP->algo__consistency_check__phase_tolerance = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM: + pHP->algo__consistency_check__min_max_tolerance = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA: + pHP->algo__consistency_check__event_sigma = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT: + pHP->algo__consistency_check__event_min_spad_count = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_hist_long = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_hist_med = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_hist_short = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE: + pdev->tuning_parms.tp_init_phase_ref_hist_long = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE: + pdev->tuning_parms.tp_init_phase_ref_hist_med = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE: + pdev->tuning_parms.tp_init_phase_ref_hist_short = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM: + pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm = + (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM: + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm = + (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM: + pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE: + pHP->algo__crosstalk_detect_min_max_tolerance = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS: + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA: + pHP->algo__crosstalk_detect_event_sigma = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS: + pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps = + (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE: + pdev->tuning_parms.tp_consistency_lite_phase_tolerance = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_PHASECAL_TARGET: + pdev->tuning_parms.tp_phasecal_target = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE: + pdev->tuning_parms.tp_cal_repeat_rate = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR: + pdev->gain_cal.standard_ranging_gain_factor = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM: + pdev->tuning_parms.tp_lite_min_clip = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM: + pdev->tuning_parms.tp_lite_long_sigma_thresh_mm = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM: + pdev->tuning_parms.tp_lite_med_sigma_thresh_mm = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM: + pdev->tuning_parms.tp_lite_short_sigma_thresh_mm = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS: + pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS: + pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS: + pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH: + pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS: + pdev->tuning_parms.tp_lite_sigma_est_amb_width_ns = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM: + pdev->tuning_parms.tp_lite_sigma_ref_mm = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_RIT_MULT: + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SEED_CONFIG: + pdev->tuning_parms.tp_lite_seed_cfg = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_QUANTIFIER: + pdev->tuning_parms.tp_lite_quantifier = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT: + pdev->tuning_parms.tp_lite_first_order_select = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS: + pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps = + (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_lite_long = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_lite_med = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_lite_short = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE: + pdev->tuning_parms.tp_init_phase_ref_lite_long = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE: + pdev->tuning_parms.tp_init_phase_ref_lite_med = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE: + pdev->tuning_parms.tp_init_phase_ref_lite_short = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_TIMED_SEED_CONFIG: + pdev->tuning_parms.tp_timed_seed_cfg = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA: + pdev->dmax_cfg.signal_thresh_sigma = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[0] = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[1] = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[2] = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[3] = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[4] = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_VHV_LOOPBOUND: + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE: + pdev->refspadchar.device_test_mode = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD: + pdev->refspadchar.VL53LX_p_005 = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US: + pdev->refspadchar.timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS: + pdev->refspadchar.target_count_rate_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS: + pdev->refspadchar.min_count_rate_limit_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS: + pdev->refspadchar.max_count_rate_limit_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES: + pXC->num_of_samples = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM: + pXC->algo__crosstalk_extract_min_valid_range_mm = + (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM: + pXC->algo__crosstalk_extract_max_valid_range_mm = + (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS: + pXC->dss_config__target_total_rate_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US: + pXC->phasecal_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS: + pXC->algo__crosstalk_extract_max_valid_rate_kcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM: + pXC->algo__crosstalk_extract_max_sigma_mm = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US: + pXC->mm_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US: + pXC->range_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS: + pdev->offsetcal_cfg.dss_config__target_total_rate_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US: + pdev->offsetcal_cfg.phasecal_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US: + pdev->offsetcal_cfg.mm_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US: + pdev->offsetcal_cfg.range_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES: + pdev->offsetcal_cfg.pre_num_of_samples = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES: + pdev->offsetcal_cfg.mm1_num_of_samples = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES: + pdev->offsetcal_cfg.mm2_num_of_samples = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS: + pdev->zonecal_cfg.dss_config__target_total_rate_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US: + pdev->zonecal_cfg.phasecal_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US: + pdev->zonecal_cfg.mm_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES: + pdev->zonecal_cfg.phasecal_num_of_samples = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US: + pdev->zonecal_cfg.range_config_timeout_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES: + pdev->zonecal_cfg.zone_num_of_samples = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD: + pdev->ssc_cfg.VL53LX_p_005 = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_SPADMAP_VCSEL_START: + pdev->ssc_cfg.vcsel_start = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS: + pdev->ssc_cfg.rate_limit_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_lite_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_histo_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_histo_mz_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_timed_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_lite_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_hist_long_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_hist_med_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_hist_short_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_mz_long_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_mz_med_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_mz_short_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_timed_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_lite_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_histo_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_mz_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_timed_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_lite_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_histo_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_mz_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_timed_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN: + pdev->smudge_correct_config.smudge_margin = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN: + pdev->smudge_correct_config.noise_margin = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT: + pdev->smudge_correct_config.user_xtalk_offset_limit = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI: + pdev->smudge_correct_config.user_xtalk_offset_limit_hi = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT: + pdev->smudge_correct_config.sample_limit = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA: + pdev->smudge_correct_config.single_xtalk_delta = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA: + pdev->smudge_correct_config.averaged_xtalk_delta = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT: + pdev->smudge_correct_config.smudge_corr_clip_limit = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD: + pdev->smudge_correct_config.scaler_calc_method = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER: + pdev->smudge_correct_config.x_gradient_scaler = + (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER: + pdev->smudge_correct_config.y_gradient_scaler = + (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET: + pdev->smudge_correct_config.user_scaler_set = + (uint8_t)tuning_parm_value; + break; + + case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY: + pdev->smudge_correct_config.smudge_corr_single_apply = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD: + pdev->smudge_correct_config.smudge_corr_ambient_threshold = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS: + pdev->smudge_correct_config.nodetect_ambient_threshold = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT: + pdev->smudge_correct_config.nodetect_sample_limit = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS: + pdev->smudge_correct_config.nodetect_xtalk_offset = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM: + pdev->smudge_correct_config.nodetect_min_range_mm = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND: + pdev->low_power_auto_data.vhv_loop_bound = + (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_lpa_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_lpa_us = + (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_very_short_mcps = + (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER: + pdev->tuning_parms.tp_phasecal_patch_power = + (uint16_t) tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_MERGE: + pdev->tuning_parms.tp_hist_merge = + (uint16_t) tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD: + pdev->tuning_parms.tp_reset_merge_threshold = + (uint16_t) tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE: + pdev->tuning_parms.tp_hist_merge_max_size = + (uint16_t) tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR: + pdev->smudge_correct_config.max_smudge_factor = + (uint32_t)tuning_parm_value; + break; + + default: + status = VL53LX_ERROR_INVALID_PARAMS; + break; + + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_enable() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_enabled = 1; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_disable() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_enabled = 0; + + return status; +} +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_apply_enable() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_apply_enabled = 1; + + return status; +} +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_apply_disable() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_apply_enabled = 0; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_single_apply_enable() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_single_apply = 1; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_single_apply_disable() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + pdev->smudge_correct_config.smudge_corr_single_apply = 0; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_set_scalers( + int16_t x_scaler_in, + int16_t y_scaler_in, + uint8_t user_scaler_set_in +) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + pdev->smudge_correct_config.x_gradient_scaler = x_scaler_in; + pdev->smudge_correct_config.y_gradient_scaler = y_scaler_in; + pdev->smudge_correct_config.user_scaler_set = user_scaler_set_in; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_current_xtalk_settings( + VL53LX_xtalk_calibration_results_t *pxtalk +) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t i; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pxtalk->algo__crosstalk_compensation_plane_offset_kcps = + pdev->xtalk_cfg.algo__crosstalk_compensation_plane_offset_kcps; + pxtalk->algo__crosstalk_compensation_x_plane_gradient_kcps = + pdev->xtalk_cfg.algo__crosstalk_compensation_x_plane_gradient_kcps; + pxtalk->algo__crosstalk_compensation_y_plane_gradient_kcps = + pdev->xtalk_cfg.algo__crosstalk_compensation_y_plane_gradient_kcps; + for (i = 0; i < VL53LX_BIN_REC_SIZE; i++) + pxtalk->algo__xtalk_cpo_HistoMerge_kcps[i] = + pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[i]; + + + return status; + +} +VL53LX_Error VL53LX::VL53LX_set_current_xtalk_settings( + VL53LX_xtalk_calibration_results_t *pxtalk +) +{ + + uint8_t i; + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->xtalk_cfg.algo__crosstalk_compensation_plane_offset_kcps = + pxtalk->algo__crosstalk_compensation_plane_offset_kcps; + pdev->xtalk_cfg.algo__crosstalk_compensation_x_plane_gradient_kcps = + pxtalk->algo__crosstalk_compensation_x_plane_gradient_kcps; + pdev->xtalk_cfg.algo__crosstalk_compensation_y_plane_gradient_kcps = + pxtalk->algo__crosstalk_compensation_y_plane_gradient_kcps; + for (i = 0; i < VL53LX_BIN_REC_SIZE; i++) + pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[i] = + pxtalk->algo__xtalk_cpo_HistoMerge_kcps[i]; + + + return status; + +} + +/* vl53lx_register_funcs.c */ + +VL53LX_Error VL53LX::VL53LX_i2c_encode_static_nvm_managed( + VL53LX_static_nvm_managed_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->i2c_slave__device_address & 0x7F; + *(pbuffer + 1) = + pdata->ana_config__vhv_ref_sel_vddpix & 0xF; + *(pbuffer + 2) = + pdata->ana_config__vhv_ref_sel_vquench & 0x7F; + *(pbuffer + 3) = + pdata->ana_config__reg_avdd1v2_sel & 0x3; + *(pbuffer + 4) = + pdata->ana_config__fast_osc__trim & 0x7F; + VL53LX_i2c_encode_uint16_t( + pdata->osc_measured__fast_osc__frequency, + 2, + pbuffer + 5); + *(pbuffer + 7) = + pdata->vhv_config__timeout_macrop_loop_bound; + *(pbuffer + 8) = + pdata->vhv_config__count_thresh; + *(pbuffer + 9) = + pdata->vhv_config__offset & 0x3F; + *(pbuffer + 10) = + pdata->vhv_config__init; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_static_nvm_managed( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_static_nvm_managed_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->i2c_slave__device_address = + (*(pbuffer + 0)) & 0x7F; + pdata->ana_config__vhv_ref_sel_vddpix = + (*(pbuffer + 1)) & 0xF; + pdata->ana_config__vhv_ref_sel_vquench = + (*(pbuffer + 2)) & 0x7F; + pdata->ana_config__reg_avdd1v2_sel = + (*(pbuffer + 3)) & 0x3; + pdata->ana_config__fast_osc__trim = + (*(pbuffer + 4)) & 0x7F; + pdata->osc_measured__fast_osc__frequency = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 5)); + pdata->vhv_config__timeout_macrop_loop_bound = + (*(pbuffer + 7)); + pdata->vhv_config__count_thresh = + (*(pbuffer + 8)); + pdata->vhv_config__offset = + (*(pbuffer + 9)) & 0x3F; + pdata->vhv_config__init = + (*(pbuffer + 10)); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_static_nvm_managed( + VL53LX_static_nvm_managed_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_static_nvm_managed( + pdata, + VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_I2C_SLAVE__DEVICE_ADDRESS, + comms_buffer, + VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_static_nvm_managed( + VL53LX_static_nvm_managed_t *pdata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_I2C_SLAVE__DEVICE_ADDRESS, + comms_buffer, + VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_static_nvm_managed( + VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_encode_customer_nvm_managed( + VL53LX_customer_nvm_managed_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->global_config__spad_enables_ref_0; + *(pbuffer + 1) = + pdata->global_config__spad_enables_ref_1; + *(pbuffer + 2) = + pdata->global_config__spad_enables_ref_2; + *(pbuffer + 3) = + pdata->global_config__spad_enables_ref_3; + *(pbuffer + 4) = + pdata->global_config__spad_enables_ref_4; + *(pbuffer + 5) = + pdata->global_config__spad_enables_ref_5 & 0xF; + *(pbuffer + 6) = + pdata->global_config__ref_en_start_select; + *(pbuffer + 7) = + pdata->ref_spad_man__num_requested_ref_spads & 0x3F; + *(pbuffer + 8) = + pdata->ref_spad_man__ref_location & 0x3; + VL53LX_i2c_encode_uint16_t( + pdata->algo__crosstalk_compensation_plane_offset_kcps, + 2, + pbuffer + 9); + VL53LX_i2c_encode_int16_t( + pdata->algo__crosstalk_compensation_x_plane_gradient_kcps, + 2, + pbuffer + 11); + VL53LX_i2c_encode_int16_t( + pdata->algo__crosstalk_compensation_y_plane_gradient_kcps, + 2, + pbuffer + 13); + VL53LX_i2c_encode_uint16_t( + pdata->ref_spad_char__total_rate_target_mcps, + 2, + pbuffer + 15); + VL53LX_i2c_encode_int16_t( + pdata->algo__part_to_part_range_offset_mm & 0x1FFF, + 2, + pbuffer + 17); + VL53LX_i2c_encode_int16_t( + pdata->mm_config__inner_offset_mm, + 2, + pbuffer + 19); + VL53LX_i2c_encode_int16_t( + pdata->mm_config__outer_offset_mm, + 2, + pbuffer + 21); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_customer_nvm_managed( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_customer_nvm_managed_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->global_config__spad_enables_ref_0 = + (*(pbuffer + 0)); + pdata->global_config__spad_enables_ref_1 = + (*(pbuffer + 1)); + pdata->global_config__spad_enables_ref_2 = + (*(pbuffer + 2)); + pdata->global_config__spad_enables_ref_3 = + (*(pbuffer + 3)); + pdata->global_config__spad_enables_ref_4 = + (*(pbuffer + 4)); + pdata->global_config__spad_enables_ref_5 = + (*(pbuffer + 5)) & 0xF; + pdata->global_config__ref_en_start_select = + (*(pbuffer + 6)); + pdata->ref_spad_man__num_requested_ref_spads = + (*(pbuffer + 7)) & 0x3F; + pdata->ref_spad_man__ref_location = + (*(pbuffer + 8)) & 0x3; + pdata->algo__crosstalk_compensation_plane_offset_kcps = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 9)); + pdata->algo__crosstalk_compensation_x_plane_gradient_kcps = + (VL53LX_i2c_decode_int16_t(2, pbuffer + 11)); + pdata->algo__crosstalk_compensation_y_plane_gradient_kcps = + (VL53LX_i2c_decode_int16_t(2, pbuffer + 13)); + pdata->ref_spad_char__total_rate_target_mcps = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 15)); + pdata->algo__part_to_part_range_offset_mm = + (VL53LX_i2c_decode_int16_t(2, pbuffer + 17)) & 0x1FFF; + pdata->mm_config__inner_offset_mm = + (VL53LX_i2c_decode_int16_t(2, pbuffer + 19)); + pdata->mm_config__outer_offset_mm = + (VL53LX_i2c_decode_int16_t(2, pbuffer + 21)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_customer_nvm_managed( + VL53LX_customer_nvm_managed_t *pdata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_customer_nvm_managed( + pdata, + VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, + comms_buffer, + VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_customer_nvm_managed( + VL53LX_customer_nvm_managed_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, + comms_buffer, + VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_customer_nvm_managed( + VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_encode_static_config( + VL53LX_static_config_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + VL53LX_i2c_encode_uint16_t( + pdata->dss_config__target_total_rate_mcps, + 2, + pbuffer + 0); + *(pbuffer + 2) = + pdata->debug__ctrl & 0x1; + *(pbuffer + 3) = + pdata->test_mode__ctrl & 0xF; + *(pbuffer + 4) = + pdata->clk_gating__ctrl & 0xF; + *(pbuffer + 5) = + pdata->nvm_bist__ctrl & 0x1F; + *(pbuffer + 6) = + pdata->nvm_bist__num_nvm_words & 0x7F; + *(pbuffer + 7) = + pdata->nvm_bist__start_address & 0x7F; + *(pbuffer + 8) = + pdata->host_if__status & 0x1; + *(pbuffer + 9) = + pdata->pad_i2c_hv__config; + *(pbuffer + 10) = + pdata->pad_i2c_hv__extsup_config & 0x1; + *(pbuffer + 11) = + pdata->gpio_hv_pad__ctrl & 0x3; + *(pbuffer + 12) = + pdata->gpio_hv_mux__ctrl & 0x1F; + *(pbuffer + 13) = + pdata->gpio__tio_hv_status & 0x3; + *(pbuffer + 14) = + pdata->gpio__fio_hv_status & 0x3; + *(pbuffer + 15) = + pdata->ana_config__spad_sel_pswidth & 0x7; + *(pbuffer + 16) = + pdata->ana_config__vcsel_pulse_width_offset & 0x1F; + *(pbuffer + 17) = + pdata->ana_config__fast_osc__config_ctrl & 0x1; + *(pbuffer + 18) = + pdata->sigma_estimator__effective_pulse_width_ns; + *(pbuffer + 19) = + pdata->sigma_estimator__effective_ambient_width_ns; + *(pbuffer + 20) = + pdata->sigma_estimator__sigma_ref_mm; + *(pbuffer + 21) = + pdata->algo__crosstalk_compensation_valid_height_mm; + *(pbuffer + 22) = + pdata->spare_host_config__static_config_spare_0; + *(pbuffer + 23) = + pdata->spare_host_config__static_config_spare_1; + VL53LX_i2c_encode_uint16_t( + pdata->algo__range_ignore_threshold_mcps, + 2, + pbuffer + 24); + *(pbuffer + 26) = + pdata->algo__range_ignore_valid_height_mm; + *(pbuffer + 27) = + pdata->algo__range_min_clip; + *(pbuffer + 28) = + pdata->algo__consistency_check__tolerance & 0xF; + *(pbuffer + 29) = + pdata->spare_host_config__static_config_spare_2; + *(pbuffer + 30) = + pdata->sd_config__reset_stages_msb & 0xF; + *(pbuffer + 31) = + pdata->sd_config__reset_stages_lsb; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_static_config( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_static_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->dss_config__target_total_rate_mcps = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 0)); + pdata->debug__ctrl = + (*(pbuffer + 2)) & 0x1; + pdata->test_mode__ctrl = + (*(pbuffer + 3)) & 0xF; + pdata->clk_gating__ctrl = + (*(pbuffer + 4)) & 0xF; + pdata->nvm_bist__ctrl = + (*(pbuffer + 5)) & 0x1F; + pdata->nvm_bist__num_nvm_words = + (*(pbuffer + 6)) & 0x7F; + pdata->nvm_bist__start_address = + (*(pbuffer + 7)) & 0x7F; + pdata->host_if__status = + (*(pbuffer + 8)) & 0x1; + pdata->pad_i2c_hv__config = + (*(pbuffer + 9)); + pdata->pad_i2c_hv__extsup_config = + (*(pbuffer + 10)) & 0x1; + pdata->gpio_hv_pad__ctrl = + (*(pbuffer + 11)) & 0x3; + pdata->gpio_hv_mux__ctrl = + (*(pbuffer + 12)) & 0x1F; + pdata->gpio__tio_hv_status = + (*(pbuffer + 13)) & 0x3; + pdata->gpio__fio_hv_status = + (*(pbuffer + 14)) & 0x3; + pdata->ana_config__spad_sel_pswidth = + (*(pbuffer + 15)) & 0x7; + pdata->ana_config__vcsel_pulse_width_offset = + (*(pbuffer + 16)) & 0x1F; + pdata->ana_config__fast_osc__config_ctrl = + (*(pbuffer + 17)) & 0x1; + pdata->sigma_estimator__effective_pulse_width_ns = + (*(pbuffer + 18)); + pdata->sigma_estimator__effective_ambient_width_ns = + (*(pbuffer + 19)); + pdata->sigma_estimator__sigma_ref_mm = + (*(pbuffer + 20)); + pdata->algo__crosstalk_compensation_valid_height_mm = + (*(pbuffer + 21)); + pdata->spare_host_config__static_config_spare_0 = + (*(pbuffer + 22)); + pdata->spare_host_config__static_config_spare_1 = + (*(pbuffer + 23)); + pdata->algo__range_ignore_threshold_mcps = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 24)); + pdata->algo__range_ignore_valid_height_mm = + (*(pbuffer + 26)); + pdata->algo__range_min_clip = + (*(pbuffer + 27)); + pdata->algo__consistency_check__tolerance = + (*(pbuffer + 28)) & 0xF; + pdata->spare_host_config__static_config_spare_2 = + (*(pbuffer + 29)); + pdata->sd_config__reset_stages_msb = + (*(pbuffer + 30)) & 0xF; + pdata->sd_config__reset_stages_lsb = + (*(pbuffer + 31)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_static_config( + VL53LX_static_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_static_config( + pdata, + VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_DSS_CONFIG__TARGET_TOTAL_RATE_MCPS, + comms_buffer, + VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_static_config( + VL53LX_static_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_DSS_CONFIG__TARGET_TOTAL_RATE_MCPS, + comms_buffer, + VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_static_config( + VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_encode_general_config( + VL53LX_general_config_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->gph_config__stream_count_update_value; + *(pbuffer + 1) = + pdata->global_config__stream_divider; + *(pbuffer + 2) = + pdata->system__interrupt_config_gpio; + *(pbuffer + 3) = + pdata->cal_config__vcsel_start & 0x7F; + VL53LX_i2c_encode_uint16_t( + pdata->cal_config__repeat_rate & 0xFFF, + 2, + pbuffer + 4); + *(pbuffer + 6) = + pdata->global_config__vcsel_width & 0x7F; + *(pbuffer + 7) = + pdata->phasecal_config__timeout_macrop; + *(pbuffer + 8) = + pdata->phasecal_config__target; + *(pbuffer + 9) = + pdata->phasecal_config__override & 0x1; + *(pbuffer + 11) = + pdata->dss_config__roi_mode_control & 0x7; + VL53LX_i2c_encode_uint16_t( + pdata->system__thresh_rate_high, + 2, + pbuffer + 12); + VL53LX_i2c_encode_uint16_t( + pdata->system__thresh_rate_low, + 2, + pbuffer + 14); + VL53LX_i2c_encode_uint16_t( + pdata->dss_config__manual_effective_spads_select, + 2, + pbuffer + 16); + *(pbuffer + 18) = + pdata->dss_config__manual_block_select; + *(pbuffer + 19) = + pdata->dss_config__aperture_attenuation; + *(pbuffer + 20) = + pdata->dss_config__max_spads_limit; + *(pbuffer + 21) = + pdata->dss_config__min_spads_limit; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_decode_general_config( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_general_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->gph_config__stream_count_update_value = + (*(pbuffer + 0)); + pdata->global_config__stream_divider = + (*(pbuffer + 1)); + pdata->system__interrupt_config_gpio = + (*(pbuffer + 2)); + pdata->cal_config__vcsel_start = + (*(pbuffer + 3)) & 0x7F; + pdata->cal_config__repeat_rate = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 4)) & 0xFFF; + pdata->global_config__vcsel_width = + (*(pbuffer + 6)) & 0x7F; + pdata->phasecal_config__timeout_macrop = + (*(pbuffer + 7)); + pdata->phasecal_config__target = + (*(pbuffer + 8)); + pdata->phasecal_config__override = + (*(pbuffer + 9)) & 0x1; + pdata->dss_config__roi_mode_control = + (*(pbuffer + 11)) & 0x7; + pdata->system__thresh_rate_high = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 12)); + pdata->system__thresh_rate_low = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 14)); + pdata->dss_config__manual_effective_spads_select = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 16)); + pdata->dss_config__manual_block_select = + (*(pbuffer + 18)); + pdata->dss_config__aperture_attenuation = + (*(pbuffer + 19)); + pdata->dss_config__max_spads_limit = + (*(pbuffer + 20)); + pdata->dss_config__min_spads_limit = + (*(pbuffer + 21)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_general_config( + VL53LX_general_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_general_config( + pdata, + VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_GPH_CONFIG__STREAM_COUNT_UPDATE_VALUE, + comms_buffer, + VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_general_config( + VL53LX_general_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES]; + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_GPH_CONFIG__STREAM_COUNT_UPDATE_VALUE, + comms_buffer, + VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_general_config( + VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_encode_timing_config( + VL53LX_timing_config_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->mm_config__timeout_macrop_a_hi & 0xF; + *(pbuffer + 1) = + pdata->mm_config__timeout_macrop_a_lo; + *(pbuffer + 2) = + pdata->mm_config__timeout_macrop_b_hi & 0xF; + *(pbuffer + 3) = + pdata->mm_config__timeout_macrop_b_lo; + *(pbuffer + 4) = + pdata->range_config__timeout_macrop_a_hi & 0xF; + *(pbuffer + 5) = + pdata->range_config__timeout_macrop_a_lo; + *(pbuffer + 6) = + pdata->range_config__vcsel_period_a & 0x3F; + *(pbuffer + 7) = + pdata->range_config__timeout_macrop_b_hi & 0xF; + *(pbuffer + 8) = + pdata->range_config__timeout_macrop_b_lo; + *(pbuffer + 9) = + pdata->range_config__vcsel_period_b & 0x3F; + VL53LX_i2c_encode_uint16_t( + pdata->range_config__sigma_thresh, + 2, + pbuffer + 10); + VL53LX_i2c_encode_uint16_t( + pdata->range_config__min_count_rate_rtn_limit_mcps, + 2, + pbuffer + 12); + *(pbuffer + 14) = + pdata->range_config__valid_phase_low; + *(pbuffer + 15) = + pdata->range_config__valid_phase_high; + VL53LX_i2c_encode_uint32_t( + pdata->system__intermeasurement_period, + 4, + pbuffer + 18); + *(pbuffer + 22) = + pdata->system__fractional_enable & 0x1; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_timing_config( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_timing_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->mm_config__timeout_macrop_a_hi = + (*(pbuffer + 0)) & 0xF; + pdata->mm_config__timeout_macrop_a_lo = + (*(pbuffer + 1)); + pdata->mm_config__timeout_macrop_b_hi = + (*(pbuffer + 2)) & 0xF; + pdata->mm_config__timeout_macrop_b_lo = + (*(pbuffer + 3)); + pdata->range_config__timeout_macrop_a_hi = + (*(pbuffer + 4)) & 0xF; + pdata->range_config__timeout_macrop_a_lo = + (*(pbuffer + 5)); + pdata->range_config__vcsel_period_a = + (*(pbuffer + 6)) & 0x3F; + pdata->range_config__timeout_macrop_b_hi = + (*(pbuffer + 7)) & 0xF; + pdata->range_config__timeout_macrop_b_lo = + (*(pbuffer + 8)); + pdata->range_config__vcsel_period_b = + (*(pbuffer + 9)) & 0x3F; + pdata->range_config__sigma_thresh = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 10)); + pdata->range_config__min_count_rate_rtn_limit_mcps = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 12)); + pdata->range_config__valid_phase_low = + (*(pbuffer + 14)); + pdata->range_config__valid_phase_high = + (*(pbuffer + 15)); + pdata->system__intermeasurement_period = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 18)); + pdata->system__fractional_enable = + (*(pbuffer + 22)) & 0x1; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_timing_config( + VL53LX_timing_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_timing_config( + pdata, + VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_MM_CONFIG__TIMEOUT_MACROP_A_HI, + comms_buffer, + VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_timing_config( + VL53LX_timing_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_MM_CONFIG__TIMEOUT_MACROP_A_HI, + comms_buffer, + VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_timing_config( + VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_encode_dynamic_config( + VL53LX_dynamic_config_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->system__grouped_parameter_hold_0 & 0x3; + VL53LX_i2c_encode_uint16_t( + pdata->system__thresh_high, + 2, + pbuffer + 1); + VL53LX_i2c_encode_uint16_t( + pdata->system__thresh_low, + 2, + pbuffer + 3); + *(pbuffer + 5) = + pdata->system__enable_xtalk_per_quadrant & 0x1; + *(pbuffer + 6) = + pdata->system__seed_config & 0x7; + *(pbuffer + 7) = + pdata->sd_config__woi_sd0; + *(pbuffer + 8) = + pdata->sd_config__woi_sd1; + *(pbuffer + 9) = + pdata->sd_config__initial_phase_sd0 & 0x7F; + *(pbuffer + 10) = + pdata->sd_config__initial_phase_sd1 & 0x7F; + *(pbuffer + 11) = + pdata->system__grouped_parameter_hold_1 & 0x3; + *(pbuffer + 12) = + pdata->sd_config__first_order_select & 0x3; + *(pbuffer + 13) = + pdata->sd_config__quantifier & 0xF; + *(pbuffer + 14) = + pdata->roi_config__user_roi_centre_spad; + *(pbuffer + 15) = + pdata->roi_config__user_roi_requested_global_xy_size; + *(pbuffer + 16) = + pdata->system__sequence_config; + *(pbuffer + 17) = + pdata->system__grouped_parameter_hold & 0x3; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_dynamic_config( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_dynamic_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->system__grouped_parameter_hold_0 = + (*(pbuffer + 0)) & 0x3; + pdata->system__thresh_high = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 1)); + pdata->system__thresh_low = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 3)); + pdata->system__enable_xtalk_per_quadrant = + (*(pbuffer + 5)) & 0x1; + pdata->system__seed_config = + (*(pbuffer + 6)) & 0x7; + pdata->sd_config__woi_sd0 = + (*(pbuffer + 7)); + pdata->sd_config__woi_sd1 = + (*(pbuffer + 8)); + pdata->sd_config__initial_phase_sd0 = + (*(pbuffer + 9)) & 0x7F; + pdata->sd_config__initial_phase_sd1 = + (*(pbuffer + 10)) & 0x7F; + pdata->system__grouped_parameter_hold_1 = + (*(pbuffer + 11)) & 0x3; + pdata->sd_config__first_order_select = + (*(pbuffer + 12)) & 0x3; + pdata->sd_config__quantifier = + (*(pbuffer + 13)) & 0xF; + pdata->roi_config__user_roi_centre_spad = + (*(pbuffer + 14)); + pdata->roi_config__user_roi_requested_global_xy_size = + (*(pbuffer + 15)); + pdata->system__sequence_config = + (*(pbuffer + 16)); + pdata->system__grouped_parameter_hold = + (*(pbuffer + 17)) & 0x3; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_dynamic_config( + VL53LX_dynamic_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_dynamic_config( + pdata, + VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_SYSTEM__GROUPED_PARAMETER_HOLD_0, + comms_buffer, + VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_dynamic_config( + VL53LX_dynamic_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_SYSTEM__GROUPED_PARAMETER_HOLD_0, + comms_buffer, + VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_dynamic_config( + VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_encode_system_control( + VL53LX_system_control_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->power_management__go1_power_force & 0x1; + *(pbuffer + 1) = + pdata->system__stream_count_ctrl & 0x1; + *(pbuffer + 2) = + pdata->firmware__enable & 0x1; + *(pbuffer + 3) = + pdata->system__interrupt_clear & 0x3; + *(pbuffer + 4) = + pdata->system__mode_start; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_system_control( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_system_control_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->power_management__go1_power_force = + (*(pbuffer + 0)) & 0x1; + pdata->system__stream_count_ctrl = + (*(pbuffer + 1)) & 0x1; + pdata->firmware__enable = + (*(pbuffer + 2)) & 0x1; + pdata->system__interrupt_clear = + (*(pbuffer + 3)) & 0x3; + pdata->system__mode_start = + (*(pbuffer + 4)); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_system_control( + VL53LX_system_control_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_system_control( + pdata, + VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE, + comms_buffer, + VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_system_control( + VL53LX_system_control_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE, + comms_buffer, + VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_system_control( + VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_encode_system_results( + VL53LX_system_results_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->result__interrupt_status & 0x3F; + *(pbuffer + 1) = + pdata->result__range_status; + *(pbuffer + 2) = + pdata->result__report_status & 0xF; + *(pbuffer + 3) = + pdata->result__stream_count; + VL53LX_i2c_encode_uint16_t( + pdata->result__dss_actual_effective_spads_sd0, + 2, + pbuffer + 4); + VL53LX_i2c_encode_uint16_t( + pdata->result__peak_signal_count_rate_mcps_sd0, + 2, + pbuffer + 6); + VL53LX_i2c_encode_uint16_t( + pdata->result__ambient_count_rate_mcps_sd0, + 2, + pbuffer + 8); + VL53LX_i2c_encode_uint16_t( + pdata->result__sigma_sd0, + 2, + pbuffer + 10); + VL53LX_i2c_encode_uint16_t( + pdata->result__phase_sd0, + 2, + pbuffer + 12); + VL53LX_i2c_encode_uint16_t( + pdata->result__final_crosstalk_corrected_range_mm_sd0, + 2, + pbuffer + 14); + VL53LX_i2c_encode_uint16_t( + pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0, + 2, + pbuffer + 16); + VL53LX_i2c_encode_uint16_t( + pdata->result__mm_inner_actual_effective_spads_sd0, + 2, + pbuffer + 18); + VL53LX_i2c_encode_uint16_t( + pdata->result__mm_outer_actual_effective_spads_sd0, + 2, + pbuffer + 20); + VL53LX_i2c_encode_uint16_t( + pdata->result__avg_signal_count_rate_mcps_sd0, + 2, + pbuffer + 22); + VL53LX_i2c_encode_uint16_t( + pdata->result__dss_actual_effective_spads_sd1, + 2, + pbuffer + 24); + VL53LX_i2c_encode_uint16_t( + pdata->result__peak_signal_count_rate_mcps_sd1, + 2, + pbuffer + 26); + VL53LX_i2c_encode_uint16_t( + pdata->result__ambient_count_rate_mcps_sd1, + 2, + pbuffer + 28); + VL53LX_i2c_encode_uint16_t( + pdata->result__sigma_sd1, + 2, + pbuffer + 30); + VL53LX_i2c_encode_uint16_t( + pdata->result__phase_sd1, + 2, + pbuffer + 32); + VL53LX_i2c_encode_uint16_t( + pdata->result__final_crosstalk_corrected_range_mm_sd1, + 2, + pbuffer + 34); + VL53LX_i2c_encode_uint16_t( + pdata->result__spare_0_sd1, + 2, + pbuffer + 36); + VL53LX_i2c_encode_uint16_t( + pdata->result__spare_1_sd1, + 2, + pbuffer + 38); + VL53LX_i2c_encode_uint16_t( + pdata->result__spare_2_sd1, + 2, + pbuffer + 40); + *(pbuffer + 42) = + pdata->result__spare_3_sd1; + *(pbuffer + 43) = + pdata->result__thresh_info; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_system_results( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->result__interrupt_status = + (*(pbuffer + 0)) & 0x3F; + pdata->result__range_status = + (*(pbuffer + 1)); + pdata->result__report_status = + (*(pbuffer + 2)) & 0xF; + pdata->result__stream_count = + (*(pbuffer + 3)); + pdata->result__dss_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 4)); + pdata->result__peak_signal_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 6)); + pdata->result__ambient_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 8)); + pdata->result__sigma_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 10)); + pdata->result__phase_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 12)); + pdata->result__final_crosstalk_corrected_range_mm_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 14)); + pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 16)); + pdata->result__mm_inner_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 18)); + pdata->result__mm_outer_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 20)); + pdata->result__avg_signal_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 22)); + pdata->result__dss_actual_effective_spads_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 24)); + pdata->result__peak_signal_count_rate_mcps_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 26)); + pdata->result__ambient_count_rate_mcps_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 28)); + pdata->result__sigma_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 30)); + pdata->result__phase_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 32)); + pdata->result__final_crosstalk_corrected_range_mm_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 34)); + pdata->result__spare_0_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 36)); + pdata->result__spare_1_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 38)); + pdata->result__spare_2_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 40)); + pdata->result__spare_3_sd1 = + (*(pbuffer + 42)); + pdata->result__thresh_info = + (*(pbuffer + 43)); + + return status; +} +VL53LX_Error VL53LX::VL53LX_set_system_results( + VL53LX_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_system_results( + pdata, + VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_RESULT__INTERRUPT_STATUS, + comms_buffer, + VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_system_results( + VL53LX_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_RESULT__INTERRUPT_STATUS, + comms_buffer, + VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_system_results( + VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_core_results( + VL53LX_core_results_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_CORE_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + VL53LX_i2c_encode_uint32_t( + pdata->result_core__ambient_window_events_sd0, + 4, + pbuffer + 0); + VL53LX_i2c_encode_uint32_t( + pdata->result_core__ranging_total_events_sd0, + 4, + pbuffer + 4); + VL53LX_i2c_encode_int32_t( + pdata->result_core__signal_total_events_sd0, + 4, + pbuffer + 8); + VL53LX_i2c_encode_uint32_t( + pdata->result_core__total_periods_elapsed_sd0, + 4, + pbuffer + 12); + VL53LX_i2c_encode_uint32_t( + pdata->result_core__ambient_window_events_sd1, + 4, + pbuffer + 16); + VL53LX_i2c_encode_uint32_t( + pdata->result_core__ranging_total_events_sd1, + 4, + pbuffer + 20); + VL53LX_i2c_encode_int32_t( + pdata->result_core__signal_total_events_sd1, + 4, + pbuffer + 24); + VL53LX_i2c_encode_uint32_t( + pdata->result_core__total_periods_elapsed_sd1, + 4, + pbuffer + 28); + *(pbuffer + 32) = + pdata->result_core__spare_0; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_decode_core_results( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_CORE_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->result_core__ambient_window_events_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 0)); + pdata->result_core__ranging_total_events_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 4)); + pdata->result_core__signal_total_events_sd0 = + (VL53LX_i2c_decode_int32_t(4, pbuffer + 8)); + pdata->result_core__total_periods_elapsed_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 12)); + pdata->result_core__ambient_window_events_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 16)); + pdata->result_core__ranging_total_events_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 20)); + pdata->result_core__signal_total_events_sd1 = + (VL53LX_i2c_decode_int32_t(4, pbuffer + 24)); + pdata->result_core__total_periods_elapsed_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 28)); + pdata->result_core__spare_0 = + (*(pbuffer + 32)); + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_core_results( + VL53LX_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_CORE_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_core_results( + pdata, + VL53LX_CORE_RESULTS_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0, + comms_buffer, + VL53LX_CORE_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_core_results( + VL53LX_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_CORE_RESULTS_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0, + comms_buffer, + VL53LX_CORE_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_core_results( + VL53LX_CORE_RESULTS_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_debug_results( + VL53LX_debug_results_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + VL53LX_i2c_encode_uint16_t( + pdata->phasecal_result__reference_phase, + 2, + pbuffer + 0); + *(pbuffer + 2) = + pdata->phasecal_result__vcsel_start & 0x7F; + *(pbuffer + 3) = + pdata->ref_spad_char_result__num_actual_ref_spads & 0x3F; + *(pbuffer + 4) = + pdata->ref_spad_char_result__ref_location & 0x3; + *(pbuffer + 5) = + pdata->vhv_result__coldboot_status & 0x1; + *(pbuffer + 6) = + pdata->vhv_result__search_result & 0x3F; + *(pbuffer + 7) = + pdata->vhv_result__latest_setting & 0x3F; + VL53LX_i2c_encode_uint16_t( + pdata->result__osc_calibrate_val & 0x3FF, + 2, + pbuffer + 8); + *(pbuffer + 10) = + pdata->ana_config__powerdown_go1 & 0x3; + *(pbuffer + 11) = + pdata->ana_config__ref_bg_ctrl & 0x3; + *(pbuffer + 12) = + pdata->ana_config__regdvdd1v2_ctrl & 0xF; + *(pbuffer + 13) = + pdata->ana_config__osc_slow_ctrl & 0x7; + *(pbuffer + 14) = + pdata->test_mode__status & 0x1; + *(pbuffer + 15) = + pdata->firmware__system_status & 0x3; + *(pbuffer + 16) = + pdata->firmware__mode_status; + *(pbuffer + 17) = + pdata->firmware__secondary_mode_status; + VL53LX_i2c_encode_uint16_t( + pdata->firmware__cal_repeat_rate_counter & 0xFFF, + 2, + pbuffer + 18); + VL53LX_i2c_encode_uint16_t( + pdata->gph__system__thresh_high, + 2, + pbuffer + 22); + VL53LX_i2c_encode_uint16_t( + pdata->gph__system__thresh_low, + 2, + pbuffer + 24); + *(pbuffer + 26) = + pdata->gph__system__enable_xtalk_per_quadrant & 0x1; + *(pbuffer + 27) = + pdata->gph__spare_0 & 0x7; + *(pbuffer + 28) = + pdata->gph__sd_config__woi_sd0; + *(pbuffer + 29) = + pdata->gph__sd_config__woi_sd1; + *(pbuffer + 30) = + pdata->gph__sd_config__initial_phase_sd0 & 0x7F; + *(pbuffer + 31) = + pdata->gph__sd_config__initial_phase_sd1 & 0x7F; + *(pbuffer + 32) = + pdata->gph__sd_config__first_order_select & 0x3; + *(pbuffer + 33) = + pdata->gph__sd_config__quantifier & 0xF; + *(pbuffer + 34) = + pdata->gph__roi_config__user_roi_centre_spad; + *(pbuffer + 35) = + pdata->gph__roi_config__user_roi_requested_global_xy_size; + *(pbuffer + 36) = + pdata->gph__system__sequence_config; + *(pbuffer + 37) = + pdata->gph__gph_id & 0x1; + *(pbuffer + 38) = + pdata->system__interrupt_set & 0x3; + *(pbuffer + 39) = + pdata->interrupt_manager__enables & 0x1F; + *(pbuffer + 40) = + pdata->interrupt_manager__clear & 0x1F; + *(pbuffer + 41) = + pdata->interrupt_manager__status & 0x1F; + *(pbuffer + 42) = + pdata->mcu_to_host_bank__wr_access_en & 0x1; + *(pbuffer + 43) = + pdata->power_management__go1_reset_status & 0x1; + *(pbuffer + 44) = + pdata->pad_startup_mode__value_ro & 0x3; + *(pbuffer + 45) = + pdata->pad_startup_mode__value_ctrl & 0x3F; + VL53LX_i2c_encode_uint32_t( + pdata->pll_period_us & 0x3FFFF, + 4, + pbuffer + 46); + VL53LX_i2c_encode_uint32_t( + pdata->interrupt_scheduler__data_out, + 4, + pbuffer + 50); + *(pbuffer + 54) = + pdata->nvm_bist__complete & 0x1; + *(pbuffer + 55) = + pdata->nvm_bist__status & 0x1; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_debug_results( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_debug_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->phasecal_result__reference_phase = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 0)); + pdata->phasecal_result__vcsel_start = + (*(pbuffer + 2)) & 0x7F; + pdata->ref_spad_char_result__num_actual_ref_spads = + (*(pbuffer + 3)) & 0x3F; + pdata->ref_spad_char_result__ref_location = + (*(pbuffer + 4)) & 0x3; + pdata->vhv_result__coldboot_status = + (*(pbuffer + 5)) & 0x1; + pdata->vhv_result__search_result = + (*(pbuffer + 6)) & 0x3F; + pdata->vhv_result__latest_setting = + (*(pbuffer + 7)) & 0x3F; + pdata->result__osc_calibrate_val = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 8)) & 0x3FF; + pdata->ana_config__powerdown_go1 = + (*(pbuffer + 10)) & 0x3; + pdata->ana_config__ref_bg_ctrl = + (*(pbuffer + 11)) & 0x3; + pdata->ana_config__regdvdd1v2_ctrl = + (*(pbuffer + 12)) & 0xF; + pdata->ana_config__osc_slow_ctrl = + (*(pbuffer + 13)) & 0x7; + pdata->test_mode__status = + (*(pbuffer + 14)) & 0x1; + pdata->firmware__system_status = + (*(pbuffer + 15)) & 0x3; + pdata->firmware__mode_status = + (*(pbuffer + 16)); + pdata->firmware__secondary_mode_status = + (*(pbuffer + 17)); + pdata->firmware__cal_repeat_rate_counter = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 18)) & 0xFFF; + pdata->gph__system__thresh_high = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 22)); + pdata->gph__system__thresh_low = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 24)); + pdata->gph__system__enable_xtalk_per_quadrant = + (*(pbuffer + 26)) & 0x1; + pdata->gph__spare_0 = + (*(pbuffer + 27)) & 0x7; + pdata->gph__sd_config__woi_sd0 = + (*(pbuffer + 28)); + pdata->gph__sd_config__woi_sd1 = + (*(pbuffer + 29)); + pdata->gph__sd_config__initial_phase_sd0 = + (*(pbuffer + 30)) & 0x7F; + pdata->gph__sd_config__initial_phase_sd1 = + (*(pbuffer + 31)) & 0x7F; + pdata->gph__sd_config__first_order_select = + (*(pbuffer + 32)) & 0x3; + pdata->gph__sd_config__quantifier = + (*(pbuffer + 33)) & 0xF; + pdata->gph__roi_config__user_roi_centre_spad = + (*(pbuffer + 34)); + pdata->gph__roi_config__user_roi_requested_global_xy_size = + (*(pbuffer + 35)); + pdata->gph__system__sequence_config = + (*(pbuffer + 36)); + pdata->gph__gph_id = + (*(pbuffer + 37)) & 0x1; + pdata->system__interrupt_set = + (*(pbuffer + 38)) & 0x3; + pdata->interrupt_manager__enables = + (*(pbuffer + 39)) & 0x1F; + pdata->interrupt_manager__clear = + (*(pbuffer + 40)) & 0x1F; + pdata->interrupt_manager__status = + (*(pbuffer + 41)) & 0x1F; + pdata->mcu_to_host_bank__wr_access_en = + (*(pbuffer + 42)) & 0x1; + pdata->power_management__go1_reset_status = + (*(pbuffer + 43)) & 0x1; + pdata->pad_startup_mode__value_ro = + (*(pbuffer + 44)) & 0x3; + pdata->pad_startup_mode__value_ctrl = + (*(pbuffer + 45)) & 0x3F; + pdata->pll_period_us = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 46)) & 0x3FFFF; + pdata->interrupt_scheduler__data_out = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 50)); + pdata->nvm_bist__complete = + (*(pbuffer + 54)) & 0x1; + pdata->nvm_bist__status = + (*(pbuffer + 55)) & 0x1; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_debug_results( + VL53LX_debug_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_debug_results( + pdata, + VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_PHASECAL_RESULT__REFERENCE_PHASE, + comms_buffer, + VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_debug_results( + VL53LX_debug_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_PHASECAL_RESULT__REFERENCE_PHASE, + comms_buffer, + VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_debug_results( + VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_nvm_copy_data( + VL53LX_nvm_copy_data_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->identification__model_id; + *(pbuffer + 1) = + pdata->identification__module_type; + *(pbuffer + 2) = + pdata->identification__revision_id; + VL53LX_i2c_encode_uint16_t( + pdata->identification__module_id, + 2, + pbuffer + 3); + *(pbuffer + 5) = + pdata->ana_config__fast_osc__trim_max & 0x7F; + *(pbuffer + 6) = + pdata->ana_config__fast_osc__freq_set & 0x7; + *(pbuffer + 7) = + pdata->ana_config__vcsel_trim & 0x7; + *(pbuffer + 8) = + pdata->ana_config__vcsel_selion & 0x3F; + *(pbuffer + 9) = + pdata->ana_config__vcsel_selion_max & 0x3F; + *(pbuffer + 10) = + pdata->protected_laser_safety__lock_bit & 0x1; + *(pbuffer + 11) = + pdata->laser_safety__key & 0x7F; + *(pbuffer + 12) = + pdata->laser_safety__key_ro & 0x1; + *(pbuffer + 13) = + pdata->laser_safety__clip & 0x3F; + *(pbuffer + 14) = + pdata->laser_safety__mult & 0x3F; + *(pbuffer + 15) = + pdata->global_config__spad_enables_rtn_0; + *(pbuffer + 16) = + pdata->global_config__spad_enables_rtn_1; + *(pbuffer + 17) = + pdata->global_config__spad_enables_rtn_2; + *(pbuffer + 18) = + pdata->global_config__spad_enables_rtn_3; + *(pbuffer + 19) = + pdata->global_config__spad_enables_rtn_4; + *(pbuffer + 20) = + pdata->global_config__spad_enables_rtn_5; + *(pbuffer + 21) = + pdata->global_config__spad_enables_rtn_6; + *(pbuffer + 22) = + pdata->global_config__spad_enables_rtn_7; + *(pbuffer + 23) = + pdata->global_config__spad_enables_rtn_8; + *(pbuffer + 24) = + pdata->global_config__spad_enables_rtn_9; + *(pbuffer + 25) = + pdata->global_config__spad_enables_rtn_10; + *(pbuffer + 26) = + pdata->global_config__spad_enables_rtn_11; + *(pbuffer + 27) = + pdata->global_config__spad_enables_rtn_12; + *(pbuffer + 28) = + pdata->global_config__spad_enables_rtn_13; + *(pbuffer + 29) = + pdata->global_config__spad_enables_rtn_14; + *(pbuffer + 30) = + pdata->global_config__spad_enables_rtn_15; + *(pbuffer + 31) = + pdata->global_config__spad_enables_rtn_16; + *(pbuffer + 32) = + pdata->global_config__spad_enables_rtn_17; + *(pbuffer + 33) = + pdata->global_config__spad_enables_rtn_18; + *(pbuffer + 34) = + pdata->global_config__spad_enables_rtn_19; + *(pbuffer + 35) = + pdata->global_config__spad_enables_rtn_20; + *(pbuffer + 36) = + pdata->global_config__spad_enables_rtn_21; + *(pbuffer + 37) = + pdata->global_config__spad_enables_rtn_22; + *(pbuffer + 38) = + pdata->global_config__spad_enables_rtn_23; + *(pbuffer + 39) = + pdata->global_config__spad_enables_rtn_24; + *(pbuffer + 40) = + pdata->global_config__spad_enables_rtn_25; + *(pbuffer + 41) = + pdata->global_config__spad_enables_rtn_26; + *(pbuffer + 42) = + pdata->global_config__spad_enables_rtn_27; + *(pbuffer + 43) = + pdata->global_config__spad_enables_rtn_28; + *(pbuffer + 44) = + pdata->global_config__spad_enables_rtn_29; + *(pbuffer + 45) = + pdata->global_config__spad_enables_rtn_30; + *(pbuffer + 46) = + pdata->global_config__spad_enables_rtn_31; + *(pbuffer + 47) = + pdata->roi_config__mode_roi_centre_spad; + *(pbuffer + 48) = + pdata->roi_config__mode_roi_xy_size; + + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_i2c_decode_nvm_copy_data( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_nvm_copy_data_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->identification__model_id = + (*(pbuffer + 0)); + pdata->identification__module_type = + (*(pbuffer + 1)); + pdata->identification__revision_id = + (*(pbuffer + 2)); + pdata->identification__module_id = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 3)); + pdata->ana_config__fast_osc__trim_max = + (*(pbuffer + 5)) & 0x7F; + pdata->ana_config__fast_osc__freq_set = + (*(pbuffer + 6)) & 0x7; + pdata->ana_config__vcsel_trim = + (*(pbuffer + 7)) & 0x7; + pdata->ana_config__vcsel_selion = + (*(pbuffer + 8)) & 0x3F; + pdata->ana_config__vcsel_selion_max = + (*(pbuffer + 9)) & 0x3F; + pdata->protected_laser_safety__lock_bit = + (*(pbuffer + 10)) & 0x1; + pdata->laser_safety__key = + (*(pbuffer + 11)) & 0x7F; + pdata->laser_safety__key_ro = + (*(pbuffer + 12)) & 0x1; + pdata->laser_safety__clip = + (*(pbuffer + 13)) & 0x3F; + pdata->laser_safety__mult = + (*(pbuffer + 14)) & 0x3F; + pdata->global_config__spad_enables_rtn_0 = + (*(pbuffer + 15)); + pdata->global_config__spad_enables_rtn_1 = + (*(pbuffer + 16)); + pdata->global_config__spad_enables_rtn_2 = + (*(pbuffer + 17)); + pdata->global_config__spad_enables_rtn_3 = + (*(pbuffer + 18)); + pdata->global_config__spad_enables_rtn_4 = + (*(pbuffer + 19)); + pdata->global_config__spad_enables_rtn_5 = + (*(pbuffer + 20)); + pdata->global_config__spad_enables_rtn_6 = + (*(pbuffer + 21)); + pdata->global_config__spad_enables_rtn_7 = + (*(pbuffer + 22)); + pdata->global_config__spad_enables_rtn_8 = + (*(pbuffer + 23)); + pdata->global_config__spad_enables_rtn_9 = + (*(pbuffer + 24)); + pdata->global_config__spad_enables_rtn_10 = + (*(pbuffer + 25)); + pdata->global_config__spad_enables_rtn_11 = + (*(pbuffer + 26)); + pdata->global_config__spad_enables_rtn_12 = + (*(pbuffer + 27)); + pdata->global_config__spad_enables_rtn_13 = + (*(pbuffer + 28)); + pdata->global_config__spad_enables_rtn_14 = + (*(pbuffer + 29)); + pdata->global_config__spad_enables_rtn_15 = + (*(pbuffer + 30)); + pdata->global_config__spad_enables_rtn_16 = + (*(pbuffer + 31)); + pdata->global_config__spad_enables_rtn_17 = + (*(pbuffer + 32)); + pdata->global_config__spad_enables_rtn_18 = + (*(pbuffer + 33)); + pdata->global_config__spad_enables_rtn_19 = + (*(pbuffer + 34)); + pdata->global_config__spad_enables_rtn_20 = + (*(pbuffer + 35)); + pdata->global_config__spad_enables_rtn_21 = + (*(pbuffer + 36)); + pdata->global_config__spad_enables_rtn_22 = + (*(pbuffer + 37)); + pdata->global_config__spad_enables_rtn_23 = + (*(pbuffer + 38)); + pdata->global_config__spad_enables_rtn_24 = + (*(pbuffer + 39)); + pdata->global_config__spad_enables_rtn_25 = + (*(pbuffer + 40)); + pdata->global_config__spad_enables_rtn_26 = + (*(pbuffer + 41)); + pdata->global_config__spad_enables_rtn_27 = + (*(pbuffer + 42)); + pdata->global_config__spad_enables_rtn_28 = + (*(pbuffer + 43)); + pdata->global_config__spad_enables_rtn_29 = + (*(pbuffer + 44)); + pdata->global_config__spad_enables_rtn_30 = + (*(pbuffer + 45)); + pdata->global_config__spad_enables_rtn_31 = + (*(pbuffer + 46)); + pdata->roi_config__mode_roi_centre_spad = + (*(pbuffer + 47)); + pdata->roi_config__mode_roi_xy_size = + (*(pbuffer + 48)); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_nvm_copy_data( + VL53LX_nvm_copy_data_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_nvm_copy_data( + pdata, + VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_IDENTIFICATION__MODEL_ID, + comms_buffer, + VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_nvm_copy_data( + VL53LX_nvm_copy_data_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_IDENTIFICATION__MODEL_ID, + comms_buffer, + VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_nvm_copy_data( + VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_encode_prev_shadow_system_results( + VL53LX_prev_shadow_system_results_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->prev_shadow_result__interrupt_status & 0x3F; + *(pbuffer + 1) = + pdata->prev_shadow_result__range_status; + *(pbuffer + 2) = + pdata->prev_shadow_result__report_status & 0xF; + *(pbuffer + 3) = + pdata->prev_shadow_result__stream_count; + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__dss_actual_effective_spads_sd0, + 2, + pbuffer + 4); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__peak_signal_count_rate_mcps_sd0, + 2, + pbuffer + 6); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__ambient_count_rate_mcps_sd0, + 2, + pbuffer + 8); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__sigma_sd0, + 2, + pbuffer + 10); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__phase_sd0, + 2, + pbuffer + 12); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__final_crosstalk_corrected_range_mm_sd0, + 2, + pbuffer + 14); + VL53LX_i2c_encode_uint16_t( + pdata->psr__peak_signal_count_rate_crosstalk_corrected_mcps_sd0, + 2, + pbuffer + 16); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__mm_inner_actual_effective_spads_sd0, + 2, + pbuffer + 18); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__mm_outer_actual_effective_spads_sd0, + 2, + pbuffer + 20); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__avg_signal_count_rate_mcps_sd0, + 2, + pbuffer + 22); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__dss_actual_effective_spads_sd1, + 2, + pbuffer + 24); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__peak_signal_count_rate_mcps_sd1, + 2, + pbuffer + 26); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__ambient_count_rate_mcps_sd1, + 2, + pbuffer + 28); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__sigma_sd1, + 2, + pbuffer + 30); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__phase_sd1, + 2, + pbuffer + 32); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__final_crosstalk_corrected_range_mm_sd1, + 2, + pbuffer + 34); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__spare_0_sd1, + 2, + pbuffer + 36); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__spare_1_sd1, + 2, + pbuffer + 38); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__spare_2_sd1, + 2, + pbuffer + 40); + VL53LX_i2c_encode_uint16_t( + pdata->prev_shadow_result__spare_3_sd1, + 2, + pbuffer + 42); + + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_i2c_decode_prev_shadow_system_results( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_prev_shadow_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->prev_shadow_result__interrupt_status = + (*(pbuffer + 0)) & 0x3F; + pdata->prev_shadow_result__range_status = + (*(pbuffer + 1)); + pdata->prev_shadow_result__report_status = + (*(pbuffer + 2)) & 0xF; + pdata->prev_shadow_result__stream_count = + (*(pbuffer + 3)); + pdata->prev_shadow_result__dss_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 4)); + pdata->prev_shadow_result__peak_signal_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 6)); + pdata->prev_shadow_result__ambient_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 8)); + pdata->prev_shadow_result__sigma_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 10)); + pdata->prev_shadow_result__phase_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 12)); + pdata->prev_shadow_result__final_crosstalk_corrected_range_mm_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 14)); + pdata->psr__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 16)); + pdata->prev_shadow_result__mm_inner_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 18)); + pdata->prev_shadow_result__mm_outer_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 20)); + pdata->prev_shadow_result__avg_signal_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 22)); + pdata->prev_shadow_result__dss_actual_effective_spads_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 24)); + pdata->prev_shadow_result__peak_signal_count_rate_mcps_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 26)); + pdata->prev_shadow_result__ambient_count_rate_mcps_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 28)); + pdata->prev_shadow_result__sigma_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 30)); + pdata->prev_shadow_result__phase_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 32)); + pdata->prev_shadow_result__final_crosstalk_corrected_range_mm_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 34)); + pdata->prev_shadow_result__spare_0_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 36)); + pdata->prev_shadow_result__spare_1_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 38)); + pdata->prev_shadow_result__spare_2_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 40)); + pdata->prev_shadow_result__spare_3_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 42)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_prev_shadow_system_results( + VL53LX_prev_shadow_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_prev_shadow_system_results( + pdata, + VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_PREV_SHADOW_RESULT__INTERRUPT_STATUS, + comms_buffer, + VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_prev_shadow_system_results( + VL53LX_prev_shadow_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_PREV_SHADOW_RESULT__INTERRUPT_STATUS, + comms_buffer, + VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_prev_shadow_system_results( + VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_prev_shadow_core_results( + VL53LX_prev_shadow_core_results_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + VL53LX_i2c_encode_uint32_t( + pdata->prev_shadow_result_core__ambient_window_events_sd0, + 4, + pbuffer + 0); + VL53LX_i2c_encode_uint32_t( + pdata->prev_shadow_result_core__ranging_total_events_sd0, + 4, + pbuffer + 4); + VL53LX_i2c_encode_int32_t( + pdata->prev_shadow_result_core__signal_total_events_sd0, + 4, + pbuffer + 8); + VL53LX_i2c_encode_uint32_t( + pdata->prev_shadow_result_core__total_periods_elapsed_sd0, + 4, + pbuffer + 12); + VL53LX_i2c_encode_uint32_t( + pdata->prev_shadow_result_core__ambient_window_events_sd1, + 4, + pbuffer + 16); + VL53LX_i2c_encode_uint32_t( + pdata->prev_shadow_result_core__ranging_total_events_sd1, + 4, + pbuffer + 20); + VL53LX_i2c_encode_int32_t( + pdata->prev_shadow_result_core__signal_total_events_sd1, + 4, + pbuffer + 24); + VL53LX_i2c_encode_uint32_t( + pdata->prev_shadow_result_core__total_periods_elapsed_sd1, + 4, + pbuffer + 28); + *(pbuffer + 32) = + pdata->prev_shadow_result_core__spare_0; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_prev_shadow_core_results( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_prev_shadow_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + ; + + if (buf_size < VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->prev_shadow_result_core__ambient_window_events_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 0)); + pdata->prev_shadow_result_core__ranging_total_events_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 4)); + pdata->prev_shadow_result_core__signal_total_events_sd0 = + (VL53LX_i2c_decode_int32_t(4, pbuffer + 8)); + pdata->prev_shadow_result_core__total_periods_elapsed_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 12)); + pdata->prev_shadow_result_core__ambient_window_events_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 16)); + pdata->prev_shadow_result_core__ranging_total_events_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 20)); + pdata->prev_shadow_result_core__signal_total_events_sd1 = + (VL53LX_i2c_decode_int32_t(4, pbuffer + 24)); + pdata->prev_shadow_result_core__total_periods_elapsed_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 28)); + pdata->prev_shadow_result_core__spare_0 = + (*(pbuffer + 32)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_prev_shadow_core_results( + VL53LX_prev_shadow_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_prev_shadow_core_results( + pdata, + VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0, + comms_buffer, + VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_prev_shadow_core_results( + VL53LX_prev_shadow_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0, + comms_buffer, + VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_prev_shadow_core_results( + VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_patch_debug( + VL53LX_patch_debug_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->result__debug_status; + *(pbuffer + 1) = + pdata->result__debug_stage; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_patch_debug( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_patch_debug_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->result__debug_status = + (*(pbuffer + 0)); + pdata->result__debug_stage = + (*(pbuffer + 1)); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_patch_debug( + VL53LX_patch_debug_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_patch_debug( + pdata, + VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_RESULT__DEBUG_STATUS, + comms_buffer, + VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_patch_debug( + VL53LX_patch_debug_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_RESULT__DEBUG_STATUS, + comms_buffer, + VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_patch_debug( + VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_gph_general_config( + VL53LX_gph_general_config_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + VL53LX_i2c_encode_uint16_t( + pdata->gph__system__thresh_rate_high, + 2, + pbuffer + 0); + VL53LX_i2c_encode_uint16_t( + pdata->gph__system__thresh_rate_low, + 2, + pbuffer + 2); + *(pbuffer + 4) = + pdata->gph__system__interrupt_config_gpio; + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_decode_gph_general_config( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_gph_general_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->gph__system__thresh_rate_high = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 0)); + pdata->gph__system__thresh_rate_low = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 2)); + pdata->gph__system__interrupt_config_gpio = + (*(pbuffer + 4)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_gph_general_config( + VL53LX_gph_general_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_gph_general_config( + pdata, + VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_GPH__SYSTEM__THRESH_RATE_HIGH, + comms_buffer, + VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_gph_general_config( + VL53LX_gph_general_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_GPH__SYSTEM__THRESH_RATE_HIGH, + comms_buffer, + VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_gph_general_config( + VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_encode_gph_static_config( + VL53LX_gph_static_config_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->gph__dss_config__roi_mode_control & 0x7; + VL53LX_i2c_encode_uint16_t( + pdata->gph__dss_config__manual_effective_spads_select, + 2, + pbuffer + 1); + *(pbuffer + 3) = + pdata->gph__dss_config__manual_block_select; + *(pbuffer + 4) = + pdata->gph__dss_config__max_spads_limit; + *(pbuffer + 5) = + pdata->gph__dss_config__min_spads_limit; + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_decode_gph_static_config( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_gph_static_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->gph__dss_config__roi_mode_control = + (*(pbuffer + 0)) & 0x7; + pdata->gph__dss_config__manual_effective_spads_select = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 1)); + pdata->gph__dss_config__manual_block_select = + (*(pbuffer + 3)); + pdata->gph__dss_config__max_spads_limit = + (*(pbuffer + 4)); + pdata->gph__dss_config__min_spads_limit = + (*(pbuffer + 5)); + + + return status; +} +VL53LX_Error VL53LX::VL53LX_set_gph_static_config( + VL53LX_gph_static_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_gph_static_config( + pdata, + VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_GPH__DSS_CONFIG__ROI_MODE_CONTROL, + comms_buffer, + VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_gph_static_config( + VL53LX_gph_static_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_GPH__DSS_CONFIG__ROI_MODE_CONTROL, + comms_buffer, + VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_gph_static_config( + VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_gph_timing_config( + VL53LX_gph_timing_config_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->gph__mm_config__timeout_macrop_a_hi & 0xF; + *(pbuffer + 1) = + pdata->gph__mm_config__timeout_macrop_a_lo; + *(pbuffer + 2) = + pdata->gph__mm_config__timeout_macrop_b_hi & 0xF; + *(pbuffer + 3) = + pdata->gph__mm_config__timeout_macrop_b_lo; + *(pbuffer + 4) = + pdata->gph__range_config__timeout_macrop_a_hi & 0xF; + *(pbuffer + 5) = + pdata->gph__range_config__timeout_macrop_a_lo; + *(pbuffer + 6) = + pdata->gph__range_config__vcsel_period_a & 0x3F; + *(pbuffer + 7) = + pdata->gph__range_config__vcsel_period_b & 0x3F; + *(pbuffer + 8) = + pdata->gph__range_config__timeout_macrop_b_hi & 0xF; + *(pbuffer + 9) = + pdata->gph__range_config__timeout_macrop_b_lo; + VL53LX_i2c_encode_uint16_t( + pdata->gph__range_config__sigma_thresh, + 2, + pbuffer + 10); + VL53LX_i2c_encode_uint16_t( + pdata->gph__range_config__min_count_rate_rtn_limit_mcps, + 2, + pbuffer + 12); + *(pbuffer + 14) = + pdata->gph__range_config__valid_phase_low; + *(pbuffer + 15) = + pdata->gph__range_config__valid_phase_high; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_i2c_decode_gph_timing_config( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_gph_timing_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->gph__mm_config__timeout_macrop_a_hi = + (*(pbuffer + 0)) & 0xF; + pdata->gph__mm_config__timeout_macrop_a_lo = + (*(pbuffer + 1)); + pdata->gph__mm_config__timeout_macrop_b_hi = + (*(pbuffer + 2)) & 0xF; + pdata->gph__mm_config__timeout_macrop_b_lo = + (*(pbuffer + 3)); + pdata->gph__range_config__timeout_macrop_a_hi = + (*(pbuffer + 4)) & 0xF; + pdata->gph__range_config__timeout_macrop_a_lo = + (*(pbuffer + 5)); + pdata->gph__range_config__vcsel_period_a = + (*(pbuffer + 6)) & 0x3F; + pdata->gph__range_config__vcsel_period_b = + (*(pbuffer + 7)) & 0x3F; + pdata->gph__range_config__timeout_macrop_b_hi = + (*(pbuffer + 8)) & 0xF; + pdata->gph__range_config__timeout_macrop_b_lo = + (*(pbuffer + 9)); + pdata->gph__range_config__sigma_thresh = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 10)); + pdata->gph__range_config__min_count_rate_rtn_limit_mcps = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 12)); + pdata->gph__range_config__valid_phase_low = + (*(pbuffer + 14)); + pdata->gph__range_config__valid_phase_high = + (*(pbuffer + 15)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_gph_timing_config( + VL53LX_gph_timing_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_gph_timing_config( + pdata, + VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_A_HI, + comms_buffer, + VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_gph_timing_config( + VL53LX_gph_timing_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_A_HI, + comms_buffer, + VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_gph_timing_config( + VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_fw_internal( + VL53LX_fw_internal_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_FW_INTERNAL_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->firmware__internal_stream_count_div; + *(pbuffer + 1) = + pdata->firmware__internal_stream_counter_val; + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_decode_fw_internal( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_fw_internal_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_FW_INTERNAL_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->firmware__internal_stream_count_div = + (*(pbuffer + 0)); + pdata->firmware__internal_stream_counter_val = + (*(pbuffer + 1)); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_fw_internal( + VL53LX_fw_internal_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_FW_INTERNAL_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_fw_internal( + pdata, + VL53LX_FW_INTERNAL_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_FIRMWARE__INTERNAL_STREAM_COUNT_DIV, + comms_buffer, + VL53LX_FW_INTERNAL_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_fw_internal( + VL53LX_fw_internal_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_FW_INTERNAL_I2C_SIZE_BYTES]; + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_FIRMWARE__INTERNAL_STREAM_COUNT_DIV, + comms_buffer, + VL53LX_FW_INTERNAL_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_fw_internal( + VL53LX_FW_INTERNAL_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_encode_patch_results( + VL53LX_patch_results_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->dss_calc__roi_ctrl & 0x3; + *(pbuffer + 1) = + pdata->dss_calc__spare_1; + *(pbuffer + 2) = + pdata->dss_calc__spare_2; + *(pbuffer + 3) = + pdata->dss_calc__spare_3; + *(pbuffer + 4) = + pdata->dss_calc__spare_4; + *(pbuffer + 5) = + pdata->dss_calc__spare_5; + *(pbuffer + 6) = + pdata->dss_calc__spare_6; + *(pbuffer + 7) = + pdata->dss_calc__spare_7; + *(pbuffer + 8) = + pdata->dss_calc__user_roi_spad_en_0; + *(pbuffer + 9) = + pdata->dss_calc__user_roi_spad_en_1; + *(pbuffer + 10) = + pdata->dss_calc__user_roi_spad_en_2; + *(pbuffer + 11) = + pdata->dss_calc__user_roi_spad_en_3; + *(pbuffer + 12) = + pdata->dss_calc__user_roi_spad_en_4; + *(pbuffer + 13) = + pdata->dss_calc__user_roi_spad_en_5; + *(pbuffer + 14) = + pdata->dss_calc__user_roi_spad_en_6; + *(pbuffer + 15) = + pdata->dss_calc__user_roi_spad_en_7; + *(pbuffer + 16) = + pdata->dss_calc__user_roi_spad_en_8; + *(pbuffer + 17) = + pdata->dss_calc__user_roi_spad_en_9; + *(pbuffer + 18) = + pdata->dss_calc__user_roi_spad_en_10; + *(pbuffer + 19) = + pdata->dss_calc__user_roi_spad_en_11; + *(pbuffer + 20) = + pdata->dss_calc__user_roi_spad_en_12; + *(pbuffer + 21) = + pdata->dss_calc__user_roi_spad_en_13; + *(pbuffer + 22) = + pdata->dss_calc__user_roi_spad_en_14; + *(pbuffer + 23) = + pdata->dss_calc__user_roi_spad_en_15; + *(pbuffer + 24) = + pdata->dss_calc__user_roi_spad_en_16; + *(pbuffer + 25) = + pdata->dss_calc__user_roi_spad_en_17; + *(pbuffer + 26) = + pdata->dss_calc__user_roi_spad_en_18; + *(pbuffer + 27) = + pdata->dss_calc__user_roi_spad_en_19; + *(pbuffer + 28) = + pdata->dss_calc__user_roi_spad_en_20; + *(pbuffer + 29) = + pdata->dss_calc__user_roi_spad_en_21; + *(pbuffer + 30) = + pdata->dss_calc__user_roi_spad_en_22; + *(pbuffer + 31) = + pdata->dss_calc__user_roi_spad_en_23; + *(pbuffer + 32) = + pdata->dss_calc__user_roi_spad_en_24; + *(pbuffer + 33) = + pdata->dss_calc__user_roi_spad_en_25; + *(pbuffer + 34) = + pdata->dss_calc__user_roi_spad_en_26; + *(pbuffer + 35) = + pdata->dss_calc__user_roi_spad_en_27; + *(pbuffer + 36) = + pdata->dss_calc__user_roi_spad_en_28; + *(pbuffer + 37) = + pdata->dss_calc__user_roi_spad_en_29; + *(pbuffer + 38) = + pdata->dss_calc__user_roi_spad_en_30; + *(pbuffer + 39) = + pdata->dss_calc__user_roi_spad_en_31; + *(pbuffer + 40) = + pdata->dss_calc__user_roi_0; + *(pbuffer + 41) = + pdata->dss_calc__user_roi_1; + *(pbuffer + 42) = + pdata->dss_calc__mode_roi_0; + *(pbuffer + 43) = + pdata->dss_calc__mode_roi_1; + *(pbuffer + 44) = + pdata->sigma_estimator_calc__spare_0; + VL53LX_i2c_encode_uint16_t( + pdata->vhv_result__peak_signal_rate_mcps, + 2, + pbuffer + 46); + VL53LX_i2c_encode_uint32_t( + pdata->vhv_result__signal_total_events_ref, + 4, + pbuffer + 48); + VL53LX_i2c_encode_uint16_t( + pdata->phasecal_result__phase_output_ref, + 2, + pbuffer + 52); + VL53LX_i2c_encode_uint16_t( + pdata->dss_result__total_rate_per_spad, + 2, + pbuffer + 54); + *(pbuffer + 56) = + pdata->dss_result__enabled_blocks; + VL53LX_i2c_encode_uint16_t( + pdata->dss_result__num_requested_spads, + 2, + pbuffer + 58); + VL53LX_i2c_encode_uint16_t( + pdata->mm_result__inner_intersection_rate, + 2, + pbuffer + 62); + VL53LX_i2c_encode_uint16_t( + pdata->mm_result__outer_complement_rate, + 2, + pbuffer + 64); + VL53LX_i2c_encode_uint16_t( + pdata->mm_result__total_offset, + 2, + pbuffer + 66); + VL53LX_i2c_encode_uint32_t( + pdata->xtalk_calc__xtalk_for_enabled_spads & 0xFFFFFF, + 4, + pbuffer + 68); + VL53LX_i2c_encode_uint32_t( + pdata->xtalk_result__avg_xtalk_user_roi_kcps & 0xFFFFFF, + 4, + pbuffer + 72); + VL53LX_i2c_encode_uint32_t( + pdata->xtalk_result__avg_xtalk_mm_inner_roi_kcps & 0xFFFFFF, + 4, + pbuffer + 76); + VL53LX_i2c_encode_uint32_t( + pdata->xtalk_result__avg_xtalk_mm_outer_roi_kcps & 0xFFFFFF, + 4, + pbuffer + 80); + VL53LX_i2c_encode_uint32_t( + pdata->range_result__accum_phase, + 4, + pbuffer + 84); + VL53LX_i2c_encode_uint16_t( + pdata->range_result__offset_corrected_range, + 2, + pbuffer + 88); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_patch_results( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_patch_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->dss_calc__roi_ctrl = + (*(pbuffer + 0)) & 0x3; + pdata->dss_calc__spare_1 = + (*(pbuffer + 1)); + pdata->dss_calc__spare_2 = + (*(pbuffer + 2)); + pdata->dss_calc__spare_3 = + (*(pbuffer + 3)); + pdata->dss_calc__spare_4 = + (*(pbuffer + 4)); + pdata->dss_calc__spare_5 = + (*(pbuffer + 5)); + pdata->dss_calc__spare_6 = + (*(pbuffer + 6)); + pdata->dss_calc__spare_7 = + (*(pbuffer + 7)); + pdata->dss_calc__user_roi_spad_en_0 = + (*(pbuffer + 8)); + pdata->dss_calc__user_roi_spad_en_1 = + (*(pbuffer + 9)); + pdata->dss_calc__user_roi_spad_en_2 = + (*(pbuffer + 10)); + pdata->dss_calc__user_roi_spad_en_3 = + (*(pbuffer + 11)); + pdata->dss_calc__user_roi_spad_en_4 = + (*(pbuffer + 12)); + pdata->dss_calc__user_roi_spad_en_5 = + (*(pbuffer + 13)); + pdata->dss_calc__user_roi_spad_en_6 = + (*(pbuffer + 14)); + pdata->dss_calc__user_roi_spad_en_7 = + (*(pbuffer + 15)); + pdata->dss_calc__user_roi_spad_en_8 = + (*(pbuffer + 16)); + pdata->dss_calc__user_roi_spad_en_9 = + (*(pbuffer + 17)); + pdata->dss_calc__user_roi_spad_en_10 = + (*(pbuffer + 18)); + pdata->dss_calc__user_roi_spad_en_11 = + (*(pbuffer + 19)); + pdata->dss_calc__user_roi_spad_en_12 = + (*(pbuffer + 20)); + pdata->dss_calc__user_roi_spad_en_13 = + (*(pbuffer + 21)); + pdata->dss_calc__user_roi_spad_en_14 = + (*(pbuffer + 22)); + pdata->dss_calc__user_roi_spad_en_15 = + (*(pbuffer + 23)); + pdata->dss_calc__user_roi_spad_en_16 = + (*(pbuffer + 24)); + pdata->dss_calc__user_roi_spad_en_17 = + (*(pbuffer + 25)); + pdata->dss_calc__user_roi_spad_en_18 = + (*(pbuffer + 26)); + pdata->dss_calc__user_roi_spad_en_19 = + (*(pbuffer + 27)); + pdata->dss_calc__user_roi_spad_en_20 = + (*(pbuffer + 28)); + pdata->dss_calc__user_roi_spad_en_21 = + (*(pbuffer + 29)); + pdata->dss_calc__user_roi_spad_en_22 = + (*(pbuffer + 30)); + pdata->dss_calc__user_roi_spad_en_23 = + (*(pbuffer + 31)); + pdata->dss_calc__user_roi_spad_en_24 = + (*(pbuffer + 32)); + pdata->dss_calc__user_roi_spad_en_25 = + (*(pbuffer + 33)); + pdata->dss_calc__user_roi_spad_en_26 = + (*(pbuffer + 34)); + pdata->dss_calc__user_roi_spad_en_27 = + (*(pbuffer + 35)); + pdata->dss_calc__user_roi_spad_en_28 = + (*(pbuffer + 36)); + pdata->dss_calc__user_roi_spad_en_29 = + (*(pbuffer + 37)); + pdata->dss_calc__user_roi_spad_en_30 = + (*(pbuffer + 38)); + pdata->dss_calc__user_roi_spad_en_31 = + (*(pbuffer + 39)); + pdata->dss_calc__user_roi_0 = + (*(pbuffer + 40)); + pdata->dss_calc__user_roi_1 = + (*(pbuffer + 41)); + pdata->dss_calc__mode_roi_0 = + (*(pbuffer + 42)); + pdata->dss_calc__mode_roi_1 = + (*(pbuffer + 43)); + pdata->sigma_estimator_calc__spare_0 = + (*(pbuffer + 44)); + pdata->vhv_result__peak_signal_rate_mcps = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 46)); + pdata->vhv_result__signal_total_events_ref = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 48)); + pdata->phasecal_result__phase_output_ref = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 52)); + pdata->dss_result__total_rate_per_spad = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 54)); + pdata->dss_result__enabled_blocks = + (*(pbuffer + 56)); + pdata->dss_result__num_requested_spads = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 58)); + pdata->mm_result__inner_intersection_rate = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 62)); + pdata->mm_result__outer_complement_rate = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 64)); + pdata->mm_result__total_offset = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 66)); + pdata->xtalk_calc__xtalk_for_enabled_spads = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 68)) & 0xFFFFFF; + pdata->xtalk_result__avg_xtalk_user_roi_kcps = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 72)) & 0xFFFFFF; + pdata->xtalk_result__avg_xtalk_mm_inner_roi_kcps = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 76)) & 0xFFFFFF; + pdata->xtalk_result__avg_xtalk_mm_outer_roi_kcps = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 80)) & 0xFFFFFF; + pdata->range_result__accum_phase = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 84)); + pdata->range_result__offset_corrected_range = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 88)); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_patch_results( + VL53LX_patch_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_patch_results( + pdata, + VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_DSS_CALC__ROI_CTRL, + comms_buffer, + VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_get_patch_results( + VL53LX_patch_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_DSS_CALC__ROI_CTRL, + comms_buffer, + VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_patch_results( + VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_encode_shadow_system_results( + VL53LX_shadow_system_results_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + *(pbuffer + 0) = + pdata->shadow_phasecal_result__vcsel_start; + *(pbuffer + 2) = + pdata->shadow_result__interrupt_status & 0x3F; + *(pbuffer + 3) = + pdata->shadow_result__range_status; + *(pbuffer + 4) = + pdata->shadow_result__report_status & 0xF; + *(pbuffer + 5) = + pdata->shadow_result__stream_count; + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__dss_actual_effective_spads_sd0, + 2, + pbuffer + 6); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__peak_signal_count_rate_mcps_sd0, + 2, + pbuffer + 8); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__ambient_count_rate_mcps_sd0, + 2, + pbuffer + 10); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__sigma_sd0, + 2, + pbuffer + 12); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__phase_sd0, + 2, + pbuffer + 14); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__final_crosstalk_corrected_range_mm_sd0, + 2, + pbuffer + 16); + VL53LX_i2c_encode_uint16_t( + pdata->shr__peak_signal_count_rate_crosstalk_corrected_mcps_sd0, + 2, + pbuffer + 18); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__mm_inner_actual_effective_spads_sd0, + 2, + pbuffer + 20); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__mm_outer_actual_effective_spads_sd0, + 2, + pbuffer + 22); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__avg_signal_count_rate_mcps_sd0, + 2, + pbuffer + 24); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__dss_actual_effective_spads_sd1, + 2, + pbuffer + 26); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__peak_signal_count_rate_mcps_sd1, + 2, + pbuffer + 28); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__ambient_count_rate_mcps_sd1, + 2, + pbuffer + 30); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__sigma_sd1, + 2, + pbuffer + 32); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__phase_sd1, + 2, + pbuffer + 34); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__final_crosstalk_corrected_range_mm_sd1, + 2, + pbuffer + 36); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__spare_0_sd1, + 2, + pbuffer + 38); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__spare_1_sd1, + 2, + pbuffer + 40); + VL53LX_i2c_encode_uint16_t( + pdata->shadow_result__spare_2_sd1, + 2, + pbuffer + 42); + *(pbuffer + 44) = + pdata->shadow_result__spare_3_sd1; + *(pbuffer + 45) = + pdata->shadow_result__thresh_info; + *(pbuffer + 80) = + pdata->shadow_phasecal_result__reference_phase_hi; + *(pbuffer + 81) = + pdata->shadow_phasecal_result__reference_phase_lo; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_shadow_system_results( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_shadow_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->shadow_phasecal_result__vcsel_start = + (*(pbuffer + 0)); + pdata->shadow_result__interrupt_status = + (*(pbuffer + 2)) & 0x3F; + pdata->shadow_result__range_status = + (*(pbuffer + 3)); + pdata->shadow_result__report_status = + (*(pbuffer + 4)) & 0xF; + pdata->shadow_result__stream_count = + (*(pbuffer + 5)); + pdata->shadow_result__dss_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 6)); + pdata->shadow_result__peak_signal_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 8)); + pdata->shadow_result__ambient_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 10)); + pdata->shadow_result__sigma_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 12)); + pdata->shadow_result__phase_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 14)); + pdata->shadow_result__final_crosstalk_corrected_range_mm_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 16)); + pdata->shr__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 18)); + pdata->shadow_result__mm_inner_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 20)); + pdata->shadow_result__mm_outer_actual_effective_spads_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 22)); + pdata->shadow_result__avg_signal_count_rate_mcps_sd0 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 24)); + pdata->shadow_result__dss_actual_effective_spads_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 26)); + pdata->shadow_result__peak_signal_count_rate_mcps_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 28)); + pdata->shadow_result__ambient_count_rate_mcps_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 30)); + pdata->shadow_result__sigma_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 32)); + pdata->shadow_result__phase_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 34)); + pdata->shadow_result__final_crosstalk_corrected_range_mm_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 36)); + pdata->shadow_result__spare_0_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 38)); + pdata->shadow_result__spare_1_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 40)); + pdata->shadow_result__spare_2_sd1 = + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 42)); + pdata->shadow_result__spare_3_sd1 = + (*(pbuffer + 44)); + pdata->shadow_result__thresh_info = + (*(pbuffer + 45)); + pdata->shadow_phasecal_result__reference_phase_hi = + (*(pbuffer + 80)); + pdata->shadow_phasecal_result__reference_phase_lo = + (*(pbuffer + 81)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_shadow_system_results( + VL53LX_shadow_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_shadow_system_results( + pdata, + VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_SHADOW_PHASECAL_RESULT__VCSEL_START, + comms_buffer, + VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_shadow_system_results( + VL53LX_shadow_system_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_SHADOW_PHASECAL_RESULT__VCSEL_START, + comms_buffer, + VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_shadow_system_results( + VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} +VL53LX_Error VL53LX::VL53LX_i2c_encode_shadow_core_results( + VL53LX_shadow_core_results_t *pdata, + uint16_t buf_size, + uint8_t *pbuffer) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + VL53LX_i2c_encode_uint32_t( + pdata->shadow_result_core__ambient_window_events_sd0, + 4, + pbuffer + 0); + VL53LX_i2c_encode_uint32_t( + pdata->shadow_result_core__ranging_total_events_sd0, + 4, + pbuffer + 4); + VL53LX_i2c_encode_int32_t( + pdata->shadow_result_core__signal_total_events_sd0, + 4, + pbuffer + 8); + VL53LX_i2c_encode_uint32_t( + pdata->shadow_result_core__total_periods_elapsed_sd0, + 4, + pbuffer + 12); + VL53LX_i2c_encode_uint32_t( + pdata->shadow_result_core__ambient_window_events_sd1, + 4, + pbuffer + 16); + VL53LX_i2c_encode_uint32_t( + pdata->shadow_result_core__ranging_total_events_sd1, + 4, + pbuffer + 20); + VL53LX_i2c_encode_int32_t( + pdata->shadow_result_core__signal_total_events_sd1, + 4, + pbuffer + 24); + VL53LX_i2c_encode_uint32_t( + pdata->shadow_result_core__total_periods_elapsed_sd1, + 4, + pbuffer + 28); + *(pbuffer + 32) = + pdata->shadow_result_core__spare_0; + + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_i2c_decode_shadow_core_results( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_shadow_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (buf_size < VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES) { + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + } + + pdata->shadow_result_core__ambient_window_events_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 0)); + pdata->shadow_result_core__ranging_total_events_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 4)); + pdata->shadow_result_core__signal_total_events_sd0 = + (VL53LX_i2c_decode_int32_t(4, pbuffer + 8)); + pdata->shadow_result_core__total_periods_elapsed_sd0 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 12)); + pdata->shadow_result_core__ambient_window_events_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 16)); + pdata->shadow_result_core__ranging_total_events_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 20)); + pdata->shadow_result_core__signal_total_events_sd1 = + (VL53LX_i2c_decode_int32_t(4, pbuffer + 24)); + pdata->shadow_result_core__total_periods_elapsed_sd1 = + (VL53LX_i2c_decode_uint32_t(4, pbuffer + 28)); + pdata->shadow_result_core__spare_0 = + (*(pbuffer + 32)); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_shadow_core_results( + VL53LX_shadow_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_encode_shadow_core_results( + pdata, + VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES, + comms_buffer); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WriteMulti( + Dev, + VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0, + comms_buffer, + VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_get_shadow_core_results( + VL53LX_shadow_core_results_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES]; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0, + comms_buffer, + VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_i2c_decode_shadow_core_results( + VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES, + comms_buffer, + pdata); + + + return status; +} + + +/* vl53lx_nvm.c */ + +VL53LX_Error VL53LX::VL53LX_nvm_enable( + uint16_t nvm_ctrl_pulse_width, + int32_t nvm_power_up_delay_us) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_powerforce(); + } + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WaitUs( + Dev, + VL53LX_ENABLE_POWERFORCE_SETTLING_TIME_US); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__PDN, + 0x01); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_RANGING_CORE__CLK_CTRL1, + 0x05); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WaitUs( + Dev, + nvm_power_up_delay_us); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__MODE, + 0x01); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrWord( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__PULSE_WIDTH_MSB, + nvm_ctrl_pulse_width); + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_nvm_read( + uint8_t start_address, + uint8_t count, + uint8_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t nvm_addr = 0; + + + + for (nvm_addr = start_address; + nvm_addr < (start_address + count) ; nvm_addr++) { + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__ADDR, + nvm_addr); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__READN, + 0x00); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WaitUs( + Dev, + VL53LX_NVM_READ_TRIGGER_DELAY_US); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__READN, + 0x01); + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_ReadMulti( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT_MMM, + pdata, + 4); + + + pdata = pdata + 4; + + + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_nvm_disable() +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__READN, + 0x01); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_WrByte( + Dev, + VL53LX_RANGING_CORE__NVM_CTRL__PDN, + 0x00); + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_powerforce(); + } + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_nvm_format_decode( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_decoded_nvm_data_t *pdata) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + uint8_t *ptmp = NULL; + int pptmp[VL53LX_NVM_MAX_FMT_RANGE_DATA]; + + if (buf_size < VL53LX_NVM_SIZE_IN_BYTES) { + return VL53LX_ERROR_BUFFER_TOO_SMALL; + } + + pdata->nvm__identification_model_id = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__IDENTIFICATION__MODEL_ID, + 0x000000FF, + 0, + 0); + pdata->nvm__identification_module_type = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__IDENTIFICATION__MODULE_TYPE, + 0x000000FF, + 0, + 0); + pdata->nvm__identification_revision_id = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__IDENTIFICATION__REVISION_ID, + 0x0000000F, + 0, + 0); + pdata->nvm__identification_module_id = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__IDENTIFICATION__MODULE_ID, + 0x0000FFFF, + 0, + 0); + pdata->nvm__i2c_valid = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__I2C_VALID, + 0x000000FF, + 0, + 0); + pdata->nvm__i2c_device_address_ews = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__I2C_SLAVE__DEVICE_ADDRESS, + 0x000000FF, + 0, + 0); + pdata->nvm__ews__fast_osc_frequency = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__EWS__OSC_MEASURED__FAST_OSC_FREQUENCY, + 0x0000FFFF, + 0, + 0); + pdata->nvm__ews__fast_osc_trim_max = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__FAST_OSC_TRIM_MAX, + 0x0000007F, + 0, + 0); + pdata->nvm__ews__fast_osc_freq_set = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__FAST_OSC_FREQ_SET, + 0x00000007, + 0, + 0); + pdata->nvm__ews__slow_osc_calibration = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__EWS__SLOW_OSC_CALIBRATION, + 0x000003FF, + 0, + 0); + pdata->nvm__fmt__fast_osc_frequency = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__FMT__OSC_MEASURED__FAST_OSC_FREQUENCY, + 0x0000FFFF, + 0, + 0); + pdata->nvm__fmt__fast_osc_trim_max = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FAST_OSC_TRIM_MAX, + 0x0000007F, + 0, + 0); + pdata->nvm__fmt__fast_osc_freq_set = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FAST_OSC_FREQ_SET, + 0x00000007, + 0, + 0); + pdata->nvm__fmt__slow_osc_calibration = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__FMT__SLOW_OSC_CALIBRATION, + 0x000003FF, + 0, + 0); + pdata->nvm__vhv_config_unlock = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__VHV_CONFIG_UNLOCK, + 0x000000FF, + 0, + 0); + pdata->nvm__ref_selvddpix = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__REF_SELVDDPIX, + 0x0000000F, + 0, + 0); + pdata->nvm__ref_selvquench = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__REF_SELVQUENCH, + 0x00000078, + 3, + 0); + pdata->nvm__regavdd1v2_sel = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__REGAVDD1V2_SEL_REGDVDD1V2_SEL, + 0x0000000C, + 2, + 0); + pdata->nvm__regdvdd1v2_sel = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__REGAVDD1V2_SEL_REGDVDD1V2_SEL, + 0x00000003, + 0, + 0); + pdata->nvm__vhv_timeout__macrop = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, + 0x00000003, + 0, + 0); + pdata->nvm__vhv_loop_bound = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, + 0x000000FC, + 2, + 0); + pdata->nvm__vhv_count_threshold = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__VHV_CONFIG__COUNT_THRESH, + 0x000000FF, + 0, + 0); + pdata->nvm__vhv_offset = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__VHV_CONFIG__OFFSET, + 0x0000003F, + 0, + 0); + pdata->nvm__vhv_init_enable = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__VHV_CONFIG__INIT, + 0x00000080, + 7, + 0); + pdata->nvm__vhv_init_value = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__VHV_CONFIG__INIT, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_vcsel_trim_ll = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_TRIM_LL, + 0x00000007, + 0, + 0); + pdata->nvm__laser_safety_vcsel_selion_ll = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_LL, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_vcsel_selion_max_ll = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_MAX_LL, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_mult_ll = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__MULT_LL, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_clip_ll = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__CLIP_LL, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_vcsel_trim_ld = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_TRIM_LD, + 0x00000007, + 0, + 0); + pdata->nvm__laser_safety_vcsel_selion_ld = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_LD, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_vcsel_selion_max_ld = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_MAX_LD, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_mult_ld = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__MULT_LD, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_clip_ld = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY__CLIP_LD, + 0x0000003F, + 0, + 0); + pdata->nvm__laser_safety_lock_byte = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY_LOCK_BYTE, + 0x000000FF, + 0, + 0); + pdata->nvm__laser_safety_unlock_byte = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__LASER_SAFETY_UNLOCK_BYTE, + 0x000000FF, + 0, + 0); + + + + ptmp = pbuffer + VL53LX_NVM__EWS__SPAD_ENABLES_RTN_0_; + for (i = 0 ; i < VL53LX_RTN_SPAD_BUFFER_SIZE ; i++) { + pdata->nvm__ews__spad_enables_rtn[i] = *ptmp++; + } + + ptmp = pbuffer + VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC1_0_; + for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) { + pdata->nvm__ews__spad_enables_ref__loc1[i] = *ptmp++; + } + + ptmp = pbuffer + VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC2_0_; + for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) { + pdata->nvm__ews__spad_enables_ref__loc2[i] = *ptmp++; + } + + ptmp = pbuffer + VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC3_0_; + for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) { + pdata->nvm__ews__spad_enables_ref__loc3[i] = *ptmp++; + } + + + + ptmp = pbuffer + VL53LX_NVM__FMT__SPAD_ENABLES_RTN_0_; + for (i = 0 ; i < VL53LX_RTN_SPAD_BUFFER_SIZE ; i++) { + pdata->nvm__fmt__spad_enables_rtn[i] = *ptmp++; + } + + ptmp = pbuffer + VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC1_0_; + for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) { + pdata->nvm__fmt__spad_enables_ref__loc1[i] = *ptmp++; + } + + ptmp = pbuffer + VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC2_0_; + for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) { + pdata->nvm__fmt__spad_enables_ref__loc2[i] = *ptmp++; + } + + ptmp = pbuffer + VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC3_0_; + for (i = 0 ; i < VL53LX_REF_SPAD_BUFFER_SIZE ; i++) { + pdata->nvm__fmt__spad_enables_ref__loc3[i] = *ptmp++; + } + + + pdata->nvm__fmt__roi_config__mode_roi_centre_spad = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__FMT__ROI_CONFIG__MODE_ROI_CENTRE_SPAD, + 0x000000FF, + 0, + 0); + pdata->nvm__fmt__roi_config__mode_roi_x_size = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__FMT__ROI_CONFIG__MODE_ROI_XY_SIZE, + 0x000000F0, + 4, + 0); + pdata->nvm__fmt__roi_config__mode_roi_y_size = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__ROI_CONFIG__MODE_ROI_XY_SIZE, + 0x0000000F, + 0, + 0); + pdata->nvm__fmt__ref_spad_apply__num_requested_ref_spad = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__FMT__REF_SPAD_APPLY__NUM_REQUESTED_REF_SPAD, + 0x000000FF, + 0, + 0); + pdata->nvm__fmt__ref_spad_man__ref_location = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__REF_SPAD_MAN__REF_LOCATION, + 0x00000003, + 0, + 0); + pdata->nvm__fmt__mm_config__inner_offset_mm = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__FMT__MM_CONFIG__INNER_OFFSET_MM, + 0x0000FFFF, + 0, + 0); + pdata->nvm__fmt__mm_config__outer_offset_mm = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__FMT__MM_CONFIG__OUTER_OFFSET_MM, + 0x0000FFFF, + 0, + 0); + pdata->nvm__fmt__algo_part_to_part_range_offset_mm = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__FMT__ALGO__PART_TO_PART_RANGE_OFFSET_MM, + 0x00000FFF, + 0, + 0); + pdata->nvm__fmt__algo__crosstalk_compensation_plane_offset_kcps = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS, + 0x0000FFFF, + 0, + 0); + pdata->nvm__fmt__algo__crosstalk_compensation_x_plane_gradient_kcps = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS, + 0x0000FFFF, + 0, + 0); + pdata->nvm__fmt__algo__crosstalk_compensation_y_plane_gradient_kcps = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS, + 0x0000FFFF, + 0, + 0); + pdata->nvm__fmt__spare__host_config__nvm_config_spare_0 = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__FMT__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_0, + 0x000000FF, + 0, + 0); + pdata->nvm__fmt__spare__host_config__nvm_config_spare_1 = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__FMT__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_1, + 0x000000FF, + 0, + 0); + pdata->nvm__customer_space_programmed = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__CUSTOMER_NVM_SPACE_PROGRAMMED, + 0x000000FF, + 0, + 0); + pdata->nvm__cust__i2c_device_address = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__CUST__I2C_SLAVE__DEVICE_ADDRESS, + 0x000000FF, + 0, + 0); + pdata->nvm__cust__ref_spad_apply__num_requested_ref_spad = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__CUST__REF_SPAD_APPLY__NUM_REQUESTED_REF_SPAD, + 0x000000FF, + 0, + 0); + pdata->nvm__cust__ref_spad_man__ref_location = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__CUST__REF_SPAD_MAN__REF_LOCATION, + 0x00000003, + 0, + 0); + pdata->nvm__cust__mm_config__inner_offset_mm = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__CUST__MM_CONFIG__INNER_OFFSET_MM, + 0x0000FFFF, + 0, + 0); + pdata->nvm__cust__mm_config__outer_offset_mm = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__CUST__MM_CONFIG__OUTER_OFFSET_MM, + 0x0000FFFF, + 0, + 0); + pdata->nvm__cust__algo_part_to_part_range_offset_mm = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__CUST__ALGO__PART_TO_PART_RANGE_OFFSET_MM, + 0x00000FFF, + 0, + 0); + pdata->nvm__cust__algo__crosstalk_compensation_plane_offset_kcps = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS, + 0x0000FFFF, + 0, + 0); + pdata->nvm__cust__algo__crosstalk_compensation_x_plane_gradient_kcps = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS, + 0x0000FFFF, + 0, + 0); + pdata->nvm__cust__algo__crosstalk_compensation_y_plane_gradient_kcps = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + + VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS, + 0x0000FFFF, + 0, + 0); + pdata->nvm__cust__spare__host_config__nvm_config_spare_0 = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__CUST__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_0, + 0x000000FF, + 0, + 0); + pdata->nvm__cust__spare__host_config__nvm_config_spare_1 = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + + VL53LX_NVM__CUST__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_1, + 0x000000FF, + 0, + 0); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_optical_centre( + buf_size, + pbuffer + VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_INDEX, + &(pdata->fmt_optical_centre)); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_cal_peak_rate_map( + buf_size, + pbuffer + VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_INDEX, + &(pdata->fmt_peak_rate_map)); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_additional_offset_cal_data( + buf_size, + pbuffer + + VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_INDEX, + &(pdata->fmt_add_offset_data)); + + + + pptmp[0] = VL53LX_NVM__FMT__RANGE_RESULTS__140MM_MM_PRE_RANGE; + pptmp[1] = VL53LX_NVM__FMT__RANGE_RESULTS__140MM_DARK; + pptmp[2] = VL53LX_NVM__FMT__RANGE_RESULTS__400MM_DARK; + pptmp[3] = VL53LX_NVM__FMT__RANGE_RESULTS__400MM_AMBIENT; + + for (i = 0 ; i < VL53LX_NVM_MAX_FMT_RANGE_DATA ; i++) { + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_fmt_range_results_data( + buf_size, + pbuffer + pptmp[i], + &(pdata->fmt_range_data[i])); + } + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_fmt_info( + buf_size, + pbuffer, + &(pdata->fmt_info)); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_ews_info( + buf_size, + pbuffer, + &(pdata->ews_info)); + + return status; + +} +VL53LX_Error VL53LX::VL53LX_nvm_decode_optical_centre( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_optical_centre_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint16_t tmp = 0; + + if (buf_size < VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE) { + return VL53LX_ERROR_BUFFER_TOO_SMALL; + } + + + tmp = 0x0100; + tmp -= (uint16_t) * (pbuffer + 2); + if (tmp > 0x0FF) { + tmp = 0; + } + + pdata->x_centre = (uint8_t)tmp; + pdata->y_centre = *(pbuffer + 3); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_nvm_decode_cal_peak_rate_map( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_cal_peak_rate_map_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t *ptmp = NULL; + uint8_t i = 0; + + if (buf_size < VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE) { + return VL53LX_ERROR_BUFFER_TOO_SMALL; + } + + pdata->cal_distance_mm = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer); + + pdata->cal_reflectance_pc = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 2); + pdata->cal_reflectance_pc = + pdata->cal_reflectance_pc >> 6; + + pdata->max_samples = VL53LX_NVM_PEAK_RATE_MAP_SAMPLES; + pdata->width = VL53LX_NVM_PEAK_RATE_MAP_WIDTH; + pdata->height = VL53LX_NVM_PEAK_RATE_MAP_HEIGHT; + + ptmp = pbuffer + 4; + for (i = 0 ; i < VL53LX_NVM_PEAK_RATE_MAP_SAMPLES ; i++) { + pdata->peak_rate_mcps[i] = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, ptmp); + ptmp += 2; + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_nvm_decode_additional_offset_cal_data( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_additional_offset_cal_data_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE) { + return VL53LX_ERROR_BUFFER_TOO_SMALL; + } + + pdata->result__mm_inner_actual_effective_spads = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer); + + pdata->result__mm_outer_actual_effective_spads = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 2); + + pdata->result__mm_inner_peak_signal_count_rtn_mcps = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 4); + + pdata->result__mm_outer_peak_signal_count_rtn_mcps = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 6); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_nvm_decode_fmt_range_results_data( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_decoded_nvm_fmt_range_data_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES) { + return VL53LX_ERROR_BUFFER_TOO_SMALL; + } + + pdata->result__actual_effective_rtn_spads = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer); + + pdata->ref_spad_array__num_requested_ref_spads = + *(pbuffer + 2); + + pdata->ref_spad_array__ref_location = + *(pbuffer + 3); + + pdata->result__peak_signal_count_rate_rtn_mcps = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 4); + + pdata->result__ambient_count_rate_rtn_mcps = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 6); + + pdata->result__peak_signal_count_rate_ref_mcps = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 8); + + pdata->result__ambient_count_rate_ref_mcps = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 10); + + pdata->measured_distance_mm = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 12); + + pdata->measured_distance_stdev_mm = + (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 14); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_nvm_decode_fmt_info( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_decoded_nvm_fmt_info_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_NVM_SIZE_IN_BYTES) { + return VL53LX_ERROR_BUFFER_TOO_SMALL; + } + + pdata->nvm__fmt__fgc[0] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_0, + 0x000000FE, + 1, + 0); + pdata->nvm__fmt__fgc[1] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_1, + 0x000001FC, + 2, + 0); + pdata->nvm__fmt__fgc[2] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_2 - 1, + 0x000003F8, + 3, + 0); + pdata->nvm__fmt__fgc[3] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_3 - 1, + 0x000007F0, + 4, + 0); + pdata->nvm__fmt__fgc[4] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_4 - 1, + 0x00000FE0, + 5, + 0); + pdata->nvm__fmt__fgc[5] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_5 - 1, + 0x00001FC0, + 6, + 0); + pdata->nvm__fmt__fgc[6] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_6 - 1, + 0x00003F80, + 7, + 0); + pdata->nvm__fmt__fgc[7] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_6, + 0x0000007F, + 0, + 0); + pdata->nvm__fmt__fgc[8] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_7, + 0x000000FE, + 1, + 0); + pdata->nvm__fmt__fgc[9] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_8, + 0x000001FC, + 2, + 0); + pdata->nvm__fmt__fgc[10] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_9 - 1, + 0x000003F8, + 3, + 0); + pdata->nvm__fmt__fgc[11] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_10 - 1, + 0x000007F0, + 4, + 0); + pdata->nvm__fmt__fgc[12] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_11 - 1, + 0x00000FE0, + 5, + 0); + pdata->nvm__fmt__fgc[13] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_12 - 1, + 0x00001FC0, + 6, + 0); + pdata->nvm__fmt__fgc[14] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_13 - 1, + 0x00003F80, + 7, + 0); + pdata->nvm__fmt__fgc[15] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_13, + 0x0000007F, + 0, + 0); + pdata->nvm__fmt__fgc[16] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_14, + 0x000000FE, + 1, + 0); + pdata->nvm__fmt__fgc[17] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__FGC__BYTE_15, + 0x000001FC, + 2, + 0); + pdata->nvm__fmt__fgc[18] = 0x00; + + pdata->nvm__fmt__test_program_major = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__TEST_PROGRAM_MAJOR_MINOR, + 0x000000E0, + 5, + 0); + pdata->nvm__fmt__test_program_minor = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__TEST_PROGRAM_MAJOR_MINOR, + 0x0000001F, + 0, + 0); + pdata->nvm__fmt__map_major = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__MAP_MAJOR_MINOR, + 0x000000E0, + 5, + 0); + pdata->nvm__fmt__map_minor = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__MAP_MAJOR_MINOR, + 0x0000001F, + 0, + 0); + pdata->nvm__fmt__year = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__YEAR_MONTH, + 0x000000F0, + 4, + 0); + pdata->nvm__fmt__month = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__YEAR_MONTH, + 0x0000000F, + 0, + 0); + pdata->nvm__fmt__day = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__DAY_MODULE_DATE_PHASE, + 0x000000F8, + 3, + 0); + pdata->nvm__fmt__module_date_phase = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__DAY_MODULE_DATE_PHASE, + 0x00000007, + 0, + 0); + pdata->nvm__fmt__time = + (uint16_t)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__FMT__TIME, + 0x0000FFFF, + 0, + 0); + pdata->nvm__fmt__tester_id = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__TESTER_ID, + 0x000000FF, + 0, + 0); + pdata->nvm__fmt__site_id = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__FMT__SITE_ID, + 0x000000FF, + 0, + 0); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_nvm_decode_ews_info( + uint16_t buf_size, + uint8_t *pbuffer, + VL53LX_decoded_nvm_ews_info_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_NVM_SIZE_IN_BYTES) { + return VL53LX_ERROR_BUFFER_TOO_SMALL; + } + + pdata->nvm__ews__test_program_major = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__TEST_PROGRAM_MAJOR_MINOR, + 0x000000E0, + 5, + 0); + pdata->nvm__ews__test_program_minor = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__TEST_PROGRAM_MAJOR_MINOR, + 0x0000001F, + 0, + 0); + pdata->nvm__ews__probe_card_major = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__PROBE_CARD_MAJOR_MINOR, + 0x000000F0, + 4, + 0); + pdata->nvm__ews__probe_card_minor = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__PROBE_CARD_MAJOR_MINOR, + 0x0000000F, + 0, + 0); + pdata->nvm__ews__tester_id = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__TESTER_ID, + 0x000000FF, + 0, + 0); + pdata->nvm__ews__lot[0] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__LOT__BYTE_0, + 0x000000FC, + 2, + 32); + pdata->nvm__ews__lot[1] = + (char)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__EWS__LOT__BYTE_1 - 1, + 0x000003F0, + 4, + 32); + pdata->nvm__ews__lot[2] = + (char)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__EWS__LOT__BYTE_2 - 1, + 0x00000FC0, + 6, + 32); + pdata->nvm__ews__lot[3] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__LOT__BYTE_2, + 0x0000003F, + 0, + 32); + pdata->nvm__ews__lot[4] = + (char)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__LOT__BYTE_3, + 0x000000FC, + 2, + 32); + pdata->nvm__ews__lot[5] = + (char)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__EWS__LOT__BYTE_4 - 1, + 0x000003F0, + 4, + 32); + pdata->nvm__ews__lot[6] = + (char)VL53LX_i2c_decode_with_mask( + 2, + pbuffer + VL53LX_NVM__EWS__LOT__BYTE_5 - 1, + 0x00000FC0, + 6, + 32); + + pdata->nvm__ews__lot[7] = 0x00; + + pdata->nvm__ews__wafer = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__WAFER, + 0x0000001F, + 0, + 0); + pdata->nvm__ews__xcoord = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__XCOORD, + 0x000000FF, + 0, + 0); + pdata->nvm__ews__ycoord = + (uint8_t)VL53LX_i2c_decode_with_mask( + 1, + pbuffer + VL53LX_NVM__EWS__YCOORD, + 0x000000FF, + 0, + 0); + + return status; + +} + + +void VL53LX::VL53LX_nvm_format_encode( + VL53LX_decoded_nvm_data_t *pnvm_info, + uint8_t *pnvm_data) +{ + SUPPRESS_UNUSED_WARNING(pnvm_info); + SUPPRESS_UNUSED_WARNING(pnvm_data); +} + +VL53LX_Error VL53LX::VL53LX_read_nvm_raw_data( + uint8_t start_address, + uint8_t count, + uint8_t *pnvm_raw_data) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_nvm_enable( + 0x0004, + VL53LX_NVM_POWER_UP_DELAY_US); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_nvm_read( + start_address, + count, + pnvm_raw_data); + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_nvm_disable(); + } + + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_read_nvm( + uint8_t nvm_format, + VL53LX_decoded_nvm_data_t *pnvm_info) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + uint8_t nvm_data[2 * VL53LX_NVM_SIZE_IN_BYTES]; + + + SUPPRESS_UNUSED_WARNING(nvm_format); + + + + status = VL53LX_read_nvm_raw_data( + 0, + VL53LX_NVM_SIZE_IN_BYTES >> 2, + nvm_data); + + + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_nvm_format_decode( + VL53LX_NVM_SIZE_IN_BYTES, + nvm_data, + pnvm_info); + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_read_nvm_optical_centre( + VL53LX_optical_centre_t *pcentre) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + uint8_t nvm_data[2 * VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE]; + + status = + VL53LX_read_nvm_raw_data( + (uint8_t)(VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_INDEX + >> 2), + (uint8_t)(VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE + >> 2), + nvm_data); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_optical_centre( + VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE, + nvm_data, + pcentre); + + return status; +} +VL53LX_Error VL53LX::VL53LX_read_nvm_cal_peak_rate_map( + VL53LX_cal_peak_rate_map_t *pcal_data) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + uint8_t nvm_data[2 * VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE]; + + + status = + VL53LX_read_nvm_raw_data( + (uint8_t)(VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_INDEX + >> 2), + (uint8_t)(VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE + >> 2), + nvm_data); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_cal_peak_rate_map( + VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE, + nvm_data, + pcal_data); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_read_nvm_additional_offset_cal_data( + VL53LX_additional_offset_cal_data_t *pcal_data) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + uint8_t nvm_data[2 * VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE]; + + status = + VL53LX_read_nvm_raw_data( + (uint8_t)( + VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_INDEX >> 2), + (uint8_t)( + VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE >> 2), + nvm_data); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_nvm_decode_additional_offset_cal_data( + VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE, + nvm_data, + pcal_data); + + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_read_nvm_fmt_range_results_data( + uint16_t range_results_select, + VL53LX_decoded_nvm_fmt_range_data_t *prange_data) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + uint8_t nvm_data[2 * VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES]; + + status = VL53LX_read_nvm_raw_data( + (uint8_t)(range_results_select >> 2), + (uint8_t)(VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES >> 2), + nvm_data); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_nvm_decode_fmt_range_results_data( + VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES, + nvm_data, + prange_data); + + return status; + +} + +/* vl53lx_platform_ipp.c */ + +VL53LX_Error VL53LX::VL53LX_ipp_hist_process_data( + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_xtalk_histogram_data_t *pxtalk, + uint8_t *pArea1, + uint8_t *pArea2, + uint8_t *phisto_merge_nb, + VL53LX_range_results_t *presults) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + SUPPRESS_UNUSED_WARNING(Dev); + + status = + VL53LX_hist_process_data( + pdmax_cal, + pdmax_cfg, + ppost_cfg, + pbins, + pxtalk, + pArea1, + pArea2, + presults, + phisto_merge_nb); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_ipp_hist_ambient_dmax( + uint16_t target_reflectance, + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_histogram_bin_data_t *pbins, + int16_t *pambient_dmax_mm) +{ + + + + + + + + + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + SUPPRESS_UNUSED_WARNING(Dev); + + status = + VL53LX_hist_ambient_dmax( + target_reflectance, + pdmax_cal, + pdmax_cfg, + pbins, + pambient_dmax_mm); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_ipp_xtalk_calibration_process_data( + VL53LX_xtalk_range_results_t *pxtalk_ranges, + VL53LX_xtalk_histogram_data_t *pxtalk_shape, + VL53LX_xtalk_calibration_results_t *pxtalk_cal) +{ + + + + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + SUPPRESS_UNUSED_WARNING(Dev); + + status = + VL53LX_xtalk_calibration_process_data( + pxtalk_ranges, + pxtalk_shape, + pxtalk_cal); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_ipp_hist_xtalk_correction( + VL53LX_customer_nvm_managed_t *pcustomer, + VL53LX_dynamic_config_t *pdyn_cfg, + VL53LX_xtalk_histogram_data_t *pxtalk_shape, + VL53LX_histogram_bin_data_t *pip_hist_data, + VL53LX_histogram_bin_data_t *pop_hist_data, + VL53LX_histogram_bin_data_t *pxtalk_count_data) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + SUPPRESS_UNUSED_WARNING(Dev); + + status = + VL53LX_f_046( + pcustomer, + pdyn_cfg, + pxtalk_shape, + pip_hist_data, + pop_hist_data, + pxtalk_count_data); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_ipp_generate_dual_reflectance_xtalk_samples( + VL53LX_xtalk_range_results_t *pxtalk_results, + uint16_t expected_target_distance_mm, + uint8_t higher_reflectance, + VL53LX_histogram_bin_data_t *pxtalk_avg_samples) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + SUPPRESS_UNUSED_WARNING(Dev); + + status = VL53LX_generate_dual_reflectance_xtalk_samples( + pxtalk_results, + expected_target_distance_mm, + higher_reflectance, + pxtalk_avg_samples); + + return status; + +} + +/* vl53lx_hist_funcs.c */ + +VL53LX_Error VL53LX::VL53LX_hist_process_data( + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins_input, + VL53LX_xtalk_histogram_data_t *pxtalk_shape, + uint8_t *pArea1, + uint8_t *pArea2, + VL53LX_range_results_t *presults, + uint8_t *HistMergeNumber) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_hist_gen3_algo_private_data_t *palgo_gen3 = + (VL53LX_hist_gen3_algo_private_data_t *) pArea1; + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered4 = + (VL53LX_hist_gen4_algo_filtered_data_t *) pArea2; + + VL53LX_hist_gen3_dmax_private_data_t dmax_algo_gen3; + VL53LX_hist_gen3_dmax_private_data_t *pdmax_algo_gen3 = + &dmax_algo_gen3; + + VL53LX_histogram_bin_data_t bins_averaged; + VL53LX_histogram_bin_data_t *pbins_averaged = &bins_averaged; + + VL53LX_range_data_t *pdata; + + uint32_t xtalk_rate_kcps = 0; + uint32_t max_xtalk_rate_per_spad_kcps = 0; + uint8_t xtalk_enable = 0; + uint8_t r = 0; + uint8_t t = 0; + uint32_t XtalkDetectMaxSigma = 0; + + + + int16_t delta_mm = 0; + + + VL53LX_f_031( + pbins_input, + pbins_averaged); + + + + + + + VL53LX_init_histogram_bin_data_struct( + 0, + pxtalk_shape->xtalk_shape.VL53LX_p_021, + &(pxtalk_shape->xtalk_hist_removed)); + + + + + + + + VL53LX_copy_xtalk_bin_data_to_histogram_data_struct( + &(pxtalk_shape->xtalk_shape), + &(pxtalk_shape->xtalk_hist_removed)); + + + + + + + + if ((status == VL53LX_ERROR_NONE) && + (ppost_cfg->algo__crosstalk_compensation_enable > 0)) + + status = + VL53LX_f_032( + ppost_cfg->algo__crosstalk_compensation_plane_offset_kcps, + ppost_cfg->algo__crosstalk_compensation_x_plane_gradient_kcps, + ppost_cfg->algo__crosstalk_compensation_y_plane_gradient_kcps, + 0, + 0, + pbins_input->result__dss_actual_effective_spads, + pbins_input->roi_config__user_roi_centre_spad, + pbins_input->roi_config__user_roi_requested_global_xy_size, + &(xtalk_rate_kcps)); + + + + + + + + + if ((status == VL53LX_ERROR_NONE) && + (ppost_cfg->algo__crosstalk_compensation_enable > 0)) + status = + VL53LX_f_033( + pbins_averaged, + &(pxtalk_shape->xtalk_shape), + xtalk_rate_kcps, + &(pxtalk_shape->xtalk_hist_removed)); + + + + + + + + + + + + + + presults->xmonitor.total_periods_elapsed = + pbins_averaged->total_periods_elapsed; + presults->xmonitor.VL53LX_p_004 = + pbins_averaged->result__dss_actual_effective_spads; + + presults->xmonitor.peak_signal_count_rate_mcps = 0; + presults->xmonitor.VL53LX_p_009 = 0; + + presults->xmonitor.range_id = 0; + presults->xmonitor.range_status = VL53LX_DEVICEERROR_NOUPDATE; + + + + + + + xtalk_enable = 0; + if (ppost_cfg->algo__crosstalk_compensation_enable > 0) { + xtalk_enable = 1; + } + + + + + + + + + + for (r = 0 ; r <= xtalk_enable ; r++) { + + + + + + ppost_cfg->algo__crosstalk_compensation_enable = r; + + + + + + + status = + VL53LX_f_025( + pdmax_cal, + pdmax_cfg, + ppost_cfg, + pbins_averaged, + &(pxtalk_shape->xtalk_hist_removed), + palgo_gen3, + pfiltered4, + pdmax_algo_gen3, + presults); + + + + + + if (!(status == VL53LX_ERROR_NONE && r == 0)) { + continue; + } + + + + + + + if (presults->active_results == 0) { + pdata = &(presults->VL53LX_p_003[0]); + pdata->ambient_count_rate_mcps = + pdmax_algo_gen3->VL53LX_p_034; + pdata->VL53LX_p_004 = + pdmax_algo_gen3->VL53LX_p_004; + } + + + + + + + + max_xtalk_rate_per_spad_kcps = (uint32_t)( + ppost_cfg->algo__crosstalk_detect_max_valid_rate_kcps); + max_xtalk_rate_per_spad_kcps *= (uint32_t)(*HistMergeNumber); + max_xtalk_rate_per_spad_kcps <<= 4; + + for (t = 0 ; t < presults->active_results ; t++) { + + pdata = &(presults->VL53LX_p_003[t]); + + + + + if (pdata->max_range_mm > pdata->min_range_mm) + delta_mm = + pdata->max_range_mm - + pdata->min_range_mm; + else + delta_mm = + pdata->min_range_mm - + pdata->max_range_mm; + + XtalkDetectMaxSigma = + ppost_cfg->algo__crosstalk_detect_max_sigma_mm; + XtalkDetectMaxSigma *= (uint32_t)(*HistMergeNumber); + XtalkDetectMaxSigma <<= 5; + if (pdata->median_range_mm > + ppost_cfg->algo__crosstalk_detect_min_valid_range_mm && + pdata->median_range_mm < + ppost_cfg->algo__crosstalk_detect_max_valid_range_mm && + pdata->VL53LX_p_009 < + max_xtalk_rate_per_spad_kcps && + pdata->VL53LX_p_002 < XtalkDetectMaxSigma && + delta_mm < + ppost_cfg->algo__crosstalk_detect_min_max_tolerance) { + + + + + memcpy( + &(presults->xmonitor), + pdata, + sizeof(VL53LX_range_data_t)); + + } + } + + } + + + + + ppost_cfg->algo__crosstalk_compensation_enable = xtalk_enable; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_hist_ambient_dmax( + uint16_t target_reflectance, + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_histogram_bin_data_t *pbins, + int16_t *pambient_dmax_mm) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_hist_gen3_dmax_private_data_t dmax_algo; + VL53LX_hist_gen3_dmax_private_data_t *pdmax_algo = &dmax_algo; + + status = + VL53LX_f_001( + target_reflectance, + pdmax_cal, + pdmax_cfg, + pbins, + pdmax_algo, + pambient_dmax_mm); + + return status; +} + +/* vl53lx_core_support.c */ + +uint32_t VL53LX::VL53LX_calc_pll_period_us( + uint16_t fast_osc_frequency) +{ + uint32_t pll_period_us = 0; + + + if (fast_osc_frequency > 0) { + pll_period_us = (0x01 << 30) / fast_osc_frequency; + } + + + return pll_period_us; +} + +uint32_t VL53LX::VL53LX_duration_maths( + uint32_t pll_period_us, + uint32_t vcsel_parm_pclks, + uint32_t window_vclks, + uint32_t elapsed_mclks) +{ + uint64_t tmp_long_int = 0; + uint32_t duration_us = 0; + + + duration_us = window_vclks * pll_period_us; + + + duration_us = duration_us >> 12; + + + tmp_long_int = (uint64_t)duration_us; + + + duration_us = elapsed_mclks * vcsel_parm_pclks; + + + duration_us = duration_us >> 4; + + + tmp_long_int = tmp_long_int * (uint64_t)duration_us; + + + tmp_long_int = tmp_long_int >> 12; + + + if (tmp_long_int > 0xFFFFFFFF) { + tmp_long_int = 0xFFFFFFFF; + } + + duration_us = (uint32_t)tmp_long_int; + + return duration_us; +} + +uint32_t VL53LX::VL53LX_events_per_spad_maths( + int32_t VL53LX_p_010, + uint16_t num_spads, + uint32_t duration) +{ + uint64_t total_hist_counts = 0; + uint64_t xtalk_per_spad = 0; + uint32_t rate_per_spad_kcps = 0; + + uint64_t dividend = ((uint64_t)VL53LX_p_010 + * 1000 * 256); + + if (num_spads != 0) + total_hist_counts = do_division_u( + dividend, (uint64_t)num_spads); + + + + if (duration > 0) { + + + uint64_t dividend = (((uint64_t)(total_hist_counts << 11)) + + ((uint64_t)duration / 2)); + + xtalk_per_spad = do_division_u(dividend, (uint64_t)duration); + } else { + xtalk_per_spad = (uint64_t)(total_hist_counts << 11); + } + + rate_per_spad_kcps = (uint32_t)xtalk_per_spad; + + return rate_per_spad_kcps; +} + +uint32_t VL53LX::VL53LX_isqrt(uint32_t num) +{ + + + + uint32_t res = 0; + uint32_t bit = 1 << 30; + + + while (bit > num) { + bit >>= 2; + } + + while (bit != 0) { + if (num >= res + bit) { + num -= res + bit; + res = (res >> 1) + bit; + } else { + res >>= 1; + } + bit >>= 2; + } + + return res; +} + +void VL53LX::VL53LX_hist_calc_zero_distance_phase( + VL53LX_histogram_bin_data_t *pdata) +{ + uint32_t period = 0; + uint32_t VL53LX_p_014 = 0; + + + period = 2048 * + (uint32_t)VL53LX_decode_vcsel_period(pdata->VL53LX_p_005); + + VL53LX_p_014 = period; + VL53LX_p_014 += (uint32_t)pdata->phasecal_result__reference_phase; + VL53LX_p_014 += (2048 * (uint32_t)pdata->phasecal_result__vcsel_start); + VL53LX_p_014 -= (2048 * (uint32_t)pdata->cal_config__vcsel_start); + + VL53LX_p_014 = VL53LX_p_014 % period; + + pdata->zero_distance_phase = (uint16_t)VL53LX_p_014; + +} + +void VL53LX::VL53LX_hist_estimate_ambient_from_thresholded_bins( + int32_t ambient_threshold_sigma, + VL53LX_histogram_bin_data_t *pdata) +{ + + + uint8_t bin = 0; + int32_t VL53LX_p_031 = 0; + + VL53LX_hist_find_min_max_bin_values(pdata); + + + + VL53LX_p_031 = + (int32_t)VL53LX_isqrt((uint32_t)pdata->min_bin_value); + VL53LX_p_031 *= ambient_threshold_sigma; + VL53LX_p_031 += 0x07; + VL53LX_p_031 = VL53LX_p_031 >> 4; + VL53LX_p_031 += pdata->min_bin_value; + + + + pdata->number_of_ambient_samples = 0; + pdata->ambient_events_sum = 0; + + for (bin = 0; bin < pdata->VL53LX_p_021; bin++) + if (pdata->bin_data[bin] < VL53LX_p_031) { + pdata->ambient_events_sum += pdata->bin_data[bin]; + pdata->number_of_ambient_samples++; + } + + + + if (pdata->number_of_ambient_samples > 0) { + pdata->VL53LX_p_028 = + pdata->ambient_events_sum; + pdata->VL53LX_p_028 += + ((int32_t)pdata->number_of_ambient_samples / 2); + pdata->VL53LX_p_028 /= + (int32_t)pdata->number_of_ambient_samples; + } + +} + + +void VL53LX::VL53LX_hist_remove_ambient_bins( + VL53LX_histogram_bin_data_t *pdata) +{ + + uint8_t bin = 0; + uint8_t lc = 0; + uint8_t i = 0; + + + + if ((pdata->bin_seq[0] & 0x07) == 0x07) { + + i = 0; + for (lc = 0; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH; lc++) { + if ((pdata->bin_seq[lc] & 0x07) != 0x07) { + pdata->bin_seq[i] = pdata->bin_seq[lc]; + pdata->bin_rep[i] = pdata->bin_rep[lc]; + i++; + } + } + + + + for (lc = i; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH; lc++) { + pdata->bin_seq[lc] = VL53LX_MAX_BIN_SEQUENCE_CODE + 1; + pdata->bin_rep[lc] = 0; + } + } + + if (pdata->number_of_ambient_bins > 0) { + + + for (bin = pdata->number_of_ambient_bins; + bin < pdata->VL53LX_p_020; bin++) { + pdata->bin_data[bin - pdata->number_of_ambient_bins] = + pdata->bin_data[bin]; + } + + + pdata->VL53LX_p_021 = + pdata->VL53LX_p_021 - + pdata->number_of_ambient_bins; + pdata->number_of_ambient_bins = 0; + } +} + + +uint32_t VL53LX::VL53LX_calc_pll_period_mm( + uint16_t fast_osc_frequency) +{ + + + uint32_t pll_period_us = 0; + uint32_t pll_period_mm = 0; + + pll_period_us = VL53LX_calc_pll_period_us(fast_osc_frequency); + + + + + pll_period_mm = + VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8 * + (pll_period_us >> 2); + + + pll_period_mm = (pll_period_mm + (0x01 << 15)) >> 16; + + return pll_period_mm; +} + + +uint16_t VL53LX::VL53LX_rate_maths( + int32_t VL53LX_p_018, + uint32_t time_us) +{ + + + uint32_t tmp_int = 0; + uint32_t frac_bits = 7; + uint16_t rate_mcps = 0; + + + + if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_MAX) { + tmp_int = VL53LX_SPAD_TOTAL_COUNT_MAX; + } else if (VL53LX_p_018 > 0) { + tmp_int = (uint32_t)VL53LX_p_018; + } + + + + + if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_RES_THRES) { + frac_bits = 3; + } else { + frac_bits = 7; + } + + + if (time_us > 0) { + tmp_int = ((tmp_int << frac_bits) + (time_us / 2)) / time_us; + } + + + if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_RES_THRES) { + tmp_int = tmp_int << 4; + } + + + + if (tmp_int > 0xFFFF) { + tmp_int = 0xFFFF; + } + + rate_mcps = (uint16_t)tmp_int; + + return rate_mcps; +} + +uint16_t VL53LX::VL53LX_rate_per_spad_maths( + uint32_t frac_bits, + uint32_t peak_count_rate, + uint16_t num_spads, + uint32_t max_output_value) +{ + + uint32_t tmp_int = 0; + + + uint16_t rate_per_spad = 0; + + + + + + if (num_spads > 0) { + tmp_int = (peak_count_rate << 8) << frac_bits; + tmp_int = (tmp_int + + ((uint32_t)num_spads / 2)) / + (uint32_t)num_spads; + } else { + tmp_int = ((peak_count_rate) << frac_bits); + } + + + + if (tmp_int > max_output_value) { + tmp_int = max_output_value; + } + + rate_per_spad = (uint16_t)tmp_int; + + return rate_per_spad; +} + +int32_t VL53LX::VL53LX_range_maths( + uint16_t fast_osc_frequency, + uint16_t VL53LX_p_014, + uint16_t zero_distance_phase, + uint8_t fractional_bits, + int32_t gain_factor, + int32_t range_offset_mm) +{ + + + uint32_t pll_period_us = 0; + int64_t tmp_long_int = 0; + int32_t range_mm = 0; + int32_t range_mm_10 = 0; + + + + pll_period_us = VL53LX_calc_pll_period_us(fast_osc_frequency); + + + + tmp_long_int = (int64_t)VL53LX_p_014 - (int64_t)zero_distance_phase; + + + + tmp_long_int = tmp_long_int * (int64_t)pll_period_us; + + + + tmp_long_int = tmp_long_int / (0x01 << 9); + + + + tmp_long_int = tmp_long_int * VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8; + + + + tmp_long_int = tmp_long_int / (0x01 << 22); + + + range_mm = (int32_t)tmp_long_int + range_offset_mm; + + + range_mm *= gain_factor; + range_mm += 0x0400; + range_mm /= 0x0800; + + + if (fractional_bits == 0) { + range_mm_10 = range_mm * 10; + range_mm_10 = range_mm_10 / (0x01 << 2); + if ((range_mm_10 % 10) < 5) { + range_mm = (int16_t)(range_mm_10 / 10); + } else { + range_mm = (int16_t)(range_mm_10 / 10 + 1); + } + } else if (fractional_bits == 1) { + range_mm = range_mm / (0x01 << 1); + } + + return range_mm; +} + +uint8_t VL53LX::VL53LX_decode_vcsel_period(uint8_t vcsel_period_reg) +{ + + + uint8_t VL53LX_p_030 = 0; + + VL53LX_p_030 = (vcsel_period_reg + 1) << 1; + + return VL53LX_p_030; +} + + +void VL53LX::VL53LX_copy_xtalk_bin_data_to_histogram_data_struct( + VL53LX_xtalk_histogram_shape_t *pxtalk, + VL53LX_histogram_bin_data_t *phist) +{ + + + phist->cal_config__vcsel_start = + pxtalk->cal_config__vcsel_start; + phist->VL53LX_p_015 = + pxtalk->VL53LX_p_015; + phist->VL53LX_p_019 = + pxtalk->VL53LX_p_019; + + phist->phasecal_result__reference_phase = + pxtalk->phasecal_result__reference_phase; + phist->phasecal_result__vcsel_start = + pxtalk->phasecal_result__vcsel_start; + + phist->vcsel_width = + pxtalk->vcsel_width; + phist->zero_distance_phase = + pxtalk->zero_distance_phase; + + phist->zone_id = pxtalk->zone_id; + phist->VL53LX_p_020 = pxtalk->VL53LX_p_020; + phist->time_stamp = pxtalk->time_stamp; +} + +void VL53LX::VL53LX_init_histogram_bin_data_struct( + int32_t bin_value, + uint16_t VL53LX_p_021, + VL53LX_histogram_bin_data_t *pdata) +{ + uint16_t i = 0; + + pdata->cfg_device_state = VL53LX_DEVICESTATE_SW_STANDBY; + pdata->rd_device_state = VL53LX_DEVICESTATE_SW_STANDBY; + + pdata->zone_id = 0; + pdata->time_stamp = 0; + + pdata->VL53LX_p_019 = 0; + pdata->VL53LX_p_020 = VL53LX_HISTOGRAM_BUFFER_SIZE; + pdata->VL53LX_p_021 = (uint8_t)VL53LX_p_021; + pdata->number_of_ambient_bins = 0; + + pdata->result__interrupt_status = 0; + pdata->result__range_status = 0; + pdata->result__report_status = 0; + pdata->result__stream_count = 0; + + pdata->result__dss_actual_effective_spads = 0; + pdata->phasecal_result__reference_phase = 0; + pdata->phasecal_result__vcsel_start = 0; + pdata->cal_config__vcsel_start = 0; + + pdata->vcsel_width = 0; + pdata->VL53LX_p_005 = 0; + pdata->VL53LX_p_015 = 0; + pdata->total_periods_elapsed = 0; + + pdata->min_bin_value = 0; + pdata->max_bin_value = 0; + + pdata->zero_distance_phase = 0; + pdata->number_of_ambient_samples = 0; + pdata->ambient_events_sum = 0; + pdata->VL53LX_p_028 = 0; + + for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) { + pdata->bin_seq[i] = (uint8_t)i; + } + + for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) { + pdata->bin_rep[i] = 1; + } + + + for (i = 0; i < VL53LX_HISTOGRAM_BUFFER_SIZE; i++) + if (i < VL53LX_p_021) { + pdata->bin_data[i] = bin_value; + } else { + pdata->bin_data[i] = 0; + } + + +} + +void VL53LX::VL53LX_decode_row_col( + uint8_t spad_number, + uint8_t *prow, + uint8_t *pcol) +{ + + + + if (spad_number > 127) { + *prow = 8 + ((255 - spad_number) & 0x07); + *pcol = (spad_number - 128) >> 3; + } else { + *prow = spad_number & 0x07; + *pcol = (127 - spad_number) >> 3; + } +} + +void VL53LX::VL53LX_hist_find_min_max_bin_values( + VL53LX_histogram_bin_data_t *pdata) +{ + uint8_t bin = 0; + + for (bin = 0; bin < pdata->VL53LX_p_021; bin++) { + + if (bin == 0 || pdata->min_bin_value >= pdata->bin_data[bin]) { + pdata->min_bin_value = pdata->bin_data[bin]; + } + + if (bin == 0 || pdata->max_bin_value <= pdata->bin_data[bin]) { + pdata->max_bin_value = pdata->bin_data[bin]; + } + + } + + +} + +void VL53LX::VL53LX_hist_estimate_ambient_from_ambient_bins( + VL53LX_histogram_bin_data_t *pdata) +{ + + uint8_t bin = 0; + + + if (pdata->number_of_ambient_bins > 0) { + + pdata->number_of_ambient_samples = + pdata->number_of_ambient_bins; + + + + pdata->ambient_events_sum = 0; + for (bin = 0; bin < pdata->number_of_ambient_bins; bin++) { + pdata->ambient_events_sum += pdata->bin_data[bin]; + } + + pdata->VL53LX_p_028 = pdata->ambient_events_sum; + pdata->VL53LX_p_028 += + ((int32_t)pdata->number_of_ambient_bins / 2); + pdata->VL53LX_p_028 /= + (int32_t)pdata->number_of_ambient_bins; + + } + +} +/* vl53lx_core.c */ +void VL53LX::VL53LX_init_version() +{ + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->version.ll_major = VL53LX_LL_API_IMPLEMENTATION_VER_MAJOR; + pdev->version.ll_minor = VL53LX_LL_API_IMPLEMENTATION_VER_MINOR; + pdev->version.ll_build = VL53LX_LL_API_IMPLEMENTATION_VER_SUB; + pdev->version.ll_revision = VL53LX_LL_API_IMPLEMENTATION_VER_REVISION; +} + +void VL53LX::VL53LX_init_ll_driver_state( + VL53LX_DeviceState device_state) +{ + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state); + + pstate->cfg_device_state = device_state; + pstate->cfg_stream_count = 0; + pstate->cfg_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->cfg_timing_status = 0; + pstate->cfg_zone_id = 0; + + pstate->rd_device_state = device_state; + pstate->rd_stream_count = 0; + pstate->rd_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->rd_timing_status = 0; + pstate->rd_zone_id = 0; + +} + + +VL53LX_Error VL53LX::VL53LX_update_ll_driver_rd_state() +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state); + + + if ((pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) { + + pstate->rd_device_state = VL53LX_DEVICESTATE_SW_STANDBY; + pstate->rd_stream_count = 0; + pstate->rd_internal_stream_count = 0; + pstate->rd_internal_stream_count_val = 0; + pstate->rd_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->rd_timing_status = 0; + pstate->rd_zone_id = 0; + + } else { + + + + if (pstate->rd_stream_count == 0xFF) { + pstate->rd_stream_count = 0x80; + } else { + pstate->rd_stream_count++; + } + + + status = VL53LX_update_internal_stream_counters( + pstate->rd_stream_count, + &(pstate->rd_internal_stream_count), + &(pstate->rd_internal_stream_count_val)); + + + + pstate->rd_gph_id ^= VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + + + + switch (pstate->rd_device_state) { + + case VL53LX_DEVICESTATE_SW_STANDBY: + + if ((pdev->dyn_cfg.system__grouped_parameter_hold & + VL53LX_GROUPEDPARAMETERHOLD_ID_MASK) > 0) { + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC; + } else { + if (pstate->rd_zone_id >= + pdev->zone_cfg.active_zones) + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA; + else + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_GATHER_DATA; + } + + pstate->rd_stream_count = 0; + pstate->rd_internal_stream_count = 0; + pstate->rd_internal_stream_count_val = 0; + pstate->rd_timing_status = 0; + pstate->rd_zone_id = 0; + + break; + + case VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC: + pstate->rd_stream_count = 0; + pstate->rd_internal_stream_count = 0; + pstate->rd_internal_stream_count_val = 0; + pstate->rd_zone_id = 0; + if (pstate->rd_zone_id >= + pdev->zone_cfg.active_zones) + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA; + else + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_GATHER_DATA; + + break; + + case VL53LX_DEVICESTATE_RANGING_GATHER_DATA: + pstate->rd_zone_id++; + if (pstate->rd_zone_id >= + pdev->zone_cfg.active_zones) + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA; + else + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_GATHER_DATA; + + break; + + case VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA: + pstate->rd_zone_id = 0; + pstate->rd_timing_status ^= 0x01; + + if (pstate->rd_zone_id >= + pdev->zone_cfg.active_zones) + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA; + else + pstate->rd_device_state = + VL53LX_DEVICESTATE_RANGING_GATHER_DATA; + break; + + default: + pstate->rd_device_state = + VL53LX_DEVICESTATE_SW_STANDBY; + pstate->rd_stream_count = 0; + pstate->rd_internal_stream_count = 0; + pstate->rd_internal_stream_count_val = 0; + pstate->rd_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->rd_timing_status = 0; + pstate->rd_zone_id = 0; + break; + } + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_check_ll_driver_rd_state() +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state); + VL53LX_system_results_t *psys_results = &(pdev->sys_results); + VL53LX_histogram_bin_data_t *phist_data = &(pdev->hist_data); + VL53LX_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs); + + uint8_t device_range_status = 0; + uint8_t device_stream_count = 0; + uint8_t device_gph_id = 0; + uint8_t histogram_mode = 0; + uint8_t expected_stream_count = 0; + uint8_t expected_gph_id = 0; + + + device_range_status = + psys_results->result__range_status & + VL53LX_RANGE_STATUS__RANGE_STATUS_MASK; + + device_stream_count = psys_results->result__stream_count; + + + + histogram_mode = + (pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) == + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM; + + + device_gph_id = (psys_results->result__interrupt_status & + VL53LX_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4; + + if (histogram_mode) + device_gph_id = (phist_data->result__interrupt_status & + VL53LX_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4; + + + + if (!((pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) == + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK)) { + goto ENDFUNC; + } + + + + if (pstate->rd_device_state == + VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) { + + if (histogram_mode == 0) { + if (device_range_status != + VL53LX_DEVICEERROR_GPHSTREAMCOUNT0READY) + status = + VL53LX_ERROR_GPH_SYNC_CHECK_FAIL; + + } + } else { + if (pstate->rd_stream_count != device_stream_count) { + status = VL53LX_ERROR_STREAM_COUNT_CHECK_FAIL; + } + + + if (pstate->rd_gph_id != device_gph_id) { + status = VL53LX_ERROR_GPH_ID_CHECK_FAIL; + } + + + + + expected_stream_count = + pZ->VL53LX_p_003[pstate->rd_zone_id].expected_stream_count; + expected_gph_id = + pZ->VL53LX_p_003[pstate->rd_zone_id].expected_gph_id; + + + + if (expected_stream_count != device_stream_count) { + + + if (!((pdev->zone_cfg.active_zones == 0) && + (device_stream_count == 255))) + status = + VL53LX_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL; + + + } + + + + if (expected_gph_id != device_gph_id) { + status = VL53LX_ERROR_ZONE_GPH_ID_CHECK_FAIL; + } + + } +ENDFUNC: + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_update_ll_driver_cfg_state() +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state); + VL53LX_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs); + + uint8_t prev_cfg_zone_id; + uint8_t prev_cfg_gph_id; + uint8_t prev_cfg_stream_count; + + if ((pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) { + + pstate->cfg_device_state = VL53LX_DEVICESTATE_SW_STANDBY; + pstate->cfg_stream_count = 0; + pstate->cfg_internal_stream_count = 0; + pstate->cfg_internal_stream_count_val = 0; + pstate->cfg_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->cfg_timing_status = 0; + pstate->cfg_zone_id = 0; + prev_cfg_zone_id = 0; + prev_cfg_gph_id = 0; + prev_cfg_stream_count = 0; + + } else { + + prev_cfg_gph_id = pstate->cfg_gph_id; + prev_cfg_zone_id = pstate->cfg_zone_id; + prev_cfg_stream_count = pstate->cfg_stream_count; + + + + if (pstate->cfg_stream_count == 0xFF) { + pstate->cfg_stream_count = 0x80; + } else { + pstate->cfg_stream_count++; + } + + + status = VL53LX_update_internal_stream_counters( + pstate->cfg_stream_count, + &(pstate->cfg_internal_stream_count), + &(pstate->cfg_internal_stream_count_val)); + + + + pstate->cfg_gph_id ^= VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + + + + switch (pstate->cfg_device_state) { + + case VL53LX_DEVICESTATE_SW_STANDBY: + pstate->cfg_zone_id = 1; + if (pstate->cfg_zone_id > + pdev->zone_cfg.active_zones) { + pstate->cfg_zone_id = 0; + pstate->cfg_timing_status ^= 0x01; + } + pstate->cfg_stream_count = 1; + + if (pdev->gen_cfg.global_config__stream_divider == 0) { + pstate->cfg_internal_stream_count = 1; + pstate->cfg_internal_stream_count_val = 0; + } else { + pstate->cfg_internal_stream_count = 0; + pstate->cfg_internal_stream_count_val = 1; + } + pstate->cfg_device_state = + VL53LX_DEVICESTATE_RANGING_DSS_AUTO; + break; + + case VL53LX_DEVICESTATE_RANGING_DSS_AUTO: + pstate->cfg_zone_id++; + if (pstate->cfg_zone_id > + pdev->zone_cfg.active_zones) { + + pstate->cfg_zone_id = 0; + pstate->cfg_timing_status ^= 0x01; + + + + + if (pdev->zone_cfg.active_zones > 0) { + pstate->cfg_device_state = + VL53LX_DEVICESTATE_RANGING_DSS_MANUAL; + } + } + break; + + case VL53LX_DEVICESTATE_RANGING_DSS_MANUAL: + pstate->cfg_zone_id++; + if (pstate->cfg_zone_id > + pdev->zone_cfg.active_zones) { + pstate->cfg_zone_id = 0; + pstate->cfg_timing_status ^= 0x01; + } + break; + + default: + pstate->cfg_device_state = + VL53LX_DEVICESTATE_SW_STANDBY; + pstate->cfg_stream_count = 0; + pstate->cfg_internal_stream_count = 0; + pstate->cfg_internal_stream_count_val = 0; + pstate->cfg_gph_id = + VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->cfg_timing_status = 0; + pstate->cfg_zone_id = 0; + break; + } + } + + + if (pdev->zone_cfg.active_zones == 0) { + + pZ->VL53LX_p_003[prev_cfg_zone_id].expected_stream_count + = prev_cfg_stream_count - 1; + + pZ->VL53LX_p_003[pstate->rd_zone_id].expected_gph_id = + prev_cfg_gph_id ^ VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + } else { + pZ->VL53LX_p_003[prev_cfg_zone_id].expected_stream_count + = prev_cfg_stream_count; + pZ->VL53LX_p_003[prev_cfg_zone_id].expected_gph_id = + prev_cfg_gph_id; + } + + + + return status; +} + +void VL53LX::VL53LX_copy_rtn_good_spads_to_buffer( + VL53LX_nvm_copy_data_t *pdata, + uint8_t *pbuffer) +{ + + + *(pbuffer + 0) = pdata->global_config__spad_enables_rtn_0; + *(pbuffer + 1) = pdata->global_config__spad_enables_rtn_1; + *(pbuffer + 2) = pdata->global_config__spad_enables_rtn_2; + *(pbuffer + 3) = pdata->global_config__spad_enables_rtn_3; + *(pbuffer + 4) = pdata->global_config__spad_enables_rtn_4; + *(pbuffer + 5) = pdata->global_config__spad_enables_rtn_5; + *(pbuffer + 6) = pdata->global_config__spad_enables_rtn_6; + *(pbuffer + 7) = pdata->global_config__spad_enables_rtn_7; + *(pbuffer + 8) = pdata->global_config__spad_enables_rtn_8; + *(pbuffer + 9) = pdata->global_config__spad_enables_rtn_9; + *(pbuffer + 10) = pdata->global_config__spad_enables_rtn_10; + *(pbuffer + 11) = pdata->global_config__spad_enables_rtn_11; + *(pbuffer + 12) = pdata->global_config__spad_enables_rtn_12; + *(pbuffer + 13) = pdata->global_config__spad_enables_rtn_13; + *(pbuffer + 14) = pdata->global_config__spad_enables_rtn_14; + *(pbuffer + 15) = pdata->global_config__spad_enables_rtn_15; + *(pbuffer + 16) = pdata->global_config__spad_enables_rtn_16; + *(pbuffer + 17) = pdata->global_config__spad_enables_rtn_17; + *(pbuffer + 18) = pdata->global_config__spad_enables_rtn_18; + *(pbuffer + 19) = pdata->global_config__spad_enables_rtn_19; + *(pbuffer + 20) = pdata->global_config__spad_enables_rtn_20; + *(pbuffer + 21) = pdata->global_config__spad_enables_rtn_21; + *(pbuffer + 22) = pdata->global_config__spad_enables_rtn_22; + *(pbuffer + 23) = pdata->global_config__spad_enables_rtn_23; + *(pbuffer + 24) = pdata->global_config__spad_enables_rtn_24; + *(pbuffer + 25) = pdata->global_config__spad_enables_rtn_25; + *(pbuffer + 26) = pdata->global_config__spad_enables_rtn_26; + *(pbuffer + 27) = pdata->global_config__spad_enables_rtn_27; + *(pbuffer + 28) = pdata->global_config__spad_enables_rtn_28; + *(pbuffer + 29) = pdata->global_config__spad_enables_rtn_29; + *(pbuffer + 30) = pdata->global_config__spad_enables_rtn_30; + *(pbuffer + 31) = pdata->global_config__spad_enables_rtn_31; +} + +void VL53LX::VL53LX_init_system_results( + VL53LX_system_results_t *pdata) +{ + + + pdata->result__interrupt_status = 0xFF; + pdata->result__range_status = 0xFF; + pdata->result__report_status = 0xFF; + pdata->result__stream_count = 0xFF; + + pdata->result__dss_actual_effective_spads_sd0 = 0xFFFF; + pdata->result__peak_signal_count_rate_mcps_sd0 = 0xFFFF; + pdata->result__ambient_count_rate_mcps_sd0 = 0xFFFF; + pdata->result__sigma_sd0 = 0xFFFF; + pdata->result__phase_sd0 = 0xFFFF; + pdata->result__final_crosstalk_corrected_range_mm_sd0 = 0xFFFF; + pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 = + 0xFFFF; + pdata->result__mm_inner_actual_effective_spads_sd0 = 0xFFFF; + pdata->result__mm_outer_actual_effective_spads_sd0 = 0xFFFF; + pdata->result__avg_signal_count_rate_mcps_sd0 = 0xFFFF; + + pdata->result__dss_actual_effective_spads_sd1 = 0xFFFF; + pdata->result__peak_signal_count_rate_mcps_sd1 = 0xFFFF; + pdata->result__ambient_count_rate_mcps_sd1 = 0xFFFF; + pdata->result__sigma_sd1 = 0xFFFF; + pdata->result__phase_sd1 = 0xFFFF; + pdata->result__final_crosstalk_corrected_range_mm_sd1 = 0xFFFF; + pdata->result__spare_0_sd1 = 0xFFFF; + pdata->result__spare_1_sd1 = 0xFFFF; + pdata->result__spare_2_sd1 = 0xFFFF; + pdata->result__spare_3_sd1 = 0xFF; + +} +void VL53LX::V53L1_init_zone_results_structure( + uint8_t active_zones, + VL53LX_zone_results_t *pdata) +{ + + + + uint8_t z = 0; + VL53LX_zone_objects_t *pobjects; + + pdata->max_zones = VL53LX_MAX_USER_ZONES; + pdata->active_zones = active_zones; + + for (z = 0; z < pdata->max_zones; z++) { + pobjects = &(pdata->VL53LX_p_003[z]); + pobjects->cfg_device_state = VL53LX_DEVICESTATE_SW_STANDBY; + pobjects->rd_device_state = VL53LX_DEVICESTATE_SW_STANDBY; + pobjects->max_objects = VL53LX_MAX_RANGE_RESULTS; + pobjects->active_objects = 0; + } +} + +void VL53LX::V53L1_init_zone_dss_configs() +{ + + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + uint8_t z = 0; + uint8_t max_zones = VL53LX_MAX_USER_ZONES; + VL53LX_zone_private_dyn_cfgs_t *pdata = &(pres->zone_dyn_cfgs); + + for (z = 0; z < max_zones; z++) { + pdata->VL53LX_p_003[z].dss_mode = + VL53LX_DSS_CONTROL__MODE_TARGET_RATE; + pdata->VL53LX_p_003[z].dss_requested_effective_spad_count = 0; + } +} + +void VL53LX::VL53LX_init_histogram_config_structure( + uint8_t even_bin0, + uint8_t even_bin1, + uint8_t even_bin2, + uint8_t even_bin3, + uint8_t even_bin4, + uint8_t even_bin5, + uint8_t odd_bin0, + uint8_t odd_bin1, + uint8_t odd_bin2, + uint8_t odd_bin3, + uint8_t odd_bin4, + uint8_t odd_bin5, + VL53LX_histogram_config_t *pdata) +{ + + + pdata->histogram_config__low_amb_even_bin_0_1 = + (even_bin1 << 4) + even_bin0; + pdata->histogram_config__low_amb_even_bin_2_3 = + (even_bin3 << 4) + even_bin2; + pdata->histogram_config__low_amb_even_bin_4_5 = + (even_bin5 << 4) + even_bin4; + + pdata->histogram_config__low_amb_odd_bin_0_1 = + (odd_bin1 << 4) + odd_bin0; + pdata->histogram_config__low_amb_odd_bin_2_3 = + (odd_bin3 << 4) + odd_bin2; + pdata->histogram_config__low_amb_odd_bin_4_5 = + (odd_bin5 << 4) + odd_bin4; + + pdata->histogram_config__mid_amb_even_bin_0_1 = + pdata->histogram_config__low_amb_even_bin_0_1; + pdata->histogram_config__mid_amb_even_bin_2_3 = + pdata->histogram_config__low_amb_even_bin_2_3; + pdata->histogram_config__mid_amb_even_bin_4_5 = + pdata->histogram_config__low_amb_even_bin_4_5; + + pdata->histogram_config__mid_amb_odd_bin_0_1 = + pdata->histogram_config__low_amb_odd_bin_0_1; + pdata->histogram_config__mid_amb_odd_bin_2 = odd_bin2; + pdata->histogram_config__mid_amb_odd_bin_3_4 = + (odd_bin4 << 4) + odd_bin3; + pdata->histogram_config__mid_amb_odd_bin_5 = odd_bin5; + + pdata->histogram_config__user_bin_offset = 0x00; + + pdata->histogram_config__high_amb_even_bin_0_1 = + pdata->histogram_config__low_amb_even_bin_0_1; + pdata->histogram_config__high_amb_even_bin_2_3 = + pdata->histogram_config__low_amb_even_bin_2_3; + pdata->histogram_config__high_amb_even_bin_4_5 = + pdata->histogram_config__low_amb_even_bin_4_5; + + pdata->histogram_config__high_amb_odd_bin_0_1 = + pdata->histogram_config__low_amb_odd_bin_0_1; + pdata->histogram_config__high_amb_odd_bin_2_3 = + pdata->histogram_config__low_amb_odd_bin_2_3; + pdata->histogram_config__high_amb_odd_bin_4_5 = + pdata->histogram_config__low_amb_odd_bin_4_5; + + + + pdata->histogram_config__amb_thresh_low = 0xFFFF; + pdata->histogram_config__amb_thresh_high = 0xFFFF; + + + + pdata->histogram_config__spad_array_selection = 0x00; + +} + +void VL53LX::VL53LX_init_histogram_multizone_config_structure( + uint8_t even_bin0, + uint8_t even_bin1, + uint8_t even_bin2, + uint8_t even_bin3, + uint8_t even_bin4, + uint8_t even_bin5, + uint8_t odd_bin0, + uint8_t odd_bin1, + uint8_t odd_bin2, + uint8_t odd_bin3, + uint8_t odd_bin4, + uint8_t odd_bin5, + VL53LX_histogram_config_t *pdata) +{ + + + pdata->histogram_config__low_amb_even_bin_0_1 = + (even_bin1 << 4) + even_bin0; + pdata->histogram_config__low_amb_even_bin_2_3 = + (even_bin3 << 4) + even_bin2; + pdata->histogram_config__low_amb_even_bin_4_5 = + (even_bin5 << 4) + even_bin4; + + pdata->histogram_config__low_amb_odd_bin_0_1 = + pdata->histogram_config__low_amb_even_bin_0_1; + pdata->histogram_config__low_amb_odd_bin_2_3 + = pdata->histogram_config__low_amb_even_bin_2_3; + pdata->histogram_config__low_amb_odd_bin_4_5 + = pdata->histogram_config__low_amb_even_bin_4_5; + + pdata->histogram_config__mid_amb_even_bin_0_1 = + pdata->histogram_config__low_amb_even_bin_0_1; + pdata->histogram_config__mid_amb_even_bin_2_3 + = pdata->histogram_config__low_amb_even_bin_2_3; + pdata->histogram_config__mid_amb_even_bin_4_5 + = pdata->histogram_config__low_amb_even_bin_4_5; + + pdata->histogram_config__mid_amb_odd_bin_0_1 + = pdata->histogram_config__low_amb_odd_bin_0_1; + pdata->histogram_config__mid_amb_odd_bin_2 = odd_bin2; + pdata->histogram_config__mid_amb_odd_bin_3_4 = + (odd_bin4 << 4) + odd_bin3; + pdata->histogram_config__mid_amb_odd_bin_5 = odd_bin5; + + pdata->histogram_config__user_bin_offset = 0x00; + + pdata->histogram_config__high_amb_even_bin_0_1 = + (odd_bin1 << 4) + odd_bin0; + pdata->histogram_config__high_amb_even_bin_2_3 = + (odd_bin3 << 4) + odd_bin2; + pdata->histogram_config__high_amb_even_bin_4_5 = + (odd_bin5 << 4) + odd_bin4; + + pdata->histogram_config__high_amb_odd_bin_0_1 + = pdata->histogram_config__high_amb_even_bin_0_1; + pdata->histogram_config__high_amb_odd_bin_2_3 + = pdata->histogram_config__high_amb_even_bin_2_3; + pdata->histogram_config__high_amb_odd_bin_4_5 + = pdata->histogram_config__high_amb_even_bin_4_5; + + + + pdata->histogram_config__amb_thresh_low = 0xFFFF; + pdata->histogram_config__amb_thresh_high = 0xFFFF; + + + + pdata->histogram_config__spad_array_selection = 0x00; +} + +void VL53LX::VL53LX_init_xtalk_bin_data_struct( + uint32_t bin_value, + uint16_t VL53LX_p_021, + VL53LX_xtalk_histogram_shape_t *pdata) +{ + + + + uint16_t i = 0; + + pdata->zone_id = 0; + pdata->time_stamp = 0; + + pdata->VL53LX_p_019 = 0; + pdata->VL53LX_p_020 = VL53LX_XTALK_HISTO_BINS; + pdata->VL53LX_p_021 = (uint8_t)VL53LX_p_021; + + pdata->phasecal_result__reference_phase = 0; + pdata->phasecal_result__vcsel_start = 0; + pdata->cal_config__vcsel_start = 0; + + pdata->vcsel_width = 0; + pdata->VL53LX_p_015 = 0; + + pdata->zero_distance_phase = 0; + + for (i = 0; i < VL53LX_XTALK_HISTO_BINS; i++) { + if (i < VL53LX_p_021) { + pdata->bin_data[i] = bin_value; + } else { + pdata->bin_data[i] = 0; + } + } +} +void VL53LX::VL53LX_i2c_encode_uint16_t( + uint16_t ip_value, + uint16_t count, + uint8_t *pbuffer) +{ + + + uint16_t i = 0; + uint16_t VL53LX_p_003 = 0; + + VL53LX_p_003 = ip_value; + + for (i = 0; i < count; i++) { + pbuffer[count - i - 1] = (uint8_t)(VL53LX_p_003 & 0x00FF); + VL53LX_p_003 = VL53LX_p_003 >> 8; + } +} + +uint16_t VL53LX::VL53LX_i2c_decode_uint16_t( + uint16_t count, + uint8_t *pbuffer) +{ + + + uint16_t value = 0x00; + + while (count-- > 0) { + value = (value << 8) | (uint16_t) * pbuffer++; + } + + return value; +} + +void VL53LX::VL53LX_i2c_encode_int16_t( + int16_t ip_value, + uint16_t count, + uint8_t *pbuffer) +{ + + + uint16_t i = 0; + int16_t VL53LX_p_003 = 0; + + VL53LX_p_003 = ip_value; + + for (i = 0; i < count; i++) { + pbuffer[count - i - 1] = (uint8_t)(VL53LX_p_003 & 0x00FF); + VL53LX_p_003 = VL53LX_p_003 >> 8; + } +} +int16_t VL53LX::VL53LX_i2c_decode_int16_t( + uint16_t count, + uint8_t *pbuffer) +{ + + + int16_t value = 0x00; + + + if (*pbuffer >= 0x80) { + value = 0xFFFF; + } + + while (count-- > 0) { + value = (value << 8) | (int16_t) * pbuffer++; + } + + return value; +} + +void VL53LX::VL53LX_i2c_encode_uint32_t( + uint32_t ip_value, + uint16_t count, + uint8_t *pbuffer) +{ + + + uint16_t i = 0; + uint32_t VL53LX_p_003 = 0; + + VL53LX_p_003 = ip_value; + + for (i = 0; i < count; i++) { + pbuffer[count - i - 1] = (uint8_t)(VL53LX_p_003 & 0x00FF); + VL53LX_p_003 = VL53LX_p_003 >> 8; + } +} + + +uint32_t VL53LX::VL53LX_i2c_decode_uint32_t( + uint16_t count, + uint8_t *pbuffer) +{ + + + uint32_t value = 0x00; + + while (count-- > 0) { + value = (value << 8) | (uint32_t) * pbuffer++; + } + + return value; +} +uint32_t VL53LX::VL53LX_i2c_decode_with_mask( + uint16_t count, + uint8_t *pbuffer, + uint32_t bit_mask, + uint32_t down_shift, + uint32_t offset) +{ + + + uint32_t value = 0x00; + + + while (count-- > 0) { + value = (value << 8) | (uint32_t) * pbuffer++; + } + + + value = value & bit_mask; + if (down_shift > 0) { + value = value >> down_shift; + } + + + value = value + offset; + + return value; +} + +void VL53LX::VL53LX_i2c_encode_int32_t( + int32_t ip_value, + uint16_t count, + uint8_t *pbuffer) +{ + + + uint16_t i = 0; + int32_t VL53LX_p_003 = 0; + + VL53LX_p_003 = ip_value; + + for (i = 0; i < count; i++) { + pbuffer[count - i - 1] = (uint8_t)(VL53LX_p_003 & 0x00FF); + VL53LX_p_003 = VL53LX_p_003 >> 8; + } +} + +int32_t VL53LX::VL53LX_i2c_decode_int32_t( + uint16_t count, + uint8_t *pbuffer) +{ + + + int32_t value = 0x00; + + + if (*pbuffer >= 0x80) { + value = 0xFFFFFFFF; + } + + while (count-- > 0) { + value = (value << 8) | (int32_t) * pbuffer++; + } + + return value; +} +VL53LX_Error VL53LX::VL53LX_start_test( + uint8_t test_mode__ctrl) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WrByte( + Dev, + VL53LX_TEST_MODE__CTRL, + test_mode__ctrl); + } + + + return status; +} +VL53LX_Error VL53LX::VL53LX_set_firmware_enable_register(uint8_t value) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->sys_ctrl.firmware__enable = value; + + status = VL53LX_WrByte( + Dev, + VL53LX_FIRMWARE__ENABLE, + pdev->sys_ctrl.firmware__enable); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_enable_firmware() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_set_firmware_enable_register(0x01); + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_disable_firmware() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_set_firmware_enable_register(0x00); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_powerforce_register( + uint8_t value) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->sys_ctrl.power_management__go1_power_force = value; + + status = VL53LX_WrByte( + Dev, + VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE, + pdev->sys_ctrl.power_management__go1_power_force); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_enable_powerforce() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_set_powerforce_register(0x01); + + return status; +} +VL53LX_Error VL53LX::VL53LX_disable_powerforce() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_set_powerforce_register(0x00); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_clear_interrupt() +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->sys_ctrl.system__interrupt_clear = VL53LX_CLEAR_RANGE_INT; + + status = VL53LX_WrByte( + Dev, + VL53LX_SYSTEM__INTERRUPT_CLEAR, + pdev->sys_ctrl.system__interrupt_clear); + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_force_shadow_stream_count_to_zero() +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WrByte( + Dev, + VL53LX_SHADOW_RESULT__STREAM_COUNT, + 0x00); + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + return status; +} +uint32_t VL53LX::VL53LX_calc_macro_period_us( + uint16_t fast_osc_frequency, + uint8_t VL53LX_p_005) +{ + + uint32_t pll_period_us = 0; + uint8_t VL53LX_p_030 = 0; + uint32_t macro_period_us = 0; + + + pll_period_us = VL53LX_calc_pll_period_us(fast_osc_frequency); + + + + VL53LX_p_030 = VL53LX_decode_vcsel_period(VL53LX_p_005); + + + + macro_period_us = + (uint32_t)VL53LX_MACRO_PERIOD_VCSEL_PERIODS * + pll_period_us; + macro_period_us = macro_period_us >> 6; + + macro_period_us = macro_period_us * (uint32_t)VL53LX_p_030; + macro_period_us = macro_period_us >> 6; + + return macro_period_us; +} + +uint16_t VL53LX::VL53LX_calc_range_ignore_threshold( + uint32_t central_rate, + int16_t x_gradient, + int16_t y_gradient, + uint8_t rate_mult) +{ + + + int32_t range_ignore_thresh_int = 0; + uint16_t range_ignore_thresh_kcps = 0; + int32_t central_rate_int = 0; + int16_t x_gradient_int = 0; + int16_t y_gradient_int = 0; + + central_rate_int = ((int32_t)central_rate * (1 << 4)) / (1000); + + if (x_gradient < 0) { + x_gradient_int = x_gradient * -1; + } + + if (y_gradient < 0) { + y_gradient_int = y_gradient * -1; + } + + + + + + range_ignore_thresh_int = (8 * x_gradient_int * 4) + + (8 * y_gradient_int * 4); + + + + range_ignore_thresh_int = range_ignore_thresh_int / 1000; + + + + range_ignore_thresh_int = range_ignore_thresh_int + central_rate_int; + + + + range_ignore_thresh_int = (int32_t)rate_mult * range_ignore_thresh_int; + + range_ignore_thresh_int = (range_ignore_thresh_int + (1 << 4)) / (1 << 5); + + + + if (range_ignore_thresh_int > 0xFFFF) { + range_ignore_thresh_kcps = 0xFFFF; + } else { + range_ignore_thresh_kcps = (uint16_t)range_ignore_thresh_int; + } + + return range_ignore_thresh_kcps; +} + +uint32_t VL53LX::VL53LX_calc_timeout_mclks( + uint32_t timeout_us, + uint32_t macro_period_us) +{ + uint32_t timeout_mclks = 0; + + timeout_mclks = + ((timeout_us << 12) + (macro_period_us >> 1)) / + macro_period_us; + + return timeout_mclks; +} +uint16_t VL53LX::VL53LX_calc_encoded_timeout( + uint32_t timeout_us, + uint32_t macro_period_us) +{ + + + uint32_t timeout_mclks = 0; + uint16_t timeout_encoded = 0; + + + timeout_mclks = + VL53LX_calc_timeout_mclks(timeout_us, macro_period_us); + + timeout_encoded = + VL53LX_encode_timeout(timeout_mclks); + + return timeout_encoded; +} + +uint32_t VL53LX::VL53LX_calc_timeout_us( + uint32_t timeout_mclks, + uint32_t macro_period_us) +{ + + + uint32_t timeout_us = 0; + uint64_t tmp = 0; + + + tmp = (uint64_t)timeout_mclks * (uint64_t)macro_period_us; + tmp += 0x00800; + tmp = tmp >> 12; + + timeout_us = (uint32_t)tmp; + + + return timeout_us; +} + +uint32_t VL53LX::VL53LX_calc_crosstalk_plane_offset_with_margin( + uint32_t plane_offset_kcps, + int16_t margin_offset_kcps) +{ + uint32_t plane_offset_with_margin = 0; + int32_t plane_offset_kcps_temp = 0; + + plane_offset_kcps_temp = + (int32_t)plane_offset_kcps + + (int32_t)margin_offset_kcps; + + if (plane_offset_kcps_temp < 0) { + plane_offset_kcps_temp = 0; + } else if (plane_offset_kcps_temp > 0x3FFFF) { + plane_offset_kcps_temp = 0x3FFFF; + } + + plane_offset_with_margin = (uint32_t) plane_offset_kcps_temp; + + return plane_offset_with_margin; + +} + +uint32_t VL53LX::VL53LX_calc_decoded_timeout_us( + uint16_t timeout_encoded, + uint32_t macro_period_us) +{ + + + uint32_t timeout_mclks = 0; + uint32_t timeout_us = 0; + + timeout_mclks = + VL53LX_decode_timeout(timeout_encoded); + + timeout_us = + VL53LX_calc_timeout_us(timeout_mclks, macro_period_us); + + return timeout_us; +} + +uint16_t VL53LX::VL53LX_encode_timeout(uint32_t timeout_mclks) +{ + + + uint16_t encoded_timeout = 0; + uint32_t ls_byte = 0; + uint16_t ms_byte = 0; + + if (timeout_mclks > 0) { + ls_byte = timeout_mclks - 1; + + while ((ls_byte & 0xFFFFFF00) > 0) { + ls_byte = ls_byte >> 1; + ms_byte++; + } + + encoded_timeout = (ms_byte << 8) + + (uint16_t)(ls_byte & 0x000000FF); + } + + return encoded_timeout; +} + +uint32_t VL53LX::VL53LX_decode_timeout(uint16_t encoded_timeout) +{ + + + uint32_t timeout_macro_clks = 0; + + timeout_macro_clks = ((uint32_t)(encoded_timeout & 0x00FF) + << (uint32_t)((encoded_timeout & 0xFF00) >> 8)) + 1; + + return timeout_macro_clks; +} + + + + +VL53LX_Error VL53LX::VL53LX_calc_timeout_register_values( + uint32_t phasecal_config_timeout_us, + uint32_t mm_config_timeout_us, + uint32_t range_config_timeout_us, + uint16_t fast_osc_frequency, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint32_t macro_period_us = 0; + uint32_t timeout_mclks = 0; + uint16_t timeout_encoded = 0; + + if (fast_osc_frequency == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } else { + + macro_period_us = + VL53LX_calc_macro_period_us( + fast_osc_frequency, + ptiming->range_config__vcsel_period_a); + + + timeout_mclks = + VL53LX_calc_timeout_mclks( + phasecal_config_timeout_us, + macro_period_us); + + + if (timeout_mclks > 0xFF) { + timeout_mclks = 0xFF; + } + + pgeneral->phasecal_config__timeout_macrop = + (uint8_t)timeout_mclks; + + + timeout_encoded = + VL53LX_calc_encoded_timeout( + mm_config_timeout_us, + macro_period_us); + + ptiming->mm_config__timeout_macrop_a_hi = + (uint8_t)((timeout_encoded & 0xFF00) >> 8); + ptiming->mm_config__timeout_macrop_a_lo = + (uint8_t)(timeout_encoded & 0x00FF); + + + timeout_encoded = + VL53LX_calc_encoded_timeout( + range_config_timeout_us, + macro_period_us); + + ptiming->range_config__timeout_macrop_a_hi = + (uint8_t)((timeout_encoded & 0xFF00) >> 8); + ptiming->range_config__timeout_macrop_a_lo = + (uint8_t)(timeout_encoded & 0x00FF); + + + macro_period_us = + VL53LX_calc_macro_period_us( + fast_osc_frequency, + ptiming->range_config__vcsel_period_b); + + + timeout_encoded = + VL53LX_calc_encoded_timeout( + mm_config_timeout_us, + macro_period_us); + + ptiming->mm_config__timeout_macrop_b_hi = + (uint8_t)((timeout_encoded & 0xFF00) >> 8); + ptiming->mm_config__timeout_macrop_b_lo = + (uint8_t)(timeout_encoded & 0x00FF); + + + timeout_encoded = VL53LX_calc_encoded_timeout( + range_config_timeout_us, + macro_period_us); + + ptiming->range_config__timeout_macrop_b_hi = + (uint8_t)((timeout_encoded & 0xFF00) >> 8); + ptiming->range_config__timeout_macrop_b_lo = + (uint8_t)(timeout_encoded & 0x00FF); + } + + return status; + +} + +uint8_t VL53LX::VL53LX_encode_vcsel_period(uint8_t VL53LX_p_030) +{ + + + uint8_t vcsel_period_reg = 0; + + vcsel_period_reg = (VL53LX_p_030 >> 1) - 1; + + return vcsel_period_reg; +} + +uint32_t VL53LX::VL53LX_decode_unsigned_integer( + uint8_t *pbuffer, + uint8_t no_of_bytes) +{ + + + uint8_t i = 0; + uint32_t decoded_value = 0; + + for (i = 0; i < no_of_bytes; i++) { + decoded_value = (decoded_value << 8) + (uint32_t)pbuffer[i]; + } + + return decoded_value; +} + + +void VL53LX::VL53LX_encode_unsigned_integer( + uint32_t ip_value, + uint8_t no_of_bytes, + uint8_t *pbuffer) +{ + + + uint8_t i = 0; + uint32_t VL53LX_p_003 = 0; + + VL53LX_p_003 = ip_value; + for (i = 0; i < no_of_bytes; i++) { + pbuffer[no_of_bytes - i - 1] = VL53LX_p_003 & 0x00FF; + VL53LX_p_003 = VL53LX_p_003 >> 8; + } +} + +VL53LX_Error VL53LX::VL53LX_hist_copy_and_scale_ambient_info( + VL53LX_zone_hist_info_t *pidata, + VL53LX_histogram_bin_data_t *podata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + int64_t evts = 0; + int64_t tmpi = 0; + int64_t tmpo = 0; + + + if (pidata->result__dss_actual_effective_spads == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } else { + if (pidata->number_of_ambient_bins > 0 && + podata->number_of_ambient_bins == 0) { + + + + tmpo = 1 + (int64_t)podata->total_periods_elapsed; + tmpo *= + (int64_t)podata->result__dss_actual_effective_spads; + + tmpi = 1 + (int64_t)pidata->total_periods_elapsed; + tmpi *= + (int64_t)pidata->result__dss_actual_effective_spads; + + evts = tmpo * + (int64_t)pidata->ambient_events_sum; + evts += (tmpi / 2); + + + if (tmpi != 0) { + evts = do_division_s(evts, tmpi); + } + + podata->ambient_events_sum = (int32_t)evts; + + + + podata->VL53LX_p_028 = + podata->ambient_events_sum; + podata->VL53LX_p_028 += + ((int32_t)pidata->number_of_ambient_bins / 2); + podata->VL53LX_p_028 /= + (int32_t)pidata->number_of_ambient_bins; + } + } + + + return status; +} + + +void VL53LX::VL53LX_hist_get_bin_sequence_config( + VL53LX_histogram_bin_data_t *pdata) +{ + + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + int32_t amb_thresh_low = 0; + int32_t amb_thresh_high = 0; + + uint8_t i = 0; + + amb_thresh_low = 1024 * + (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_low; + amb_thresh_high = 1024 * + (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_high; + + + + if ((pdev->ll_state.rd_stream_count & 0x01) == 0) { + + pdata->bin_seq[5] = + pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 >> 4; + pdata->bin_seq[4] = + pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 & 0x0F; + pdata->bin_seq[3] = + pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 >> 4; + pdata->bin_seq[2] = + pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 & 0x0F; + pdata->bin_seq[1] = + pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 >> 4; + pdata->bin_seq[0] = + pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 & 0x0F; + + if (pdata->ambient_events_sum > amb_thresh_high) { + pdata->bin_seq[5] = + pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5 + >> 4; + pdata->bin_seq[4] = + pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5 + & 0x0F; + pdata->bin_seq[3] = + pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3 + >> 4; + pdata->bin_seq[2] = + pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3 + & 0x0F; + pdata->bin_seq[1] = + pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1 + >> 4; + pdata->bin_seq[0] = + pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1 + & 0x0F; + } + + if (pdata->ambient_events_sum < amb_thresh_low) { + pdata->bin_seq[5] = + pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5 + >> 4; + pdata->bin_seq[4] = + pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5 + & 0x0F; + pdata->bin_seq[3] = + pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3 + >> 4; + pdata->bin_seq[2] = + pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3 + & 0x0F; + pdata->bin_seq[1] = + pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1 + >> 4; + pdata->bin_seq[0] = + pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1 + & 0x0F; + } + + } else { + pdata->bin_seq[5] = + pdev->hist_cfg.histogram_config__mid_amb_odd_bin_5 + & 0x0F; + pdata->bin_seq[4] = + pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4 + & 0x0F; + pdata->bin_seq[3] = + pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4 + >> 4; + pdata->bin_seq[2] = + pdev->hist_cfg.histogram_config__mid_amb_odd_bin_2 & + 0x0F; + pdata->bin_seq[1] = + pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1 + >> 4; + pdata->bin_seq[0] = + pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1 + & 0x0F; + + if (pdata->ambient_events_sum > amb_thresh_high) { + pdata->bin_seq[5] = + pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5 + >> 4; + pdata->bin_seq[4] = + pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5 + & 0x0F; + pdata->bin_seq[3] = + pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3 + >> 4; + pdata->bin_seq[2] = + pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3 + & 0x0F; + pdata->bin_seq[1] = + pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1 + >> 4; + pdata->bin_seq[0] = + pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1 + & 0x0F; + } + + if (pdata->ambient_events_sum < amb_thresh_low) { + pdata->bin_seq[5] = + pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5 + >> 4; + pdata->bin_seq[4] = + pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5 + & 0x0F; + pdata->bin_seq[3] = + pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3 + >> 4; + pdata->bin_seq[2] = + pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3 + & 0x0F; + pdata->bin_seq[1] = + pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1 + >> 4; + pdata->bin_seq[0] = + pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1 + & 0x0F; + } + } + + + + for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) { + pdata->bin_rep[i] = 1; + } + +} + + +VL53LX_Error VL53LX::VL53LX_hist_phase_consistency_check( + VL53LX_zone_hist_info_t *phist_prev, + VL53LX_zone_objects_t *prange_prev, + VL53LX_range_results_t *prange_curr) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t lc = 0; + uint8_t p = 0; + + uint16_t phase_delta = 0; + uint16_t phase_tolerance = 0; + + int32_t events_delta = 0; + int32_t events_tolerance = 0; + + + uint8_t event_sigma; + uint16_t event_min_spad_count; + uint16_t min_max_tolerance; + uint8_t pht; + + VL53LX_DeviceError range_status = 0; + + + event_sigma = + pdev->histpostprocess.algo__consistency_check__event_sigma; + event_min_spad_count = + pdev->histpostprocess.algo__consistency_check__event_min_spad_count; + min_max_tolerance = + pdev->histpostprocess.algo__consistency_check__min_max_tolerance; + + + pht = pdev->histpostprocess.algo__consistency_check__phase_tolerance; + phase_tolerance = (uint16_t)pht; + phase_tolerance = phase_tolerance << 8; + + + + if (prange_prev->rd_device_state != + VL53LX_DEVICESTATE_RANGING_GATHER_DATA && + prange_prev->rd_device_state != + VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA) { + return status; + } + + + + if (phase_tolerance == 0) { + return status; + } + + for (lc = 0; lc < prange_curr->active_results; lc++) { + + if (!((prange_curr->VL53LX_p_003[lc].range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE) || + (prange_curr->VL53LX_p_003[lc].range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK))) { + continue; + } + + + + + + + if (prange_prev->active_objects == 0) + prange_curr->VL53LX_p_003[lc].range_status = + VL53LX_DEVICEERROR_PREV_RANGE_NO_TARGETS; + else + prange_curr->VL53LX_p_003[lc].range_status = + VL53LX_DEVICEERROR_PHASECONSISTENCY; + + + + + + for (p = 0; p < prange_prev->active_objects; p++) { + + if (prange_curr->VL53LX_p_003[lc].VL53LX_p_011 > + prange_prev->VL53LX_p_003[p].VL53LX_p_011) { + phase_delta = + prange_curr->VL53LX_p_003[lc].VL53LX_p_011 - + prange_prev->VL53LX_p_003[p].VL53LX_p_011; + } else { + phase_delta = + prange_prev->VL53LX_p_003[p].VL53LX_p_011 - + prange_curr->VL53LX_p_003[lc].VL53LX_p_011; + } + + if (phase_delta < phase_tolerance) { + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_hist_events_consistency_check( + event_sigma, + event_min_spad_count, + phist_prev, + &(prange_prev->VL53LX_p_003[p]), + &(prange_curr->VL53LX_p_003[lc]), + &events_tolerance, + &events_delta, + &range_status); + + + + + if (status == VL53LX_ERROR_NONE && + range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE) + status = + VL53LX_hist_merged_pulse_check( + min_max_tolerance, + &(prange_curr->VL53LX_p_003[lc]), + &range_status); + + prange_curr->VL53LX_p_003[lc].range_status = + range_status; + } + } + + } + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_hist_events_consistency_check( + uint8_t event_sigma, + uint16_t min_effective_spad_count, + VL53LX_zone_hist_info_t *phist_prev, + VL53LX_object_data_t *prange_prev, + VL53LX_range_data_t *prange_curr, + int32_t *pevents_tolerance, + int32_t *pevents_delta, + VL53LX_DeviceError *prange_status) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + int64_t tmpp = 0; + int64_t tmpc = 0; + int64_t events_scaler = 0; + int64_t events_scaler_sq = 0; + int64_t c_signal_events = 0; + int64_t c_sig_noise_sq = 0; + int64_t c_amb_noise_sq = 0; + int64_t p_amb_noise_sq = 0; + + int32_t p_signal_events = 0; + uint32_t noise_sq_sum = 0; + + + + if (event_sigma == 0) { + *prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE; + return status; + } + + + + tmpp = 1 + (int64_t)phist_prev->total_periods_elapsed; + tmpp *= (int64_t)phist_prev->result__dss_actual_effective_spads; + + + + tmpc = 1 + (int64_t)prange_curr->total_periods_elapsed; + tmpc *= (int64_t)prange_curr->VL53LX_p_004; + + + + events_scaler = tmpp * 4096; + if (tmpc != 0) { + events_scaler += (tmpc / 2); + events_scaler = do_division_s(events_scaler, tmpc); + } + + events_scaler_sq = events_scaler * events_scaler; + events_scaler_sq += 2048; + events_scaler_sq /= 4096; + + + + c_signal_events = (int64_t)prange_curr->VL53LX_p_017; + c_signal_events -= (int64_t)prange_curr->VL53LX_p_016; + c_signal_events *= (int64_t)events_scaler; + c_signal_events += 2048; + c_signal_events /= 4096; + + c_sig_noise_sq = (int64_t)events_scaler_sq; + c_sig_noise_sq *= (int64_t)prange_curr->VL53LX_p_017; + c_sig_noise_sq += 2048; + c_sig_noise_sq /= 4096; + + c_amb_noise_sq = (int64_t)events_scaler_sq; + c_amb_noise_sq *= (int64_t)prange_curr->VL53LX_p_016; + c_amb_noise_sq += 2048; + c_amb_noise_sq /= 4096; + + + c_amb_noise_sq += 2; + c_amb_noise_sq /= 4; + + + + p_amb_noise_sq = + (int64_t)prange_prev->VL53LX_p_016; + + + p_amb_noise_sq += 2; + p_amb_noise_sq /= 4; + + noise_sq_sum = + (uint32_t)prange_prev->VL53LX_p_017 + + (uint32_t)c_sig_noise_sq + + (uint32_t)p_amb_noise_sq + + (uint32_t)c_amb_noise_sq; + + *pevents_tolerance = + (int32_t)VL53LX_isqrt(noise_sq_sum * 16); + + *pevents_tolerance *= (int32_t)event_sigma; + *pevents_tolerance += 32; + *pevents_tolerance /= 64; + + p_signal_events = (int32_t)prange_prev->VL53LX_p_017; + p_signal_events -= (int32_t)prange_prev->VL53LX_p_016; + + if ((int32_t)c_signal_events > p_signal_events) + *pevents_delta = + (int32_t)c_signal_events - p_signal_events; + else + *pevents_delta = + p_signal_events - (int32_t)c_signal_events; + + if (*pevents_delta > *pevents_tolerance && + prange_curr->VL53LX_p_004 > min_effective_spad_count) { + *prange_status = VL53LX_DEVICEERROR_EVENTCONSISTENCY; + } else { + *prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE; + } + return status; +} + + +VL53LX_Error VL53LX::VL53LX_hist_merged_pulse_check( + int16_t min_max_tolerance_mm, + VL53LX_range_data_t *pdata, + VL53LX_DeviceError *prange_status) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + int16_t delta_mm = 0; + + if (pdata->max_range_mm > pdata->min_range_mm) + delta_mm = + pdata->max_range_mm - pdata->min_range_mm; + else + delta_mm = + pdata->min_range_mm - pdata->max_range_mm; + + if (min_max_tolerance_mm > 0 && + delta_mm > min_max_tolerance_mm) { + *prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE; + } else { + *prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_hist_xmonitor_consistency_check( + VL53LX_zone_hist_info_t *phist_prev, + VL53LX_zone_objects_t *prange_prev, + VL53LX_range_data_t *prange_curr) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + int32_t events_delta = 0; + int32_t events_tolerance = 0; + uint8_t event_sigma; + uint16_t min_spad_count; + + event_sigma = pdev->histpostprocess.algo__crosstalk_detect_event_sigma; + min_spad_count = + pdev->histpostprocess.algo__consistency_check__event_min_spad_count; + + if (prange_curr->range_status == VL53LX_DEVICEERROR_RANGECOMPLETE || + prange_curr->range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK || + prange_curr->range_status == + VL53LX_DEVICEERROR_EVENTCONSISTENCY) { + + if (prange_prev->xmonitor.range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE || + prange_prev->xmonitor.range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK || + prange_prev->xmonitor.range_status == + VL53LX_DEVICEERROR_EVENTCONSISTENCY) { + + prange_curr->range_status = + VL53LX_DEVICEERROR_RANGECOMPLETE; + + status = + VL53LX_hist_events_consistency_check( + event_sigma, + min_spad_count, + phist_prev, + &(prange_prev->xmonitor), + prange_curr, + &events_tolerance, + &events_delta, + &(prange_curr->range_status)); + + } + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_hist_wrap_dmax( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_histogram_bin_data_t *pcurrent, + int16_t *pwrap_dmax_mm) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint32_t pll_period_mm = 0; + uint32_t wrap_dmax_phase = 0; + uint32_t range_mm = 0; + + *pwrap_dmax_mm = 0; + + + if (pcurrent->VL53LX_p_015 != 0) { + + + + pll_period_mm = + VL53LX_calc_pll_period_mm( + pcurrent->VL53LX_p_015); + + + + wrap_dmax_phase = + (uint32_t)phistpostprocess->valid_phase_high << 8; + + + + range_mm = wrap_dmax_phase * pll_period_mm; + range_mm = (range_mm + (1 << 14)) >> 15; + + *pwrap_dmax_mm = (int16_t)range_mm; + } + + return status; +} + +void VL53LX::VL53LX_hist_combine_mm1_mm2_offsets( + int16_t mm1_offset_mm, + int16_t mm2_offset_mm, + uint8_t encoded_mm_roi_centre, + uint8_t encoded_mm_roi_size, + uint8_t encoded_zone_centre, + uint8_t encoded_zone_size, + VL53LX_additional_offset_cal_data_t *pcal_data, + uint8_t *pgood_spads, + uint16_t aperture_attenuation, + int16_t *prange_offset_mm) +{ + + + + uint16_t max_mm_inner_effective_spads = 0; + uint16_t max_mm_outer_effective_spads = 0; + uint16_t mm_inner_effective_spads = 0; + uint16_t mm_outer_effective_spads = 0; + + uint32_t scaled_mm1_peak_rate_mcps = 0; + uint32_t scaled_mm2_peak_rate_mcps = 0; + + int32_t tmp0 = 0; + int32_t tmp1 = 0; + + + + VL53LX_calc_mm_effective_spads( + encoded_mm_roi_centre, + encoded_mm_roi_size, + 0xC7, + 0xFF, + pgood_spads, + aperture_attenuation, + &max_mm_inner_effective_spads, + &max_mm_outer_effective_spads); + + if ((max_mm_inner_effective_spads == 0) || + (max_mm_outer_effective_spads == 0)) { + goto FAIL; + } + + + VL53LX_calc_mm_effective_spads( + encoded_mm_roi_centre, + encoded_mm_roi_size, + encoded_zone_centre, + encoded_zone_size, + pgood_spads, + aperture_attenuation, + &mm_inner_effective_spads, + &mm_outer_effective_spads); + + + + scaled_mm1_peak_rate_mcps = + (uint32_t)pcal_data->result__mm_inner_peak_signal_count_rtn_mcps; + scaled_mm1_peak_rate_mcps *= (uint32_t)mm_inner_effective_spads; + scaled_mm1_peak_rate_mcps /= (uint32_t)max_mm_inner_effective_spads; + + scaled_mm2_peak_rate_mcps = + (uint32_t)pcal_data->result__mm_outer_peak_signal_count_rtn_mcps; + scaled_mm2_peak_rate_mcps *= (uint32_t)mm_outer_effective_spads; + scaled_mm2_peak_rate_mcps /= (uint32_t)max_mm_outer_effective_spads; + + + + tmp0 = ((int32_t)mm1_offset_mm * (int32_t)scaled_mm1_peak_rate_mcps); + tmp0 += ((int32_t)mm2_offset_mm * (int32_t)scaled_mm2_peak_rate_mcps); + + tmp1 = (int32_t)scaled_mm1_peak_rate_mcps + + (int32_t)scaled_mm2_peak_rate_mcps; + + + + if (tmp1 != 0) { + tmp0 = (tmp0 * 4) / tmp1; + } +FAIL: + *prange_offset_mm = (int16_t)tmp0; + +} + +VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_calc_window( + int16_t target_distance_mm, + uint16_t target_width_oversize, + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pxtalk_data->pll_period_mm = + VL53LX_calc_pll_period_mm(phist_bins->VL53LX_p_015); + if (pxtalk_data->pll_period_mm == 0) { + pxtalk_data->pll_period_mm = 1; + } + + + pxtalk_data->xtalk_width_phase = + (int32_t)phist_bins->vcsel_width * 128; + pxtalk_data->target_width_phase = + pxtalk_data->xtalk_width_phase + + (int32_t)target_width_oversize * 128; + + + + pxtalk_data->xtalk_start_phase = + (int32_t)phist_bins->zero_distance_phase - + (pxtalk_data->xtalk_width_phase / 2); + pxtalk_data->xtalk_end_phase = + (int32_t)pxtalk_data->xtalk_start_phase + + pxtalk_data->xtalk_width_phase; + + if (pxtalk_data->xtalk_start_phase < 0) { + pxtalk_data->xtalk_start_phase = 0; + } + + + + + pxtalk_data->VL53LX_p_012 = + (uint8_t)(pxtalk_data->xtalk_start_phase / 2048); + + + pxtalk_data->VL53LX_p_013 = + (uint8_t)((pxtalk_data->xtalk_end_phase + 2047) / 2048); + + + + pxtalk_data->target_start_phase = + (int32_t)target_distance_mm * 2048 * 16; + pxtalk_data->target_start_phase += + ((int32_t)pxtalk_data->pll_period_mm / 2); + pxtalk_data->target_start_phase /= (int32_t)pxtalk_data->pll_period_mm; + pxtalk_data->target_start_phase += + (int32_t)phist_bins->zero_distance_phase; + + + + pxtalk_data->target_start_phase -= + (pxtalk_data->target_width_phase / 2); + pxtalk_data->target_end_phase = + (int32_t)pxtalk_data->target_start_phase + + pxtalk_data->target_width_phase; + + if (pxtalk_data->target_start_phase < 0) { + pxtalk_data->target_start_phase = 0; + } + + + pxtalk_data->target_start = + (uint8_t)(pxtalk_data->target_start_phase / 2048); + + + if (pxtalk_data->VL53LX_p_013 > (pxtalk_data->target_start - 1)) { + pxtalk_data->VL53LX_p_013 = pxtalk_data->target_start - 1; + } + + + pxtalk_data->effective_width = + (2048 * ((int32_t)pxtalk_data->VL53LX_p_013 + 1)); + pxtalk_data->effective_width -= pxtalk_data->xtalk_start_phase; + + + if (pxtalk_data->effective_width > pxtalk_data->xtalk_width_phase) { + pxtalk_data->effective_width = pxtalk_data->xtalk_width_phase; + } + + if (pxtalk_data->effective_width < 1) { + pxtalk_data->effective_width = 1; + } + + + pxtalk_data->event_scaler = pxtalk_data->xtalk_width_phase * 1000; + pxtalk_data->event_scaler += (pxtalk_data->effective_width / 2); + pxtalk_data->event_scaler /= pxtalk_data->effective_width; + + + if (pxtalk_data->event_scaler < 1000) { + pxtalk_data->event_scaler = 1000; + } + + if (pxtalk_data->event_scaler > 4000) { + pxtalk_data->event_scaler = 4000; + } + + + pxtalk_data->event_scaler_sum += pxtalk_data->event_scaler; + + + pxtalk_data->peak_duration_us_sum += + (uint32_t)phist_bins->peak_duration_us; + + + pxtalk_data->effective_spad_count_sum += + (uint32_t)phist_bins->result__dss_actual_effective_spads; + + + pxtalk_data->zero_distance_phase_sum += + (uint32_t)phist_bins->zero_distance_phase; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_calc_event_sums( + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t lb = 0; + uint8_t i = 0; + + + for (lb = pxtalk_data->VL53LX_p_012; + lb <= pxtalk_data->VL53LX_p_013; + lb++) { + + + i = (lb + phist_bins->number_of_ambient_bins + + phist_bins->VL53LX_p_021) % + phist_bins->VL53LX_p_021; + + + pxtalk_data->signal_events_sum += phist_bins->bin_data[i]; + pxtalk_data->signal_events_sum -= + phist_bins->VL53LX_p_028; + } + + + + for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS && + lb < phist_bins->VL53LX_p_021; lb++) { + + + i = (lb + phist_bins->number_of_ambient_bins + + phist_bins->VL53LX_p_021) % + phist_bins->VL53LX_p_021; + + + pxtalk_data->bin_data_sums[lb] += phist_bins->bin_data[i]; + pxtalk_data->bin_data_sums[lb] -= + phist_bins->VL53LX_p_028; + } + + pxtalk_data->sample_count += 1; + + + return status; +} +VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_calc_rate_per_spad( + VL53LX_hist_xtalk_extract_data_t *pxtalk_data) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint64_t tmp64_0 = 0; + uint64_t tmp64_1 = 0; + uint64_t xtalk_per_spad = 0; + + + if (pxtalk_data->signal_events_sum > 0) { + tmp64_0 = + ((uint64_t)pxtalk_data->signal_events_sum * + (uint64_t)pxtalk_data->sample_count * + (uint64_t)pxtalk_data->event_scaler_avg * 256U) << 9U; + tmp64_1 = + (uint64_t)pxtalk_data->effective_spad_count_sum * + (uint64_t)pxtalk_data->peak_duration_us_sum; + + + + if (tmp64_1 > 0U) { + + tmp64_0 = tmp64_0 + (tmp64_1 >> 1U); + xtalk_per_spad = do_division_u(tmp64_0, tmp64_1); + } else { + xtalk_per_spad = (uint64_t)tmp64_0; + } + + } else { + status = VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL; + } + + pxtalk_data->xtalk_rate_kcps_per_spad = (uint32_t)xtalk_per_spad; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_calc_shape( + VL53LX_hist_xtalk_extract_data_t *pxtalk_data, + VL53LX_xtalk_histogram_shape_t *pxtalk_shape) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + int32_t lb = 0; + uint64_t total_events = 0U; + uint64_t tmp64_0 = 0U; + int32_t remaining_area = 1024; + + pxtalk_shape->VL53LX_p_019 = 0; + pxtalk_shape->VL53LX_p_020 = VL53LX_XTALK_HISTO_BINS; + pxtalk_shape->VL53LX_p_021 = VL53LX_XTALK_HISTO_BINS; + + pxtalk_shape->zero_distance_phase = + (uint16_t)pxtalk_data->zero_distance_phase_avg; + pxtalk_shape->phasecal_result__reference_phase = + (uint16_t)pxtalk_data->zero_distance_phase_avg + (3 * 2048); + + + + if (pxtalk_data->signal_events_sum > 0) + total_events = + (uint64_t)pxtalk_data->signal_events_sum * + (uint64_t)pxtalk_data->event_scaler_avg; + else { + total_events = 1; + } + if (total_events == 0) { + total_events = 1; + } + + + remaining_area = 1024; + pxtalk_data->max_shape_value = 0; + + for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) { + + if ((lb < (int32_t)pxtalk_data->VL53LX_p_012 || + lb > (int32_t)pxtalk_data->VL53LX_p_013) || + pxtalk_data->bin_data_sums[lb] < 0) { + + + if (remaining_area > 0 && remaining_area < 1024) { + if (remaining_area > + pxtalk_data->max_shape_value) { + pxtalk_shape->bin_data[lb] = + (uint32_t)pxtalk_data->max_shape_value; + remaining_area -= + pxtalk_data->max_shape_value; + } else { + pxtalk_shape->bin_data[lb] = + (uint32_t)remaining_area; + remaining_area = 0; + } + } else { + pxtalk_shape->bin_data[lb] = 0; + } + + } else { + + tmp64_0 = + (uint64_t)pxtalk_data->bin_data_sums[lb] + * 1024U * 1000U; + tmp64_0 += (total_events >> 1); + tmp64_0 = do_division_u(tmp64_0, total_events); + if (tmp64_0 > 0xFFFFU) { + tmp64_0 = 0xFFFFU; + } + + pxtalk_shape->bin_data[lb] = (uint32_t)tmp64_0; + + + if ((int32_t)pxtalk_shape->bin_data[lb] > + pxtalk_data->max_shape_value) + pxtalk_data->max_shape_value = + (int32_t)pxtalk_shape->bin_data[lb]; + + remaining_area -= (int32_t)pxtalk_shape->bin_data[lb]; + } + } + + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_hist_xtalk_shape_model( + uint16_t events_per_bin, + uint16_t pulse_centre, + uint16_t pulse_width, + VL53LX_xtalk_histogram_shape_t *pxtalk_shape) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint32_t phase_start = 0; + uint32_t phase_stop = 0; + uint32_t phase_bin = 0; + + uint32_t bin_start = 0; + uint32_t bin_stop = 0; + + uint32_t lb = 0; + uint16_t VL53LX_p_018 = 0; + + pxtalk_shape->VL53LX_p_019 = 0; + pxtalk_shape->VL53LX_p_020 = VL53LX_XTALK_HISTO_BINS; + pxtalk_shape->VL53LX_p_021 = VL53LX_XTALK_HISTO_BINS; + + pxtalk_shape->zero_distance_phase = pulse_centre; + pxtalk_shape->phasecal_result__reference_phase = + pulse_centre + (3 * 2048); + + + if (pulse_centre > (pulse_width >> 1)) + phase_start = (uint32_t)pulse_centre - + ((uint32_t)pulse_width >> 1); + else { + phase_start = 0; + } + + phase_stop = (uint32_t)pulse_centre + + ((uint32_t)pulse_width >> 1); + + + bin_start = (phase_start / 2048); + bin_stop = (phase_stop / 2048); + + for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) { + VL53LX_p_018 = 0; + + + if (lb == bin_start && lb == bin_stop) { + VL53LX_p_018 = + VL53LX_hist_xtalk_shape_model_interp( + events_per_bin, + phase_stop - phase_start); + + } else if (lb > bin_start && lb < bin_stop) { + + + VL53LX_p_018 = events_per_bin; + + } else if (lb == bin_start) { + + + phase_bin = (lb + 1) * 2048; + VL53LX_p_018 = + VL53LX_hist_xtalk_shape_model_interp( + events_per_bin, + (phase_bin - phase_start)); + + } else if (lb == bin_stop) { + + + phase_bin = lb * 2048; + VL53LX_p_018 = + VL53LX_hist_xtalk_shape_model_interp( + events_per_bin, + (phase_stop - phase_bin)); + } + + pxtalk_shape->bin_data[lb] = VL53LX_p_018; + } + + + return status; +} + +uint16_t VL53LX::VL53LX_hist_xtalk_shape_model_interp( + uint16_t events_per_bin, + uint32_t phase_delta) +{ + + uint32_t VL53LX_p_018 = 0; + + VL53LX_p_018 = (uint32_t)events_per_bin * phase_delta; + VL53LX_p_018 += 1024; + VL53LX_p_018 /= 2048; + + + if (VL53LX_p_018 > 0xFFFFU) { + VL53LX_p_018 = 0xFFFFU; + } + + return (uint16_t)VL53LX_p_018; +} + +void VL53LX::VL53LX_spad_number_to_byte_bit_index( + uint8_t spad_number, + uint8_t *pbyte_index, + uint8_t *pbit_index, + uint8_t *pbit_mask) +{ + + + + *pbyte_index = spad_number >> 3; + *pbit_index = spad_number & 0x07; + *pbit_mask = 0x01 << *pbit_index; + +} + +void VL53LX::VL53LX_encode_row_col( + uint8_t row, + uint8_t col, + uint8_t *pspad_number) +{ + + + if (row > 7) { + *pspad_number = 128 + (col << 3) + (15 - row); + } else { + *pspad_number = ((15 - col) << 3) + row; + } + +} +void VL53LX::VL53LX_decode_zone_size( + uint8_t encoded_xy_size, + uint8_t *pwidth, + uint8_t *pheight) +{ + + + + *pheight = encoded_xy_size >> 4; + *pwidth = encoded_xy_size & 0x0F; + +} + +void VL53LX::VL53LX_encode_zone_size( + uint8_t width, + uint8_t height, + uint8_t *pencoded_xy_size) +{ + + + *pencoded_xy_size = (height << 4) + width; + +} + +void VL53LX::VL53LX_decode_zone_limits( + uint8_t encoded_xy_centre, + uint8_t encoded_xy_size, + int16_t *px_ll, + int16_t *py_ll, + int16_t *px_ur, + int16_t *py_ur) +{ + + + + uint8_t x_centre = 0; + uint8_t y_centre = 0; + uint8_t width = 0; + uint8_t height = 0; + + + + VL53LX_decode_row_col( + encoded_xy_centre, + &y_centre, + &x_centre); + + VL53LX_decode_zone_size( + encoded_xy_size, + &width, + &height); + + + + *px_ll = (int16_t)x_centre - ((int16_t)width + 1) / 2; + if (*px_ll < 0) { + *px_ll = 0; + } + + *px_ur = *px_ll + (int16_t)width; + if (*px_ur > (VL53LX_SPAD_ARRAY_WIDTH - 1)) { + *px_ur = VL53LX_SPAD_ARRAY_WIDTH - 1; + } + + *py_ll = (int16_t)y_centre - ((int16_t)height + 1) / 2; + if (*py_ll < 0) { + *py_ll = 0; + } + + *py_ur = *py_ll + (int16_t)height; + if (*py_ur > (VL53LX_SPAD_ARRAY_HEIGHT - 1)) { + *py_ur = VL53LX_SPAD_ARRAY_HEIGHT - 1; + } +} + +uint8_t VL53LX::VL53LX_is_aperture_location( + uint8_t row, + uint8_t col) +{ + + + uint8_t is_aperture = 0; + uint8_t mod_row = row % 4; + uint8_t mod_col = col % 4; + + if (mod_row == 0 && mod_col == 2) { + is_aperture = 1; + } + + if (mod_row == 2 && mod_col == 0) { + is_aperture = 1; + } + + return is_aperture; +} + +void VL53LX::VL53LX_calc_max_effective_spads( + uint8_t encoded_zone_centre, + uint8_t encoded_zone_size, + uint8_t *pgood_spads, + uint16_t aperture_attenuation, + uint16_t *pmax_effective_spads) +{ + + + + int16_t x = 0; + int16_t y = 0; + + int16_t zone_x_ll = 0; + int16_t zone_y_ll = 0; + int16_t zone_x_ur = 0; + int16_t zone_y_ur = 0; + + uint8_t spad_number = 0; + uint8_t byte_index = 0; + uint8_t bit_index = 0; + uint8_t bit_mask = 0; + + uint8_t is_aperture = 0; + + + + VL53LX_decode_zone_limits( + encoded_zone_centre, + encoded_zone_size, + &zone_x_ll, + &zone_y_ll, + &zone_x_ur, + &zone_y_ur); + + + + *pmax_effective_spads = 0; + + for (y = zone_y_ll; y <= zone_y_ur; y++) { + for (x = zone_x_ll; x <= zone_x_ur; x++) { + + + + VL53LX_encode_row_col( + (uint8_t)y, + (uint8_t)x, + &spad_number); + + + + VL53LX_spad_number_to_byte_bit_index( + spad_number, + &byte_index, + &bit_index, + &bit_mask); + + + + if ((pgood_spads[byte_index] & bit_mask) > 0) { + + + is_aperture = VL53LX_is_aperture_location( + (uint8_t)y, + (uint8_t)x); + + if (is_aperture > 0) + *pmax_effective_spads += + aperture_attenuation; + else { + *pmax_effective_spads += 0x0100; + } + + } + } + } +} + + + + +void VL53LX::VL53LX_calc_mm_effective_spads( + uint8_t encoded_mm_roi_centre, + uint8_t encoded_mm_roi_size, + uint8_t encoded_zone_centre, + uint8_t encoded_zone_size, + uint8_t *pgood_spads, + uint16_t aperture_attenuation, + uint16_t *pmm_inner_effective_spads, + uint16_t *pmm_outer_effective_spads) +{ + + int16_t x = 0; + int16_t y = 0; + + int16_t mm_x_ll = 0; + int16_t mm_y_ll = 0; + int16_t mm_x_ur = 0; + int16_t mm_y_ur = 0; + + int16_t zone_x_ll = 0; + int16_t zone_y_ll = 0; + int16_t zone_x_ur = 0; + int16_t zone_y_ur = 0; + + uint8_t spad_number = 0; + uint8_t byte_index = 0; + uint8_t bit_index = 0; + uint8_t bit_mask = 0; + + uint8_t is_aperture = 0; + uint16_t spad_attenuation = 0; + + + + VL53LX_decode_zone_limits( + encoded_mm_roi_centre, + encoded_mm_roi_size, + &mm_x_ll, + &mm_y_ll, + &mm_x_ur, + &mm_y_ur); + + VL53LX_decode_zone_limits( + encoded_zone_centre, + encoded_zone_size, + &zone_x_ll, + &zone_y_ll, + &zone_x_ur, + &zone_y_ur); + + + + *pmm_inner_effective_spads = 0; + *pmm_outer_effective_spads = 0; + + for (y = zone_y_ll; y <= zone_y_ur; y++) { + for (x = zone_x_ll; x <= zone_x_ur; x++) { + + + + VL53LX_encode_row_col( + (uint8_t)y, + (uint8_t)x, + &spad_number); + + + + VL53LX_spad_number_to_byte_bit_index( + spad_number, + &byte_index, + &bit_index, + &bit_mask); + + + + if ((pgood_spads[byte_index] & bit_mask) > 0) { + + + is_aperture = VL53LX_is_aperture_location( + (uint8_t)y, + (uint8_t)x); + + if (is_aperture > 0) { + spad_attenuation = aperture_attenuation; + } else { + spad_attenuation = 0x0100; + } + + + + if (x >= mm_x_ll && x <= mm_x_ur && + y >= mm_y_ll && y <= mm_y_ur) + *pmm_inner_effective_spads += + spad_attenuation; + else + *pmm_outer_effective_spads += + spad_attenuation; + } + } + } +} + + +void VL53LX::VL53LX_hist_copy_results_to_sys_and_core( + VL53LX_histogram_bin_data_t *pbins, + VL53LX_range_results_t *phist, + VL53LX_system_results_t *psys, + VL53LX_core_results_t *pcore) +{ + + + uint8_t i = 0; + + VL53LX_range_data_t *pdata; + + VL53LX_init_system_results(psys); + + psys->result__interrupt_status = pbins->result__interrupt_status; + psys->result__range_status = phist->active_results; + psys->result__report_status = pbins->result__report_status; + psys->result__stream_count = pbins->result__stream_count; + + pdata = &(phist->VL53LX_p_003[0]); + + for (i = 0; i < phist->active_results; i++) { + + switch (i) { + case 0: + psys->result__dss_actual_effective_spads_sd0 = + pdata->VL53LX_p_004; + psys->result__peak_signal_count_rate_mcps_sd0 = + pdata->peak_signal_count_rate_mcps; + psys->result__avg_signal_count_rate_mcps_sd0 = + pdata->avg_signal_count_rate_mcps; + psys->result__ambient_count_rate_mcps_sd0 = + pdata->ambient_count_rate_mcps; + + psys->result__sigma_sd0 = pdata->VL53LX_p_002; + psys->result__phase_sd0 = pdata->VL53LX_p_011; + + psys->result__final_crosstalk_corrected_range_mm_sd0 = + (uint16_t)pdata->median_range_mm; + + psys->result__phase_sd1 = pdata->zero_distance_phase; + + pcore->result_core__ranging_total_events_sd0 = + pdata->VL53LX_p_017; + pcore->result_core__signal_total_events_sd0 = + pdata->VL53LX_p_010; + pcore->result_core__total_periods_elapsed_sd0 = + pdata->total_periods_elapsed; + pcore->result_core__ambient_window_events_sd0 = + pdata->VL53LX_p_016; + + break; + case 1: + psys->result__dss_actual_effective_spads_sd1 = + pdata->VL53LX_p_004; + psys->result__peak_signal_count_rate_mcps_sd1 = + pdata->peak_signal_count_rate_mcps; + psys->result__ambient_count_rate_mcps_sd1 = + pdata->ambient_count_rate_mcps; + + psys->result__sigma_sd1 = pdata->VL53LX_p_002; + psys->result__phase_sd1 = pdata->VL53LX_p_011; + + psys->result__final_crosstalk_corrected_range_mm_sd1 = + (uint16_t)pdata->median_range_mm; + + pcore->result_core__ranging_total_events_sd1 = + pdata->VL53LX_p_017; + pcore->result_core__signal_total_events_sd1 = + pdata->VL53LX_p_010; + pcore->result_core__total_periods_elapsed_sd1 = + pdata->total_periods_elapsed; + pcore->result_core__ambient_window_events_sd1 = + pdata->VL53LX_p_016; + break; + } + + pdata++; + } + +} + +VL53LX_Error VL53LX::VL53LX_sum_histogram_data( + VL53LX_histogram_bin_data_t *phist_input, + VL53LX_histogram_bin_data_t *phist_output) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + uint8_t smallest_bin_num = 0; + + + if (status == VL53LX_ERROR_NONE) { + if (phist_output->VL53LX_p_021 >= + phist_input->VL53LX_p_021) { + smallest_bin_num = phist_input->VL53LX_p_021; + } else { + smallest_bin_num = phist_output->VL53LX_p_021; + } + } + + + + + + if (status == VL53LX_ERROR_NONE) + for (i = 0; i < smallest_bin_num; i++) + + { + phist_output->bin_data[i] += phist_input->bin_data[i]; + } + + if (status == VL53LX_ERROR_NONE) + phist_output->VL53LX_p_028 += + phist_input->VL53LX_p_028; + + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_avg_histogram_data( + uint8_t no_of_samples, + VL53LX_histogram_bin_data_t *phist_sum, + VL53LX_histogram_bin_data_t *phist_avg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + + + if (status == VL53LX_ERROR_NONE) { + for (i = 0; i < phist_sum->VL53LX_p_021; i++) { + + + + if (no_of_samples > 0) + phist_avg->bin_data[i] = + phist_sum->bin_data[i] / + (int32_t)no_of_samples; + else { + phist_avg->bin_data[i] = phist_sum->bin_data[i]; + } + } + } + + if (status == VL53LX_ERROR_NONE) { + if (no_of_samples > 0) + phist_avg->VL53LX_p_028 = + phist_sum->VL53LX_p_028 / + (int32_t)no_of_samples; + else + phist_avg->VL53LX_p_028 = + phist_sum->VL53LX_p_028; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_save_cfg_data() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg; + VL53LX_dynamic_config_t *pdynamic = &(pdev->dyn_cfg); + + + pzone_dyn_cfg = + &(pres->zone_dyn_cfgs.VL53LX_p_003[pdev->ll_state.cfg_zone_id]); + + pzone_dyn_cfg->expected_stream_count = + pdev->ll_state.cfg_stream_count; + + pzone_dyn_cfg->expected_gph_id = + pdev->ll_state.cfg_gph_id; + + pzone_dyn_cfg->roi_config__user_roi_centre_spad = + pdynamic->roi_config__user_roi_centre_spad; + + pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size = + pdynamic->roi_config__user_roi_requested_global_xy_size; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_dynamic_zone_update( + VL53LX_range_results_t *presults) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + VL53LX_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs); + + uint8_t zone_id = pdev->ll_state.rd_zone_id; + uint8_t i; + uint16_t max_total_rate_per_spads; + uint16_t target_rate = + pdev->stat_cfg.dss_config__target_total_rate_mcps; + uint32_t temp = 0xFFFF; + + pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count = 0; + + + max_total_rate_per_spads = + presults->VL53LX_p_003[0].total_rate_per_spad_mcps; + + + for (i = 1; i < presults->active_results; i++) { + + + if (presults->VL53LX_p_003[i].total_rate_per_spad_mcps > + max_total_rate_per_spads) + max_total_rate_per_spads = + presults->VL53LX_p_003[i].total_rate_per_spad_mcps; + + } + + if (max_total_rate_per_spads == 0) { + + temp = 0xFFFF; + } else { + + temp = target_rate << 14; + + temp = temp / max_total_rate_per_spads; + + + if (temp > 0xFFFF) { + temp = 0xFFFF; + } + + } + + pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count = + (uint16_t)temp; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_multizone_hist_bins_update() +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state); + VL53LX_zone_config_t *pzone_cfg = &(pdev->zone_cfg); + VL53LX_histogram_config_t *phist_cfg = &(pdev->hist_cfg); + VL53LX_histogram_config_t *pmulti_hist = + &(pzone_cfg->multizone_hist_cfg); + + uint8_t next_range_is_odd_timing = (pstate->cfg_stream_count) % 2; + + if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] == + VL53LX_ZONECONFIG_BINCONFIG__LOWAMB) { + if (!next_range_is_odd_timing) { + phist_cfg->histogram_config__low_amb_even_bin_0_1 = + pmulti_hist->histogram_config__low_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_even_bin_2_3 = + pmulti_hist->histogram_config__low_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_even_bin_4_5 = + pmulti_hist->histogram_config__low_amb_even_bin_4_5; + } + + if (next_range_is_odd_timing) { + phist_cfg->histogram_config__low_amb_odd_bin_0_1 = + pmulti_hist->histogram_config__low_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_odd_bin_2_3 = + pmulti_hist->histogram_config__low_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_odd_bin_4_5 = + pmulti_hist->histogram_config__low_amb_even_bin_4_5; + } + } else if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] == + VL53LX_ZONECONFIG_BINCONFIG__MIDAMB) { + if (!next_range_is_odd_timing) { + phist_cfg->histogram_config__low_amb_even_bin_0_1 = + pmulti_hist->histogram_config__mid_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_even_bin_2_3 = + pmulti_hist->histogram_config__mid_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_even_bin_4_5 = + pmulti_hist->histogram_config__mid_amb_even_bin_4_5; + } + + if (next_range_is_odd_timing) { + phist_cfg->histogram_config__low_amb_odd_bin_0_1 = + pmulti_hist->histogram_config__mid_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_odd_bin_2_3 = + pmulti_hist->histogram_config__mid_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_odd_bin_4_5 = + pmulti_hist->histogram_config__mid_amb_even_bin_4_5; + } + } else if (pzone_cfg->bin_config[pdev->ll_state.cfg_zone_id] == + VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB) { + if (!next_range_is_odd_timing) { + phist_cfg->histogram_config__low_amb_even_bin_0_1 = + pmulti_hist->histogram_config__high_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_even_bin_2_3 = + pmulti_hist->histogram_config__high_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_even_bin_4_5 = + pmulti_hist->histogram_config__high_amb_even_bin_4_5; + } + + if (next_range_is_odd_timing) { + phist_cfg->histogram_config__low_amb_odd_bin_0_1 = + pmulti_hist->histogram_config__high_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_odd_bin_2_3 = + pmulti_hist->histogram_config__high_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_odd_bin_4_5 = + pmulti_hist->histogram_config__high_amb_even_bin_4_5; + } + } + + + + if (status == VL53LX_ERROR_NONE) { + VL53LX_copy_hist_bins_to_static_cfg( + phist_cfg, + &(pdev->stat_cfg), + &(pdev->tim_cfg)); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_update_internal_stream_counters( + uint8_t external_stream_count, + uint8_t *pinternal_stream_count, + uint8_t *pinternal_stream_count_val) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t stream_divider; + + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + stream_divider = pdev->gen_cfg.global_config__stream_divider; + + if (stream_divider == 0) { + + + *pinternal_stream_count = external_stream_count; + + } else if (*pinternal_stream_count_val == (stream_divider - 1)) { + + + if (*pinternal_stream_count == 0xFF) { + *pinternal_stream_count = 0x80; + } else { + *pinternal_stream_count = *pinternal_stream_count + 1; + } + + + *pinternal_stream_count_val = 0; + + } else { + + + *pinternal_stream_count_val = *pinternal_stream_count_val + 1; + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_histogram_multizone_initial_bin_config( + VL53LX_zone_config_t *pzone_cfg, + VL53LX_histogram_config_t *phist_cfg, + VL53LX_histogram_config_t *pmulti_hist) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + if (pzone_cfg->bin_config[0] == + VL53LX_ZONECONFIG_BINCONFIG__LOWAMB) { + phist_cfg->histogram_config__low_amb_even_bin_0_1 = + pmulti_hist->histogram_config__low_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_even_bin_2_3 = + pmulti_hist->histogram_config__low_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_even_bin_4_5 = + pmulti_hist->histogram_config__low_amb_even_bin_4_5; + + phist_cfg->histogram_config__low_amb_odd_bin_0_1 = + pmulti_hist->histogram_config__low_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_odd_bin_2_3 = + pmulti_hist->histogram_config__low_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_odd_bin_4_5 = + pmulti_hist->histogram_config__low_amb_even_bin_4_5; + } else if (pzone_cfg->bin_config[0] == + VL53LX_ZONECONFIG_BINCONFIG__MIDAMB) { + phist_cfg->histogram_config__low_amb_even_bin_0_1 = + pmulti_hist->histogram_config__mid_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_even_bin_2_3 = + pmulti_hist->histogram_config__mid_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_even_bin_4_5 = + pmulti_hist->histogram_config__mid_amb_even_bin_4_5; + + phist_cfg->histogram_config__low_amb_odd_bin_0_1 = + pmulti_hist->histogram_config__mid_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_odd_bin_2_3 = + pmulti_hist->histogram_config__mid_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_odd_bin_4_5 = + pmulti_hist->histogram_config__mid_amb_even_bin_4_5; + } else if (pzone_cfg->bin_config[0] == + VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB) { + phist_cfg->histogram_config__low_amb_even_bin_0_1 = + pmulti_hist->histogram_config__high_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_even_bin_2_3 = + pmulti_hist->histogram_config__high_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_even_bin_4_5 = + pmulti_hist->histogram_config__high_amb_even_bin_4_5; + phist_cfg->histogram_config__low_amb_odd_bin_0_1 = + pmulti_hist->histogram_config__high_amb_even_bin_0_1; + phist_cfg->histogram_config__low_amb_odd_bin_2_3 = + pmulti_hist->histogram_config__high_amb_even_bin_2_3; + phist_cfg->histogram_config__low_amb_odd_bin_4_5 = + pmulti_hist->histogram_config__high_amb_even_bin_4_5; + } + + return status; +} + +uint8_t VL53LX::VL53LX_encode_GPIO_interrupt_config( + VL53LX_GPIO_interrupt_config_t *pintconf) +{ + uint8_t system__interrupt_config; + + system__interrupt_config = pintconf->intr_mode_distance; + system__interrupt_config |= ((pintconf->intr_mode_rate) << 2); + system__interrupt_config |= ((pintconf->intr_new_measure_ready) << 5); + system__interrupt_config |= ((pintconf->intr_no_target) << 6); + system__interrupt_config |= ((pintconf->intr_combined_mode) << 7); + + return system__interrupt_config; +} + +VL53LX_GPIO_interrupt_config_t VL53LX::VL53LX_decode_GPIO_interrupt_config( + uint8_t system__interrupt_config) +{ + VL53LX_GPIO_interrupt_config_t intconf; + + intconf.intr_mode_distance = system__interrupt_config & 0x03; + intconf.intr_mode_rate = (system__interrupt_config >> 2) & 0x03; + intconf.intr_new_measure_ready = (system__interrupt_config >> 5) & 0x01; + intconf.intr_no_target = (system__interrupt_config >> 6) & 0x01; + intconf.intr_combined_mode = (system__interrupt_config >> 7) & 0x01; + + + intconf.threshold_rate_low = 0; + intconf.threshold_rate_high = 0; + intconf.threshold_distance_low = 0; + intconf.threshold_distance_high = 0; + + return intconf; +} + +VL53LX_Error VL53LX::VL53LX_set_GPIO_distance_threshold( + uint16_t threshold_high, + uint16_t threshold_low) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + pdev->dyn_cfg.system__thresh_high = threshold_high; + pdev->dyn_cfg.system__thresh_low = threshold_low; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_GPIO_rate_threshold( + uint16_t threshold_high, + uint16_t threshold_low) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + + pdev->gen_cfg.system__thresh_rate_high = threshold_high; + pdev->gen_cfg.system__thresh_rate_low = threshold_low; + + return status; +} +VL53LX_Error VL53LX::VL53LX_set_GPIO_thresholds_from_struct( + VL53LX_GPIO_interrupt_config_t *pintconf) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_set_GPIO_distance_threshold( + pintconf->threshold_distance_high, + pintconf->threshold_distance_low); + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_set_GPIO_rate_threshold( + pintconf->threshold_rate_high, + pintconf->threshold_rate_low); + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_set_ref_spad_char_config( + uint8_t vcsel_period_a, + uint32_t phasecal_timeout_us, + uint16_t total_rate_target_mcps, + uint16_t max_count_rate_rtn_limit_mcps, + uint16_t min_count_rate_rtn_limit_mcps, + uint16_t fast_osc_frequency) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t buffer[2]; + + uint32_t macro_period_us = 0; + uint32_t timeout_mclks = 0; + + macro_period_us = + VL53LX_calc_macro_period_us( + fast_osc_frequency, + vcsel_period_a); + if (macro_period_us == 0) { + macro_period_us = 1; + } + + + timeout_mclks = phasecal_timeout_us << 12; + timeout_mclks = timeout_mclks + (macro_period_us >> 1); + timeout_mclks = timeout_mclks / macro_period_us; + + if (timeout_mclks > 0xFF) { + pdev->gen_cfg.phasecal_config__timeout_macrop = 0xFF; + } else + pdev->gen_cfg.phasecal_config__timeout_macrop = + (uint8_t)timeout_mclks; + + pdev->tim_cfg.range_config__vcsel_period_a = vcsel_period_a; + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WrByte( + Dev, + VL53LX_PHASECAL_CONFIG__TIMEOUT_MACROP, + pdev->gen_cfg.phasecal_config__timeout_macrop); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WrByte( + Dev, + VL53LX_RANGE_CONFIG__VCSEL_PERIOD_A, + pdev->tim_cfg.range_config__vcsel_period_a); + + + + buffer[0] = pdev->tim_cfg.range_config__vcsel_period_a; + buffer[1] = pdev->tim_cfg.range_config__vcsel_period_a; + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WriteMulti( + Dev, + VL53LX_SD_CONFIG__WOI_SD0, + buffer, + 2); + + + + pdev->customer.ref_spad_char__total_rate_target_mcps = + total_rate_target_mcps; + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WrWord( + Dev, + VL53LX_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS, + total_rate_target_mcps); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WrWord( + Dev, + VL53LX_RANGE_CONFIG__SIGMA_THRESH, + max_count_rate_rtn_limit_mcps); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WrWord( + Dev, + VL53LX_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS, + min_count_rate_rtn_limit_mcps); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_set_ssc_config( + VL53LX_ssc_config_t *pssc_cfg, + uint16_t fast_osc_frequency) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t buffer[5]; + + uint32_t macro_period_us = 0; + uint16_t timeout_encoded = 0; + + macro_period_us = + VL53LX_calc_macro_period_us( + fast_osc_frequency, + pssc_cfg->VL53LX_p_005); + + + timeout_encoded = + VL53LX_calc_encoded_timeout( + pssc_cfg->timeout_us, + macro_period_us); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WrByte( + Dev, + VL53LX_CAL_CONFIG__VCSEL_START, + pssc_cfg->vcsel_start); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WrByte( + Dev, + VL53LX_GLOBAL_CONFIG__VCSEL_WIDTH, + pssc_cfg->vcsel_width); + + + + buffer[0] = (uint8_t)((timeout_encoded & 0x0000FF00) >> 8); + buffer[1] = (uint8_t)(timeout_encoded & 0x000000FF); + buffer[2] = pssc_cfg->VL53LX_p_005; + buffer[3] = (uint8_t)((pssc_cfg->rate_limit_mcps & 0x0000FF00) >> 8); + buffer[4] = (uint8_t)(pssc_cfg->rate_limit_mcps & 0x000000FF); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WriteMulti( + Dev, + VL53LX_RANGE_CONFIG__TIMEOUT_MACROP_B_HI, + buffer, + 5); + + + + buffer[0] = pssc_cfg->VL53LX_p_005; + buffer[1] = pssc_cfg->VL53LX_p_005; + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WriteMulti( + Dev, + VL53LX_SD_CONFIG__WOI_SD0, + buffer, + 2); + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WrByte( + Dev, + VL53LX_NVM_BIST__CTRL, + pssc_cfg->array_select); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_get_spad_rate_data( + VL53LX_spad_rate_data_t *pspad_rates) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + int i = 0; + + uint8_t VL53LX_p_003[512]; + uint8_t *pdata = &VL53LX_p_003[0]; + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_firmware(); + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_ReadMulti( + Dev, + VL53LX_PRIVATE__PATCH_BASE_ADDR_RSLV, + pdata, + 512); + + + pdata = &VL53LX_p_003[0]; + for (i = 0; i < VL53LX_NO_OF_SPAD_ENABLES; i++) { + pspad_rates->rate_data[i] = + (uint16_t)VL53LX_decode_unsigned_integer(pdata, 2); + pdata += 2; + } + + + + pspad_rates->VL53LX_p_020 = VL53LX_NO_OF_SPAD_ENABLES; + pspad_rates->no_of_values = VL53LX_NO_OF_SPAD_ENABLES; + pspad_rates->fractional_bits = 15; + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_firmware(); + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_calc_required_samples() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev); + VL53LX_smudge_corrector_config_t *pconfig = + &(pdev->smudge_correct_config); + VL53LX_smudge_corrector_internals_t *pint = + &(pdev->smudge_corrector_internals); + + VL53LX_range_results_t *presults = &(pres->range_results); + VL53LX_range_data_t *pxmonitor = &(presults->xmonitor); + + uint32_t peak_duration_us = pxmonitor->peak_duration_us; + + uint64_t temp64a; + uint64_t temp64z; + + temp64a = pxmonitor->VL53LX_p_017 + + pxmonitor->VL53LX_p_016; + if (peak_duration_us == 0) { + peak_duration_us = 1000; + } + temp64a = do_division_u((temp64a * 1000), peak_duration_us); + temp64a = do_division_u((temp64a * 1000), peak_duration_us); + + temp64z = pconfig->noise_margin * pxmonitor->VL53LX_p_004; + if (temp64z == 0) { + temp64z = 1; + } + temp64a = temp64a * 1000 * 256; + temp64a = do_division_u(temp64a, temp64z); + temp64a = temp64a * 1000 * 256; + temp64a = do_division_u(temp64a, temp64z); + + pint->required_samples = (uint32_t)temp64a; + + + if (pint->required_samples < 2) { + pint->required_samples = 2; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_calc_new_xtalk( + uint32_t xtalk_offset_out, + VL53LX_smudge_corrector_config_t *pconfig, + VL53LX_smudge_corrector_data_t *pout, + uint8_t add_smudge, + uint8_t soft_update +) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + int16_t x_gradient_scaler; + int16_t y_gradient_scaler; + uint32_t orig_xtalk_offset; + int16_t orig_x_gradient; + int16_t orig_y_gradient; + uint8_t histo_merge_nb; + uint8_t i; + int32_t itemp32; + uint32_t SmudgeFactor; + VL53LX_xtalk_config_t *pX = &(pdev->xtalk_cfg); + VL53LX_xtalk_calibration_results_t *pC = &(pdev->xtalk_cal); + uint32_t *pcpo; + uint32_t max, nXtalk, cXtalk; + + if (add_smudge == 1) { + pout->algo__crosstalk_compensation_plane_offset_kcps = + (uint32_t)xtalk_offset_out + + (uint32_t)pconfig->smudge_margin; + } else { + pout->algo__crosstalk_compensation_plane_offset_kcps = + (uint32_t)xtalk_offset_out; + } + + + orig_xtalk_offset = + pX->nvm_default__crosstalk_compensation_plane_offset_kcps; + + orig_x_gradient = + pX->nvm_default__crosstalk_compensation_x_plane_gradient_kcps; + + orig_y_gradient = + pX->nvm_default__crosstalk_compensation_y_plane_gradient_kcps; + + if (((pconfig->user_scaler_set == 0) || + (pconfig->scaler_calc_method == 1)) && + (pC->algo__crosstalk_compensation_plane_offset_kcps != 0)) { + + VL53LX_compute_histo_merge_nb(&histo_merge_nb); + + if (histo_merge_nb == 0) { + histo_merge_nb = 1; + } + if (pdev->tuning_parms.tp_hist_merge != 1) + orig_xtalk_offset = + pC->algo__crosstalk_compensation_plane_offset_kcps; + else + orig_xtalk_offset = + pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb - 1]; + + orig_x_gradient = + pC->algo__crosstalk_compensation_x_plane_gradient_kcps; + + orig_y_gradient = + pC->algo__crosstalk_compensation_y_plane_gradient_kcps; + } + + + if ((pconfig->user_scaler_set == 0) && (orig_x_gradient == 0)) { + pout->gradient_zero_flag |= 0x01; + } + + if ((pconfig->user_scaler_set == 0) && (orig_y_gradient == 0)) { + pout->gradient_zero_flag |= 0x02; + } + + + + if (orig_xtalk_offset == 0) { + orig_xtalk_offset = 1; + } + + + + if (pconfig->user_scaler_set == 1) { + x_gradient_scaler = pconfig->x_gradient_scaler; + y_gradient_scaler = pconfig->y_gradient_scaler; + } else { + + x_gradient_scaler = (int16_t)do_division_s( + (((int32_t)orig_x_gradient) << 6), + orig_xtalk_offset); + pconfig->x_gradient_scaler = x_gradient_scaler; + y_gradient_scaler = (int16_t)do_division_s( + (((int32_t)orig_y_gradient) << 6), + orig_xtalk_offset); + pconfig->y_gradient_scaler = y_gradient_scaler; + } + + + + if (pconfig->scaler_calc_method == 0) { + + + itemp32 = (int32_t)( + pout->algo__crosstalk_compensation_plane_offset_kcps * + x_gradient_scaler); + itemp32 = itemp32 >> 6; + if (itemp32 > 0xFFFF) { + itemp32 = 0xFFFF; + } + + pout->algo__crosstalk_compensation_x_plane_gradient_kcps = + (int16_t)itemp32; + + itemp32 = (int32_t)( + pout->algo__crosstalk_compensation_plane_offset_kcps * + y_gradient_scaler); + itemp32 = itemp32 >> 6; + if (itemp32 > 0xFFFF) { + itemp32 = 0xFFFF; + } + + pout->algo__crosstalk_compensation_y_plane_gradient_kcps = + (int16_t)itemp32; + } else if (pconfig->scaler_calc_method == 1) { + + + itemp32 = (int32_t)(orig_xtalk_offset - + pout->algo__crosstalk_compensation_plane_offset_kcps); + itemp32 = (int32_t)(do_division_s(itemp32, 16)); + itemp32 = itemp32 << 2; + itemp32 = itemp32 + (int32_t)(orig_x_gradient); + if (itemp32 > 0xFFFF) { + itemp32 = 0xFFFF; + } + + pout->algo__crosstalk_compensation_x_plane_gradient_kcps = + (int16_t)itemp32; + + itemp32 = (int32_t)(orig_xtalk_offset - + pout->algo__crosstalk_compensation_plane_offset_kcps); + itemp32 = (int32_t)(do_division_s(itemp32, 80)); + itemp32 = itemp32 << 2; + itemp32 = itemp32 + (int32_t)(orig_y_gradient); + if (itemp32 > 0xFFFF) { + itemp32 = 0xFFFF; + } + + pout->algo__crosstalk_compensation_y_plane_gradient_kcps = + (int16_t)itemp32; + } + + + if ((pconfig->smudge_corr_apply_enabled == 1) && + (soft_update != 1)) { + + pout->new_xtalk_applied_flag = 1; + nXtalk = pout->algo__crosstalk_compensation_plane_offset_kcps; + + VL53LX_compute_histo_merge_nb(&histo_merge_nb); + max = pdev->tuning_parms.tp_hist_merge_max_size; + pcpo = &(pC->algo__xtalk_cpo_HistoMerge_kcps[0]); + if ((histo_merge_nb > 0) && + (pdev->tuning_parms.tp_hist_merge == 1) && + (nXtalk != 0)) { + cXtalk = + pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb - 1]; + SmudgeFactor = cXtalk * 1000 / nXtalk; + if (SmudgeFactor >= pconfig->max_smudge_factor) { + pout->new_xtalk_applied_flag = 0; + } else if (SmudgeFactor > 0) + for (i = 0; i < max; i++) { + *pcpo *= 1000; + *pcpo /= SmudgeFactor; + pcpo++; + } + } + if (pout->new_xtalk_applied_flag) { + + pX->algo__crosstalk_compensation_plane_offset_kcps = + pout->algo__crosstalk_compensation_plane_offset_kcps; + pX->algo__crosstalk_compensation_x_plane_gradient_kcps = + pout->algo__crosstalk_compensation_x_plane_gradient_kcps; + pX->algo__crosstalk_compensation_y_plane_gradient_kcps = + pout->algo__crosstalk_compensation_y_plane_gradient_kcps; + + if (pconfig->smudge_corr_single_apply == 1) { + + pconfig->smudge_corr_apply_enabled = 0; + pconfig->smudge_corr_single_apply = 0; + } + } + } + + + if (soft_update != 1) { + pout->smudge_corr_valid = 1; + } + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_corrector() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev); + VL53LX_smudge_corrector_config_t *pconfig = + &(pdev->smudge_correct_config); + VL53LX_smudge_corrector_internals_t *pint = + &(pdev->smudge_corrector_internals); + VL53LX_smudge_corrector_data_t *pout = + &(pres->range_results.smudge_corrector_data); + VL53LX_range_results_t *pR = &(pres->range_results); + VL53LX_xtalk_config_t *pX = &(pdev->xtalk_cfg); + + uint8_t run_smudge_detection = 0; + uint8_t merging_complete = 0; + uint8_t run_nodetect = 0; + uint8_t ambient_check = 0; + int32_t itemp32 = 0; + uint64_t utemp64 = 0; + uint8_t continue_processing = CONT_CONTINUE; + uint32_t xtalk_offset_out = 0; + uint32_t xtalk_offset_in = 0; + uint32_t current_xtalk = 0; + uint32_t smudge_margin_adjusted = 0; + uint8_t i = 0; + uint8_t nodetect_index = 0; + uint16_t amr; + uint32_t cco; + uint8_t histo_merge_nb; + + + VL53LX_compute_histo_merge_nb(&histo_merge_nb); + if ((histo_merge_nb == 0) || + (pdev->tuning_parms.tp_hist_merge != 1)) { + histo_merge_nb = 1; + } + + + VL53LX_dynamic_xtalk_correction_output_init(pres); + + + ambient_check = (pconfig->smudge_corr_ambient_threshold == 0) || + ((pconfig->smudge_corr_ambient_threshold * histo_merge_nb) > + ((uint32_t)pR->xmonitor.ambient_count_rate_mcps)); + + + merging_complete = + ((pdev->tuning_parms.tp_hist_merge != 1) || + (histo_merge_nb == pdev->tuning_parms.tp_hist_merge_max_size)); + run_smudge_detection = + (pconfig->smudge_corr_enabled == 1) && + ambient_check && + (pR->xmonitor.range_status + == VL53LX_DEVICEERROR_RANGECOMPLETE) && + merging_complete; + + + if ((pR->xmonitor.range_status + != VL53LX_DEVICEERROR_RANGECOMPLETE) && + (pconfig->smudge_corr_enabled == 1)) { + + run_nodetect = 2; + for (i = 0; i < pR->active_results; i++) { + if (pR->VL53LX_p_003[i].range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE) { + if (pR->VL53LX_p_003[i].median_range_mm + <= + pconfig->nodetect_min_range_mm) { + run_nodetect = 0; + } else { + if (run_nodetect == 2) { + run_nodetect = 1; + nodetect_index = i; + } + } + } + } + + if (run_nodetect == 2) + + { + run_nodetect = 0; + } + + amr = + pR->VL53LX_p_003[nodetect_index].ambient_count_rate_mcps; + + if (run_nodetect == 1) { + + + + + utemp64 = 1000 * ((uint64_t)amr); + + + utemp64 = utemp64 << 9; + + + if (utemp64 < pconfig->nodetect_ambient_threshold) { + run_nodetect = 1; + } else { + run_nodetect = 0; + } + + } + } + + + if (run_smudge_detection) { + + pint->nodetect_counter = 0; + + + VL53LX_dynamic_xtalk_correction_calc_required_samples(); + + + xtalk_offset_in = + pR->xmonitor.VL53LX_p_009; + + + cco = pX->algo__crosstalk_compensation_plane_offset_kcps; + current_xtalk = ((uint32_t)cco) << 2; + + + smudge_margin_adjusted = + ((uint32_t)(pconfig->smudge_margin)) << 2; + + + itemp32 = xtalk_offset_in - current_xtalk + + smudge_margin_adjusted; + + if (itemp32 < 0) { + itemp32 = itemp32 * (-1); + } + + + if (itemp32 > ((int32_t)pconfig->single_xtalk_delta)) { + if ((int32_t)xtalk_offset_in > + ((int32_t)current_xtalk - + (int32_t)smudge_margin_adjusted)) { + pout->single_xtalk_delta_flag = 1; + } else { + pout->single_xtalk_delta_flag = 2; + } + } + + + pint->current_samples = pint->current_samples + 1; + + + if (pint->current_samples > pconfig->sample_limit) { + pout->sample_limit_exceeded_flag = 1; + continue_processing = CONT_RESET; + } else { + pint->accumulator = pint->accumulator + + xtalk_offset_in; + } + + if (pint->current_samples < pint->required_samples) { + continue_processing = CONT_NEXT_LOOP; + } + + + xtalk_offset_out = + (uint32_t)(do_division_u(pint->accumulator, + pint->current_samples)); + + + itemp32 = xtalk_offset_out - current_xtalk + + smudge_margin_adjusted; + + if (itemp32 < 0) { + itemp32 = itemp32 * (-1); + } + + if (continue_processing == CONT_CONTINUE && + (itemp32 >= ((int32_t)(pconfig->averaged_xtalk_delta))) + ) { + if ((int32_t)xtalk_offset_out > + ((int32_t)current_xtalk - + (int32_t)smudge_margin_adjusted)) { + pout->averaged_xtalk_delta_flag = 1; + } else { + pout->averaged_xtalk_delta_flag = 2; + } + } + + if (continue_processing == CONT_CONTINUE && + (itemp32 < ((int32_t)(pconfig->averaged_xtalk_delta))) + ) + + { + continue_processing = CONT_RESET; + } + + + + pout->smudge_corr_clipped = 0; + if ((continue_processing == CONT_CONTINUE) && + (pconfig->smudge_corr_clip_limit != 0)) { + if (xtalk_offset_out > + (pconfig->smudge_corr_clip_limit * histo_merge_nb)) { + pout->smudge_corr_clipped = 1; + continue_processing = CONT_RESET; + } + } + + + + if (pconfig->user_xtalk_offset_limit_hi && + (xtalk_offset_out > + pconfig->user_xtalk_offset_limit)) + xtalk_offset_out = + pconfig->user_xtalk_offset_limit; + + + + if ((pconfig->user_xtalk_offset_limit_hi == 0) && + (xtalk_offset_out < + pconfig->user_xtalk_offset_limit)) + xtalk_offset_out = + pconfig->user_xtalk_offset_limit; + + + + xtalk_offset_out = xtalk_offset_out >> 2; + if (xtalk_offset_out > 0x3FFFF) { + xtalk_offset_out = 0x3FFFF; + } + + + if (continue_processing == CONT_CONTINUE) { + + VL53LX_dynamic_xtalk_correction_calc_new_xtalk( + xtalk_offset_out, + pconfig, + pout, + 1, + 0 + ); + + + continue_processing = CONT_RESET; + } else { + + VL53LX_dynamic_xtalk_correction_calc_new_xtalk( + xtalk_offset_out, + pconfig, + pout, + 1, + 1 + ); + } + + + if (continue_processing == CONT_RESET) { + pint->accumulator = 0; + pint->current_samples = 0; + pint->nodetect_counter = 0; + } + + } + + continue_processing = CONT_CONTINUE; + if (run_nodetect == 1) { + + pint->nodetect_counter += 1; + + + if (pint->nodetect_counter < pconfig->nodetect_sample_limit) { + continue_processing = CONT_NEXT_LOOP; + } + + + xtalk_offset_out = (uint32_t)(pconfig->nodetect_xtalk_offset); + + if (continue_processing == CONT_CONTINUE) { + + VL53LX_dynamic_xtalk_correction_calc_new_xtalk( + xtalk_offset_out, + pconfig, + pout, + 0, + 0 + ); + + + pout->smudge_corr_valid = 2; + + + continue_processing = CONT_RESET; + } else { + + VL53LX_dynamic_xtalk_correction_calc_new_xtalk( + xtalk_offset_out, + pconfig, + pout, + 0, + 1 + ); + } + + + if (continue_processing == CONT_RESET) { + pint->accumulator = 0; + pint->current_samples = 0; + pint->nodetect_counter = 0; + } + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_data_init() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_enabled = 1; + pdev->smudge_correct_config.smudge_corr_apply_enabled = 1; + pdev->smudge_correct_config.smudge_corr_single_apply = + VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY_DEFAULT; + + pdev->smudge_correct_config.smudge_margin = + VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN_DEFAULT; + pdev->smudge_correct_config.noise_margin = + VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN_DEFAULT; + pdev->smudge_correct_config.user_xtalk_offset_limit = + VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_DEFAULT; + pdev->smudge_correct_config.user_xtalk_offset_limit_hi = + VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI_DEFAULT; + pdev->smudge_correct_config.sample_limit = + VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT_DEFAULT; + pdev->smudge_correct_config.single_xtalk_delta = + VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA_DEFAULT; + pdev->smudge_correct_config.averaged_xtalk_delta = + VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA_DEFAULT; + pdev->smudge_correct_config.smudge_corr_clip_limit = + VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT_DEFAULT; + pdev->smudge_correct_config.smudge_corr_ambient_threshold = + VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD_DEFAULT; + pdev->smudge_correct_config.scaler_calc_method = + 0; + pdev->smudge_correct_config.x_gradient_scaler = + VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER_DEFAULT; + pdev->smudge_correct_config.y_gradient_scaler = + VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER_DEFAULT; + pdev->smudge_correct_config.user_scaler_set = + VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET_DEFAULT; + pdev->smudge_correct_config.nodetect_ambient_threshold = + VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS_DEFAULT; + pdev->smudge_correct_config.nodetect_sample_limit = + VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT_DEFAULT; + pdev->smudge_correct_config.nodetect_xtalk_offset = + VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS_DEFAULT; + pdev->smudge_correct_config.nodetect_min_range_mm = + VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM_DEFAULT; + pdev->smudge_correct_config.max_smudge_factor = + VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR_DEFAULT; + + + pdev->smudge_corrector_internals.current_samples = 0; + pdev->smudge_corrector_internals.required_samples = 0; + pdev->smudge_corrector_internals.accumulator = 0; + pdev->smudge_corrector_internals.nodetect_counter = 0; + + + VL53LX_dynamic_xtalk_correction_output_init(pres); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_dynamic_xtalk_correction_output_init( + VL53LX_LLDriverResults_t *pres +) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_smudge_corrector_data_t *pdata; + + pdata = &(pres->range_results.smudge_corrector_data); + + pdata->smudge_corr_valid = 0; + pdata->smudge_corr_clipped = 0; + pdata->single_xtalk_delta_flag = 0; + pdata->averaged_xtalk_delta_flag = 0; + pdata->sample_limit_exceeded_flag = 0; + pdata->gradient_zero_flag = 0; + pdata->new_xtalk_applied_flag = 0; + + pdata->algo__crosstalk_compensation_plane_offset_kcps = 0; + pdata->algo__crosstalk_compensation_x_plane_gradient_kcps = 0; + pdata->algo__crosstalk_compensation_y_plane_gradient_kcps = 0; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_xtalk_cal_data_init() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps = 0; + pdev->xtalk_cal.algo__crosstalk_compensation_x_plane_gradient_kcps = 0; + pdev->xtalk_cal.algo__crosstalk_compensation_y_plane_gradient_kcps = 0; + memset(&pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0], 0, + sizeof(pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps)); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_low_power_auto_data_init() +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->low_power_auto_data.vhv_loop_bound = + VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND_DEFAULT; + pdev->low_power_auto_data.is_low_power_auto_mode = 0; + pdev->low_power_auto_data.low_power_auto_range_count = 0; + pdev->low_power_auto_data.saved_interrupt_config = 0; + pdev->low_power_auto_data.saved_vhv_init = 0; + pdev->low_power_auto_data.saved_vhv_timeout = 0; + pdev->low_power_auto_data.first_run_phasecal_result = 0; + pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0; + pdev->low_power_auto_data.dss__required_spads = 0; + + return status; +} +VL53LX_Error VL53LX::VL53LX_low_power_auto_data_stop_range() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->low_power_auto_data.low_power_auto_range_count = 0xFF; + + pdev->low_power_auto_data.first_run_phasecal_result = 0; + pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0; + pdev->low_power_auto_data.dss__required_spads = 0; + + + if (pdev->low_power_auto_data.saved_vhv_init != 0) + pdev->stat_nvm.vhv_config__init = + pdev->low_power_auto_data.saved_vhv_init; + if (pdev->low_power_auto_data.saved_vhv_timeout != 0) + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound = + pdev->low_power_auto_data.saved_vhv_timeout; + + pdev->gen_cfg.phasecal_config__override = 0x00; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_config_low_power_auto_mode( + VL53LX_general_config_t *pgeneral, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_low_power_auto_data_t *plpadata +) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + plpadata->is_low_power_auto_mode = 1; + + + plpadata->low_power_auto_range_count = 0; + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + + + + VL53LX_SEQUENCE_RANGE_EN; + + + pgeneral->dss_config__manual_effective_spads_select = 200 << 8; + pgeneral->dss_config__roi_mode_control = + VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_low_power_auto_setup_manual_calibration() +{ + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdev->low_power_auto_data.saved_vhv_init = + pdev->stat_nvm.vhv_config__init; + pdev->low_power_auto_data.saved_vhv_timeout = + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound; + + + pdev->stat_nvm.vhv_config__init &= 0x7F; + + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound = + (pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound & 0x03) + + (pdev->low_power_auto_data.vhv_loop_bound << 2); + + pdev->gen_cfg.phasecal_config__override = 0x01; + pdev->low_power_auto_data.first_run_phasecal_result = + pdev->dbg_results.phasecal_result__vcsel_start; + pdev->gen_cfg.cal_config__vcsel_start = + pdev->low_power_auto_data.first_run_phasecal_result; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_low_power_auto_update_DSS() +{ + + + + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_system_results_t *pS = &(pdev->sys_results); + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint32_t utemp32a; + + utemp32a = + pS->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 + + pS->result__ambient_count_rate_mcps_sd0; + + + if (utemp32a > 0xFFFF) { + utemp32a = 0xFFFF; + } + + + + utemp32a = utemp32a << 16; + + + if (pdev->sys_results.result__dss_actual_effective_spads_sd0 == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } else { + + utemp32a = utemp32a / + pdev->sys_results.result__dss_actual_effective_spads_sd0; + + pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = + utemp32a; + + + utemp32a = pdev->stat_cfg.dss_config__target_total_rate_mcps << + 16; + + + if (pdev->low_power_auto_data.dss__total_rate_per_spad_mcps + == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } else { + + utemp32a = utemp32a / + pdev->low_power_auto_data.dss__total_rate_per_spad_mcps; + + + if (utemp32a > 0xFFFF) { + utemp32a = 0xFFFF; + } + + + pdev->low_power_auto_data.dss__required_spads = + (uint16_t)utemp32a; + + + pdev->gen_cfg.dss_config__manual_effective_spads_select + = pdev->low_power_auto_data.dss__required_spads; + pdev->gen_cfg.dss_config__roi_mode_control = + VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS; + } + + } + + if (status == VL53LX_ERROR_DIVISION_BY_ZERO) { + + + + pdev->low_power_auto_data.dss__required_spads = 0x8000; + + + pdev->gen_cfg.dss_config__manual_effective_spads_select = + pdev->low_power_auto_data.dss__required_spads; + pdev->gen_cfg.dss_config__roi_mode_control = + VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS; + + + status = VL53LX_ERROR_NONE; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_compute_histo_merge_nb(uint8_t *histo_merge_nb) +{ + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t i, timing; + uint8_t sum = 0; + + timing = (pdev->hist_data.bin_seq[0] == 7 ? 1 : 0); + for (i = 0; i < VL53LX_BIN_REC_SIZE; i++) + if (pdev->multi_bins_rec[i][timing][7] > 0) { + sum++; + } + *histo_merge_nb = sum; + + return status; +} + +/* vl53lx_wait.c */ + + +VL53LX_Error VL53LX::VL53LX_wait_for_boot_completion() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t fw_ready = 0; + + if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) { + + + + status = + VL53LX_poll_for_boot_completion(VL53LX_BOOT_COMPLETION_POLLING_TIMEOUT_MS); + + } else { + + + + fw_ready = 0; + while (fw_ready == 0x00 && status == VL53LX_ERROR_NONE) { + status = VL53LX_is_boot_complete( + &fw_ready); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WaitMs( + Dev, + VL53LX_POLLING_DELAY_MS); + } + } + } + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_wait_for_firmware_ready() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t fw_ready = 0; + uint8_t mode_start = 0; + + mode_start = + pdev->sys_ctrl.system__mode_start & + VL53LX_DEVICEMEASUREMENTMODE_MODE_MASK; + + + + if ((mode_start == VL53LX_DEVICEMEASUREMENTMODE_TIMED) || + (mode_start == VL53LX_DEVICEMEASUREMENTMODE_SINGLESHOT)) { + + if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) { + + + + status = + VL53LX_poll_for_firmware_ready( + VL53LX_RANGE_COMPLETION_POLLING_TIMEOUT_MS); + + } else { + + + + fw_ready = 0; + while (fw_ready == 0x00 && status == + VL53LX_ERROR_NONE) { + status = VL53LX_is_firmware_ready( + &fw_ready); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WaitMs( + Dev, + VL53LX_POLLING_DELAY_MS); + } + } + } + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_wait_for_range_completion() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t data_ready = 0; + + if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) { + + + + status = + VL53LX_poll_for_range_completion( + VL53LX_RANGE_COMPLETION_POLLING_TIMEOUT_MS); + + } else { + + + + data_ready = 0; + while (data_ready == 0x00 && status == VL53LX_ERROR_NONE) { + status = VL53LX_is_new_data_ready( + &data_ready); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WaitMs( + Dev, + VL53LX_POLLING_DELAY_MS); + } + } + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_wait_for_test_completion() +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t data_ready = 0; + + + if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) { + + + + status = + VL53LX_poll_for_range_completion( + VL53LX_TEST_COMPLETION_POLLING_TIMEOUT_MS); + + } else { + + + + data_ready = 0; + while (data_ready == 0x00 && status == VL53LX_ERROR_NONE) { + status = VL53LX_is_new_data_ready( + &data_ready); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WaitMs( + Dev, + VL53LX_POLLING_DELAY_MS); + } + } + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_is_boot_complete( + uint8_t *pready) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t firmware__system_status = 0; + + status = + VL53LX_RdByte( + Dev, + VL53LX_FIRMWARE__SYSTEM_STATUS, + &firmware__system_status); + + + + if ((firmware__system_status & 0x01) == 0x01) { + *pready = 0x01; + VL53LX_init_ll_driver_state( + VL53LX_DEVICESTATE_SW_STANDBY); + } else { + *pready = 0x00; + VL53LX_init_ll_driver_state( + VL53LX_DEVICESTATE_FW_COLDBOOT); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_is_firmware_ready( + uint8_t *pready) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + status = VL53LX_is_firmware_ready_silicon( + pready); + + pdev->fw_ready = *pready; + + return status; +} +VL53LX_Error VL53LX::VL53LX_is_new_data_ready( + uint8_t *pready) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t gpio__mux_active_high_hv = 0; + uint8_t gpio__tio_hv_status = 0; + uint8_t interrupt_ready = 0; + + gpio__mux_active_high_hv = + pdev->stat_cfg.gpio_hv_mux__ctrl & + VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_MASK; + + if (gpio__mux_active_high_hv == VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH) { + interrupt_ready = 0x01; + } else { + interrupt_ready = 0x00; + } + + + status = VL53LX_RdByte( + Dev, + VL53LX_GPIO__TIO_HV_STATUS, + &gpio__tio_hv_status); + + + + if ((gpio__tio_hv_status & 0x01) == interrupt_ready) { + *pready = 0x01; + } else { + *pready = 0x00; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_poll_for_boot_completion( + uint32_t timeout_ms) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + // status = VL53LX_WaitUs( +// Dev, + // VL53LX_FIRMWARE_BOOT_TIME_US); + wait_us(VL53LX_FIRMWARE_BOOT_TIME_US*10); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WaitValueMaskEx( + Dev, + timeout_ms, + VL53LX_FIRMWARE__SYSTEM_STATUS, + 0x01, + 0x01, + VL53LX_POLLING_DELAY_MS); +printf("VL53LX_poll_for_boot_completion %d \n",status); + if (status == VL53LX_ERROR_NONE) { + VL53LX_init_ll_driver_state(VL53LX_DEVICESTATE_SW_STANDBY); + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_poll_for_firmware_ready( + uint32_t timeout_ms) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint32_t start_time_ms = 0; + uint32_t current_time_ms = 0; + int32_t poll_delay_ms = VL53LX_POLLING_DELAY_MS; + uint8_t fw_ready = 0; + + + + VL53LX_GetTickCount(&start_time_ms); + pdev->fw_ready_poll_duration_ms = 0; + + while ((status == VL53LX_ERROR_NONE) && + (pdev->fw_ready_poll_duration_ms < timeout_ms) && + (fw_ready == 0)) { + + status = VL53LX_is_firmware_ready( + &fw_ready); + + if (status == VL53LX_ERROR_NONE && + fw_ready == 0 && + poll_delay_ms > 0) { + status = VL53LX_WaitMs( + Dev, + poll_delay_ms); + } + + + VL53LX_GetTickCount(¤t_time_ms); + pdev->fw_ready_poll_duration_ms = + current_time_ms - start_time_ms; + } + + if (fw_ready == 0 && status == VL53LX_ERROR_NONE) { + status = VL53LX_ERROR_TIME_OUT; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_poll_for_range_completion( + uint32_t timeout_ms) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t gpio__mux_active_high_hv = 0; + uint8_t interrupt_ready = 0; + + gpio__mux_active_high_hv = + pdev->stat_cfg.gpio_hv_mux__ctrl & + VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_MASK; + + if (gpio__mux_active_high_hv == VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH) { + interrupt_ready = 0x01; + } else { + interrupt_ready = 0x00; + } + + status = + VL53LX_WaitValueMaskEx( + Dev, + timeout_ms, + VL53LX_GPIO__TIO_HV_STATUS, + interrupt_ready, + 0x01, + VL53LX_POLLING_DELAY_MS); + + return status; +} + +/* vl53lx_zone_presets.c */ + +VL53LX_Error VL53LX::VL53LX_init_zone_config_structure( + uint8_t x_off, + uint8_t x_inc, + uint8_t x_zones, + uint8_t y_off, + uint8_t y_inc, + uint8_t y_zones, + uint8_t width, + uint8_t height, + VL53LX_zone_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t x = 0; + uint8_t y = 0; + uint16_t i = 0; + + + pdata->max_zones = VL53LX_MAX_USER_ZONES; + + i = 0; + + for (x = 0 ; x < x_zones ; x++) { + for (y = 0 ; y < y_zones ; y++) { + + if (i < VL53LX_MAX_USER_ZONES) { + + pdata->active_zones = (uint8_t)i; + pdata->user_zones[i].height = height; + pdata->user_zones[i].width = width; + pdata->user_zones[i].x_centre = + x_off + (x * x_inc); + pdata->user_zones[i].y_centre = + y_off + (y * y_inc); + } + + i++; + } + } + + status = VL53LX_init_zone_config_histogram_bins(pdata); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_zone_preset_xtalk_planar( + VL53LX_general_config_t *pgeneral, + VL53LX_zone_config_t *pzone_cfg) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + pgeneral->global_config__stream_divider = 0x05; + + + pzone_cfg->active_zones = 0x04; + + pzone_cfg->user_zones[0].height = 15; + pzone_cfg->user_zones[0].width = 7; + pzone_cfg->user_zones[0].x_centre = 4; + pzone_cfg->user_zones[0].y_centre = 8; + + pzone_cfg->user_zones[1].height = 15; + pzone_cfg->user_zones[1].width = 7; + pzone_cfg->user_zones[1].x_centre = 12; + pzone_cfg->user_zones[1].y_centre = 8; + + pzone_cfg->user_zones[2].height = 7; + pzone_cfg->user_zones[2].width = 15; + pzone_cfg->user_zones[2].x_centre = 8; + pzone_cfg->user_zones[2].y_centre = 4; + + pzone_cfg->user_zones[3].height = 7; + pzone_cfg->user_zones[3].width = 15; + pzone_cfg->user_zones[3].x_centre = 8; + pzone_cfg->user_zones[3].y_centre = 12; + + + + pzone_cfg->user_zones[4].height = 15; + pzone_cfg->user_zones[4].width = 15; + pzone_cfg->user_zones[4].x_centre = 8; + pzone_cfg->user_zones[4].y_centre = 8; + + status = VL53LX_init_zone_config_histogram_bins(pzone_cfg); + + return status; +} + +VL53LX_Error VL53LX::VL53LX_init_zone_config_histogram_bins( + VL53LX_zone_config_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i; + + + for (i = 0; i < pdata->max_zones; i++) { + pdata->bin_config[i] = VL53LX_ZONECONFIG_BINCONFIG__LOWAMB; + } + + return status; +} + +/* vl53lx_api_preset_modes.h */ + +VL53LX_Error VL53LX::VL53LX_init_refspadchar_config_struct( + VL53LX_refspadchar_config_t *pdata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->device_test_mode = + VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE_DEFAULT; + pdata->VL53LX_p_005 = + VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD_DEFAULT; + pdata->timeout_us = + VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US_DEFAULT; + pdata->target_count_rate_mcps = + VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS_DEFAULT; + pdata->min_count_rate_limit_mcps = + VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS_DEFAULT; + pdata->max_count_rate_limit_mcps = + VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_init_ssc_config_struct( + VL53LX_ssc_config_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->array_select = VL53LX_DEVICESSCARRAY_RTN; + + + pdata->VL53LX_p_005 = + VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD_DEFAULT; + + + pdata->vcsel_start = + VL53LX_TUNINGPARM_SPADMAP_VCSEL_START_DEFAULT; + + + pdata->vcsel_width = 0x02; + + + pdata->timeout_us = 36000; + + + pdata->rate_limit_mcps = + VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS_DEFAULT; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_init_xtalk_config_struct( + VL53LX_customer_nvm_managed_t *pnvm, + VL53LX_xtalk_config_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->algo__crosstalk_compensation_plane_offset_kcps = + pnvm->algo__crosstalk_compensation_plane_offset_kcps; + pdata->algo__crosstalk_compensation_x_plane_gradient_kcps = + pnvm->algo__crosstalk_compensation_x_plane_gradient_kcps; + pdata->algo__crosstalk_compensation_y_plane_gradient_kcps = + pnvm->algo__crosstalk_compensation_y_plane_gradient_kcps; + + + + pdata->nvm_default__crosstalk_compensation_plane_offset_kcps = + (uint32_t)pnvm->algo__crosstalk_compensation_plane_offset_kcps; + pdata->nvm_default__crosstalk_compensation_x_plane_gradient_kcps = + pnvm->algo__crosstalk_compensation_x_plane_gradient_kcps; + pdata->nvm_default__crosstalk_compensation_y_plane_gradient_kcps = + pnvm->algo__crosstalk_compensation_y_plane_gradient_kcps; + + pdata->histogram_mode_crosstalk_margin_kcps = + VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS_DEFAULT; + pdata->lite_mode_crosstalk_margin_kcps = + VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS_DEFAULT; + + + + pdata->crosstalk_range_ignore_threshold_mult = + VL53LX_TUNINGPARM_LITE_RIT_MULT_DEFAULT; + + if ((pdata->algo__crosstalk_compensation_plane_offset_kcps == 0x00) + && (pdata->algo__crosstalk_compensation_x_plane_gradient_kcps + == 0x00) + && (pdata->algo__crosstalk_compensation_y_plane_gradient_kcps + == 0x00)) { + pdata->global_crosstalk_compensation_enable = 0x00; + } else { + pdata->global_crosstalk_compensation_enable = 0x01; + } + + + if ((status == VL53LX_ERROR_NONE) && + (pdata->global_crosstalk_compensation_enable == 0x01)) { + pdata->crosstalk_range_ignore_threshold_rate_mcps = + VL53LX_calc_range_ignore_threshold( + pdata->algo__crosstalk_compensation_plane_offset_kcps, + pdata->algo__crosstalk_compensation_x_plane_gradient_kcps, + pdata->algo__crosstalk_compensation_y_plane_gradient_kcps, + pdata->crosstalk_range_ignore_threshold_mult); + } else { + pdata->crosstalk_range_ignore_threshold_rate_mcps = 0; + } + + + + + pdata->algo__crosstalk_detect_min_valid_range_mm = + VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT; + pdata->algo__crosstalk_detect_max_valid_range_mm = + VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT; + pdata->algo__crosstalk_detect_max_valid_rate_kcps = + VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT; + pdata->algo__crosstalk_detect_max_sigma_mm = + VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_init_xtalk_extract_config_struct( + VL53LX_xtalkextract_config_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->dss_config__target_total_rate_mcps = + VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS_DEFAULT; + + pdata->mm_config_timeout_us = + VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US_DEFAULT; + + pdata->num_of_samples = + VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES_DEFAULT; + + pdata->phasecal_config_timeout_us = + VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US_DEFAULT; + + pdata->range_config_timeout_us = + VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US_DEFAULT; + + + + pdata->algo__crosstalk_extract_min_valid_range_mm = + VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM_DEFAULT; + pdata->algo__crosstalk_extract_max_valid_range_mm = + VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM_DEFAULT; + pdata->algo__crosstalk_extract_max_valid_rate_kcps = + VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS_DEFAULT; + pdata->algo__crosstalk_extract_max_sigma_mm = + VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM_DEFAULT; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_init_offset_cal_config_struct( + VL53LX_offsetcal_config_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->dss_config__target_total_rate_mcps = + VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS_DEFAULT; + + pdata->phasecal_config_timeout_us = + VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US_DEFAULT; + + pdata->range_config_timeout_us = + VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US_DEFAULT; + + pdata->mm_config_timeout_us = + VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US_DEFAULT; + + + pdata->pre_num_of_samples = + VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES_DEFAULT; + pdata->mm1_num_of_samples = + VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES_DEFAULT; + pdata->mm2_num_of_samples = + VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_init_zone_cal_config_struct( + VL53LX_zonecal_config_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->dss_config__target_total_rate_mcps = + VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS_DEFAULT; + + pdata->phasecal_config_timeout_us = + VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US_DEFAULT; + + pdata->range_config_timeout_us = + VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US_DEFAULT; + + pdata->mm_config_timeout_us = + VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US_DEFAULT; + + pdata->phasecal_num_of_samples = + VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES_DEFAULT; + pdata->zone_num_of_samples = + VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES_DEFAULT; + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_init_hist_post_process_config_struct( + uint8_t xtalk_compensation_enable, + VL53LX_hist_post_process_config_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->hist_algo_select = + VL53LX_TUNINGPARM_HIST_ALGO_SELECT_DEFAULT; + + + + pdata->hist_target_order = + VL53LX_TUNINGPARM_HIST_TARGET_ORDER_DEFAULT; + + + + pdata->filter_woi0 = + VL53LX_TUNINGPARM_HIST_FILTER_WOI_0_DEFAULT; + pdata->filter_woi1 = + VL53LX_TUNINGPARM_HIST_FILTER_WOI_1_DEFAULT; + + + pdata->hist_amb_est_method = + VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD_DEFAULT; + + pdata->ambient_thresh_sigma0 = + VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0_DEFAULT; + pdata->ambient_thresh_sigma1 = + VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1_DEFAULT; + + + pdata->ambient_thresh_events_scaler = + VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER_DEFAULT; + + + pdata->min_ambient_thresh_events = + VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS_DEFAULT; + + pdata->noise_threshold = + VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD_DEFAULT; + + pdata->signal_total_events_limit = + VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT_DEFAULT; + pdata->sigma_estimator__sigma_ref_mm = + VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM_DEFAULT; + + + pdata->sigma_thresh = + VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM_DEFAULT; + + pdata->range_offset_mm = 0; + + pdata->gain_factor = + VL53LX_TUNINGPARM_HIST_GAIN_FACTOR_DEFAULT; + + + + pdata->valid_phase_low = 0x08; + pdata->valid_phase_high = 0x88; + + + + pdata->algo__consistency_check__phase_tolerance = + VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE_DEFAULT; + + + + pdata->algo__consistency_check__event_sigma = + VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_DEFAULT; + + + pdata->algo__consistency_check__event_min_spad_count = + VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT_DEFAULT; + + + + pdata->algo__consistency_check__min_max_tolerance = + VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM_DEFAULT; + + + pdata->algo__crosstalk_compensation_enable = xtalk_compensation_enable; + + + pdata->algo__crosstalk_detect_min_valid_range_mm = + VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT; + pdata->algo__crosstalk_detect_max_valid_range_mm = + VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT; + pdata->algo__crosstalk_detect_max_valid_rate_kcps = + VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT; + pdata->algo__crosstalk_detect_max_sigma_mm = + VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM_DEFAULT; + + + + + + pdata->algo__crosstalk_detect_event_sigma = + VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA_DEFAULT; + + + + pdata->algo__crosstalk_detect_min_max_tolerance = + VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE_DEFAULT; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_init_dmax_calibration_data_struct( + VL53LX_dmax_calibration_data_t *pdata) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->ref__actual_effective_spads = 0x5F2D; + + pdata->ref__peak_signal_count_rate_mcps = 0x0844; + + pdata->ref__distance_mm = 0x08A5; + + + pdata->ref_reflectance_pc = 0x0014; + + pdata->coverglass_transmission = 0x0100; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_init_tuning_parm_storage_struct( + VL53LX_tuning_parm_storage_t *pdata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->tp_tuning_parm_version = + VL53LX_TUNINGPARM_VERSION_DEFAULT; + pdata->tp_tuning_parm_key_table_version = + VL53LX_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT; + pdata->tp_tuning_parm_lld_version = + VL53LX_TUNINGPARM_LLD_VERSION_DEFAULT; + pdata->tp_init_phase_rtn_lite_long = + VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_lite_med = + VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_lite_short = + VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE_DEFAULT; + pdata->tp_init_phase_ref_lite_long = + VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE_DEFAULT; + pdata->tp_init_phase_ref_lite_med = + VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE_DEFAULT; + pdata->tp_init_phase_ref_lite_short = + VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_hist_long = + VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_hist_med = + VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_hist_short = + VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE_DEFAULT; + pdata->tp_init_phase_ref_hist_long = + VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE_DEFAULT; + pdata->tp_init_phase_ref_hist_med = + VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE_DEFAULT; + pdata->tp_init_phase_ref_hist_short = + VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE_DEFAULT; + pdata->tp_consistency_lite_phase_tolerance = + VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE_DEFAULT; + pdata->tp_phasecal_target = + VL53LX_TUNINGPARM_PHASECAL_TARGET_DEFAULT; + pdata->tp_cal_repeat_rate = + VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE_DEFAULT; + pdata->tp_lite_min_clip = + VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM_DEFAULT; + pdata->tp_lite_long_sigma_thresh_mm = + VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM_DEFAULT; + pdata->tp_lite_med_sigma_thresh_mm = + VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM_DEFAULT; + pdata->tp_lite_short_sigma_thresh_mm = + VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM_DEFAULT; + pdata->tp_lite_long_min_count_rate_rtn_mcps = + VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS_DEFAULT; + pdata->tp_lite_med_min_count_rate_rtn_mcps = + VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS_DEFAULT; + pdata->tp_lite_short_min_count_rate_rtn_mcps = + VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS_DEFAULT; + pdata->tp_lite_sigma_est_pulse_width_ns = + VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH_DEFAULT; + pdata->tp_lite_sigma_est_amb_width_ns = + VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS_DEFAULT; + pdata->tp_lite_sigma_ref_mm = + VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM_DEFAULT; + pdata->tp_lite_seed_cfg = + VL53LX_TUNINGPARM_LITE_SEED_CONFIG_DEFAULT; + pdata->tp_timed_seed_cfg = + VL53LX_TUNINGPARM_TIMED_SEED_CONFIG_DEFAULT; + pdata->tp_lite_quantifier = + VL53LX_TUNINGPARM_LITE_QUANTIFIER_DEFAULT; + pdata->tp_lite_first_order_select = + VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT_DEFAULT; + + + + + pdata->tp_dss_target_lite_mcps = + VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT; + pdata->tp_dss_target_histo_mcps = + VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT; + pdata->tp_dss_target_histo_mz_mcps = + VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT; + pdata->tp_dss_target_timed_mcps = + VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT; + pdata->tp_phasecal_timeout_lite_us = + VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_hist_long_us = + VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_hist_med_us = + VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_hist_short_us = + VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_mz_long_us = + VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_mz_med_us = + VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_mz_short_us = + VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_timed_us = + VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_mm_timeout_lite_us = + VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_mm_timeout_histo_us = + VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_mm_timeout_mz_us = + VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_mm_timeout_timed_us = + VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_lite_us = + VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_histo_us = + VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_mz_us = + VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_timed_us = + VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US_DEFAULT; + + + + pdata->tp_mm_timeout_lpa_us = + VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_lpa_us = + VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US_DEFAULT; + + pdata->tp_dss_target_very_short_mcps = + VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS_DEFAULT; + + pdata->tp_phasecal_patch_power = + VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER_DEFAULT; + + pdata->tp_hist_merge = + VL53LX_TUNINGPARM_HIST_MERGE_DEFAULT; + + pdata->tp_reset_merge_threshold = + VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD_DEFAULT; + + pdata->tp_hist_merge_max_size = + VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_init_hist_gen3_dmax_config_struct( + VL53LX_hist_gen3_dmax_config_t *pdata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pdata->dss_config__target_total_rate_mcps = 0x1400; + pdata->dss_config__aperture_attenuation = 0x38; + + pdata->signal_thresh_sigma = + VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA_DEFAULT; + pdata->ambient_thresh_sigma = 0x70; + pdata->min_ambient_thresh_events = 16; + pdata->signal_total_events_limit = 100; + pdata->max_effective_spads = 0xFFFF; + + + + pdata->target_reflectance_for_dmax_calc[0] = + VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0_DEFAULT; + pdata->target_reflectance_for_dmax_calc[1] = + VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1_DEFAULT; + pdata->target_reflectance_for_dmax_calc[2] = + VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2_DEFAULT; + pdata->target_reflectance_for_dmax_calc[3] = + VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3_DEFAULT; + pdata->target_reflectance_for_dmax_calc[4] = + VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4_DEFAULT; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging( + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + pstatic->dss_config__target_total_rate_mcps = 0x0A00; + pstatic->debug__ctrl = 0x00; + pstatic->test_mode__ctrl = 0x00; + pstatic->clk_gating__ctrl = 0x00; + pstatic->nvm_bist__ctrl = 0x00; + pstatic->nvm_bist__num_nvm_words = 0x00; + pstatic->nvm_bist__start_address = 0x00; + pstatic->host_if__status = 0x00; + pstatic->pad_i2c_hv__config = 0x00; + pstatic->pad_i2c_hv__extsup_config = 0x00; + + + pstatic->gpio_hv_pad__ctrl = 0x00; + + + pstatic->gpio_hv_mux__ctrl = + VL53LX_DEVICEINTERRUPTPOLARITY_ACTIVE_LOW | + VL53LX_DEVICEGPIOMODE_OUTPUT_RANGE_AND_ERROR_INTERRUPTS; + + pstatic->gpio__tio_hv_status = 0x02; + pstatic->gpio__fio_hv_status = 0x00; + pstatic->ana_config__spad_sel_pswidth = 0x02; + pstatic->ana_config__vcsel_pulse_width_offset = 0x08; + pstatic->ana_config__fast_osc__config_ctrl = 0x00; + + pstatic->sigma_estimator__effective_pulse_width_ns = + ptuning_parms->tp_lite_sigma_est_pulse_width_ns; + pstatic->sigma_estimator__effective_ambient_width_ns = + ptuning_parms->tp_lite_sigma_est_amb_width_ns; + pstatic->sigma_estimator__sigma_ref_mm = + ptuning_parms->tp_lite_sigma_ref_mm; + + pstatic->algo__crosstalk_compensation_valid_height_mm = 0x01; + pstatic->spare_host_config__static_config_spare_0 = 0x00; + pstatic->spare_host_config__static_config_spare_1 = 0x00; + + pstatic->algo__range_ignore_threshold_mcps = 0x0000; + + + pstatic->algo__range_ignore_valid_height_mm = 0xff; + pstatic->algo__range_min_clip = + ptuning_parms->tp_lite_min_clip; + + pstatic->algo__consistency_check__tolerance = + ptuning_parms->tp_consistency_lite_phase_tolerance; + pstatic->spare_host_config__static_config_spare_2 = 0x00; + pstatic->sd_config__reset_stages_msb = 0x00; + pstatic->sd_config__reset_stages_lsb = 0x00; + + pgeneral->gph_config__stream_count_update_value = 0x00; + pgeneral->global_config__stream_divider = 0x00; + pgeneral->system__interrupt_config_gpio = + VL53LX_INTERRUPT_CONFIG_NEW_SAMPLE_READY; + pgeneral->cal_config__vcsel_start = 0x0B; + + + pgeneral->cal_config__repeat_rate = + ptuning_parms->tp_cal_repeat_rate; + pgeneral->global_config__vcsel_width = 0x02; + + pgeneral->phasecal_config__timeout_macrop = 0x0D; + + pgeneral->phasecal_config__target = + ptuning_parms->tp_phasecal_target; + pgeneral->phasecal_config__override = 0x00; + pgeneral->dss_config__roi_mode_control = + VL53LX_DEVICEDSSMODE__TARGET_RATE; + + pgeneral->system__thresh_rate_high = 0x0000; + pgeneral->system__thresh_rate_low = 0x0000; + + pgeneral->dss_config__manual_effective_spads_select = 0x8C00; + pgeneral->dss_config__manual_block_select = 0x00; + + + pgeneral->dss_config__aperture_attenuation = 0x38; + pgeneral->dss_config__max_spads_limit = 0xFF; + pgeneral->dss_config__min_spads_limit = 0x01; + + + + + ptiming->mm_config__timeout_macrop_a_hi = 0x00; + ptiming->mm_config__timeout_macrop_a_lo = 0x1a; + ptiming->mm_config__timeout_macrop_b_hi = 0x00; + ptiming->mm_config__timeout_macrop_b_lo = 0x20; + + ptiming->range_config__timeout_macrop_a_hi = 0x01; + ptiming->range_config__timeout_macrop_a_lo = 0xCC; + + ptiming->range_config__vcsel_period_a = 0x0B; + + ptiming->range_config__timeout_macrop_b_hi = 0x01; + ptiming->range_config__timeout_macrop_b_lo = 0xF5; + + ptiming->range_config__vcsel_period_b = 0x09; + + ptiming->range_config__sigma_thresh = + ptuning_parms->tp_lite_med_sigma_thresh_mm; + + ptiming->range_config__min_count_rate_rtn_limit_mcps = + ptuning_parms->tp_lite_med_min_count_rate_rtn_mcps; + + + ptiming->range_config__valid_phase_low = 0x08; + ptiming->range_config__valid_phase_high = 0x78; + ptiming->system__intermeasurement_period = 0x00000000; + ptiming->system__fractional_enable = 0x00; + + + + phistogram->histogram_config__low_amb_even_bin_0_1 = 0x07; + phistogram->histogram_config__low_amb_even_bin_2_3 = 0x21; + phistogram->histogram_config__low_amb_even_bin_4_5 = 0x43; + + phistogram->histogram_config__low_amb_odd_bin_0_1 = 0x10; + phistogram->histogram_config__low_amb_odd_bin_2_3 = 0x32; + phistogram->histogram_config__low_amb_odd_bin_4_5 = 0x54; + + phistogram->histogram_config__mid_amb_even_bin_0_1 = 0x07; + phistogram->histogram_config__mid_amb_even_bin_2_3 = 0x21; + phistogram->histogram_config__mid_amb_even_bin_4_5 = 0x43; + + phistogram->histogram_config__mid_amb_odd_bin_0_1 = 0x10; + phistogram->histogram_config__mid_amb_odd_bin_2 = 0x02; + phistogram->histogram_config__mid_amb_odd_bin_3_4 = 0x43; + phistogram->histogram_config__mid_amb_odd_bin_5 = 0x05; + + phistogram->histogram_config__user_bin_offset = 0x00; + + phistogram->histogram_config__high_amb_even_bin_0_1 = 0x07; + phistogram->histogram_config__high_amb_even_bin_2_3 = 0x21; + phistogram->histogram_config__high_amb_even_bin_4_5 = 0x43; + + phistogram->histogram_config__high_amb_odd_bin_0_1 = 0x10; + phistogram->histogram_config__high_amb_odd_bin_2_3 = 0x32; + phistogram->histogram_config__high_amb_odd_bin_4_5 = 0x54; + + phistogram->histogram_config__amb_thresh_low = 0xFFFF; + phistogram->histogram_config__amb_thresh_high = 0xFFFF; + + phistogram->histogram_config__spad_array_selection = 0x00; + + + pzone_cfg->max_zones = VL53LX_MAX_USER_ZONES; + pzone_cfg->active_zones = 0x00; + pzone_cfg->user_zones[0].height = 0x0f; + pzone_cfg->user_zones[0].width = 0x0f; + pzone_cfg->user_zones[0].x_centre = 0x08; + pzone_cfg->user_zones[0].y_centre = 0x08; + + + + pdynamic->system__grouped_parameter_hold_0 = 0x01; + + pdynamic->system__thresh_high = 0x0000; + pdynamic->system__thresh_low = 0x0000; + pdynamic->system__enable_xtalk_per_quadrant = 0x00; + pdynamic->system__seed_config = + ptuning_parms->tp_lite_seed_cfg; + + + pdynamic->sd_config__woi_sd0 = 0x0B; + + pdynamic->sd_config__woi_sd1 = 0x09; + + pdynamic->sd_config__initial_phase_sd0 = + ptuning_parms->tp_init_phase_rtn_lite_med; + pdynamic->sd_config__initial_phase_sd1 = + ptuning_parms->tp_init_phase_ref_lite_med; + + pdynamic->system__grouped_parameter_hold_1 = 0x01; + + + + pdynamic->sd_config__first_order_select = + ptuning_parms->tp_lite_first_order_select; + pdynamic->sd_config__quantifier = + ptuning_parms->tp_lite_quantifier; + + + pdynamic->roi_config__user_roi_centre_spad = 0xC7; + + pdynamic->roi_config__user_roi_requested_global_xy_size = 0xFF; + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM2_EN | + VL53LX_SEQUENCE_RANGE_EN; + + pdynamic->system__grouped_parameter_hold = 0x02; + + + + + psystem->system__stream_count_ctrl = 0x00; + psystem->firmware__enable = 0x01; + psystem->system__interrupt_clear = + VL53LX_CLEAR_RANGE_INT; + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_STREAMING | + VL53LX_DEVICEREADOUTMODE_SINGLE_SD | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging_short_range( + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + ptiming->range_config__vcsel_period_a = 0x07; + ptiming->range_config__vcsel_period_b = 0x05; + ptiming->range_config__sigma_thresh = + ptuning_parms->tp_lite_short_sigma_thresh_mm; + ptiming->range_config__min_count_rate_rtn_limit_mcps = + ptuning_parms->tp_lite_short_min_count_rate_rtn_mcps; + ptiming->range_config__valid_phase_low = 0x08; + ptiming->range_config__valid_phase_high = 0x38; + + + + pdynamic->sd_config__woi_sd0 = 0x07; + pdynamic->sd_config__woi_sd1 = 0x05; + pdynamic->sd_config__initial_phase_sd0 = + ptuning_parms->tp_init_phase_rtn_lite_short; + pdynamic->sd_config__initial_phase_sd1 = + ptuning_parms->tp_init_phase_ref_lite_short; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging_long_range( + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + ptiming->range_config__vcsel_period_a = 0x0F; + ptiming->range_config__vcsel_period_b = 0x0D; + ptiming->range_config__sigma_thresh = + ptuning_parms->tp_lite_long_sigma_thresh_mm; + ptiming->range_config__min_count_rate_rtn_limit_mcps = + ptuning_parms->tp_lite_long_min_count_rate_rtn_mcps; + ptiming->range_config__valid_phase_low = 0x08; + ptiming->range_config__valid_phase_high = 0xB8; + + + + pdynamic->sd_config__woi_sd0 = 0x0F; + pdynamic->sd_config__woi_sd1 = 0x0D; + pdynamic->sd_config__initial_phase_sd0 = + ptuning_parms->tp_init_phase_rtn_lite_long; + pdynamic->sd_config__initial_phase_sd1 = + ptuning_parms->tp_init_phase_ref_lite_long; + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging_mm1_cal( + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + pgeneral->dss_config__roi_mode_control = + VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS; + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM1_EN; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_standard_ranging_mm2_cal( + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + + status = VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + pgeneral->dss_config__roi_mode_control = + VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS; + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM2_EN; + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_timed_ranging( + + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + pdynamic->system__grouped_parameter_hold = 0x00; + + + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0xB1; + + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0xD4; + + + + ptiming->system__intermeasurement_period = 0x00000600; + pdynamic->system__seed_config = + ptuning_parms->tp_timed_seed_cfg; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO | + VL53LX_DEVICEREADOUTMODE_SINGLE_SD | + VL53LX_DEVICEMEASUREMENTMODE_TIMED; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_timed_ranging_short_range( + + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + status = VL53LX_preset_mode_standard_ranging_short_range( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + pdynamic->system__grouped_parameter_hold = 0x00; + + + + + + ptiming->range_config__timeout_macrop_a_hi = 0x01; + ptiming->range_config__timeout_macrop_a_lo = 0x84; + + ptiming->range_config__timeout_macrop_b_hi = 0x01; + ptiming->range_config__timeout_macrop_b_lo = 0xB1; + + ptiming->system__intermeasurement_period = 0x00000600; + pdynamic->system__seed_config = + ptuning_parms->tp_timed_seed_cfg; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO | + VL53LX_DEVICEREADOUTMODE_SINGLE_SD | + VL53LX_DEVICEMEASUREMENTMODE_TIMED; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_timed_ranging_long_range( + + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + status = VL53LX_preset_mode_standard_ranging_long_range( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + pdynamic->system__grouped_parameter_hold = 0x00; + + + + + + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0x97; + + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0xB1; + + ptiming->system__intermeasurement_period = 0x00000600; + pdynamic->system__seed_config = + ptuning_parms->tp_timed_seed_cfg; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO | + VL53LX_DEVICEREADOUTMODE_SINGLE_SD | + VL53LX_DEVICEMEASUREMENTMODE_TIMED; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_low_power_auto_ranging( + + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg, + VL53LX_low_power_auto_data_t *plpadata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_timed_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_config_low_power_auto_mode( + pgeneral, + pdynamic, + plpadata + ); + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_preset_mode_low_power_auto_short_ranging( + + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg, + VL53LX_low_power_auto_data_t *plpadata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_timed_ranging_short_range( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_config_low_power_auto_mode( + pgeneral, + pdynamic, + plpadata + ); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_low_power_auto_long_ranging( + + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg, + VL53LX_low_power_auto_data_t *plpadata) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_timed_ranging_long_range( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_config_low_power_auto_mode( + pgeneral, + pdynamic, + plpadata + ); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_singleshot_ranging( + + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + pdynamic->system__grouped_parameter_hold = 0x00; + + + + + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0xB1; + + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0xD4; + + pdynamic->system__seed_config = + ptuning_parms->tp_timed_seed_cfg; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO | + VL53LX_DEVICEREADOUTMODE_SINGLE_SD | + VL53LX_DEVICEMEASUREMENTMODE_SINGLESHOT; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + pstatic->dss_config__target_total_rate_mcps = 0x1400; + + + + VL53LX_init_histogram_config_structure( + 7, 0, 1, 2, 3, 4, + 0, 1, 2, 3, 4, 5, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 0, 1, 2, 3, 4, + 0, 1, 2, 3, 4, 5, + &(pzone_cfg->multizone_hist_cfg)); + + + + + ptiming->range_config__vcsel_period_a = 0x09; + ptiming->range_config__vcsel_period_b = 0x0B; + pdynamic->sd_config__woi_sd0 = 0x09; + pdynamic->sd_config__woi_sd1 = 0x0B; + + + + + ptiming->mm_config__timeout_macrop_a_hi = 0x00; + ptiming->mm_config__timeout_macrop_a_lo = 0x20; + ptiming->mm_config__timeout_macrop_b_hi = 0x00; + ptiming->mm_config__timeout_macrop_b_lo = 0x1A; + + + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0x28; + + + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0x21; + + + pgeneral->phasecal_config__timeout_macrop = 0xF5; + + + + phistpostprocess->valid_phase_low = 0x08; + phistpostprocess->valid_phase_high = 0x88; + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + + + VL53LX_SEQUENCE_RANGE_EN; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | + VL53LX_DEVICEREADOUTMODE_DUAL_SD | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_with_mm1( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + VL53LX_init_histogram_config_structure( + 7, 0, 1, 2, 3, 4, + 8 + 0, 8 + 1, 8 + 2, 3, 4, 5, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 0, 1, 2, 3, 4, + 8 + 0, 8 + 1, 8 + 2, 3, 4, 5, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM1_EN | + VL53LX_SEQUENCE_RANGE_EN; + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | + VL53LX_DEVICEREADOUTMODE_DUAL_SD | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_with_mm2( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging_with_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM2_EN | + VL53LX_SEQUENCE_RANGE_EN; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_mm1_cal( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + VL53LX_init_histogram_config_structure( + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, + 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, 8 + 5, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, + 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, 8 + 5, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + pgeneral->dss_config__roi_mode_control = + VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS; + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM1_EN | + VL53LX_SEQUENCE_RANGE_EN; + + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_mm2_cal( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging_mm1_cal( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + if (status == VL53LX_ERROR_NONE) { + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM2_EN | + VL53LX_SEQUENCE_RANGE_EN; + + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_short_timing( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + pstatic->dss_config__target_total_rate_mcps = 0x1400; + + + + VL53LX_init_histogram_config_structure( + 7, 0, 1, 2, 3, 4, + 7, 0, 1, 2, 3, 4, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 0, 1, 2, 3, 4, + 7, 0, 1, 2, 3, 4, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + ptiming->range_config__vcsel_period_a = 0x04; + ptiming->range_config__vcsel_period_b = 0x03; + ptiming->mm_config__timeout_macrop_a_hi = 0x00; + ptiming->mm_config__timeout_macrop_a_lo = 0x42; + ptiming->mm_config__timeout_macrop_b_hi = 0x00; + ptiming->mm_config__timeout_macrop_b_lo = 0x42; + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0x52; + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0x66; + + pgeneral->cal_config__vcsel_start = 0x04; + + + + pgeneral->phasecal_config__timeout_macrop = 0xa4; + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + + + VL53LX_SEQUENCE_RANGE_EN; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | + VL53LX_DEVICEREADOUTMODE_DUAL_SD | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_long_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + + VL53LX_init_histogram_config_structure( + 7, 0, 1, 2, 3, 4, + 0, 1, 2, 3, 4, 5, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 0, 1, 2, 3, 4, + 0, 1, 2, 3, 4, 5, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + ptiming->range_config__vcsel_period_a = 0x09; + ptiming->range_config__vcsel_period_b = 0x0b; + + + + ptiming->mm_config__timeout_macrop_a_hi = 0x00; + ptiming->mm_config__timeout_macrop_a_lo = 0x21; + ptiming->mm_config__timeout_macrop_b_hi = 0x00; + ptiming->mm_config__timeout_macrop_b_lo = 0x1b; + + + + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0x29; + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0x22; + + + + pgeneral->cal_config__vcsel_start = 0x09; + + + + pgeneral->phasecal_config__timeout_macrop = 0xF5; + + + + pdynamic->sd_config__woi_sd0 = 0x09; + pdynamic->sd_config__woi_sd1 = 0x0B; + pdynamic->sd_config__initial_phase_sd0 = + ptuning_parms->tp_init_phase_rtn_hist_long; + pdynamic->sd_config__initial_phase_sd1 = + ptuning_parms->tp_init_phase_ref_hist_long; + + + + phistpostprocess->valid_phase_low = 0x08; + phistpostprocess->valid_phase_high = 0x88; + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_RANGE_EN; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | + VL53LX_DEVICEREADOUTMODE_DUAL_SD | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_long_range_mm1( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_long_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + + VL53LX_init_histogram_config_structure( + 7, 0, 1, 2, 3, 4, + 8 + 0, 8 + 1, 8 + 2, 3, 4, 5, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 0, 1, 2, 3, 4, + 8 + 0, 8 + 1, 8 + 2, 3, 4, 5, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM1_EN | + VL53LX_SEQUENCE_RANGE_EN; + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_long_range_mm2( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + status = + VL53LX_preset_mode_histogram_long_range_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM2_EN | + VL53LX_SEQUENCE_RANGE_EN; + } + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_medium_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + + VL53LX_init_histogram_config_structure( + 7, 0, 1, 1, 2, 2, + 0, 1, 2, 1, 2, 3, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 0, 1, 1, 2, 2, + 0, 1, 2, 1, 2, 3, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + ptiming->range_config__vcsel_period_a = 0x05; + ptiming->range_config__vcsel_period_b = 0x07; + + + + ptiming->mm_config__timeout_macrop_a_hi = 0x00; + ptiming->mm_config__timeout_macrop_a_lo = 0x36; + ptiming->mm_config__timeout_macrop_b_hi = 0x00; + ptiming->mm_config__timeout_macrop_b_lo = 0x28; + + + + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0x44; + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0x33; + + + + pgeneral->cal_config__vcsel_start = 0x05; + + + + pgeneral->phasecal_config__timeout_macrop = 0xF5; + + + + pdynamic->sd_config__woi_sd0 = 0x05; + pdynamic->sd_config__woi_sd1 = 0x07; + pdynamic->sd_config__initial_phase_sd0 = + ptuning_parms->tp_init_phase_rtn_hist_med; + pdynamic->sd_config__initial_phase_sd1 = + ptuning_parms->tp_init_phase_ref_hist_med; + + + + phistpostprocess->valid_phase_low = 0x08; + phistpostprocess->valid_phase_high = 0x48; + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_RANGE_EN; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | + VL53LX_DEVICEREADOUTMODE_DUAL_SD | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_medium_range_mm1( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_medium_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + VL53LX_init_histogram_config_structure( + 7, 0, 1, 1, 2, 2, + 8 + 0, 8 + 1, 8 + 2, 1, 2, 3, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 0, 1, 1, 2, 2, + 8 + 0, 8 + 1, 8 + 2, 1, 2, 3, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM1_EN | + VL53LX_SEQUENCE_RANGE_EN; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_medium_range_mm2( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_medium_range_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM2_EN | + VL53LX_SEQUENCE_RANGE_EN; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_short_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + + VL53LX_init_histogram_config_structure( + 7, 7, 0, 1, 1, 1, + 0, 1, 1, 1, 2, 2, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 7, 0, 1, 1, 1, + 0, 1, 1, 1, 2, 2, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + ptiming->range_config__vcsel_period_a = 0x03; + ptiming->range_config__vcsel_period_b = 0x05; + + + + ptiming->mm_config__timeout_macrop_a_hi = 0x00; + ptiming->mm_config__timeout_macrop_a_lo = 0x52; + ptiming->mm_config__timeout_macrop_b_hi = 0x00; + ptiming->mm_config__timeout_macrop_b_lo = 0x37; + + + + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0x66; + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0x44; + + + + pgeneral->cal_config__vcsel_start = 0x03; + + + + pgeneral->phasecal_config__timeout_macrop = 0xF5; + + + + pdynamic->sd_config__woi_sd0 = 0x03; + pdynamic->sd_config__woi_sd1 = 0x05; + pdynamic->sd_config__initial_phase_sd0 = + ptuning_parms->tp_init_phase_rtn_hist_short; + pdynamic->sd_config__initial_phase_sd1 = + ptuning_parms->tp_init_phase_ref_hist_short; + + + phistpostprocess->valid_phase_low = 0x08; + phistpostprocess->valid_phase_high = 0x28; + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM1_EN | + + VL53LX_SEQUENCE_RANGE_EN; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | + VL53LX_DEVICEREADOUTMODE_DUAL_SD | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_preset_mode_special_histogram_short_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + status = + VL53LX_preset_mode_histogram_short_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + + VL53LX_init_histogram_config_structure( + 7, 7, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 1, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 7, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 1, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + ptiming->range_config__vcsel_period_a = 0x02; + ptiming->range_config__vcsel_period_b = 0x03; + + + + pgeneral->cal_config__vcsel_start = 0x00; + + + + pgeneral->phasecal_config__target = 0x31; + + + + pdynamic->sd_config__woi_sd0 = 0x02; + pdynamic->sd_config__woi_sd1 = 0x03; + pdynamic->sd_config__initial_phase_sd0 = + ptuning_parms->tp_init_phase_rtn_hist_short; + pdynamic->sd_config__initial_phase_sd1 = + ptuning_parms->tp_init_phase_ref_hist_short; + + + + phistpostprocess->valid_phase_low = 0x10; + phistpostprocess->valid_phase_high = 0x18; + + } + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_short_range_mm1( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_short_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + + + VL53LX_init_histogram_config_structure( + 7, 7, 0, 1, 1, 1, + 8 + 0, 8 + 1, 1, 1, 2, 2, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 7, 7, 0, 1, 1, 1, + 8 + 0, 8 + 1, 1, 1, 2, 2, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM1_EN | + VL53LX_SEQUENCE_RANGE_EN; + + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_short_range_mm2( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_short_range_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM2_EN | + VL53LX_SEQUENCE_RANGE_EN; + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_characterisation( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + pstatic->debug__ctrl = 0x01; + psystem->power_management__go1_power_force = 0x01; + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_RANGE_EN; + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | + VL53LX_DEVICEREADOUTMODE_SPLIT_MANUAL | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_xtalk_planar( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + status = + VL53LX_preset_mode_histogram_multizone_long_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + status = + VL53LX_zone_preset_xtalk_planar( + pgeneral, + pzone_cfg); + + + + ptiming->range_config__vcsel_period_a = 0x09; + ptiming->range_config__vcsel_period_b = 0x09; + + + + VL53LX_init_histogram_config_structure( + 7, 0, 1, 2, 3, 4, + 7, 0, 1, 2, 3, 4, + phistogram); + + + + VL53LX_init_histogram_multizone_config_structure( + 7, 0, 1, 2, 3, 4, + 7, 0, 1, 2, 3, 4, + &(pzone_cfg->multizone_hist_cfg)); + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_set_histogram_multizone_initial_bin_config( + pzone_cfg, + phistogram, + &(pzone_cfg->multizone_hist_cfg)); + } + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_xtalk_mm1( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + + if (status == VL53LX_ERROR_NONE) { + + + + + + VL53LX_init_histogram_config_structure( + 8 + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, + 8 + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, + phistogram); + + + VL53LX_init_histogram_multizone_config_structure( + 8 + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, + 8 + 7, 8 + 0, 8 + 1, 8 + 2, 8 + 3, 8 + 4, + &(pzone_cfg->multizone_hist_cfg)); + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + + + + ptiming->range_config__vcsel_period_a = 0x09; + ptiming->range_config__vcsel_period_b = 0x09; + + + + ptiming->mm_config__timeout_macrop_a_hi = 0x00; + ptiming->mm_config__timeout_macrop_a_lo = 0x21; + ptiming->mm_config__timeout_macrop_b_hi = 0x00; + ptiming->mm_config__timeout_macrop_b_lo = 0x21; + + + + ptiming->range_config__timeout_macrop_a_hi = 0x00; + ptiming->range_config__timeout_macrop_a_lo = 0x29; + ptiming->range_config__timeout_macrop_b_hi = 0x00; + ptiming->range_config__timeout_macrop_b_lo = 0x29; + + + + pgeneral->cal_config__vcsel_start = 0x09; + + + + pgeneral->phasecal_config__timeout_macrop = 0xF5; + + + + pdynamic->sd_config__woi_sd0 = 0x09; + pdynamic->sd_config__woi_sd1 = 0x09; + pdynamic->sd_config__initial_phase_sd0 = 0x09; + pdynamic->sd_config__initial_phase_sd1 = 0x06; + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM1_EN | + VL53LX_SEQUENCE_RANGE_EN; + + + + + psystem->system__mode_start = + VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | + VL53LX_DEVICEREADOUTMODE_DUAL_SD | + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + + return status; +} +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_xtalk_mm2( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_xtalk_mm1( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + pdynamic->system__sequence_config = + VL53LX_SEQUENCE_VHV_EN | + VL53LX_SEQUENCE_PHASECAL_EN | + VL53LX_SEQUENCE_DSS1_EN | + VL53LX_SEQUENCE_DSS2_EN | + VL53LX_SEQUENCE_MM2_EN | + VL53LX_SEQUENCE_RANGE_EN; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_multizone( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_medium_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + status = + VL53LX_init_zone_config_structure( + 4, 8, 2, + 4, 8, 2, + 7, 7, + pzone_cfg); + + pgeneral->global_config__stream_divider = + pzone_cfg->active_zones + 1; + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_set_histogram_multizone_initial_bin_config( + pzone_cfg, + phistogram, + &(pzone_cfg->multizone_hist_cfg)); + } + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_multizone_short_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_short_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + status = + VL53LX_init_zone_config_structure( + 4, 8, 2, + 4, 8, 2, + 7, 7, + pzone_cfg); + + pgeneral->global_config__stream_divider = + pzone_cfg->active_zones + 1; + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_set_histogram_multizone_initial_bin_config( + pzone_cfg, + phistogram, + &(pzone_cfg->multizone_hist_cfg) + ); + } + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_multizone_long_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_long_range( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + + + status = + VL53LX_init_zone_config_structure( + 4, 8, 2, + 4, 8, 2, + 7, 7, + pzone_cfg); + + pgeneral->global_config__stream_divider = + pzone_cfg->active_zones + 1; + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_set_histogram_multizone_initial_bin_config( + pzone_cfg, + phistogram, + &(pzone_cfg->multizone_hist_cfg)); + } + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_olt( + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = VL53LX_preset_mode_standard_ranging( + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) + + { + psystem->system__stream_count_ctrl = 0x01; + } + + + return status; +} + +void VL53LX::VL53LX_copy_hist_cfg_to_static_cfg( + VL53LX_histogram_config_t *phistogram, + VL53LX_static_config_t *pstatic, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic) +{ + + SUPPRESS_UNUSED_WARNING(pgeneral); + + pstatic->sigma_estimator__effective_pulse_width_ns = + phistogram->histogram_config__high_amb_even_bin_0_1; + pstatic->sigma_estimator__effective_ambient_width_ns = + phistogram->histogram_config__high_amb_even_bin_2_3; + pstatic->sigma_estimator__sigma_ref_mm = + phistogram->histogram_config__high_amb_even_bin_4_5; + + pstatic->algo__crosstalk_compensation_valid_height_mm = + phistogram->histogram_config__high_amb_odd_bin_0_1; + + pstatic->spare_host_config__static_config_spare_0 = + phistogram->histogram_config__high_amb_odd_bin_2_3; + pstatic->spare_host_config__static_config_spare_1 = + phistogram->histogram_config__high_amb_odd_bin_4_5; + + pstatic->algo__range_ignore_threshold_mcps = + (((uint16_t)phistogram->histogram_config__mid_amb_even_bin_0_1) + << 8) + + (uint16_t)phistogram->histogram_config__mid_amb_even_bin_2_3; + + pstatic->algo__range_ignore_valid_height_mm = + phistogram->histogram_config__mid_amb_even_bin_4_5; + pstatic->algo__range_min_clip = + phistogram->histogram_config__mid_amb_odd_bin_0_1; + pstatic->algo__consistency_check__tolerance = + phistogram->histogram_config__mid_amb_odd_bin_2; + + pstatic->spare_host_config__static_config_spare_2 = + phistogram->histogram_config__mid_amb_odd_bin_3_4; + pstatic->sd_config__reset_stages_msb = + phistogram->histogram_config__mid_amb_odd_bin_5; + + pstatic->sd_config__reset_stages_lsb = + phistogram->histogram_config__user_bin_offset; + + ptiming->range_config__sigma_thresh = + (((uint16_t)phistogram->histogram_config__low_amb_even_bin_0_1) + << 8) + + (uint16_t)phistogram->histogram_config__low_amb_even_bin_2_3; + + ptiming->range_config__min_count_rate_rtn_limit_mcps = + (((uint16_t)phistogram->histogram_config__low_amb_even_bin_4_5) + << 8) + + (uint16_t)phistogram->histogram_config__low_amb_odd_bin_0_1; + + ptiming->range_config__valid_phase_low = + phistogram->histogram_config__low_amb_odd_bin_2_3; + ptiming->range_config__valid_phase_high = + phistogram->histogram_config__low_amb_odd_bin_4_5; + + pdynamic->system__thresh_high = + phistogram->histogram_config__amb_thresh_low; + + pdynamic->system__thresh_low = + phistogram->histogram_config__amb_thresh_high; + + pdynamic->system__enable_xtalk_per_quadrant = + phistogram->histogram_config__spad_array_selection; + + +} + +void VL53LX::VL53LX_copy_hist_bins_to_static_cfg( + VL53LX_histogram_config_t *phistogram, + VL53LX_static_config_t *pstatic, + VL53LX_timing_config_t *ptiming) +{ + + pstatic->sigma_estimator__effective_pulse_width_ns = + phistogram->histogram_config__high_amb_even_bin_0_1; + pstatic->sigma_estimator__effective_ambient_width_ns = + phistogram->histogram_config__high_amb_even_bin_2_3; + pstatic->sigma_estimator__sigma_ref_mm = + phistogram->histogram_config__high_amb_even_bin_4_5; + + pstatic->algo__crosstalk_compensation_valid_height_mm = + phistogram->histogram_config__high_amb_odd_bin_0_1; + + pstatic->spare_host_config__static_config_spare_0 = + phistogram->histogram_config__high_amb_odd_bin_2_3; + pstatic->spare_host_config__static_config_spare_1 = + phistogram->histogram_config__high_amb_odd_bin_4_5; + + pstatic->algo__range_ignore_threshold_mcps = + (((uint16_t)phistogram->histogram_config__mid_amb_even_bin_0_1) + << 8) + + (uint16_t)phistogram->histogram_config__mid_amb_even_bin_2_3; + + pstatic->algo__range_ignore_valid_height_mm = + phistogram->histogram_config__mid_amb_even_bin_4_5; + pstatic->algo__range_min_clip = + phistogram->histogram_config__mid_amb_odd_bin_0_1; + pstatic->algo__consistency_check__tolerance = + phistogram->histogram_config__mid_amb_odd_bin_2; + + pstatic->spare_host_config__static_config_spare_2 = + phistogram->histogram_config__mid_amb_odd_bin_3_4; + pstatic->sd_config__reset_stages_msb = + phistogram->histogram_config__mid_amb_odd_bin_5; + + ptiming->range_config__sigma_thresh = + (((uint16_t)phistogram->histogram_config__low_amb_even_bin_0_1) + << 8) + + (uint16_t)phistogram->histogram_config__low_amb_even_bin_2_3; + + ptiming->range_config__min_count_rate_rtn_limit_mcps = + (((uint16_t)phistogram->histogram_config__low_amb_even_bin_4_5) + << 8) + + (uint16_t)phistogram->histogram_config__low_amb_odd_bin_0_1; + + ptiming->range_config__valid_phase_low = + phistogram->histogram_config__low_amb_odd_bin_2_3; + ptiming->range_config__valid_phase_high = + phistogram->histogram_config__low_amb_odd_bin_4_5; + + +} + +VL53LX_Error VL53LX::VL53LX_preset_mode_histogram_ranging_ref( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_preset_mode_histogram_ranging( + phistpostprocess, + pstatic, + phistogram, + pgeneral, + ptiming, + pdynamic, + psystem, + ptuning_parms, + pzone_cfg); + + + + if (status == VL53LX_ERROR_NONE) { + + phistogram->histogram_config__spad_array_selection = 0x01; + + + + VL53LX_copy_hist_cfg_to_static_cfg( + phistogram, + pstatic, + pgeneral, + ptiming, + pdynamic); + } + + return status; +} + +/* vl53lx_silicon_core.c */ + +VL53LX_Error VL53LX::VL53LX_is_firmware_ready_silicon( + uint8_t *pready) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t comms_buffer[5]; + + status = VL53LX_ReadMulti( + Dev, + VL53LX_INTERRUPT_MANAGER__ENABLES, + comms_buffer, + 5); + + if (status != VL53LX_ERROR_NONE) { + goto ENDFUNC; + } + + pdev->dbg_results.interrupt_manager__enables = + comms_buffer[0]; + pdev->dbg_results.interrupt_manager__clear = + comms_buffer[1]; + pdev->dbg_results.interrupt_manager__status = + comms_buffer[2]; + pdev->dbg_results.mcu_to_host_bank__wr_access_en = + comms_buffer[3]; + pdev->dbg_results.power_management__go1_reset_status = + comms_buffer[4]; + + if ((pdev->sys_ctrl.power_management__go1_power_force & 0x01) + == 0x01) { + + if (((pdev->dbg_results.interrupt_manager__enables & + 0x1F) == 0x1F) && + ((pdev->dbg_results.interrupt_manager__clear + & 0x1F) == 0x1F)) { + *pready = 0x01; + } else { + *pready = 0x00; + } + + } else { + + + if ((pdev->dbg_results.power_management__go1_reset_status + & 0x01) == 0x00) { + *pready = 0x01; + } else { + *pready = 0x00; + } + } +ENDFUNC: + return status; +} + +/* vl53lx_hist_core.c */ +void VL53LX::VL53LX_f_022( + uint8_t VL53LX_p_032, + uint8_t filter_woi, + VL53LX_histogram_bin_data_t *pbins, + int32_t *pa, + int32_t *pb, + int32_t *pc) +{ + + + uint8_t w = 0; + uint8_t j = 0; + + *pa = 0; + *pb = pbins->bin_data[VL53LX_p_032]; + *pc = 0; + + for (w = 0 ; w < ((filter_woi << 1) + 1) ; w++) { + + + j = ((VL53LX_p_032 + w + pbins->VL53LX_p_021) - + filter_woi) % pbins->VL53LX_p_021; + + if (w < filter_woi) { + *pa += pbins->bin_data[j]; + } else if (w > filter_woi) { + *pc += pbins->bin_data[j]; + } + } +} + + +VL53LX_Error VL53LX::VL53LX_f_018( + uint16_t vcsel_width, + uint16_t fast_osc_frequency, + uint32_t total_periods_elapsed, + uint16_t VL53LX_p_004, + VL53LX_range_data_t *pdata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint32_t pll_period_us = 0; + uint32_t periods_elapsed = 0; + uint32_t count_rate_total = 0; + + + pdata->width = vcsel_width; + pdata->fast_osc_frequency = fast_osc_frequency; + pdata->total_periods_elapsed = total_periods_elapsed; + pdata->VL53LX_p_004 = VL53LX_p_004; + + + + + if (pdata->fast_osc_frequency == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } + + if (pdata->total_periods_elapsed == 0) { + status = VL53LX_ERROR_DIVISION_BY_ZERO; + } + + if (status == VL53LX_ERROR_NONE) { + + + + + pll_period_us = + VL53LX_calc_pll_period_us(pdata->fast_osc_frequency); + + periods_elapsed = pdata->total_periods_elapsed + 1; + + pdata->peak_duration_us = VL53LX_duration_maths( + pll_period_us, + (uint32_t)pdata->width, + VL53LX_RANGING_WINDOW_VCSEL_PERIODS, + periods_elapsed); + + pdata->woi_duration_us = VL53LX_duration_maths( + pll_period_us, + ((uint32_t)pdata->VL53LX_p_029) << 4, + VL53LX_RANGING_WINDOW_VCSEL_PERIODS, + periods_elapsed); + + + + + pdata->peak_signal_count_rate_mcps = VL53LX_rate_maths( + (int32_t)pdata->VL53LX_p_010, + pdata->peak_duration_us); + + pdata->avg_signal_count_rate_mcps = VL53LX_rate_maths( + (int32_t)pdata->VL53LX_p_010, + pdata->woi_duration_us); + + pdata->ambient_count_rate_mcps = VL53LX_rate_maths( + (int32_t)pdata->VL53LX_p_016, + pdata->woi_duration_us); + + + + + count_rate_total = + (uint32_t)pdata->peak_signal_count_rate_mcps + + (uint32_t)pdata->ambient_count_rate_mcps; + + pdata->total_rate_per_spad_mcps = + VL53LX_rate_per_spad_maths( + 0x06, + count_rate_total, + pdata->VL53LX_p_004, + 0xFFFF); + + + + + pdata->VL53LX_p_009 = + VL53LX_events_per_spad_maths( + pdata->VL53LX_p_010, + pdata->VL53LX_p_004, + pdata->peak_duration_us); + + + + } + + return status; +} + + +void VL53LX::VL53LX_f_019( + uint16_t gain_factor, + int16_t range_offset_mm, + VL53LX_range_data_t *pdata) +{ + + pdata->min_range_mm = + (int16_t)VL53LX_range_maths( + pdata->fast_osc_frequency, + pdata->VL53LX_p_026, + pdata->zero_distance_phase, + 0, + + (int32_t)gain_factor, + (int32_t)range_offset_mm); + + pdata->median_range_mm = + (int16_t)VL53LX_range_maths( + pdata->fast_osc_frequency, + pdata->VL53LX_p_011, + pdata->zero_distance_phase, + 0, + + (int32_t)gain_factor, + (int32_t)range_offset_mm); + + pdata->max_range_mm = + (int16_t)VL53LX_range_maths( + pdata->fast_osc_frequency, + pdata->VL53LX_p_027, + pdata->zero_distance_phase, + 0, + + (int32_t)gain_factor, + (int32_t)range_offset_mm); + +} + +void VL53LX::VL53LX_f_029( + VL53LX_histogram_bin_data_t *pdata, + int32_t ambient_estimate_counts_per_bin) +{ + uint8_t i = 0; + + for (i = 0 ; i < pdata->VL53LX_p_021 ; i++) + pdata->bin_data[i] = pdata->bin_data[i] - + ambient_estimate_counts_per_bin; +} + + + + +void VL53LX::VL53LX_f_005( + VL53LX_histogram_bin_data_t *pxtalk, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_histogram_bin_data_t *pxtalk_realigned) +{ + + + uint8_t i = 0; + uint8_t min_bins = 0; + int8_t bin_offset = 0; + int8_t bin_access = 0; + + + memcpy( + pxtalk_realigned, + pbins, + sizeof(VL53LX_histogram_bin_data_t)); + + for (i = 0 ; i < pxtalk_realigned->VL53LX_p_020 ; i++) { + pxtalk_realigned->bin_data[i] = 0; + } + + + bin_offset = VL53LX_f_030( + pbins, + pxtalk); + + + if (pxtalk->VL53LX_p_021 < pbins->VL53LX_p_021) { + min_bins = pxtalk->VL53LX_p_021; + } else { + min_bins = pbins->VL53LX_p_021; + } + + + for (i = 0 ; i < min_bins ; i++) { + + + + + if (bin_offset >= 0) + bin_access = ((int8_t)i + (int8_t)bin_offset) + % (int8_t)pbins->VL53LX_p_021; + else + bin_access = ((int8_t)pbins->VL53LX_p_021 + + ((int8_t)i + (int8_t)bin_offset)) + % (int8_t)pbins->VL53LX_p_021; + + if (pbins->bin_data[(uint8_t)bin_access] > + pxtalk->bin_data[i]) { + + pbins->bin_data[(uint8_t)bin_access] = + pbins->bin_data[(uint8_t)bin_access] + - pxtalk->bin_data[i]; + + } else { + pbins->bin_data[(uint8_t)bin_access] = 0; + } + + + pxtalk_realigned->bin_data[(uint8_t)bin_access] = + pxtalk->bin_data[i]; + + + } + + +} + + + + +int8_t VL53LX::VL53LX_f_030( + VL53LX_histogram_bin_data_t *pdata1, + VL53LX_histogram_bin_data_t *pdata2) +{ + + + int32_t phase_delta = 0; + int8_t bin_offset = 0; + uint32_t period = 0; + uint32_t remapped_phase = 0; + + period = 2048 * + (uint32_t)VL53LX_decode_vcsel_period(pdata1->VL53LX_p_005); + + remapped_phase = (uint32_t)pdata2->zero_distance_phase % period; + + + phase_delta = (int32_t)pdata1->zero_distance_phase + - (int32_t)remapped_phase; + + + if (phase_delta > 0) { + bin_offset = (int8_t)((phase_delta + 1024) / 2048); + } else { + bin_offset = (int8_t)((phase_delta - 1024) / 2048); + } + + + return bin_offset; +} + + +VL53LX_Error VL53LX::VL53LX_f_031( + VL53LX_histogram_bin_data_t *pidata, + VL53LX_histogram_bin_data_t *podata) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t bin_initial_index[VL53LX_MAX_BIN_SEQUENCE_CODE + 1]; + uint8_t bin_repeat_count[VL53LX_MAX_BIN_SEQUENCE_CODE + 1]; + + uint8_t bin_cfg = 0; + uint8_t bin_seq_length = 0; + int32_t repeat_count = 0; + + uint8_t VL53LX_p_032 = 0; + uint8_t lc = 0; + uint8_t i = 0; + + memcpy(podata, pidata, sizeof(VL53LX_histogram_bin_data_t)); + + podata->VL53LX_p_021 = 0; + + for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) { + podata->bin_seq[lc] = VL53LX_MAX_BIN_SEQUENCE_CODE + 1; + } + + for (lc = 0 ; lc < podata->VL53LX_p_020 ; lc++) { + podata->bin_data[lc] = 0; + } + + + + + for (lc = 0 ; lc <= VL53LX_MAX_BIN_SEQUENCE_CODE ; lc++) { + bin_initial_index[lc] = 0x00; + bin_repeat_count[lc] = 0x00; + } + + + + + + bin_seq_length = 0x00; + + for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) { + + bin_cfg = pidata->bin_seq[lc]; + + + if (bin_repeat_count[bin_cfg] == 0) { + bin_initial_index[bin_cfg] = bin_seq_length * 4; + podata->bin_seq[bin_seq_length] = bin_cfg; + bin_seq_length++; + } + + bin_repeat_count[bin_cfg]++; + + + VL53LX_p_032 = bin_initial_index[bin_cfg]; + + for (i = 0 ; i < 4 ; i++) + podata->bin_data[VL53LX_p_032 + i] += + pidata->bin_data[lc * 4 + i]; + + } + + + + + for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) { + + bin_cfg = podata->bin_seq[lc]; + + if (bin_cfg <= VL53LX_MAX_BIN_SEQUENCE_CODE) + podata->bin_rep[lc] = + bin_repeat_count[bin_cfg]; + else { + podata->bin_rep[lc] = 0; + } + } + + podata->VL53LX_p_021 = bin_seq_length * 4; + + + for (lc = 0 ; lc <= VL53LX_MAX_BIN_SEQUENCE_CODE ; lc++) { + + repeat_count = (int32_t)bin_repeat_count[lc]; + + if (repeat_count > 0) { + + VL53LX_p_032 = bin_initial_index[lc]; + + for (i = 0 ; i < 4 ; i++) { + podata->bin_data[VL53LX_p_032 + i] += + (repeat_count / 2); + podata->bin_data[VL53LX_p_032 + i] /= + repeat_count; + } + } + } + + podata->number_of_ambient_bins = 0; + if ((bin_repeat_count[7] > 0) || + (bin_repeat_count[15] > 0)) { + podata->number_of_ambient_bins = 4; + } + + return status; +} + + +/* vl53lx_xtalk.c */ + + +VL53LX_Error VL53LX::VL53LX_xtalk_calibration_process_data( + VL53LX_xtalk_range_results_t *pxtalk_results, + VL53LX_xtalk_histogram_data_t *pxtalk_shape, + VL53LX_xtalk_calibration_results_t *pxtalk_cal) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_xtalk_algo_data_t xtalk_debug; + VL53LX_xtalk_algo_data_t *pdebug = &xtalk_debug; + VL53LX_xtalk_range_data_t *pxtalk_data = NULL; + + VL53LX_histogram_bin_data_t avg_bins; + VL53LX_histogram_bin_data_t *pavg_bins = &avg_bins; + + memcpy(pavg_bins, &(pxtalk_results->central_histogram_avg), + sizeof(VL53LX_histogram_bin_data_t)); + + + + + if (status == VL53LX_ERROR_NONE) + + VL53LX_init_histogram_bin_data_struct( + 0, 0, &(pdebug->VL53LX_p_056)); + + if (status == VL53LX_ERROR_NONE) + + VL53LX_init_histogram_bin_data_struct( + 0, 0, &(pdebug->VL53LX_p_057)); + + + + + + + if (status == VL53LX_ERROR_NONE) + + status = VL53LX_f_039( + pxtalk_results, + pdebug, + &(pxtalk_cal->algo__crosstalk_compensation_x_plane_gradient_kcps + ), + &(pxtalk_cal->algo__crosstalk_compensation_y_plane_gradient_kcps + )); + + + + + + + + if (status != VL53LX_ERROR_NONE) { + goto ENDFUNC; + } + + pxtalk_data = &(pxtalk_results->VL53LX_p_003[4]); + + if (pxtalk_data->no_of_samples > 0) { + + + + + if (status == VL53LX_ERROR_NONE) { + + memcpy(&(pdebug->VL53LX_p_056), + pavg_bins, + sizeof(VL53LX_histogram_bin_data_t)); + } + + + + + status = VL53LX_f_040( + pxtalk_data, + pdebug, + &(pxtalk_cal->algo__crosstalk_compensation_plane_offset_kcps)); + + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_f_041( + pavg_bins, + pdebug, + pxtalk_data, + pxtalk_results->central_histogram__window_start, + pxtalk_results->central_histogram__window_end, + &(pxtalk_shape->xtalk_shape)); + + } else { + + + + + pxtalk_cal->algo__crosstalk_compensation_plane_offset_kcps = 0; + + + + + pdebug->VL53LX_p_058 = 0; + + + + } +ENDFUNC: + return status; +} + + +VL53LX_Error VL53LX::VL53LX_generate_dual_reflectance_xtalk_samples( + VL53LX_xtalk_range_results_t *pxtalk_results, + uint16_t expected_target_distance_mm, + uint8_t higher_reflectance, + VL53LX_histogram_bin_data_t *pxtalk_avg_samples +) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_histogram_bin_data_t *pzone_avg_1 = + &(pxtalk_results->histogram_avg_1[0]); + VL53LX_histogram_bin_data_t *pzone_avg_2 = + &(pxtalk_results->histogram_avg_2[0]); + + VL53LX_histogram_bin_data_t *pxtalk_output = pxtalk_avg_samples; + + + + + int i = 0; + + + + + for (i = 0 ; i < 5 ; i++) { + + if (status == VL53LX_ERROR_NONE) + + VL53LX_init_histogram_bin_data_struct( + 0, 0, pzone_avg_1); + + if (status == VL53LX_ERROR_NONE) + + VL53LX_init_histogram_bin_data_struct( + 0, 0, pzone_avg_2); + + pzone_avg_1++; + pzone_avg_2++; + } + + + + + + pzone_avg_1 = &(pxtalk_results->histogram_avg_1[0]); + pzone_avg_2 = &(pxtalk_results->histogram_avg_2[0]); + + for (i = 0 ; i < 5 ; i++) { + + if (status == VL53LX_ERROR_NONE) { + + status = VL53LX_f_042( + pzone_avg_1, + pzone_avg_2, + expected_target_distance_mm, + 0x01, + + higher_reflectance, + pxtalk_output + ); + + + + + pzone_avg_1++; + pzone_avg_2++; + pxtalk_output++; + + } + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_042( + VL53LX_histogram_bin_data_t *pzone_avg_1, + VL53LX_histogram_bin_data_t *pzone_avg_2, + uint16_t expected_target_distance, + uint8_t subtract_amb, + uint8_t higher_reflectance, + VL53LX_histogram_bin_data_t *pxtalk_output +) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_histogram_bin_data_t zone_avg_realigned; + + + + SUPPRESS_UNUSED_WARNING(pxtalk_output); + SUPPRESS_UNUSED_WARNING(expected_target_distance); + + + + + if ((status == VL53LX_ERROR_NONE) && (subtract_amb == 0x01)) { + VL53LX_f_029( + pzone_avg_1, + pzone_avg_1->VL53LX_p_028); + + + + pzone_avg_1->VL53LX_p_028 = 0x0; + } + + if ((status == VL53LX_ERROR_NONE) && (subtract_amb == 0x01)) { + VL53LX_f_029( + pzone_avg_2, + pzone_avg_2->VL53LX_p_028); + + + + pzone_avg_2->VL53LX_p_028 = 0x0; + } + + + + + + + + if (status == VL53LX_ERROR_NONE) { + if (higher_reflectance == 0x01) { + VL53LX_f_005( + pzone_avg_2, + pzone_avg_1, + &zone_avg_realigned); + } else { + + + + + VL53LX_f_005( + pzone_avg_1, + pzone_avg_2, + &zone_avg_realigned); + + + + + + } + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_041( + VL53LX_histogram_bin_data_t *pavg_bins, + VL53LX_xtalk_algo_data_t *pdebug, + VL53LX_xtalk_range_data_t *pxtalk_data, + uint8_t histogram__window_start, + uint8_t histogram__window_end, + VL53LX_xtalk_histogram_shape_t *pxtalk_shape) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + + + uint32_t ambient_thresh = 0; + + + + + if (status == VL53LX_ERROR_NONE) + + VL53LX_f_029( + pavg_bins, + pavg_bins->VL53LX_p_028); + + + + + if (status == VL53LX_ERROR_NONE) + + VL53LX_f_043( + 6, + pavg_bins->VL53LX_p_028, + &ambient_thresh); + + + + + + + + + if (status == VL53LX_ERROR_NONE) + + status = VL53LX_f_044( + pavg_bins, + ambient_thresh, + histogram__window_start, + histogram__window_end); + + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_f_045( + pavg_bins, + pxtalk_data, + pdebug, + pxtalk_shape); + + + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_f_039( + VL53LX_xtalk_range_results_t *pxtalk_results, + VL53LX_xtalk_algo_data_t *pdebug, + int16_t *xgradient, + int16_t *ygradient +) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_xtalk_range_data_t *presults_int = NULL; + + int i = 0; + + uint32_t xtalk_per_spad[4]; + int32_t VL53LX_p_059 = 0; + int32_t VL53LX_p_060 = 0; + + uint8_t result_invalid = 0; + + + + *xgradient = 0; + *ygradient = 0; + + + + + + for (i = 0; i < 4; i++) { + xtalk_per_spad[i] = 0; + } + + + + + for (i = 0; i < 4; i++) { + + if (status == VL53LX_ERROR_NONE) { + + presults_int = &(pxtalk_results->VL53LX_p_003[i]); + + + + + + + if (presults_int->no_of_samples == 0) { + + + + result_invalid = 1; + pdebug->VL53LX_p_061[i] = 0; + + + } else { + + xtalk_per_spad[i] = + presults_int->rate_per_spad_kcps_avg; + + + + + pdebug->VL53LX_p_061[i] = + (uint32_t)xtalk_per_spad[i]; + + } + } + + } + + + + + + + + + if ((status == VL53LX_ERROR_NONE) && (result_invalid == 0)) { + + + + + if (status == VL53LX_ERROR_NONE) { + + VL53LX_p_059 = ((int32_t)xtalk_per_spad[1] + - (int32_t)xtalk_per_spad[0]) / (8); + VL53LX_p_060 = ((int32_t)xtalk_per_spad[3] + - (int32_t)xtalk_per_spad[2]) / (8); + } + + + + + + + if (status == VL53LX_ERROR_NONE) { + + if (VL53LX_p_059 < -32767) { + VL53LX_p_059 = -32767; + } else { + if (VL53LX_p_059 > 32767) { + VL53LX_p_059 = 32767; + } + } + + if (VL53LX_p_060 < -32767) { + VL53LX_p_060 = -32767; + } else { + if (VL53LX_p_060 > 32767) { + VL53LX_p_060 = 32767; + } + } + + + + + pdebug->VL53LX_p_059 = (int16_t)VL53LX_p_059; + pdebug->VL53LX_p_060 = (int16_t)VL53LX_p_060; + } + + } else { + + + + + VL53LX_p_059 = 0; + VL53LX_p_060 = 0; + + pdebug->VL53LX_p_059 = 0; + pdebug->VL53LX_p_060 = 0; + } + + + + + if (status == VL53LX_ERROR_NONE) { + *xgradient = (int16_t)VL53LX_p_059; + *ygradient = (int16_t)VL53LX_p_060; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_040( + VL53LX_xtalk_range_data_t *pxtalk_data, + VL53LX_xtalk_algo_data_t *pdebug, + uint32_t *xtalk_mean_offset_kcps +) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint32_t xtalk_per_spad = 0; + uint8_t result_invalid = 0; + + + *xtalk_mean_offset_kcps = 0; + + + + if (pxtalk_data->no_of_samples == 0) { + + + + + result_invalid = 1; + + + + + pdebug->VL53LX_p_058 = 0; + + } + + + + + + if ((status == VL53LX_ERROR_NONE) && (result_invalid == 0)) { + + + + + + xtalk_per_spad = pxtalk_data->rate_per_spad_kcps_avg >> 2; + + + + + pdebug->VL53LX_p_058 = xtalk_per_spad; + + + + if (xtalk_per_spad < 0x3FFFF) { + *xtalk_mean_offset_kcps = (uint32_t)xtalk_per_spad; + } else { + *xtalk_mean_offset_kcps = 0x3FFFF; + } + + } else { + + + + + *xtalk_mean_offset_kcps = 0; + } + + + return status; + +} + + + +VL53LX_Error VL53LX::VL53LX_f_045( + VL53LX_histogram_bin_data_t *phist_data, + VL53LX_xtalk_range_data_t *pxtalk_data, + VL53LX_xtalk_algo_data_t *pdebug, + VL53LX_xtalk_histogram_shape_t *pxtalk_histo +) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + int i = 0; + uint64_t bin_data[VL53LX_XTALK_HISTO_BINS]; + + pxtalk_histo->VL53LX_p_020 = + phist_data->VL53LX_p_020; + pxtalk_histo->cal_config__vcsel_start = + phist_data->cal_config__vcsel_start; + pxtalk_histo->VL53LX_p_015 = + phist_data->VL53LX_p_015; + pxtalk_histo->VL53LX_p_019 = + phist_data->VL53LX_p_019; + pxtalk_histo->time_stamp = + phist_data->time_stamp; + pxtalk_histo->vcsel_width = + phist_data->vcsel_width; + pxtalk_histo->zero_distance_phase = + phist_data->zero_distance_phase; + pxtalk_histo->zone_id = + phist_data->zone_id; + pxtalk_histo->VL53LX_p_021 = + VL53LX_XTALK_HISTO_BINS; + pxtalk_histo->phasecal_result__reference_phase = + phist_data->phasecal_result__reference_phase; + pxtalk_histo->phasecal_result__vcsel_start = + phist_data->phasecal_result__vcsel_start; + + + + + + memcpy(&(pdebug->VL53LX_p_057), + phist_data, sizeof(VL53LX_histogram_bin_data_t)); + + + + + + + + + + + for (i = 0; i < pxtalk_histo->VL53LX_p_021; i++) { + if (phist_data->bin_data[i + + phist_data->number_of_ambient_bins] > 0) { + bin_data[i] = + (((uint64_t)phist_data->bin_data[i + + phist_data->number_of_ambient_bins] << 10) + + ((uint64_t)pxtalk_data->signal_total_events_avg + / 2)) + / (uint64_t)pxtalk_data->signal_total_events_avg; + } else { + bin_data[i] = 0; + } + } + + + + + + for (i = 0; i < VL53LX_XTALK_HISTO_BINS; i++) { + pxtalk_histo->bin_data[i] = (uint32_t)bin_data[i]; + } + + + + + for (i = 0; i < pxtalk_histo->VL53LX_p_021; i++) { + pdebug->VL53LX_p_062[i] = pxtalk_histo->bin_data[i]; + } + + + + return status; + +} + + + +VL53LX_Error VL53LX::VL53LX_f_046( + VL53LX_customer_nvm_managed_t *pcustomer, + VL53LX_dynamic_config_t *pdyn_cfg, + VL53LX_xtalk_histogram_data_t *pxtalk_shape, + VL53LX_histogram_bin_data_t *pip_hist_data, + VL53LX_histogram_bin_data_t *pop_hist_data, + VL53LX_histogram_bin_data_t *pxtalk_count_data) +{ + + + + + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + + + + uint32_t xtalk_rate_kcps = 0; + + + + memcpy(pop_hist_data, pip_hist_data, + sizeof(VL53LX_histogram_bin_data_t)); + + + + + status = + VL53LX_f_032( + pcustomer->algo__crosstalk_compensation_plane_offset_kcps, + pcustomer->algo__crosstalk_compensation_x_plane_gradient_kcps, + pcustomer->algo__crosstalk_compensation_y_plane_gradient_kcps, + 0, + + 0, + + pip_hist_data->result__dss_actual_effective_spads, + + + pdyn_cfg->roi_config__user_roi_centre_spad, + pdyn_cfg->roi_config__user_roi_requested_global_xy_size, + &(xtalk_rate_kcps)); + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_033( + pip_hist_data, + &(pxtalk_shape->xtalk_shape), + xtalk_rate_kcps, + pxtalk_count_data); + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_047( + pop_hist_data, + pxtalk_count_data, + pip_hist_data->number_of_ambient_bins); + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_032( + uint32_t mean_offset, + int16_t xgradient, + int16_t ygradient, + int8_t centre_offset_x, + int8_t centre_offset_y, + uint16_t roi_effective_spads, + uint8_t roi_centre_spad, + uint8_t roi_xy_size, + uint32_t *xtalk_rate_kcps +) +{ + + + + + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t row = 0; + uint8_t col = 0; + + + + + int16_t bound_l_x = 0; + + int16_t bound_r_x = 0; + + int16_t bound_u_y = 0; + + int16_t bound_d_y = 0; + + + int64_t xtalk_rate_ll = 0; + + int64_t xtalk_rate_ur = 0; + + + int64_t xtalk_avg = 0; + + SUPPRESS_UNUSED_WARNING(roi_effective_spads); + + + + if (status == VL53LX_ERROR_NONE) { + + VL53LX_decode_row_col( + roi_centre_spad, + &row, + &col); + } + + + if (status == VL53LX_ERROR_NONE) { + + if ((((int16_t)roi_xy_size / 16) & 0x01) == 1) + bound_l_x = (int16_t) col - + (((int16_t)roi_xy_size / 32) + 1); + else + bound_l_x = (int16_t) col - + ((int16_t)roi_xy_size / 32); + + bound_r_x = (int16_t) col + ((int16_t)roi_xy_size / 32); + + if ((((int16_t)roi_xy_size) & 0x01) == 1) + bound_d_y = (int16_t) row - + ((((int16_t)roi_xy_size & 0x0f) / 2) + 1); + else + bound_d_y = (int16_t) row - + (((int16_t)roi_xy_size & 0x0f) / 2); + + bound_u_y = (int16_t) row + + (((int16_t)roi_xy_size & 0xf) / 2); + } + + + if (status == VL53LX_ERROR_NONE) { + + bound_l_x = (2 * bound_l_x) - 15 + + (2 * (int16_t)centre_offset_x); + bound_r_x = (2 * bound_r_x) - 15 + + (2 * (int16_t)centre_offset_x); + bound_u_y = (2 * bound_u_y) - 15 + + (2 * (int16_t)centre_offset_y); + bound_d_y = (2 * bound_d_y) - 15 + + (2 * (int16_t)centre_offset_y); + } + + + + + if (status == VL53LX_ERROR_NONE) { + + xtalk_rate_ll = ((int64_t)bound_l_x * + ((int64_t)xgradient)) + ((int64_t)bound_d_y * + ((int64_t)ygradient)); + xtalk_rate_ll = (xtalk_rate_ll + 1) / 2; + + xtalk_rate_ll += ((int64_t)mean_offset * 4); + + xtalk_rate_ur = ((int64_t)bound_r_x * + ((int64_t)xgradient)) + ((int64_t)bound_u_y * + ((int64_t)ygradient)); + xtalk_rate_ur = (xtalk_rate_ur + 1) / 2; + + xtalk_rate_ur += ((int64_t)mean_offset * 4); + } + + + if (status == VL53LX_ERROR_NONE) + + { + xtalk_avg = ((xtalk_rate_ll + xtalk_rate_ur) + 1) / 2; + } + + + + if (status == VL53LX_ERROR_NONE) + + if (xtalk_avg < 0) { + xtalk_avg = 0; + } + + *xtalk_rate_kcps = (uint32_t) xtalk_avg; + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_f_033( + VL53LX_histogram_bin_data_t *phist_data, + VL53LX_xtalk_histogram_shape_t *pxtalk_data, + uint32_t xtalk_rate_kcps, + VL53LX_histogram_bin_data_t *pxtalkcount_data +) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint64_t xtalk_events_per_spad = 0; + uint64_t xtalk_total_events = 0; + uint64_t xtalk_temp_bin = 0; + + uint8_t i = 0; + + xtalk_events_per_spad = ((((uint64_t)xtalk_rate_kcps * + (uint64_t)phist_data->peak_duration_us) + 500) / 1000); + + xtalk_total_events = xtalk_events_per_spad * + (uint64_t)phist_data->result__dss_actual_effective_spads; + + + xtalk_total_events = (xtalk_total_events) / 256; + + + xtalk_total_events = (xtalk_total_events + 1024) / 2048; + + + if (xtalk_total_events > 0xFFFFFFFF) { + xtalk_total_events = 0xFFFFFFFF; + } + + for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) { + xtalk_temp_bin = (uint64_t)pxtalk_data->bin_data[i] * + (uint64_t)xtalk_total_events; + xtalk_temp_bin = (xtalk_temp_bin + 512) / 1024; + + pxtalkcount_data->bin_data[i] = (uint32_t)xtalk_temp_bin; + + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_047( + VL53LX_histogram_bin_data_t *phist_data, + VL53LX_histogram_bin_data_t *pxtalk_data, + uint8_t xtalk_bin_offset) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + + int32_t temp_bin; + + if (status == VL53LX_ERROR_NONE) + + for (i = xtalk_bin_offset; + i < pxtalk_data->VL53LX_p_021; i++) { + + + temp_bin = (int32_t)phist_data->bin_data[i] - + (int32_t)pxtalk_data->bin_data[i - xtalk_bin_offset]; + + if (temp_bin < 0) { + temp_bin = 0; + } + + phist_data->bin_data[i] = (uint32_t)temp_bin; + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_044( + VL53LX_histogram_bin_data_t *pxtalk_data, + uint32_t amb_threshold, + uint8_t VL53LX_p_019, + uint8_t VL53LX_p_024) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + uint8_t first_bin_int = 0; + uint8_t first_bin_inc = 0; + uint8_t last_bin_int = 0; + uint8_t realign_bin = 0; + uint8_t realign_index = 0; + int32_t realign_bin_data[VL53LX_HISTOGRAM_BUFFER_SIZE]; + + + for (i = 0 ; i < VL53LX_HISTOGRAM_BUFFER_SIZE ; i++) { + realign_bin_data[i] = 0; + } + + first_bin_int = VL53LX_p_019; + last_bin_int = VL53LX_p_024; + + VL53LX_hist_remove_ambient_bins(pxtalk_data); + + first_bin_int = (first_bin_int) % + pxtalk_data->VL53LX_p_021; + + last_bin_int = (last_bin_int) % + pxtalk_data->VL53LX_p_021; + + first_bin_inc = (first_bin_int + 1) % pxtalk_data->VL53LX_p_021; + + if (first_bin_inc > last_bin_int) { + + + + realign_bin = pxtalk_data->VL53LX_p_021 - first_bin_inc; + + + + first_bin_int = (first_bin_int + realign_bin) % + pxtalk_data->VL53LX_p_021; + last_bin_int = (last_bin_int + realign_bin) % + pxtalk_data->VL53LX_p_021; + + + + pxtalk_data->zero_distance_phase = + pxtalk_data->zero_distance_phase + + ((uint16_t)realign_bin * 2048); + } + + if (realign_bin > 0) { + + + for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) { + realign_bin_data[i] = pxtalk_data->bin_data[i]; + } + + + + for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) { + realign_index = (pxtalk_data->VL53LX_p_021 - + realign_bin + i) + % pxtalk_data->VL53LX_p_021; + + pxtalk_data->bin_data[i] = + realign_bin_data[realign_index]; + } + } + + + for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) { + + + if (first_bin_int <= last_bin_int) { + if ((i >= first_bin_int) && (i <= last_bin_int)) { + if (pxtalk_data->bin_data[i] < + (int32_t)amb_threshold) { + pxtalk_data->bin_data[i] = 0; + } + } else { + pxtalk_data->bin_data[i] = 0; + } + } else { + if ((i >= first_bin_int) || (i <= last_bin_int)) { + if (pxtalk_data->bin_data[i] < + (int32_t)amb_threshold) { + pxtalk_data->bin_data[i] = 0; + } + } else { + pxtalk_data->bin_data[i] = 0; + } + } + } + + + return status; +} + +VL53LX_Error VL53LX::VL53LX_f_043( + uint8_t sigma_mult, + int32_t VL53LX_p_028, + uint32_t *ambient_noise) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint32_t ambient_events_per_bin_int = 0; + + if (VL53LX_p_028 <= 0) { + ambient_events_per_bin_int = 1; + } else { + ambient_events_per_bin_int = (uint32_t)VL53LX_p_028; + } + + *ambient_noise = VL53LX_isqrt(ambient_events_per_bin_int); + + *ambient_noise = *ambient_noise * (uint32_t)sigma_mult; + + return status; +} + +/* vl53lx_sigma_estimate.c */ + + +uint16_t VL53LX::VL53LX_f_034( + uint8_t sigma_estimator__effective_pulse_width_ns, + uint8_t sigma_estimator__effective_ambient_width_ns, + uint8_t sigma_estimator__sigma_ref_mm, + VL53LX_range_data_t *pdata) +{ + uint16_t sigma_est = VL53LX_D_002; + + uint32_t tmp0 = 0; + uint32_t tmp1 = 0; + uint32_t tmp2 = 0; + + uint32_t sigma_est__rtn_array = 0; + uint32_t sigma_est__ref_array = 0; + + if (pdata->peak_signal_count_rate_mcps > 0 && + pdata->VL53LX_p_010 > 0) { + + tmp0 = 100 * + (uint32_t)sigma_estimator__effective_pulse_width_ns; + + tmp1 = ((uint32_t)sigma_estimator__effective_pulse_width_ns * + 100 * + (uint32_t)sigma_estimator__effective_ambient_width_ns); + + tmp1 = (tmp1 + + (uint32_t)pdata->peak_signal_count_rate_mcps / 2) / + (uint32_t)pdata->peak_signal_count_rate_mcps; + + sigma_est__rtn_array = + VL53LX_f_035(tmp0, tmp1); + + sigma_est__rtn_array = + ((VL53LX_SPEED_OF_LIGHT_IN_AIR + 1000) / 2000) * + sigma_est__rtn_array; + + + + tmp2 = + VL53LX_isqrt(12 * (uint32_t)pdata->VL53LX_p_010); + + if (tmp2 > 0) { + + sigma_est__rtn_array = + (sigma_est__rtn_array + tmp2 / 2) / tmp2; + + + + sigma_est__ref_array = + 100 * (uint32_t)sigma_estimator__sigma_ref_mm; + + sigma_est = + (uint16_t)VL53LX_f_035( + (uint32_t)sigma_est__ref_array, + sigma_est__rtn_array); + + } else { + sigma_est = VL53LX_D_002; + } + + } + + pdata->VL53LX_p_002 = sigma_est; + + return sigma_est; + +} + + +uint16_t VL53LX::VL53LX_f_036( + uint8_t sigma_estimator__effective_pulse_width_ns, + uint8_t sigma_estimator__effective_ambient_width_ns, + uint8_t sigma_estimator__sigma_ref_mm, + VL53LX_range_data_t *pdata) +{ + + + uint16_t sigma_est = VL53LX_D_002; + + uint32_t eqn7 = 0; + uint32_t sigma_est__ref_sq = 0; + uint32_t sigma_est__rtn_sq = 0; + + uint64_t tmp0 = 0; + uint64_t tmp1 = 0; + + + if (pdata->peak_signal_count_rate_mcps > 0 && + pdata->VL53LX_p_010 > 0) { + + + eqn7 = 4573 * 4573; + eqn7 = eqn7 / (3 * (uint32_t)pdata->VL53LX_p_010); + + + tmp0 = ((uint64_t)sigma_estimator__effective_pulse_width_ns) + << 8; + + + + tmp1 = ((uint64_t)pdata->ambient_count_rate_mcps * + (uint64_t)sigma_estimator__effective_ambient_width_ns) + << 8; + + tmp1 = tmp1 / (uint64_t)pdata->peak_signal_count_rate_mcps; + + + tmp1 = 16 * (uint64_t)eqn7 * (tmp0 * tmp0 + tmp1 * tmp1); + tmp1 = tmp1 / (15625 * 15625); + sigma_est__rtn_sq = (uint32_t)tmp1; + + + + + sigma_est__ref_sq = ((uint32_t)sigma_estimator__sigma_ref_mm) + << 2; + + sigma_est__ref_sq = sigma_est__ref_sq * sigma_est__ref_sq; + + + + + sigma_est = (uint16_t)VL53LX_isqrt(sigma_est__ref_sq + + sigma_est__rtn_sq); + + } + + pdata->VL53LX_p_002 = sigma_est; + + return sigma_est; + +} + + + +VL53LX_Error VL53LX::VL53LX_f_037( + uint8_t sigma_estimator__sigma_ref_mm, + uint32_t VL53LX_p_007, + uint32_t VL53LX_p_032, + uint32_t VL53LX_p_001, + uint32_t a_zp, + uint32_t c_zp, + uint32_t bx, + uint32_t ax_zp, + uint32_t cx_zp, + uint32_t VL53LX_p_028, + uint16_t fast_osc_frequency, + uint16_t *psigma_est) +{ + + + + VL53LX_Error status = VL53LX_ERROR_DIVISION_BY_ZERO; + uint32_t sigma_int = VL53LX_D_002; + + uint32_t pll_period_mm = 0; + + uint64_t tmp0 = 0; + uint64_t tmp1 = 0; + uint64_t b_minus_amb = 0; + uint64_t VL53LX_p_055 = 0; + + *psigma_est = VL53LX_D_002; + + if (fast_osc_frequency != 0) { + + + + + + pll_period_mm = VL53LX_calc_pll_period_mm(fast_osc_frequency); + + + + pll_period_mm = (pll_period_mm + 0x02) >> 2; + + + + + if (VL53LX_p_028 > VL53LX_p_032) + b_minus_amb = (uint64_t)VL53LX_p_028 - + (uint64_t)VL53LX_p_032; + else + b_minus_amb = (uint64_t)VL53LX_p_032 - + (uint64_t)VL53LX_p_028; + + + + + if (VL53LX_p_007 > VL53LX_p_001) + VL53LX_p_055 = (uint64_t)VL53LX_p_007 - + (uint64_t)VL53LX_p_001; + else + VL53LX_p_055 = (uint64_t)VL53LX_p_001 - + (uint64_t)VL53LX_p_007; + + + if (b_minus_amb != 0) { + + + + tmp0 = (uint64_t)pll_period_mm * + (uint64_t)pll_period_mm; + tmp0 = tmp0 * ((uint64_t)c_zp + + (uint64_t)cx_zp + (uint64_t)a_zp + + (uint64_t)ax_zp); + tmp0 = (tmp0 + (b_minus_amb >> 1)) / b_minus_amb; + + tmp1 = (uint64_t)pll_period_mm * + (uint64_t)pll_period_mm * VL53LX_p_055; + tmp1 = (tmp1 + (b_minus_amb >> 1)) / b_minus_amb; + + tmp1 = tmp1 * VL53LX_p_055; + tmp1 = (tmp1 + (b_minus_amb >> 1)) / b_minus_amb; + + tmp1 = tmp1 * ((uint64_t)VL53LX_p_032 + (uint64_t)bx + + (uint64_t)VL53LX_p_028); + tmp1 = (tmp1 + (b_minus_amb >> 1)) / b_minus_amb; + + + + tmp0 = tmp0 + tmp1; + tmp0 = (tmp0 + (b_minus_amb >> 1)) / b_minus_amb; + tmp0 = (tmp0 + 0x01) >> 2; + + + + + + + tmp1 = (uint64_t)sigma_estimator__sigma_ref_mm << 2; + tmp1 = tmp1 * tmp1; + tmp0 = tmp0 + tmp1; + + + + + + + if (tmp0 > 0xFFFFFFFF) { + tmp0 = 0xFFFFFFFF; + } + + sigma_int = VL53LX_isqrt((uint32_t)tmp0); + + + + + + + if (sigma_int > VL53LX_D_002) + *psigma_est = + (uint16_t)VL53LX_D_002; + else { + *psigma_est = (uint16_t)sigma_int; + } + + status = VL53LX_ERROR_NONE; + } + + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_023( + uint8_t sigma_estimator__sigma_ref_mm, + uint32_t VL53LX_p_007, + uint32_t VL53LX_p_032, + uint32_t VL53LX_p_001, + uint32_t a_zp, + uint32_t c_zp, + uint32_t bx, + uint32_t ax_zp, + uint32_t cx_zp, + uint32_t VL53LX_p_028, + uint16_t fast_osc_frequency, + uint16_t *psigma_est) +{ + + VL53LX_Error status = VL53LX_ERROR_DIVISION_BY_ZERO; + uint32_t sigma_int = VL53LX_D_002; + + uint32_t pll_period_mm = 0; + + uint64_t tmp0 = 0; + uint64_t tmp1 = 0; + uint64_t b_minus_amb = 0; + uint64_t VL53LX_p_055 = 0; + + *psigma_est = VL53LX_D_002; + + + + if (fast_osc_frequency != 0) { + + + pll_period_mm = VL53LX_calc_pll_period_mm(fast_osc_frequency); + + + + + if (VL53LX_p_028 > VL53LX_p_032) + b_minus_amb = (uint64_t)VL53LX_p_028 - + (uint64_t)VL53LX_p_032; + else + b_minus_amb = (uint64_t)VL53LX_p_032 - + (uint64_t)VL53LX_p_028; + + + + + if (VL53LX_p_007 > VL53LX_p_001) + VL53LX_p_055 = (uint64_t)VL53LX_p_007 - + (uint64_t)VL53LX_p_001; + else + VL53LX_p_055 = (uint64_t)VL53LX_p_001 - + (uint64_t)VL53LX_p_007; + + + + + if (b_minus_amb != 0) { + + + tmp0 = (uint64_t)VL53LX_p_032 + (uint64_t)bx + + (uint64_t)VL53LX_p_028; + if (tmp0 > VL53LX_D_003) { + tmp0 = VL53LX_D_003; + } + + + + + tmp1 = (uint64_t)VL53LX_p_055 * (uint64_t)VL53LX_p_055; + tmp1 = tmp1 << 8; + + + + if (tmp1 > VL53LX_D_004) { + tmp1 = VL53LX_D_004; + } + + + + tmp1 = tmp1 / b_minus_amb; + tmp1 = tmp1 / b_minus_amb; + + + + if (tmp1 > (uint64_t)VL53LX_D_005) { + tmp1 = (uint64_t)VL53LX_D_005; + } + + + + tmp0 = tmp1 * tmp0; + + + + + + tmp1 = (uint64_t)c_zp + (uint64_t)cx_zp + + (uint64_t)a_zp + (uint64_t)ax_zp; + + + + if (tmp1 > (uint64_t)VL53LX_D_003) { + tmp1 = (uint64_t)VL53LX_D_003; + } + + tmp1 = tmp1 << 8; + + + + + tmp0 = tmp1 + tmp0; + if (tmp0 > (uint64_t)VL53LX_D_006) { + tmp0 = (uint64_t)VL53LX_D_006; + } + + if (tmp0 > (uint64_t)VL53LX_D_007) { + tmp0 = tmp0 / b_minus_amb; + tmp0 = tmp0 * pll_period_mm; + } else { + tmp0 = tmp0 * pll_period_mm; + tmp0 = tmp0 / b_minus_amb; + } + + + + if (tmp0 > (uint64_t)VL53LX_D_006) { + tmp0 = (uint64_t)VL53LX_D_006; + } + + + + + if (tmp0 > (uint64_t)VL53LX_D_007) { + tmp0 = tmp0 / b_minus_amb; + tmp0 = tmp0 / 4; + tmp0 = tmp0 * pll_period_mm; + } else { + tmp0 = tmp0 * pll_period_mm; + tmp0 = tmp0 / b_minus_amb; + tmp0 = tmp0 / 4; + } + + + + if (tmp0 > (uint64_t)VL53LX_D_006) { + tmp0 = (uint64_t)VL53LX_D_006; + } + + + + tmp0 = tmp0 >> 2; + + + + if (tmp0 > (uint64_t)VL53LX_D_007) { + tmp0 = (uint64_t)VL53LX_D_007; + } + + + + tmp1 = (uint64_t)sigma_estimator__sigma_ref_mm << 7; + tmp1 = tmp1 * tmp1; + tmp0 = tmp0 + tmp1; + + + + if (tmp0 > (uint64_t)VL53LX_D_007) { + tmp0 = (uint64_t)VL53LX_D_007; + } + + + + sigma_int = VL53LX_isqrt((uint32_t)tmp0); + + *psigma_est = (uint16_t)sigma_int; + + status = VL53LX_ERROR_NONE; + } + + } + + return status; +} + + +uint32_t VL53LX::VL53LX_f_038( + uint64_t VL53LX_p_007, + uint32_t size +) +{ + + uint64_t next; + uint64_t upper; + uint64_t lower; + uint32_t stepsize; + uint32_t count; + + + next = VL53LX_p_007; + upper = 0; + lower = 0; + stepsize = size / 2; + count = 0; + + while (1) { + upper = next >> stepsize; + lower = next & ((1 << stepsize) - 1); + + if (upper != 0) { + count += stepsize; + next = upper; + } else { + next = lower; + } + + stepsize = stepsize / 2; + if (stepsize == 0) { + break; + } + } + + return count; +} + + +uint32_t VL53LX::VL53LX_f_035( + uint32_t VL53LX_p_007, + uint32_t VL53LX_p_032) +{ + + uint32_t res = 0; + + if (VL53LX_p_007 > 65535 || VL53LX_p_032 > 65535) { + res = 65535; + } else + res = VL53LX_isqrt(VL53LX_p_007 * VL53LX_p_007 + + VL53LX_p_032 * VL53LX_p_032); + + return res; +} + +/* vl53lx_hist_algos_gen3.c */ + +void VL53LX::VL53LX_f_003( + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + uint8_t lb = 0; + + palgo->VL53LX_p_020 = VL53LX_HISTOGRAM_BUFFER_SIZE; + palgo->VL53LX_p_019 = 0; + palgo->VL53LX_p_021 = 0; + palgo->VL53LX_p_039 = 0; + palgo->VL53LX_p_028 = 0; + palgo->VL53LX_p_031 = 0; + + for (lb = palgo->VL53LX_p_019; lb < palgo->VL53LX_p_020; lb++) { + palgo->VL53LX_p_040[lb] = 0; + palgo->VL53LX_p_041[lb] = 0; + palgo->VL53LX_p_042[lb] = 0; + palgo->VL53LX_p_043[lb] = 0; + palgo->VL53LX_p_018[lb] = 0; + } + + palgo->VL53LX_p_044 = 0; + palgo->VL53LX_p_045 = VL53LX_D_001; + palgo->VL53LX_p_046 = 0; + + + + + VL53LX_init_histogram_bin_data_struct( + 0, + VL53LX_HISTOGRAM_BUFFER_SIZE, + &(palgo->VL53LX_p_006)); + VL53LX_init_histogram_bin_data_struct( + 0, + VL53LX_HISTOGRAM_BUFFER_SIZE, + &(palgo->VL53LX_p_047)); + VL53LX_init_histogram_bin_data_struct( + 0, + VL53LX_HISTOGRAM_BUFFER_SIZE, + &(palgo->VL53LX_p_048)); + VL53LX_init_histogram_bin_data_struct( + 0, + VL53LX_HISTOGRAM_BUFFER_SIZE, + &(palgo->VL53LX_p_049)); + VL53LX_init_histogram_bin_data_struct( + 0, + VL53LX_HISTOGRAM_BUFFER_SIZE, + &(palgo->VL53LX_p_050)); +} + + +VL53LX_Error VL53LX::VL53LX_f_004( + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins_input, + VL53LX_histogram_bin_data_t *pxtalk, + VL53LX_hist_gen3_algo_private_data_t *palgo, + VL53LX_hist_gen3_dmax_private_data_t *pdmax_algo, + VL53LX_range_results_t *presults) +{ + + + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t *ppulse_data; + VL53LX_range_data_t *prange_data; + + uint8_t p = 0; + + VL53LX_f_003(palgo); + + + + + + + memcpy( + &(palgo->VL53LX_p_006), + pbins_input, + sizeof(VL53LX_histogram_bin_data_t)); + + + + + + + presults->cfg_device_state = pbins_input->cfg_device_state; + presults->rd_device_state = pbins_input->rd_device_state; + presults->zone_id = pbins_input->zone_id; + presults->stream_count = pbins_input->result__stream_count; + presults->wrap_dmax_mm = 0; + presults->max_results = VL53LX_MAX_RANGE_RESULTS; + presults->active_results = 0; + + for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) { + presults->VL53LX_p_022[p] = 0; + } + + + + + VL53LX_hist_calc_zero_distance_phase(&(palgo->VL53LX_p_006)); + + + + + + + if (ppost_cfg->hist_amb_est_method == + VL53LX_HIST_AMB_EST_METHOD__THRESHOLDED_BINS) { + VL53LX_hist_estimate_ambient_from_thresholded_bins( + (int32_t)ppost_cfg->ambient_thresh_sigma0, + &(palgo->VL53LX_p_006)); + } else { + VL53LX_hist_estimate_ambient_from_ambient_bins( + &(palgo->VL53LX_p_006)); + } + + + + + + VL53LX_hist_remove_ambient_bins(&(palgo->VL53LX_p_006)); + + + + + + if (ppost_cfg->algo__crosstalk_compensation_enable > 0) { + VL53LX_f_005( + pxtalk, + &(palgo->VL53LX_p_006), + &(palgo->VL53LX_p_047)); + } + + + + + + + pdmax_cfg->ambient_thresh_sigma = + ppost_cfg->ambient_thresh_sigma1; + + for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) { + if (status == VL53LX_ERROR_NONE) { + + status = + VL53LX_f_001( + pdmax_cfg->target_reflectance_for_dmax_calc[p], + pdmax_cal, + pdmax_cfg, + &(palgo->VL53LX_p_006), + pdmax_algo, + &(presults->VL53LX_p_022[p])); + } + } + + + + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_006( + ppost_cfg->ambient_thresh_events_scaler, + (int32_t)ppost_cfg->ambient_thresh_sigma1, + (int32_t)ppost_cfg->min_ambient_thresh_events, + ppost_cfg->algo__crosstalk_compensation_enable, + &(palgo->VL53LX_p_006), + &(palgo->VL53LX_p_047), + palgo); + + + + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_007(palgo); + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_008(palgo); + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_009(palgo); + + + + + + + + for (p = 0; p < palgo->VL53LX_p_046; p++) { + + ppulse_data = &(palgo->VL53LX_p_003[p]); + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_010( + p, + &(palgo->VL53LX_p_006), + palgo); + } + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_011( + p, + &(palgo->VL53LX_p_006), + palgo, + palgo->VL53LX_p_006.VL53LX_p_028, + &(palgo->VL53LX_p_048)); + } + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_011( + p, + &(palgo->VL53LX_p_006), + palgo, + 0, + &(palgo->VL53LX_p_049)); + } + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_011( + p, + &(palgo->VL53LX_p_047), + palgo, + 0, + &(palgo->VL53LX_p_050)); + } + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_012( + p, + &(palgo->VL53LX_p_048), + palgo); + } + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_013( + p, + ppost_cfg->noise_threshold, + palgo); + } + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_014( + ppulse_data->VL53LX_p_023, + ppost_cfg->sigma_estimator__sigma_ref_mm, + palgo->VL53LX_p_030, + ppulse_data->VL53LX_p_051, + ppost_cfg->algo__crosstalk_compensation_enable, + &(palgo->VL53LX_p_048), + &(palgo->VL53LX_p_049), + &(palgo->VL53LX_p_050), + &(ppulse_data->VL53LX_p_002)); + } + + + + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_015( + p, + 1, + &(palgo->VL53LX_p_006), + palgo); + + } + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_016( + ppost_cfg->hist_target_order, + palgo); + + + + + + + for (p = 0; p < palgo->VL53LX_p_046; p++) { + + ppulse_data = &(palgo->VL53LX_p_003[p]); + + + + if (!(presults->active_results < presults->max_results)) { + continue; + } + + + + + + + if (!(ppulse_data->VL53LX_p_010 > + ppost_cfg->signal_total_events_limit && + ppulse_data->VL53LX_p_023 < 0xFF)) { + continue; + } + + prange_data = + &(presults->VL53LX_p_003[presults->active_results]); + + if (status == VL53LX_ERROR_NONE) + VL53LX_f_017( + presults->active_results, + ppost_cfg->valid_phase_low, + ppost_cfg->valid_phase_high, + ppost_cfg->sigma_thresh, + &(palgo->VL53LX_p_006), + ppulse_data, + prange_data); + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_018( + palgo->VL53LX_p_006.vcsel_width, + palgo->VL53LX_p_006.VL53LX_p_015, + palgo->VL53LX_p_006.total_periods_elapsed, + palgo->VL53LX_p_006.result__dss_actual_effective_spads, + prange_data); + + + if (status == VL53LX_ERROR_NONE) + VL53LX_f_019( + ppost_cfg->gain_factor, + ppost_cfg->range_offset_mm, + prange_data); + + presults->active_results++; + + + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_006( + uint16_t ambient_threshold_events_scaler, + int32_t ambient_threshold_sigma, + int32_t min_ambient_threshold_events, + uint8_t algo__crosstalk_compensation_enable, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_histogram_bin_data_t *pxtalk, + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t lb = 0; + uint8_t VL53LX_p_001 = 0; + int64_t tmp = 0; + int32_t amb_events = 0; + int32_t VL53LX_p_018 = 0; + int32_t samples = 0; + + palgo->VL53LX_p_020 = pbins->VL53LX_p_020; + palgo->VL53LX_p_019 = pbins->VL53LX_p_019; + palgo->VL53LX_p_021 = pbins->VL53LX_p_021; + palgo->VL53LX_p_028 = pbins->VL53LX_p_028; + + + + + + + palgo->VL53LX_p_030 = + VL53LX_decode_vcsel_period(pbins->VL53LX_p_005); + + tmp = (int64_t)pbins->VL53LX_p_028; + tmp *= (int64_t)ambient_threshold_events_scaler; + tmp += 2048; + tmp = do_division_s(tmp, 4096); + amb_events = (int32_t)tmp; + + + for (lb = 0; lb < pbins->VL53LX_p_021; lb++) { + + VL53LX_p_001 = lb >> 2; + samples = (int32_t)pbins->bin_rep[VL53LX_p_001]; + + if (samples > 0) { + + if (lb < pxtalk->VL53LX_p_021 && + algo__crosstalk_compensation_enable > 0) + VL53LX_p_018 = samples * (amb_events + + pxtalk->bin_data[lb]); + else { + VL53LX_p_018 = samples * amb_events; + } + + VL53LX_p_018 = VL53LX_isqrt(VL53LX_p_018); + + VL53LX_p_018 += (samples / 2); + VL53LX_p_018 /= samples; + VL53LX_p_018 *= ambient_threshold_sigma; + VL53LX_p_018 += 8; + VL53LX_p_018 /= 16; + VL53LX_p_018 += amb_events; + + if (VL53LX_p_018 < min_ambient_threshold_events) { + VL53LX_p_018 = min_ambient_threshold_events; + } + + palgo->VL53LX_p_052[lb] = VL53LX_p_018; + palgo->VL53LX_p_031 = VL53LX_p_018; + } + + } + + palgo->VL53LX_p_039 = 0; + + for (lb = pbins->VL53LX_p_019; lb < pbins->VL53LX_p_021; lb++) { + + if (pbins->bin_data[lb] > palgo->VL53LX_p_052[lb]) { + palgo->VL53LX_p_040[lb] = 1; + palgo->VL53LX_p_041[lb] = 1; + palgo->VL53LX_p_039++; + } else { + palgo->VL53LX_p_040[lb] = 0; + palgo->VL53LX_p_041[lb] = 0; + } + } + + + + return status; + +} + + + +VL53LX_Error VL53LX::VL53LX_f_007( + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + uint8_t j = 0; + uint8_t found = 0; + + + palgo->VL53LX_p_044 = 0; + + for (i = 0; i < palgo->VL53LX_p_030; i++) { + + j = (i + 1) % palgo->VL53LX_p_030; + + + + if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) { + if (palgo->VL53LX_p_041[i] == 0 && + palgo->VL53LX_p_041[j] == 1 && + found == 0) { + palgo->VL53LX_p_044 = i; + found = 1; + } + } + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_008( + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + uint8_t i = 0; + uint8_t j = 0; + uint8_t lb = 0; + + + + for (lb = palgo->VL53LX_p_044; + lb < (palgo->VL53LX_p_044 + + palgo->VL53LX_p_030); + lb++) { + + + + + + + i = lb % palgo->VL53LX_p_030; + j = (lb + 1) % palgo->VL53LX_p_030; + + + + + + + if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) { + + if (palgo->VL53LX_p_041[i] == 0 && + palgo->VL53LX_p_041[j] == 1) { + palgo->VL53LX_p_046++; + } + + if (palgo->VL53LX_p_041[i] > 0) { + palgo->VL53LX_p_042[i] = palgo->VL53LX_p_046; + } else { + palgo->VL53LX_p_042[i] = 0; + } + } + + } + + + + if (palgo->VL53LX_p_046 > palgo->VL53LX_p_045) { + palgo->VL53LX_p_046 = palgo->VL53LX_p_045; + } + + return status; + +} + +VL53LX_Error VL53LX::VL53LX_f_009( + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + uint8_t j = 0; + uint8_t blb = 0; + uint8_t pulse_no = 0; + + uint8_t max_filter_half_width = 0; + + VL53LX_hist_pulse_data_t *pdata; + + + + max_filter_half_width = palgo->VL53LX_p_030 - 1; + max_filter_half_width = max_filter_half_width >> 1; + + for (blb = palgo->VL53LX_p_044; + blb < (palgo->VL53LX_p_044 + + palgo->VL53LX_p_030); + blb++) { + + + + + + + i = blb % palgo->VL53LX_p_030; + j = (blb + 1) % palgo->VL53LX_p_030; + + + + + + + if (i < palgo->VL53LX_p_021 && + j < palgo->VL53LX_p_021) { + + + + + if (palgo->VL53LX_p_042[i] == 0 && + palgo->VL53LX_p_042[j] > 0) { + + pulse_no = palgo->VL53LX_p_042[j] - 1; + pdata = &(palgo->VL53LX_p_003[pulse_no]); + + if (pulse_no < palgo->VL53LX_p_045) { + pdata->VL53LX_p_012 = blb; + pdata->VL53LX_p_019 = blb + 1; + pdata->VL53LX_p_023 = 0xFF; + + pdata->VL53LX_p_024 = 0; + pdata->VL53LX_p_013 = 0; + } + } + + + + + if (palgo->VL53LX_p_042[i] > 0 + && palgo->VL53LX_p_042[j] == 0) { + + pulse_no = palgo->VL53LX_p_042[i] - 1; + pdata = &(palgo->VL53LX_p_003[pulse_no]); + + if (pulse_no < palgo->VL53LX_p_045) { + + pdata->VL53LX_p_024 = blb; + pdata->VL53LX_p_013 = blb + 1; + + pdata->VL53LX_p_025 = + (pdata->VL53LX_p_024 + 1) - + pdata->VL53LX_p_019; + pdata->VL53LX_p_051 = + (pdata->VL53LX_p_013 + 1) - + pdata->VL53LX_p_012; + + if (pdata->VL53LX_p_051 > + max_filter_half_width) + pdata->VL53LX_p_051 = + max_filter_half_width; + } + + } + } + } + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_f_016( + VL53LX_HistTargetOrder target_order, + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t tmp; + VL53LX_hist_pulse_data_t *ptmp = &tmp; + VL53LX_hist_pulse_data_t *p0; + VL53LX_hist_pulse_data_t *p1; + + uint8_t i = 0; + uint8_t swapped = 1; + + if (!(palgo->VL53LX_p_046 > 1)) { + goto ENDFUNC; + } + + while (swapped > 0) { + + swapped = 0; + + for (i = 1; i < palgo->VL53LX_p_046; i++) { + + p0 = &(palgo->VL53LX_p_003[i - 1]); + p1 = &(palgo->VL53LX_p_003[i]); + + + + + if (target_order + == VL53LX_HIST_TARGET_ORDER__STRONGEST_FIRST) { + + if (p0->VL53LX_p_010 < + p1->VL53LX_p_010) { + + + + + memcpy(ptmp, + p1, sizeof(VL53LX_hist_pulse_data_t)); + memcpy(p1, + p0, sizeof(VL53LX_hist_pulse_data_t)); + memcpy(p0, + ptmp, sizeof(VL53LX_hist_pulse_data_t)); + + swapped = 1; + } + + } else { + + if (p0->VL53LX_p_011 > p1->VL53LX_p_011) { + + + + + memcpy(ptmp, + p1, sizeof(VL53LX_hist_pulse_data_t)); + memcpy(p1, + p0, sizeof(VL53LX_hist_pulse_data_t)); + memcpy(p0, + ptmp, sizeof(VL53LX_hist_pulse_data_t)); + + swapped = 1; + } + + } + } + } +ENDFUNC: + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_f_010( + uint8_t pulse_no, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + uint8_t lb = 0; + + VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]); + + + pdata->VL53LX_p_017 = 0; + pdata->VL53LX_p_016 = 0; + + for (lb = pdata->VL53LX_p_012; lb <= pdata->VL53LX_p_013; lb++) { + i = lb % palgo->VL53LX_p_030; + pdata->VL53LX_p_017 += pbins->bin_data[i]; + pdata->VL53LX_p_016 += palgo->VL53LX_p_028; + } + + + pdata->VL53LX_p_010 = + pdata->VL53LX_p_017 - pdata->VL53LX_p_016; + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_015( + uint8_t pulse_no, + uint8_t clip_events, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + int16_t VL53LX_p_012 = 0; + int16_t VL53LX_p_013 = 0; + int16_t window_width = 0; + uint32_t tmp_phase = 0; + + VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]); + + i = pdata->VL53LX_p_023 % palgo->VL53LX_p_030; + + VL53LX_p_012 = (int16_t)i; + VL53LX_p_012 += (int16_t)pdata->VL53LX_p_012; + VL53LX_p_012 -= (int16_t)pdata->VL53LX_p_023; + + VL53LX_p_013 = (int16_t)i; + VL53LX_p_013 += (int16_t)pdata->VL53LX_p_013; + VL53LX_p_013 -= (int16_t)pdata->VL53LX_p_023; + + + + + window_width = VL53LX_p_013 - VL53LX_p_012; + if (window_width > 3) { + window_width = 3; + } + + status = + VL53LX_f_020( + VL53LX_p_012, + VL53LX_p_012 + window_width, + palgo->VL53LX_p_030, + clip_events, + pbins, + &(pdata->VL53LX_p_026)); + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_020( + VL53LX_p_013 - window_width, + VL53LX_p_013, + palgo->VL53LX_p_030, + clip_events, + pbins, + &(pdata->VL53LX_p_027)); + + + + + + if (pdata->VL53LX_p_026 > pdata->VL53LX_p_027) { + tmp_phase = pdata->VL53LX_p_026; + pdata->VL53LX_p_026 = pdata->VL53LX_p_027; + pdata->VL53LX_p_027 = tmp_phase; + } + + + if (pdata->VL53LX_p_011 < pdata->VL53LX_p_026) { + pdata->VL53LX_p_026 = pdata->VL53LX_p_011; + } + + if (pdata->VL53LX_p_011 > pdata->VL53LX_p_027) { + pdata->VL53LX_p_027 = pdata->VL53LX_p_011; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_020( + int16_t VL53LX_p_019, + int16_t VL53LX_p_024, + uint8_t VL53LX_p_030, + uint8_t clip_events, + VL53LX_histogram_bin_data_t *pbins, + uint32_t *pphase) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + int16_t i = 0; + int16_t lb = 0; + + int64_t VL53LX_p_018 = 0; + int64_t event_sum = 0; + int64_t weighted_sum = 0; + + + *pphase = VL53LX_MAX_ALLOWED_PHASE; + + for (lb = VL53LX_p_019; lb <= VL53LX_p_024; lb++) { + + + + if (lb < 0) { + i = lb + (int16_t)VL53LX_p_030; + } else { + i = lb % (int16_t)VL53LX_p_030; + } + + VL53LX_p_018 = + (int64_t)pbins->bin_data[i] - + (int64_t)pbins->VL53LX_p_028; + + + + + + + if (clip_events > 0 && VL53LX_p_018 < 0) { + VL53LX_p_018 = 0; + } + + event_sum += VL53LX_p_018; + + weighted_sum += + (VL53LX_p_018 * (1024 + (2048 * (int64_t)lb))); + + + } + + if (event_sum > 0) { + + weighted_sum += (event_sum / 2); + weighted_sum /= event_sum; + + if (weighted_sum < 0) { + weighted_sum = 0; + } + + *pphase = (uint32_t)weighted_sum; + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_011( + uint8_t pulse_no, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_gen3_algo_private_data_t *palgo, + int32_t pad_value, + VL53LX_histogram_bin_data_t *ppulse) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + uint8_t lb = 0; + + VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]); + + memcpy(ppulse, pbins, sizeof(VL53LX_histogram_bin_data_t)); + + for (lb = palgo->VL53LX_p_044; + lb < (palgo->VL53LX_p_044 + + palgo->VL53LX_p_030); + lb++) { + + if (lb < pdata->VL53LX_p_012 || lb > pdata->VL53LX_p_013) { + i = lb % palgo->VL53LX_p_030; + if (i < ppulse->VL53LX_p_021) { + ppulse->bin_data[i] = pad_value; + } + } + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_012( + uint8_t pulse_no, + VL53LX_histogram_bin_data_t *ppulse, + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]); + + uint8_t lb = 0; + uint8_t i = 0; + uint8_t j = 0; + uint8_t w = 0; + + + + for (lb = pdata->VL53LX_p_012; lb <= pdata->VL53LX_p_013; lb++) { + + i = lb % palgo->VL53LX_p_030; + + + + palgo->VL53LX_p_043[i] = 0; + palgo->VL53LX_p_018[i] = 0; + + for (w = 0; w < (pdata->VL53LX_p_051 << 1); w++) { + + + + + + j = lb + w + palgo->VL53LX_p_030; + j = j - pdata->VL53LX_p_051; + j = j % palgo->VL53LX_p_030; + + + + + + + if (i < ppulse->VL53LX_p_021 && j < + ppulse->VL53LX_p_021) { + if (w < pdata->VL53LX_p_051) + palgo->VL53LX_p_043[i] += + ppulse->bin_data[j]; + else + palgo->VL53LX_p_043[i] -= + ppulse->bin_data[j]; + } + } + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_013( + uint8_t pulse_no, + uint16_t noise_threshold, + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]); + + uint8_t lb = 0; + uint8_t i = 0; + uint8_t j = 0; + int32_t bin_x_delta = 0; + + for (lb = pdata->VL53LX_p_012; lb < pdata->VL53LX_p_013; lb++) { + + i = lb % palgo->VL53LX_p_030; + j = (lb + 1) % palgo->VL53LX_p_030; + + if (i < palgo->VL53LX_p_021 && + j < palgo->VL53LX_p_021) { + + if (palgo->VL53LX_p_043[i] <= 0 && + palgo->VL53LX_p_043[j] > 0) { + + + + + + bin_x_delta = palgo->VL53LX_p_043[j] - + palgo->VL53LX_p_043[i]; + + + + if (bin_x_delta > + (int32_t)noise_threshold) { + + pdata->VL53LX_p_023 = lb; + + VL53LX_f_021( + lb, + palgo->VL53LX_p_043[i], + palgo->VL53LX_p_043[j], + palgo->VL53LX_p_030, + &(pdata->VL53LX_p_011)); + } + } + } + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_021( + uint8_t bin, + int32_t filta0, + int32_t filta1, + uint8_t VL53LX_p_030, + uint32_t *pmean_phase) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + int32_t mean_phase = VL53LX_MAX_ALLOWED_PHASE; + int32_t bin_x_phase = abs(filta0); + int32_t bin_x_delta = filta1 - filta0; + + + if (bin_x_delta == 0) { + mean_phase = 1024; + } else + mean_phase = ((bin_x_phase * 2048) + + (bin_x_delta >> 1)) / bin_x_delta; + + mean_phase += (2048 * (int64_t)bin); + + + + if (mean_phase < 0) { + mean_phase = 0; + } + + if (mean_phase > VL53LX_MAX_ALLOWED_PHASE) { + mean_phase = VL53LX_MAX_ALLOWED_PHASE; + } + + + + mean_phase = mean_phase % ((int32_t)VL53LX_p_030 * 2048); + + *pmean_phase = (uint32_t)mean_phase; + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_014( + uint8_t bin, + uint8_t sigma_estimator__sigma_ref_mm, + uint8_t VL53LX_p_030, + uint8_t VL53LX_p_051, + uint8_t crosstalk_compensation_enable, + VL53LX_histogram_bin_data_t *phist_data_ap, + VL53LX_histogram_bin_data_t *phist_data_zp, + VL53LX_histogram_bin_data_t *pxtalk_hist, + uint16_t *psigma_est) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_Error func_status = VL53LX_ERROR_NONE; + + uint8_t i = 0; + int32_t VL53LX_p_007 = 0; + int32_t VL53LX_p_032 = 0; + int32_t VL53LX_p_001 = 0; + int32_t a_zp = 0; + int32_t c_zp = 0; + int32_t ax = 0; + int32_t bx = 0; + int32_t cx = 0; + + + + + i = bin % VL53LX_p_030; + + + + + VL53LX_f_022( + i, + VL53LX_p_051, + phist_data_zp, + &a_zp, + &VL53LX_p_032, + &c_zp); + + + + + VL53LX_f_022( + i, + VL53LX_p_051, + phist_data_ap, + &VL53LX_p_007, + &VL53LX_p_032, + &VL53LX_p_001); + + if (crosstalk_compensation_enable > 0) + VL53LX_f_022( + i, + VL53LX_p_051, + pxtalk_hist, + &ax, + &bx, + &cx); + + + func_status = + VL53LX_f_023( + sigma_estimator__sigma_ref_mm, + (uint32_t)VL53LX_p_007, + + (uint32_t)VL53LX_p_032, + + (uint32_t)VL53LX_p_001, + + (uint32_t)a_zp, + + (uint32_t)c_zp, + + (uint32_t)bx, + (uint32_t)ax, + (uint32_t)cx, + (uint32_t)phist_data_ap->VL53LX_p_028, + phist_data_ap->VL53LX_p_015, + psigma_est); + + + if (func_status == VL53LX_ERROR_DIVISION_BY_ZERO) { + *psigma_est = 0xFFFF; + } + + + return status; +} + + +void VL53LX::VL53LX_f_017( + uint8_t range_id, + uint8_t valid_phase_low, + uint8_t valid_phase_high, + uint16_t sigma_thres, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_pulse_data_t *ppulse, + VL53LX_range_data_t *pdata) +{ + + uint16_t lower_phase_limit = 0; + uint16_t upper_phase_limit = 0; + + + + + pdata->range_id = range_id; + pdata->time_stamp = 0; + + pdata->VL53LX_p_012 = ppulse->VL53LX_p_012; + pdata->VL53LX_p_019 = ppulse->VL53LX_p_019; + pdata->VL53LX_p_023 = ppulse->VL53LX_p_023; + pdata->VL53LX_p_024 = ppulse->VL53LX_p_024; + pdata->VL53LX_p_013 = ppulse->VL53LX_p_013; + pdata->VL53LX_p_025 = ppulse->VL53LX_p_025; + + + + + pdata->VL53LX_p_029 = + (ppulse->VL53LX_p_013 + 1) - ppulse->VL53LX_p_012; + + + + + pdata->zero_distance_phase = pbins->zero_distance_phase; + pdata->VL53LX_p_002 = ppulse->VL53LX_p_002; + pdata->VL53LX_p_026 = (uint16_t)ppulse->VL53LX_p_026; + pdata->VL53LX_p_011 = (uint16_t)ppulse->VL53LX_p_011; + pdata->VL53LX_p_027 = (uint16_t)ppulse->VL53LX_p_027; + pdata->VL53LX_p_017 = (uint32_t)ppulse->VL53LX_p_017; + pdata->VL53LX_p_010 = ppulse->VL53LX_p_010; + pdata->VL53LX_p_016 = (uint32_t)ppulse->VL53LX_p_016; + pdata->total_periods_elapsed = pbins->total_periods_elapsed; + + + + + pdata->range_status = VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK; + + + + if (sigma_thres > 0 && + (uint32_t)ppulse->VL53LX_p_002 > ((uint32_t)sigma_thres << 5)) { + pdata->range_status = VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK; + } + + + + + lower_phase_limit = (uint8_t)valid_phase_low << 8; + if (lower_phase_limit < pdata->zero_distance_phase) + lower_phase_limit = + pdata->zero_distance_phase - + lower_phase_limit; + else { + lower_phase_limit = 0; + } + + upper_phase_limit = (uint8_t)valid_phase_high << 8; + upper_phase_limit += pbins->zero_distance_phase; + + if (pdata->VL53LX_p_011 < lower_phase_limit || + pdata->VL53LX_p_011 > upper_phase_limit) { + pdata->range_status = VL53LX_DEVICEERROR_RANGEPHASECHECK; + } + +} + + + +/* vl53lx_hist_algos_gen4.c */ + +void VL53LX::VL53LX_f_024( + VL53LX_hist_gen4_algo_filtered_data_t *palgo) +{ + + uint8_t lb = 0; + + palgo->VL53LX_p_020 = VL53LX_HISTOGRAM_BUFFER_SIZE; + palgo->VL53LX_p_019 = 0; + palgo->VL53LX_p_021 = 0; + + for (lb = palgo->VL53LX_p_019; lb < palgo->VL53LX_p_020; lb++) { + palgo->VL53LX_p_007[lb] = 0; + palgo->VL53LX_p_032[lb] = 0; + palgo->VL53LX_p_001[lb] = 0; + palgo->VL53LX_p_053[lb] = 0; + palgo->VL53LX_p_054[lb] = 0; + palgo->VL53LX_p_040[lb] = 0; + } +} +VL53LX_Error VL53LX::VL53LX_f_025( + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins_input, + VL53LX_histogram_bin_data_t *pxtalk, + VL53LX_hist_gen3_algo_private_data_t *palgo3, + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered, + VL53LX_hist_gen3_dmax_private_data_t *pdmax_algo, + VL53LX_range_results_t *presults) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t *ppulse_data; + VL53LX_range_data_t *prange_data; + + uint8_t p = 0; + VL53LX_histogram_bin_data_t *pB = &(palgo3->VL53LX_p_006); + + VL53LX_f_003(palgo3); + + memcpy( + &(palgo3->VL53LX_p_006), + pbins_input, + sizeof(VL53LX_histogram_bin_data_t)); + + presults->cfg_device_state = pbins_input->cfg_device_state; + presults->rd_device_state = pbins_input->rd_device_state; + presults->zone_id = pbins_input->zone_id; + presults->stream_count = pbins_input->result__stream_count; + presults->wrap_dmax_mm = 0; + presults->max_results = VL53LX_MAX_RANGE_RESULTS; + presults->active_results = 0; + + for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) { + presults->VL53LX_p_022[p] = 0; + } + + + + + VL53LX_hist_calc_zero_distance_phase(&(palgo3->VL53LX_p_006)); + + + + + + + if (ppost_cfg->hist_amb_est_method == + VL53LX_HIST_AMB_EST_METHOD__THRESHOLDED_BINS) + VL53LX_hist_estimate_ambient_from_thresholded_bins( + (int32_t)ppost_cfg->ambient_thresh_sigma0, + &(palgo3->VL53LX_p_006)); + else + VL53LX_hist_estimate_ambient_from_ambient_bins( + &(palgo3->VL53LX_p_006)); + + + + + + VL53LX_hist_remove_ambient_bins(&(palgo3->VL53LX_p_006)); + + + + + + if (ppost_cfg->algo__crosstalk_compensation_enable > 0) + VL53LX_f_005( + pxtalk, + &(palgo3->VL53LX_p_006), + &(palgo3->VL53LX_p_047)); + + + + + + + pdmax_cfg->ambient_thresh_sigma = + ppost_cfg->ambient_thresh_sigma1; + + for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) { + if (status == VL53LX_ERROR_NONE) { + + status = + VL53LX_f_001( + pdmax_cfg->target_reflectance_for_dmax_calc[p], + pdmax_cal, + pdmax_cfg, + &(palgo3->VL53LX_p_006), + pdmax_algo, + &(presults->VL53LX_p_022[p])); + } + } + + + + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_006( + ppost_cfg->ambient_thresh_events_scaler, + (int32_t)ppost_cfg->ambient_thresh_sigma1, + (int32_t)ppost_cfg->min_ambient_thresh_events, + ppost_cfg->algo__crosstalk_compensation_enable, + &(palgo3->VL53LX_p_006), + &(palgo3->VL53LX_p_047), + palgo3); + + + + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_007(palgo3); + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_008(palgo3); + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_009(palgo3); + + + + + + + for (p = 0; p < palgo3->VL53LX_p_046; p++) { + + ppulse_data = &(palgo3->VL53LX_p_003[p]); + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_010( + p, + &(palgo3->VL53LX_p_006), + palgo3); + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_011( + p, + &(palgo3->VL53LX_p_006), + palgo3, + pB->VL53LX_p_028, + &(palgo3->VL53LX_p_048)); + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_011( + p, + &(palgo3->VL53LX_p_006), + palgo3, + 0, + &(palgo3->VL53LX_p_049)); + } + + + + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_f_011( + p, + &(palgo3->VL53LX_p_047), + palgo3, + 0, + &(palgo3->VL53LX_p_050)); + } + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_026( + p, + &(palgo3->VL53LX_p_048), + palgo3, + pfiltered); + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_027( + p, + ppost_cfg->noise_threshold, + pfiltered, + palgo3); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_014( + ppulse_data->VL53LX_p_023, + ppost_cfg->sigma_estimator__sigma_ref_mm, + palgo3->VL53LX_p_030, + ppulse_data->VL53LX_p_051, + ppost_cfg->algo__crosstalk_compensation_enable, + &(palgo3->VL53LX_p_048), + &(palgo3->VL53LX_p_049), + &(palgo3->VL53LX_p_050), + &(ppulse_data->VL53LX_p_002)); + + + + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_015( + p, + 1, + &(palgo3->VL53LX_p_006), + palgo3); + + } + + + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_016( + ppost_cfg->hist_target_order, + palgo3); + + + + + + + for (p = 0; p < palgo3->VL53LX_p_046; p++) { + + ppulse_data = &(palgo3->VL53LX_p_003[p]); + + + + if (!(presults->active_results < presults->max_results)) { + continue; + } + + + + + + + + + if (ppulse_data->VL53LX_p_010 > + ppost_cfg->signal_total_events_limit && + ppulse_data->VL53LX_p_023 < 0xFF) { + + prange_data = + &(presults->VL53LX_p_003[presults->active_results]); + + if (status == VL53LX_ERROR_NONE) + VL53LX_f_017( + presults->active_results, + ppost_cfg->valid_phase_low, + ppost_cfg->valid_phase_high, + ppost_cfg->sigma_thresh, + &(palgo3->VL53LX_p_006), + ppulse_data, + prange_data); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_f_018( + pB->vcsel_width, + pB->VL53LX_p_015, + pB->total_periods_elapsed, + pB->result__dss_actual_effective_spads, + prange_data); + + if (status == VL53LX_ERROR_NONE) + VL53LX_f_019( + ppost_cfg->gain_factor, + ppost_cfg->range_offset_mm, + prange_data); + + presults->active_results++; + } + + } + + + + return status; +} + + + +VL53LX_Error VL53LX::VL53LX_f_026( + uint8_t pulse_no, + VL53LX_histogram_bin_data_t *ppulse, + VL53LX_hist_gen3_algo_private_data_t *palgo3, + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t *pdata = &(palgo3->VL53LX_p_003[pulse_no]); + + uint8_t lb = 0; + uint8_t i = 0; + int32_t suma = 0; + int32_t sumb = 0; + int32_t sumc = 0; + + + pfiltered->VL53LX_p_020 = palgo3->VL53LX_p_020; + pfiltered->VL53LX_p_019 = palgo3->VL53LX_p_019; + pfiltered->VL53LX_p_021 = palgo3->VL53LX_p_021; + + for (lb = pdata->VL53LX_p_012; lb <= pdata->VL53LX_p_013; lb++) { + + i = lb % palgo3->VL53LX_p_030; + + + + VL53LX_f_022( + i, + pdata->VL53LX_p_051, + ppulse, + &suma, + &sumb, + &sumc); + + + + pfiltered->VL53LX_p_007[i] = suma; + pfiltered->VL53LX_p_032[i] = sumb; + pfiltered->VL53LX_p_001[i] = sumc; + + + + + pfiltered->VL53LX_p_053[i] = + (suma + sumb) - + (sumc + palgo3->VL53LX_p_028); + + + + + pfiltered->VL53LX_p_054[i] = + (sumb + sumc) - + (suma + palgo3->VL53LX_p_028); + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_027( + uint8_t pulse_no, + uint16_t noise_threshold, + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered, + VL53LX_hist_gen3_algo_private_data_t *palgo3) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_Error func_status = VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t *pdata = &(palgo3->VL53LX_p_003[pulse_no]); + + uint8_t lb = 0; + uint8_t i = 0; + uint8_t j = 0; + + SUPPRESS_UNUSED_WARNING(noise_threshold); + + for (lb = pdata->VL53LX_p_012; lb < pdata->VL53LX_p_013; lb++) { + + i = lb % palgo3->VL53LX_p_030; + j = (lb + 1) % palgo3->VL53LX_p_030; + + if (i < palgo3->VL53LX_p_021 && + j < palgo3->VL53LX_p_021) { + + if (pfiltered->VL53LX_p_053[i] == 0 && + pfiltered->VL53LX_p_054[i] == 0) + + + { + pfiltered->VL53LX_p_040[i] = 0; + } + + else if (pfiltered->VL53LX_p_053[i] >= 0 && + pfiltered->VL53LX_p_054[i] >= 0) { + pfiltered->VL53LX_p_040[i] = 1; + } + + else if (pfiltered->VL53LX_p_053[i] < 0 && + pfiltered->VL53LX_p_054[i] >= 0 && + pfiltered->VL53LX_p_053[j] >= 0 && + pfiltered->VL53LX_p_054[j] < 0) { + pfiltered->VL53LX_p_040[i] = 1; + } + + else { + pfiltered->VL53LX_p_040[i] = 0; + } + + + + if (pfiltered->VL53LX_p_040[i] > 0) { + + pdata->VL53LX_p_023 = lb; + + func_status = + VL53LX_f_028( + lb, + pfiltered->VL53LX_p_007[i], + pfiltered->VL53LX_p_032[i], + pfiltered->VL53LX_p_001[i], + 0, + + 0, + + 0, + + palgo3->VL53LX_p_028, + palgo3->VL53LX_p_030, + &(pdata->VL53LX_p_011)); + + if (func_status == + VL53LX_ERROR_DIVISION_BY_ZERO) { + pfiltered->VL53LX_p_040[i] = 0; + } + + } + } + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_f_028( + uint8_t bin, + int32_t VL53LX_p_007, + int32_t VL53LX_p_032, + int32_t VL53LX_p_001, + int32_t ax, + int32_t bx, + int32_t cx, + int32_t VL53LX_p_028, + uint8_t VL53LX_p_030, + uint32_t *pmean_phase) +{ + + + + + + VL53LX_Error status = VL53LX_ERROR_DIVISION_BY_ZERO; + + int64_t mean_phase = VL53LX_MAX_ALLOWED_PHASE; + int64_t VL53LX_p_055 = 0; + int64_t b_minus_amb = 0; + + + + + + + + + VL53LX_p_055 = 4096 * ((int64_t)VL53LX_p_001 - + (int64_t)cx - (int64_t)VL53LX_p_007 - (int64_t)ax); + b_minus_amb = 2 * 4096 * ((int64_t)VL53LX_p_032 - + (int64_t)bx - (int64_t)VL53LX_p_028); + + if (b_minus_amb != 0) { + + mean_phase = ((4096 * VL53LX_p_055) + + (b_minus_amb / 2)) / b_minus_amb; + mean_phase += 2048; + mean_phase += (4096 * (int64_t)bin); + + + + mean_phase = (mean_phase + 1) / 2; + + + + if (mean_phase < 0) { + mean_phase = 0; + } + if (mean_phase > VL53LX_MAX_ALLOWED_PHASE) { + mean_phase = VL53LX_MAX_ALLOWED_PHASE; + } + + + + mean_phase = mean_phase % + ((int64_t)VL53LX_p_030 * 2048); + + status = VL53LX_ERROR_NONE; + + } + + *pmean_phase = (uint32_t)mean_phase; + + return status; +} + +/* vl53lx_dmax.c */ +VL53LX_Error VL53LX::VL53LX_f_001( + uint16_t target_reflectance, + VL53LX_dmax_calibration_data_t *pcal, + VL53LX_hist_gen3_dmax_config_t *pcfg, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_gen3_dmax_private_data_t *pdata, + int16_t *pambient_dmax_mm) +{ + + VL53LX_Error status = VL53LX_ERROR_NONE; + + uint32_t pll_period_us = 0; + uint32_t periods_elapsed = 0; + + uint32_t tmp32 = 0; + uint64_t tmp64 = 0; + + uint32_t amb_thres_delta = 0; + + pdata->VL53LX_p_004 = 0x0000; + pdata->VL53LX_p_033 = 0x0000; + pdata->VL53LX_p_034 = 0x0000; + pdata->VL53LX_p_009 = 0x0000; + pdata->VL53LX_p_028 = 0x0000; + pdata->VL53LX_p_035 = 0x0000; + pdata->VL53LX_p_036 = 0; + pdata->VL53LX_p_022 = 0; + + *pambient_dmax_mm = 0; + + + + + + if ((pbins->VL53LX_p_015 != 0) && + (pbins->total_periods_elapsed != 0)) { + + + + + pll_period_us = + VL53LX_calc_pll_period_us(pbins->VL53LX_p_015); + + + + + periods_elapsed = pbins->total_periods_elapsed + 1; + + + + + + + pdata->VL53LX_p_037 = + VL53LX_duration_maths( + pll_period_us, + 1 << 4, + VL53LX_RANGING_WINDOW_VCSEL_PERIODS, + periods_elapsed); + + + + pdata->VL53LX_p_034 = + VL53LX_rate_maths( + pbins->VL53LX_p_028, + pdata->VL53LX_p_037); + + + + + pdata->VL53LX_p_033 = + VL53LX_events_per_spad_maths( + pbins->VL53LX_p_028, + pbins->result__dss_actual_effective_spads, + pdata->VL53LX_p_037); + + + + + + + + + + + + + + + + pdata->VL53LX_p_038 = pcfg->max_effective_spads; + pdata->VL53LX_p_004 = pcfg->max_effective_spads; + + if (pdata->VL53LX_p_033 > 0) { + tmp64 = + (uint64_t)pcfg->dss_config__target_total_rate_mcps; + tmp64 *= 1000; + tmp64 <<= (11 + 1); + tmp64 += + ((uint64_t)pdata->VL53LX_p_033 / 2); + tmp64 /= (uint64_t)pdata->VL53LX_p_033; + + if (tmp64 < (uint64_t)pcfg->max_effective_spads) { + pdata->VL53LX_p_004 = (uint16_t)tmp64; + } + } + } + + + + + if ((pcal->ref__actual_effective_spads != 0) && + (pbins->VL53LX_p_015 != 0) && + (pcal->ref_reflectance_pc != 0) && + (pbins->total_periods_elapsed != 0)) { + + + + + + + + + + + + + + tmp64 = (uint64_t)pcal->ref__peak_signal_count_rate_mcps; + tmp64 *= (1000 * 256); + tmp64 += ((uint64_t)pcal->ref__actual_effective_spads / 2); + tmp64 /= (uint64_t)pcal->ref__actual_effective_spads; + + pdata->VL53LX_p_009 = (uint32_t)tmp64; + pdata->VL53LX_p_009 <<= 4; + + + + + + + tmp64 = (uint64_t)pdata->VL53LX_p_037; + tmp64 *= (uint64_t)pdata->VL53LX_p_033; + tmp64 *= (uint64_t)pdata->VL53LX_p_004; + tmp64 += (1 << (11 + 7)); + tmp64 >>= (11 + 8); + tmp64 += 500; + tmp64 /= 1000; + + + + if (tmp64 > 0x00FFFFFF) { + tmp64 = 0x00FFFFFF; + } + + pdata->VL53LX_p_028 = (uint32_t)tmp64; + + + + + + + tmp64 = (uint64_t)pdata->VL53LX_p_037; + tmp64 *= (uint64_t)pdata->VL53LX_p_009; + tmp64 *= (uint64_t)pdata->VL53LX_p_004; + tmp64 += (1 << (11 + 7)); + tmp64 >>= (11 + 8); + + + + + + + + tmp64 *= ((uint64_t)target_reflectance * + (uint64_t)pcal->coverglass_transmission); + + tmp64 += (((uint64_t)pcal->ref_reflectance_pc * 256) / 2); + tmp64 /= ((uint64_t)pcal->ref_reflectance_pc * 256); + + tmp64 += 500; + tmp64 /= 1000; + + + + if (tmp64 > 0x00FFFFFF) { + tmp64 = 0x00FFFFFF; + } + + pdata->VL53LX_p_035 = (uint32_t)tmp64; + + + + + + + + + + + + + + + + tmp32 = VL53LX_isqrt(pdata->VL53LX_p_028 << 8); + tmp32 *= (uint32_t)pcfg->ambient_thresh_sigma; + + + + + + + + if (pdata->VL53LX_p_028 < + (uint32_t)pcfg->min_ambient_thresh_events) { + + amb_thres_delta = + pcfg->min_ambient_thresh_events - + (uint32_t)pdata->VL53LX_p_028; + + + + amb_thres_delta <<= 8; + + if (tmp32 < amb_thres_delta) { + tmp32 = amb_thres_delta; + } + } + + + + + pdata->VL53LX_p_022 = + (int16_t)VL53LX_f_002( + tmp32, + + pdata->VL53LX_p_035, + (uint32_t)pcal->ref__distance_mm, + (uint32_t)pcfg->signal_thresh_sigma); + + + + + + + + + tmp32 = (uint32_t)pdata->VL53LX_p_035; + tmp32 *= (uint32_t)pbins->vcsel_width; + tmp32 += (1 << 3); + tmp32 /= (1 << 4); + + pdata->VL53LX_p_036 = + (int16_t)VL53LX_f_002( + 256 * (uint32_t)pcfg->signal_total_events_limit, + tmp32, + (uint32_t)pcal->ref__distance_mm, + (uint32_t)pcfg->signal_thresh_sigma); + + + + + + + + if (pdata->VL53LX_p_036 < pdata->VL53LX_p_022) { + *pambient_dmax_mm = pdata->VL53LX_p_036; + } else { + *pambient_dmax_mm = pdata->VL53LX_p_022; + } + + } + + return status; + +} + + +uint32_t VL53LX::VL53LX_f_002( + uint32_t events_threshold, + uint32_t ref_signal_events, + uint32_t ref_distance_mm, + uint32_t signal_thresh_sigma) +{ + + uint32_t tmp32 = 0; + uint32_t range_mm = 0; + + tmp32 = 4 * events_threshold; + + + + + + + tmp32 += ((uint32_t)signal_thresh_sigma * + (uint32_t)signal_thresh_sigma); + + + + + + + tmp32 = VL53LX_isqrt(tmp32); + tmp32 += (uint32_t)signal_thresh_sigma; + + + + + + + + range_mm = + (uint32_t)VL53LX_isqrt(ref_signal_events << 4); + range_mm *= ref_distance_mm; + + range_mm += (tmp32); + range_mm /= (2 * tmp32); + + return range_mm; + +} + +/* vl53lx_api_calibration.c */ + + +VL53LX_Error VL53LX::VL53LX_run_ref_spad_char( + VL53LX_Error *pcal_status) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t comms_buffer[6]; + + VL53LX_refspadchar_config_t *prefspadchar = &(pdev->refspadchar); + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_powerforce(); + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_ref_spad_char_config( + prefspadchar->VL53LX_p_005, + prefspadchar->timeout_us, + prefspadchar->target_count_rate_mcps, + prefspadchar->max_count_rate_limit_mcps, + prefspadchar->min_count_rate_limit_mcps, + pdev->stat_nvm.osc_measured__fast_osc__frequency); + + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_run_device_test( + prefspadchar->device_test_mode); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_ReadMulti( + Dev, + VL53LX_REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS, + comms_buffer, + 2); + + if (status == VL53LX_ERROR_NONE) { + pdev->dbg_results.ref_spad_char_result__num_actual_ref_spads = + comms_buffer[0]; + pdev->dbg_results.ref_spad_char_result__ref_location = + comms_buffer[1]; + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WriteMulti( + Dev, + VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS, + comms_buffer, + 2); + + if (status == VL53LX_ERROR_NONE) { + pdev->customer.ref_spad_man__num_requested_ref_spads = + comms_buffer[0]; + pdev->customer.ref_spad_man__ref_location = + comms_buffer[1]; + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_ReadMulti( + Dev, + VL53LX_RESULT__SPARE_0_SD1, + comms_buffer, + 6); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_WriteMulti( + Dev, + VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, + comms_buffer, + 6); + + if (status == VL53LX_ERROR_NONE) { + pdev->customer.global_config__spad_enables_ref_0 = + comms_buffer[0]; + pdev->customer.global_config__spad_enables_ref_1 = + comms_buffer[1]; + pdev->customer.global_config__spad_enables_ref_2 = + comms_buffer[2]; + pdev->customer.global_config__spad_enables_ref_3 = + comms_buffer[3]; + pdev->customer.global_config__spad_enables_ref_4 = + comms_buffer[4]; + pdev->customer.global_config__spad_enables_ref_5 = + comms_buffer[5]; + } + /* + if (status == VL53LX_ERROR_NONE) + VL53LX_print_customer_nvm_managed( + &(pdev->customer), + "run_ref_spad_char():pdev->lldata.customer.", + VL53LX_TRACE_MODULE_REF_SPAD_CHAR); + */ + if (status == VL53LX_ERROR_NONE) { + + switch (pdev->sys_results.result__range_status) { + + case VL53LX_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS: + status = VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS; + break; + + case VL53LX_DEVICEERROR_REFSPADCHARMORETHANTARGET: + status = VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH; + break; + + case VL53LX_DEVICEERROR_REFSPADCHARLESSTHANTARGET: + status = VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW; + break; + } + } + + + + *pcal_status = status; + + + /* + IGNORE_STATUS( + IGNORE_REF_SPAD_CHAR_NOT_ENOUGH_SPADS, + VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS, + status); + + IGNORE_STATUS( + IGNORE_REF_SPAD_CHAR_RATE_TOO_HIGH, + VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH, + status); + + IGNORE_STATUS( + IGNORE_REF_SPAD_CHAR_RATE_TOO_LOW, + VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW, + status); + + */ + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_run_xtalk_extraction( + VL53LX_Error *pcal_status) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + + + VL53LX_xtalkextract_config_t *pX = &(pdev->xtalk_extract_cfg); + VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg); + VL53LX_xtalk_calibration_results_t *pXC = &(pdev->xtalk_cal); + + uint8_t results_invalid = 0; + + uint8_t i = 0; + uint16_t tmp16 = 0; + + uint8_t measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + + VL53LX_init_histogram_bin_data_struct( + 0, + (uint16_t)VL53LX_HISTOGRAM_BUFFER_SIZE, + &(pdev->xtalk_results.central_histogram_avg)); + + VL53LX_init_histogram_bin_data_struct( + 0, + (uint16_t)VL53LX_HISTOGRAM_BUFFER_SIZE, + &(pdev->xtalk_results.central_histogram_sum)); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_preset_mode( + VL53LX_DEVICEPRESETMODE_HISTOGRAM_XTALK_PLANAR, + + pX->dss_config__target_total_rate_mcps, + pX->phasecal_config_timeout_us, + pX->mm_config_timeout_us, + pX->range_config_timeout_us, + + 100); + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_xtalk_compensation(); + } + + + + pdev->xtalk_results.max_results = VL53LX_MAX_XTALK_RANGE_RESULTS; + pdev->xtalk_results.active_results = pdev->zone_cfg.active_zones + 1; + + + + pdev->xtalk_results.central_histogram__window_start = 0xFF; + pdev->xtalk_results.central_histogram__window_end = 0x00; + + pdev->xtalk_results.num_of_samples_status = 0x00; + pdev->xtalk_results.zero_samples_status = 0x00; + pdev->xtalk_results.max_sigma_status = 0x00; + + for (i = 0; i < pdev->xtalk_results.max_results; i++) { + pdev->xtalk_results.VL53LX_p_003[i].no_of_samples = 0; + pdev->xtalk_results.VL53LX_p_003[i].signal_total_events_avg = 0; + pdev->xtalk_results.VL53LX_p_003[i].signal_total_events_sum = 0; + pdev->xtalk_results.VL53LX_p_003[i].rate_per_spad_kcps_sum = 0; + pdev->xtalk_results.VL53LX_p_003[i].rate_per_spad_kcps_avg = 0; + pdev->xtalk_results.VL53LX_p_003[i].sigma_mm_sum = 0; + pdev->xtalk_results.VL53LX_p_003[i].sigma_mm_avg = 0; + + pdev->xtalk_results.VL53LX_p_003[i].median_phase_sum = 0; + pdev->xtalk_results.VL53LX_p_003[i].median_phase_avg = 0; + + } + + + if (status == VL53LX_ERROR_NONE) { + + status = + VL53LX_get_and_avg_xtalk_samples( + pX->num_of_samples, + + measurement_mode, + + pX->algo__crosstalk_extract_max_valid_range_mm, + pX->algo__crosstalk_extract_min_valid_range_mm, + pX->algo__crosstalk_extract_max_valid_rate_kcps, + + 0x0, + 0x4, + &(pdev->xtalk_results), + &(pdev->xtalk_results.central_histogram_sum), + &(pdev->xtalk_results.central_histogram_avg)); + } + + + + + + + + if (status == VL53LX_ERROR_NONE) + if ((pdev->xtalk_results.VL53LX_p_003[4].no_of_samples == 0) || + (pdev->xtalk_results.VL53LX_p_003[4].sigma_mm_avg > + ((uint32_t)pX->algo__crosstalk_extract_max_sigma_mm + << 5))) { + results_invalid = 0x01; + } + + /* + if (status == VL53LX_ERROR_NONE) + VL53LX_print_xtalk_range_results( + &(pdev->xtalk_results), + "pdev->xtalk_results", + VL53LX_TRACE_MODULE_CORE); + */ + if ((status == VL53LX_ERROR_NONE) && (results_invalid == 0)) { + status = + VL53LX_ipp_xtalk_calibration_process_data( + &(pdev->xtalk_results), + &(pdev->xtalk_shapes), + &(pdev->xtalk_cal)); + } + if ((status == VL53LX_ERROR_NONE) && (results_invalid == 0)) { + for (i = 0; i < VL53LX_BIN_REC_SIZE; i++) + pXC->algo__xtalk_cpo_HistoMerge_kcps[i] = + pXC->algo__crosstalk_compensation_plane_offset_kcps; + pC->algo__crosstalk_compensation_x_plane_gradient_kcps = + pXC->algo__crosstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps = + pXC->algo__crosstalk_compensation_y_plane_gradient_kcps; + pC->algo__crosstalk_compensation_plane_offset_kcps = + pXC->algo__crosstalk_compensation_plane_offset_kcps; + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_xtalk_compensation(); + } + + if (status == VL53LX_ERROR_NONE) { + for (i = 0; i < pdev->xtalk_results.max_results; i++) { + + if (pdev->xtalk_results.VL53LX_p_003[i].no_of_samples != + + pX->num_of_samples) { + + pdev->xtalk_results.num_of_samples_status = + pdev->xtalk_results.num_of_samples_status | + (1 << i); + } + + if (pdev->xtalk_results.VL53LX_p_003[i].no_of_samples == + 0x00) { + pdev->xtalk_results.zero_samples_status = + pdev->xtalk_results.zero_samples_status | + (1 << i); + } + + + + + tmp16 = pX->algo__crosstalk_extract_max_sigma_mm; + if (pdev->xtalk_results.VL53LX_p_003[i].sigma_mm_avg > + ((uint32_t)tmp16 << 5)) { + pdev->xtalk_results.max_sigma_status = + pdev->xtalk_results.max_sigma_status | + (1 << i); + } + + } + } + + + if (results_invalid > 0) { + + if (pdev->xtalk_results.VL53LX_p_003[4].no_of_samples == 0) { + status = VL53LX_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL; + } else { + + + if (pdev->xtalk_results.VL53LX_p_003[4].sigma_mm_avg > + (((uint32_t)pX->algo__crosstalk_extract_max_sigma_mm) + << 5)) { + status = + VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL; + } + + } + } else { + + if (pdev->xtalk_results.zero_samples_status != 0x00) { + status = VL53LX_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT; + } else { + if (pdev->xtalk_results.max_sigma_status != 0x00) { + status = + VL53LX_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT; + } else { + if (pdev->xtalk_results.num_of_samples_status != + 0x00) + status = + VL53LX_WARNING_XTALK_MISSING_SAMPLES; + } + } + } + + + + pdev->xtalk_results.cal_status = status; + *pcal_status = pdev->xtalk_results.cal_status; + + + + /*IGNORE_STATUS( + IGNORE_XTALK_EXTRACTION_NO_SAMPLE_FAIL, + VL53LX_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL, + status); + + IGNORE_STATUS( + IGNORE_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL, + VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL, + status); + + IGNORE_STATUS( + IGNORE_XTALK_EXTRACTION_NO_SAMPLE_FOR_GRADIENT_WARN, + VL53LX_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT, + status); + + IGNORE_STATUS( + IGNORE_XTALK_EXTRACTION_SIGMA_LIMIT_FOR_GRADIENT_WARN, + VL53LX_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT, + status); + + IGNORE_STATUS( + IGNORE_XTALK_EXTRACTION_MISSING_SAMPLES_WARN, + VL53LX_WARNING_XTALK_MISSING_SAMPLES, + status); + */ + /* + + VL53LX_print_customer_nvm_managed( + &(pdev->customer), + "run_xtalk_extraction():pdev->lldata.customer.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + VL53LX_print_xtalk_config( + &(pdev->xtalk_cfg), + "run_xtalk_extraction():pdev->lldata.xtalk_cfg.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + VL53LX_print_xtalk_extract_config( + &(pdev->xtalk_extract_cfg), + "run_xtalk_extraction():pdev->lldata.xtalk_extract_cfg.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + VL53LX_print_histogram_bin_data( + &(pdev->hist_data), + "run_xtalk_extraction():pdev->lldata.hist_data.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + VL53LX_print_xtalk_histogram_data( + &(pdev->xtalk_shapes), + "pdev->lldata.xtalk_shapes.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + VL53LX_print_xtalk_range_results( + &(pdev->xtalk_results), + "run_xtalk_extraction():pdev->lldata.xtalk_results.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + #endif + */ + + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_get_and_avg_xtalk_samples( + uint8_t num_of_samples, + uint8_t measurement_mode, + int16_t xtalk_filter_thresh_max_mm, + int16_t xtalk_filter_thresh_min_mm, + uint16_t xtalk_max_valid_rate_kcps, + uint8_t xtalk_result_id, + uint8_t xtalk_histo_id, + VL53LX_xtalk_range_results_t *pXR, + VL53LX_histogram_bin_data_t *psum_histo, + VL53LX_histogram_bin_data_t *pavg_histo) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + + VL53LX_range_results_t *prs = + (VL53LX_range_results_t *) pdev->wArea1; + + VL53LX_range_data_t *prange_data; + VL53LX_xtalk_range_data_t *pxtalk_range_data; + + uint8_t i = 0; + uint8_t j = 0; + uint8_t zone_id = 0; + uint8_t final_zone = pdev->zone_cfg.active_zones + 1; + uint8_t valid_result; + + uint8_t smudge_corr_en = 0; + + + + + smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled; + + status = VL53LX_dynamic_xtalk_correction_disable(); + + + VL53LX_load_patch(); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_init_and_start_range( + measurement_mode, + VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); + + + for (i = 0; i <= (final_zone * num_of_samples); i++) { + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_wait_for_range_completion(); + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_get_device_results( + VL53LX_DEVICERESULTSLEVEL_FULL, + prs); + + + + if (status == VL53LX_ERROR_NONE && + pdev->ll_state.rd_device_state != + VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) { + + zone_id = pdev->ll_state.rd_zone_id + xtalk_result_id; + prange_data = &(prs->VL53LX_p_003[0]); + + + if (prs->active_results > 1) { + for (j = 1; + j < prs->active_results; j++) { + if (prs->VL53LX_p_003[j].median_range_mm + < + prange_data->median_range_mm) + prange_data = + &(prs->VL53LX_p_003[j]); + + } + } + + pxtalk_range_data = &(pXR->VL53LX_p_003[zone_id]); + + + + if ((prs->active_results > 0) && + (prange_data->median_range_mm < + xtalk_filter_thresh_max_mm) && + (prange_data->median_range_mm > + xtalk_filter_thresh_min_mm) && + (prange_data->VL53LX_p_009 < + (uint32_t)(xtalk_max_valid_rate_kcps * 16))) { + valid_result = 1; + } else { + valid_result = 0; + } + + if (valid_result == 1) { + + pxtalk_range_data->no_of_samples++; + + pxtalk_range_data->rate_per_spad_kcps_sum += + prange_data->VL53LX_p_009; + + pxtalk_range_data->signal_total_events_sum += + prange_data->VL53LX_p_010; + + pxtalk_range_data->sigma_mm_sum += + (uint32_t)prange_data->VL53LX_p_002; + + + + pxtalk_range_data->median_phase_sum += + (uint32_t)prange_data->VL53LX_p_011; + + + + + } + + if ((valid_result == 1) && (zone_id >= 4)) { + status = VL53LX_sum_histogram_data( + &(pdev->hist_data), + psum_histo); + + + + if (prange_data->VL53LX_p_012 < + pXR->central_histogram__window_start) + pXR->central_histogram__window_start = + prange_data->VL53LX_p_012; + + + if (prange_data->VL53LX_p_013 > + pXR->central_histogram__window_end) + pXR->central_histogram__window_end = + prange_data->VL53LX_p_013; + + } + + } + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_wait_for_firmware_ready(); + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_clear_interrupt_and_enable_next_range( + measurement_mode); + + + } + + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_stop_range(); + } + + VL53LX_unload_patch(); + + + + for (i = 0; i < (pdev->zone_cfg.active_zones + 1); i++) { + + pxtalk_range_data = &(pXR->VL53LX_p_003[i + xtalk_result_id]); + + if (pxtalk_range_data->no_of_samples > 0) { + pxtalk_range_data->rate_per_spad_kcps_avg = + pxtalk_range_data->rate_per_spad_kcps_sum / + (uint32_t)pxtalk_range_data->no_of_samples; + + pxtalk_range_data->signal_total_events_avg = + pxtalk_range_data->signal_total_events_sum / + (int32_t)pxtalk_range_data->no_of_samples; + + pxtalk_range_data->sigma_mm_avg = + pxtalk_range_data->sigma_mm_sum / + (uint32_t)pxtalk_range_data->no_of_samples; + + + + pxtalk_range_data->median_phase_avg = + pxtalk_range_data->median_phase_sum / + (uint32_t)pxtalk_range_data->no_of_samples; + + + + } else { + pxtalk_range_data->rate_per_spad_kcps_avg = + pxtalk_range_data->rate_per_spad_kcps_sum; + pxtalk_range_data->signal_total_events_avg = + pxtalk_range_data->signal_total_events_sum; + pxtalk_range_data->sigma_mm_avg = + pxtalk_range_data->sigma_mm_sum; + + + + pxtalk_range_data->median_phase_avg = + pxtalk_range_data->median_phase_sum; + + + } + } + + + + memcpy(pavg_histo, &(pdev->hist_data), + sizeof(VL53LX_histogram_bin_data_t)); + + + + if (status == VL53LX_ERROR_NONE) { + + pxtalk_range_data = &(pXR->VL53LX_p_003[xtalk_histo_id]); + + status = VL53LX_avg_histogram_data( + pxtalk_range_data->no_of_samples, + psum_histo, + pavg_histo); + } + + + + + if (status == VL53LX_ERROR_NONE) { + if (smudge_corr_en == 1) { + status = VL53LX_dynamic_xtalk_correction_enable(); + } + } + + + return status; + +} + + +VL53LX_Error VL53LX::VL53LX_run_offset_calibration( + int16_t cal_distance_mm, + uint16_t cal_reflectance_pc, + VL53LX_Error *pcal_status) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_DevicePresetModes device_preset_modes[ + VL53LX_MAX_OFFSET_RANGE_RESULTS]; + + VL53LX_range_results_t *prange_results = + (VL53LX_range_results_t *) pdev->wArea1; + + VL53LX_range_data_t *pRData = NULL; + VL53LX_offset_range_data_t *pfs = NULL; + VL53LX_general_config_t *pG = &(pdev->gen_cfg); + VL53LX_additional_offset_cal_data_t *pAO = &(pdev->add_off_cal_data); + + uint8_t i = 0; + uint8_t m = 0; + uint8_t measurement_mode = + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + uint16_t manual_effective_spads = + pG->dss_config__manual_effective_spads_select; + + uint8_t num_of_samples[VL53LX_MAX_OFFSET_RANGE_RESULTS]; + + uint8_t smudge_corr_en = 0; + + + + + switch (pdev->offset_calibration_mode) { + + case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM: + case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY: + device_preset_modes[0] = + VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING; + device_preset_modes[1] = + VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM1_CAL; + device_preset_modes[2] = + VL53LX_DEVICEPRESETMODE_HISTOGRAM_RANGING_MM2_CAL; + break; + + default: + device_preset_modes[0] = + VL53LX_DEVICEPRESETMODE_STANDARD_RANGING; + device_preset_modes[1] = + VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL; + device_preset_modes[2] = + VL53LX_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL; + break; + } + + + + num_of_samples[0] = pdev->offsetcal_cfg.pre_num_of_samples; + num_of_samples[1] = pdev->offsetcal_cfg.mm1_num_of_samples; + num_of_samples[2] = pdev->offsetcal_cfg.mm2_num_of_samples; + + + + + switch (pdev->offset_calibration_mode) { + + case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY: + case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY: + + pdev->offset_results.active_results = 1; + + break; + + default: + + pdev->customer.mm_config__inner_offset_mm = 0; + pdev->customer.mm_config__outer_offset_mm = 0; + pdev->offset_results.active_results = + VL53LX_MAX_OFFSET_RANGE_RESULTS; + + break; + } + + pdev->customer.algo__part_to_part_range_offset_mm = 0; + + + + pdev->offset_results.max_results = VL53LX_MAX_OFFSET_RANGE_RESULTS; + pdev->offset_results.cal_distance_mm = cal_distance_mm; + pdev->offset_results.cal_reflectance_pc = cal_reflectance_pc; + + for (m = 0; m < VL53LX_MAX_OFFSET_RANGE_RESULTS; m++) { + + pfs = &(pdev->offset_results.VL53LX_p_003[m]); + pfs->preset_mode = 0; + pfs->no_of_samples = 0; + pfs->effective_spads = 0; + pfs->peak_rate_mcps = 0; + pfs->VL53LX_p_002 = 0; + pfs->median_range_mm = 0; + } + + + + + smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled; + + status = VL53LX_dynamic_xtalk_correction_disable(); + + + + for (m = 0; m < pdev->offset_results.active_results; m++) { + + pfs = &(pdev->offset_results.VL53LX_p_003[m]); + + pfs->preset_mode = device_preset_modes[m]; + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_preset_mode( + device_preset_modes[m], + + pdev->offsetcal_cfg.dss_config__target_total_rate_mcps, + pdev->offsetcal_cfg.phasecal_config_timeout_us, + pdev->offsetcal_cfg.mm_config_timeout_us, + pdev->offsetcal_cfg.range_config_timeout_us, + + 100); + + pG->dss_config__manual_effective_spads_select = + manual_effective_spads; + + + VL53LX_load_patch(); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_init_and_start_range( + measurement_mode, + VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); + + for (i = 0; i <= (num_of_samples[m] + 2); i++) { + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_wait_for_range_completion(); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_get_device_results( + VL53LX_DEVICERESULTSLEVEL_FULL, + prange_results); + + + + pRData = &(prange_results->VL53LX_p_003[0]); + + if ((prange_results->active_results > 0 && + prange_results->stream_count > 1) && + (pRData->range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE)) { + + pfs->no_of_samples++; + pfs->effective_spads += + (uint32_t)pRData->VL53LX_p_004; + pfs->peak_rate_mcps += + (uint32_t)pRData->peak_signal_count_rate_mcps; + pfs->VL53LX_p_002 += + (uint32_t)pRData->VL53LX_p_002; + pfs->median_range_mm += + (int32_t)pRData->median_range_mm; + + pfs->dss_config__roi_mode_control = + pG->dss_config__roi_mode_control; + pfs->dss_config__manual_effective_spads_select = + pG->dss_config__manual_effective_spads_select; + + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_wait_for_firmware_ready(); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_clear_interrupt_and_enable_next_range( + measurement_mode); + } + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_stop_range(); + } + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WaitUs(Dev, 1000); + } + VL53LX_unload_patch(); + + + if (pfs->no_of_samples > 0) { + + pfs->effective_spads += (pfs->no_of_samples / 2); + pfs->effective_spads /= pfs->no_of_samples; + + pfs->peak_rate_mcps += (pfs->no_of_samples / 2); + pfs->peak_rate_mcps /= pfs->no_of_samples; + + pfs->VL53LX_p_002 += (pfs->no_of_samples / 2); + pfs->VL53LX_p_002 /= pfs->no_of_samples; + + pfs->median_range_mm += (pfs->no_of_samples / 2); + pfs->median_range_mm /= pfs->no_of_samples; + + pfs->range_mm_offset = (int32_t)cal_distance_mm; + pfs->range_mm_offset -= pfs->median_range_mm; + + + if (pfs->preset_mode == + VL53LX_DEVICEPRESETMODE_STANDARD_RANGING) + manual_effective_spads = + (uint16_t)pfs->effective_spads; + } + } + + + + switch (pdev->offset_calibration_mode) { + + case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY: + case VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY: + + + pdev->customer.mm_config__inner_offset_mm += + (int16_t)pdev->offset_results.VL53LX_p_003[0].range_mm_offset; + pdev->customer.mm_config__outer_offset_mm += + (int16_t)pdev->offset_results.VL53LX_p_003[0].range_mm_offset; + break; + + default: + + pdev->customer.mm_config__inner_offset_mm = + (int16_t)pdev->offset_results.VL53LX_p_003[1].range_mm_offset; + pdev->customer.mm_config__outer_offset_mm = + (int16_t)pdev->offset_results.VL53LX_p_003[2].range_mm_offset; + pdev->customer.algo__part_to_part_range_offset_mm = 0; + + + + pAO->result__mm_inner_actual_effective_spads = + (uint16_t)pdev->offset_results.VL53LX_p_003[1].effective_spads; + pAO->result__mm_outer_actual_effective_spads = + (uint16_t)pdev->offset_results.VL53LX_p_003[2].effective_spads; + + pAO->result__mm_inner_peak_signal_count_rtn_mcps = + (uint16_t)pdev->offset_results.VL53LX_p_003[1].peak_rate_mcps; + pAO->result__mm_outer_peak_signal_count_rtn_mcps = + (uint16_t)pdev->offset_results.VL53LX_p_003[2].peak_rate_mcps; + + break; + } + + + + pdev->cust_dmax_cal.ref__actual_effective_spads = + (uint16_t)pdev->offset_results.VL53LX_p_003[0].effective_spads; + pdev->cust_dmax_cal.ref__peak_signal_count_rate_mcps = + (uint16_t)pdev->offset_results.VL53LX_p_003[0].peak_rate_mcps; + + + pdev->cust_dmax_cal.ref__distance_mm = cal_distance_mm * 16; + + pdev->cust_dmax_cal.ref_reflectance_pc = cal_reflectance_pc; + pdev->cust_dmax_cal.coverglass_transmission = 0x0100; + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_customer_nvm_managed( + &(pdev->customer)); + + + + + if (status == VL53LX_ERROR_NONE) { + if (smudge_corr_en == 1) { + status = VL53LX_dynamic_xtalk_correction_enable(); + } + } + + + + + for (m = 0; m < pdev->offset_results.active_results; m++) { + + pfs = &(pdev->offset_results.VL53LX_p_003[m]); + + if (status == VL53LX_ERROR_NONE) { + + pdev->offset_results.cal_report = m; + + if (pfs->no_of_samples < num_of_samples[m]) + status = + VL53LX_WARNING_OFFSET_CAL_MISSING_SAMPLES; + + + if (m == 0 && pfs->VL53LX_p_002 > + ((uint32_t)VL53LX_OFFSET_CAL_MAX_SIGMA_MM << 5)) + status = + VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH; + + if (pfs->peak_rate_mcps > + VL53LX_OFFSET_CAL_MAX_PRE_PEAK_RATE_MCPS) + status = + VL53LX_WARNING_OFFSET_CAL_RATE_TOO_HIGH; + + if (pfs->dss_config__manual_effective_spads_select < + VL53LX_OFFSET_CAL_MIN_EFFECTIVE_SPADS) + status = + VL53LX_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW; + + if (pfs->dss_config__manual_effective_spads_select == 0) + status = + VL53LX_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL; + + if (pfs->no_of_samples == 0) { + status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL; + } + } + } + + + + pdev->offset_results.cal_status = status; + *pcal_status = pdev->offset_results.cal_status; + + + /* + IGNORE_STATUS( + IGNORE_OFFSET_CAL_MISSING_SAMPLES, + VL53LX_WARNING_OFFSET_CAL_MISSING_SAMPLES, + status); + + IGNORE_STATUS( + IGNORE_OFFSET_CAL_SIGMA_TOO_HIGH, + VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH, + status); + + IGNORE_STATUS( + IGNORE_OFFSET_CAL_RATE_TOO_HIGH, + VL53LX_WARNING_OFFSET_CAL_RATE_TOO_HIGH, + status); + + IGNORE_STATUS( + IGNORE_OFFSET_CAL_SPAD_COUNT_TOO_LOW, + VL53LX_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW, + status); + */ + + /* + #ifdef VL53LX_LOG_ENABLE + + + + VL53LX_print_customer_nvm_managed( + &(pdev->customer), + "run_offset_calibration():pdev->lldata.customer.", + VL53LX_TRACE_MODULE_OFFSET_DATA); + + VL53LX_print_dmax_calibration_data( + &(pdev->fmt_dmax_cal), + "run_offset_calibration():pdev->lldata.fmt_dmax_cal.", + VL53LX_TRACE_MODULE_OFFSET_DATA); + + VL53LX_print_dmax_calibration_data( + &(pdev->cust_dmax_cal), + "run_offset_calibration():pdev->lldata.cust_dmax_cal.", + VL53LX_TRACE_MODULE_OFFSET_DATA); + + VL53LX_print_additional_offset_cal_data( + &(pdev->add_off_cal_data), + "run_offset_calibration():pdev->lldata.add_off_cal_data.", + VL53LX_TRACE_MODULE_OFFSET_DATA); + + VL53LX_print_offset_range_results( + &(pdev->offset_results), + "run_offset_calibration():pdev->lldata.offset_results.", + VL53LX_TRACE_MODULE_OFFSET_DATA); + #endif + */ + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_run_phasecal_average( + uint8_t measurement_mode, + uint8_t phasecal_result__vcsel_start, + uint16_t phasecal_num_of_samples, + VL53LX_range_results_t *prange_results, + uint16_t *pphasecal_result__reference_phase, + uint16_t *pzero_distance_phase) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + uint16_t i = 0; + uint16_t m = 0; + uint32_t samples = 0; + + uint32_t period = 0; + uint32_t VL53LX_p_014 = 0; + uint32_t phasecal_result__reference_phase = 0; + uint32_t zero_distance_phase = 0; + + + VL53LX_load_patch(); + + for (m = 0; m < phasecal_num_of_samples; m++) { + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_init_and_start_range( + measurement_mode, + VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); + + for (i = 0; i <= 1; i++) { + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_wait_for_range_completion(); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_get_device_results( + VL53LX_DEVICERESULTSLEVEL_FULL, + prange_results); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_wait_for_firmware_ready(); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_clear_interrupt_and_enable_next_range( + measurement_mode); + } + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_stop_range(); + } + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WaitUs(Dev, 1000); + } + + + + if (status == VL53LX_ERROR_NONE) { + + samples++; + + + period = 2048 * + (uint32_t)VL53LX_decode_vcsel_period( + pdev->hist_data.VL53LX_p_005); + + VL53LX_p_014 = period; + VL53LX_p_014 += (uint32_t)( + pdev->hist_data.phasecal_result__reference_phase); + VL53LX_p_014 += + (2048 * + (uint32_t)phasecal_result__vcsel_start); + VL53LX_p_014 -= (2048 * + (uint32_t)pdev->hist_data.cal_config__vcsel_start); + + VL53LX_p_014 = VL53LX_p_014 % period; + + phasecal_result__reference_phase += (uint32_t)( + pdev->hist_data.phasecal_result__reference_phase); + + zero_distance_phase += (uint32_t)VL53LX_p_014; + } + } + VL53LX_unload_patch(); + + + + if (status == VL53LX_ERROR_NONE && samples > 0) { + + phasecal_result__reference_phase += (samples >> 1); + phasecal_result__reference_phase /= samples; + + zero_distance_phase += (samples >> 1); + zero_distance_phase /= samples; + + *pphasecal_result__reference_phase = + (uint16_t)phasecal_result__reference_phase; + *pzero_distance_phase = + (uint16_t)zero_distance_phase; + } + + return status; +} + +VL53LX_Error VL53LX::VL53LX_run_zone_calibration( + VL53LX_DevicePresetModes device_preset_mode, + VL53LX_DeviceZonePreset zone_preset, + VL53LX_zone_config_t *pzone_cfg, + int16_t cal_distance_mm, + uint16_t cal_reflectance_pc, + VL53LX_Error *pcal_status) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_LLDriverResults_t *pres = + VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_range_results_t *pRR = + (VL53LX_range_results_t *) pdev->wArea1; + VL53LX_range_data_t *prange_data = NULL; + VL53LX_zone_calibration_data_t *pzone_data = NULL; + + uint16_t i = 0; + uint16_t m = 0; + + uint8_t z = 0; + uint8_t measurement_mode = + VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + + VL53LX_OffsetCorrectionMode offset_cor_mode = + VL53LX_OFFSETCORRECTIONMODE__NONE; + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_preset_mode( + device_preset_mode, + + pdev->zonecal_cfg.dss_config__target_total_rate_mcps, + pdev->zonecal_cfg.phasecal_config_timeout_us, + pdev->zonecal_cfg.mm_config_timeout_us, + pdev->zonecal_cfg.range_config_timeout_us, + + 100); + + + + if (zone_preset == VL53LX_DEVICEZONEPRESET_CUSTOM) { + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_zone_config( + pzone_cfg); + + } else if (zone_preset != VL53LX_DEVICEZONEPRESET_NONE) { + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_zone_preset( + zone_preset); + } + + + + pres->zone_cal.preset_mode = device_preset_mode; + pres->zone_cal.zone_preset = zone_preset; + + pres->zone_cal.cal_distance_mm = cal_distance_mm * 16; + pres->zone_cal.cal_reflectance_pc = cal_reflectance_pc; + pres->zone_cal.max_zones = VL53LX_MAX_USER_ZONES; + pres->zone_cal.active_zones = pdev->zone_cfg.active_zones + 1; + + for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) { + pres->zone_cal.VL53LX_p_003[i].no_of_samples = 0; + pres->zone_cal.VL53LX_p_003[i].effective_spads = 0; + pres->zone_cal.VL53LX_p_003[i].peak_rate_mcps = 0; + pres->zone_cal.VL53LX_p_003[i].VL53LX_p_011 = 0; + pres->zone_cal.VL53LX_p_003[i].VL53LX_p_002 = 0; + pres->zone_cal.VL53LX_p_003[i].median_range_mm = 0; + pres->zone_cal.VL53LX_p_003[i].range_mm_offset = 0; + } + + pres->zone_cal.phasecal_result__reference_phase = 0; + pres->zone_cal.zero_distance_phase = 0; + + + + status = + VL53LX_get_offset_correction_mode( + &offset_cor_mode); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_offset_correction_mode( + VL53LX_OFFSETCORRECTIONMODE__NONE); + + + VL53LX_load_patch(); + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_init_and_start_range( + measurement_mode, + VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); + + + + + m = (pdev->zonecal_cfg.zone_num_of_samples + 2) * + (uint16_t)pres->zone_cal.active_zones; + + + for (i = 0; i <= m; i++) { + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_wait_for_range_completion(); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_get_device_results( + VL53LX_DEVICERESULTSLEVEL_FULL, + pRR); + + + + prange_data = &(pRR->VL53LX_p_003[0]); + + if (pRR->active_results > 0 && + i > (uint16_t)pres->zone_cal.active_zones) { + + if (prange_data->range_status == + VL53LX_DEVICEERROR_RANGECOMPLETE) { + + pres->zone_cal.phasecal_result__reference_phase + = + pdev->hist_data.phasecal_result__reference_phase + ; + pres->zone_cal.zero_distance_phase = + pdev->hist_data.zero_distance_phase; + + pzone_data = + &(pres->zone_cal.VL53LX_p_003[pRR->zone_id]); + pzone_data->no_of_samples++; + pzone_data->effective_spads += + (uint32_t)prange_data->VL53LX_p_004; + pzone_data->peak_rate_mcps += (uint32_t)( + prange_data->peak_signal_count_rate_mcps); + pzone_data->VL53LX_p_011 += + (uint32_t)prange_data->VL53LX_p_011; + pzone_data->VL53LX_p_002 += + (uint32_t)prange_data->VL53LX_p_002; + pzone_data->median_range_mm += + (int32_t)prange_data->median_range_mm; + + } + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_wait_for_firmware_ready(); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_clear_interrupt_and_enable_next_range( + measurement_mode); + } + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_stop_range(); + } + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_WaitUs(Dev, 1000); + } + VL53LX_unload_patch(); + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_run_phasecal_average( + measurement_mode, + pdev->hist_data.phasecal_result__vcsel_start, + + pdev->zonecal_cfg.phasecal_num_of_samples, + + pRR, + &(pres->zone_cal.phasecal_result__reference_phase), + &(pres->zone_cal.zero_distance_phase)); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_offset_correction_mode( + offset_cor_mode); + + + + if (status == VL53LX_ERROR_NONE) { + + for (z = 0; z < pres->zone_cal.active_zones; z++) { + + pzone_data = &(pres->zone_cal.VL53LX_p_003[z]); + + + if (pzone_data->no_of_samples > 0) { + + pzone_data->effective_spads += + (pzone_data->no_of_samples / 2); + pzone_data->effective_spads /= + pzone_data->no_of_samples; + + pzone_data->peak_rate_mcps += + (pzone_data->no_of_samples / 2); + pzone_data->peak_rate_mcps /= + pzone_data->no_of_samples; + + pzone_data->VL53LX_p_011 += + (pzone_data->no_of_samples / 2); + pzone_data->VL53LX_p_011 /= + pzone_data->no_of_samples; + + pzone_data->VL53LX_p_002 += + (pzone_data->no_of_samples / 2); + pzone_data->VL53LX_p_002 /= + pzone_data->no_of_samples; + + + + pzone_data->median_range_mm = + VL53LX_range_maths( + pdev->stat_nvm.osc_measured__fast_osc__frequency + , (uint16_t)pzone_data->VL53LX_p_011, + pres->zone_cal.zero_distance_phase, + 2, + 0x0800, + 0); + + pzone_data->range_mm_offset = + ((int32_t)cal_distance_mm) * 4; + pzone_data->range_mm_offset -= + pzone_data->median_range_mm; + + + if (pzone_data->no_of_samples < + pdev->zonecal_cfg.zone_num_of_samples) + status = + VL53LX_WARNING_ZONE_CAL_MISSING_SAMPLES; + + + if (pzone_data->VL53LX_p_002 > + ((uint32_t)VL53LX_ZONE_CAL_MAX_SIGMA_MM + << 5)) + status = + VL53LX_WARNING_ZONE_CAL_SIGMA_TOO_HIGH; + + if (pzone_data->peak_rate_mcps > + VL53LX_ZONE_CAL_MAX_PRE_PEAK_RATE_MCPS) + status = + VL53LX_WARNING_ZONE_CAL_RATE_TOO_HIGH; + + } else { + status = VL53LX_ERROR_ZONE_CAL_NO_SAMPLE_FAIL; + } + } + } + + + + pres->zone_cal.cal_status = status; + *pcal_status = pres->zone_cal.cal_status; + + /* + + IGNORE_STATUS( + IGNORE_ZONE_CAL_MISSING_SAMPLES, + VL53LX_WARNING_ZONE_CAL_MISSING_SAMPLES, + status); + + IGNORE_STATUS( + IGNORE_ZONE_CAL_SIGMA_TOO_HIGH, + VL53LX_WARNING_ZONE_CAL_SIGMA_TOO_HIGH, + status); + + IGNORE_STATUS( + IGNORE_ZONE_CAL_RATE_TOO_HIGH, + VL53LX_WARNING_ZONE_CAL_RATE_TOO_HIGH, + status); + */ + /* + #ifdef VL53LX_LOG_ENABLE + + + + VL53LX_print_zone_calibration_results( + &(pres->zone_cal), + "run_zone_calibration():pdev->llresults.zone_cal.", + VL53LX_TRACE_MODULE_OFFSET_DATA); + + #endif + */ + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_run_spad_rate_map( + VL53LX_DeviceTestMode device_test_mode, + VL53LX_DeviceSscArray array_select, + uint32_t ssc_config_timeout_us, + VL53LX_spad_rate_data_t *pspad_rate_data) +{ + + + + VL53LX_Error status = VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_enable_powerforce(); + } + + + + if (status == VL53LX_ERROR_NONE) { + pdev->ssc_cfg.array_select = array_select; + pdev->ssc_cfg.timeout_us = ssc_config_timeout_us; + status = + VL53LX_set_ssc_config( + &(pdev->ssc_cfg), + pdev->stat_nvm.osc_measured__fast_osc__frequency); + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_run_device_test( + device_test_mode); + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_get_spad_rate_data( + pspad_rate_data); + + if (device_test_mode == VL53LX_DEVICETESTMODE_LCR_VCSEL_ON) { + pspad_rate_data->fractional_bits = 7; + } else { + pspad_rate_data->fractional_bits = 15; + } + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_powerforce(); + } + /* + #ifdef VL53LX_LOG_ENABLE + + + if (status == VL53LX_ERROR_NONE) { + VL53LX_print_spad_rate_data( + pspad_rate_data, + "run_spad_rate_map():", + VL53LX_TRACE_MODULE_SPAD_RATE_MAP); + VL53LX_print_spad_rate_map( + pspad_rate_data, + "run_spad_rate_map():", + VL53LX_TRACE_MODULE_SPAD_RATE_MAP); + } + #endif + */ + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_run_device_test( + VL53LX_DeviceTestMode device_test_mode) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t comms_buffer[2]; + uint8_t gpio_hv_mux__ctrl = 0; + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_RdByte( + Dev, + VL53LX_GPIO_HV_MUX__CTRL, + &gpio_hv_mux__ctrl); + + if (status == VL53LX_ERROR_NONE) { + pdev->stat_cfg.gpio_hv_mux__ctrl = gpio_hv_mux__ctrl; + } + + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_start_test( + device_test_mode); + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_wait_for_test_completion(); + } + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_ReadMulti( + Dev, + VL53LX_RESULT__RANGE_STATUS, + comms_buffer, + 2); + + if (status == VL53LX_ERROR_NONE) { + pdev->sys_results.result__range_status = comms_buffer[0]; + pdev->sys_results.result__report_status = comms_buffer[1]; + } + + + + pdev->sys_results.result__range_status &= + VL53LX_RANGE_STATUS__RANGE_STATUS_MASK; + + if (status == VL53LX_ERROR_NONE) { + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_clear_interrupt(); + } + } + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_start_test(0x00); + + + return status; +} + +void VL53LX::VL53LX_hist_xtalk_extract_data_init( + VL53LX_hist_xtalk_extract_data_t *pxtalk_data) +{ + + + int32_t lb = 0; + + pxtalk_data->sample_count = 0U; + pxtalk_data->pll_period_mm = 0U; + pxtalk_data->peak_duration_us_sum = 0U; + pxtalk_data->effective_spad_count_sum = 0U; + pxtalk_data->zero_distance_phase_sum = 0U; + pxtalk_data->zero_distance_phase_avg = 0U; + pxtalk_data->event_scaler_sum = 0U; + pxtalk_data->event_scaler_avg = 4096U; + pxtalk_data->signal_events_sum = 0; + pxtalk_data->xtalk_rate_kcps_per_spad = 0U; + pxtalk_data->VL53LX_p_012 = 0U; + pxtalk_data->VL53LX_p_013 = 0U; + pxtalk_data->target_start = 0U; + + for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) { + pxtalk_data->bin_data_sums[lb] = 0; + } + +} + +VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_update( + int16_t target_distance_mm, + uint16_t target_width_oversize, + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data) +{ + VL53LX_Error status = VL53LX_ERROR_NONE; + + status = + VL53LX_hist_xtalk_extract_calc_window( + target_distance_mm, + target_width_oversize, + phist_bins, + pxtalk_data); + + if (status == VL53LX_ERROR_NONE) { + status = + VL53LX_hist_xtalk_extract_calc_event_sums( + phist_bins, + pxtalk_data); + } + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_hist_xtalk_extract_fini( + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data, + VL53LX_xtalk_calibration_results_t *pxtalk_cal, + VL53LX_xtalk_histogram_shape_t *pxtalk_shape) +{ + + + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_xtalk_calibration_results_t *pX = pxtalk_cal; + + + if (pxtalk_data->sample_count > 0) { + + + pxtalk_data->event_scaler_avg = pxtalk_data->event_scaler_sum; + pxtalk_data->event_scaler_avg += + (pxtalk_data->sample_count >> 1); + pxtalk_data->event_scaler_avg /= pxtalk_data->sample_count; + + + + status = + VL53LX_hist_xtalk_extract_calc_rate_per_spad( + pxtalk_data); + + + + if (status == VL53LX_ERROR_NONE) { + + + pxtalk_data->zero_distance_phase_avg = + pxtalk_data->zero_distance_phase_sum; + pxtalk_data->zero_distance_phase_avg += + (pxtalk_data->sample_count >> 1); + pxtalk_data->zero_distance_phase_avg /= + pxtalk_data->sample_count; + + + status = + VL53LX_hist_xtalk_extract_calc_shape( + pxtalk_data, + pxtalk_shape); + + + + + pxtalk_shape->phasecal_result__vcsel_start = + phist_bins->phasecal_result__vcsel_start; + pxtalk_shape->cal_config__vcsel_start = + phist_bins->cal_config__vcsel_start; + pxtalk_shape->vcsel_width = + phist_bins->vcsel_width; + pxtalk_shape->VL53LX_p_015 = + phist_bins->VL53LX_p_015; + } + + + if (status == VL53LX_ERROR_NONE) { + + + pX->algo__crosstalk_compensation_plane_offset_kcps = + pxtalk_data->xtalk_rate_kcps_per_spad; + pX->algo__crosstalk_compensation_x_plane_gradient_kcps + = 0U; + pX->algo__crosstalk_compensation_y_plane_gradient_kcps + = 0U; + + } + } + + + return status; +} + + +VL53LX_Error VL53LX::VL53LX_run_hist_xtalk_extraction( + int16_t cal_distance_mm, + VL53LX_Error *pcal_status) +{ + + +#define OVERSIZE 4 + VL53LX_Error status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalkextract_config_t *pX = &(pdev->xtalk_extract_cfg); + VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg); + VL53LX_xtalk_calibration_results_t *pXC = &(pdev->xtalk_cal); + + + + uint8_t smudge_corr_en = 0; + uint8_t i = 0; + int8_t k = 0; + uint8_t nbloops; + int32_t initMergeSize = 0; + int32_t MergeEnabled = 0; + uint32_t deltaXtalk; + uint32_t stepXtalk; + uint32_t XtalkMin; + uint32_t XtalkMax; + uint8_t measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + int8_t MaxId; + uint8_t histo_merge_nb; + uint8_t wait_for_accumulation; + VL53LX_range_results_t *prange_results = + (VL53LX_range_results_t *) pdev->wArea1; + uint8_t Very1stRange = 0; + + + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_set_preset_mode( + VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE, + pX->dss_config__target_total_rate_mcps, + pX->phasecal_config_timeout_us, + pX->mm_config_timeout_us, + pX->range_config_timeout_us, + 100); + + + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_disable_xtalk_compensation(); + } + + + + smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled; + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_dynamic_xtalk_correction_disable(); + } + + + VL53LX_load_patch(); + + VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, + &initMergeSize); + VL53LX_get_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE, + &MergeEnabled); + memset(&pdev->xtalk_cal, 0, sizeof(pdev->xtalk_cal)); + + if (status == VL53LX_ERROR_NONE) + status = VL53LX_init_and_start_range(measurement_mode, + VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); + + MaxId = pdev->tuning_parms.tp_hist_merge_max_size - 1; + nbloops = (MergeEnabled == 0 ? 1 : 2); + for (k = 0; k < nbloops; k++) { + + VL53LX_hist_xtalk_extract_data_init( + &(pdev->xtalk_extract)); + VL53LX_set_tuning_parm( + VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, + k * MaxId + 1); + + for (i = 0; i <= pX->num_of_samples; i++) { + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_wait_for_range_completion(); + } + if (status == VL53LX_ERROR_NONE) + status = VL53LX_get_device_results( + VL53LX_DEVICERESULTSLEVEL_FULL, + prange_results); + Very1stRange = + (pdev->ll_state.rd_device_state == + VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC); + + VL53LX_compute_histo_merge_nb(&histo_merge_nb); + wait_for_accumulation = ((k != 0) && + (MergeEnabled) && + (status == VL53LX_ERROR_NONE) && + (histo_merge_nb < + pdev->tuning_parms.tp_hist_merge_max_size)); + if (wait_for_accumulation) { + i = 0; + } else { + if ((status == VL53LX_ERROR_NONE) && + (!Very1stRange)) { + status = + VL53LX_hist_xtalk_extract_update( + cal_distance_mm, + OVERSIZE, + &(pdev->hist_data), + &(pdev->xtalk_extract)); + } + } + + if (status == VL53LX_ERROR_NONE) { + status = VL53LX_wait_for_firmware_ready(); + } + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_clear_interrupt_and_enable_next_range(measurement_mode); + + + if (status == VL53LX_ERROR_NONE) + status = + VL53LX_hist_xtalk_extract_fini( + &(pdev->hist_data), + &(pdev->xtalk_extract), + &(pdev->xtalk_cal), + &(pdev->xtalk_shapes.xtalk_shape)); + if (status != VL53LX_ERROR_NONE) { + goto LOOPOUT; + } + pXC->algo__xtalk_cpo_HistoMerge_kcps[k * MaxId] = + pXC->algo__crosstalk_compensation_plane_offset_kcps; + } + } + +LOOPOUT: + + VL53LX_stop_range(); + + VL53LX_set_tuning_parm(VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, + initMergeSize); + VL53LX_unload_patch(); + + if (status != VL53LX_ERROR_NONE) { + status = VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL; + } else if ((MergeEnabled == 1) && (MaxId > 0)) { + XtalkMin = pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0]; + XtalkMax = + pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[MaxId]; + pdev->xtalk_cal. + algo__crosstalk_compensation_plane_offset_kcps = XtalkMin; + if (XtalkMax > XtalkMin) { + deltaXtalk = XtalkMax - XtalkMin; + stepXtalk = deltaXtalk / MaxId; + for (k = 1; k < MaxId; k++) + pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[k] = + XtalkMin + stepXtalk * k; + } else + status = + VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL; + } + + if (status == VL53LX_ERROR_NONE) { + pC->algo__crosstalk_compensation_x_plane_gradient_kcps = + pXC->algo__crosstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps = + pXC->algo__crosstalk_compensation_y_plane_gradient_kcps; + pC->algo__crosstalk_compensation_plane_offset_kcps = + pXC->algo__crosstalk_compensation_plane_offset_kcps; + } + + + pdev->xtalk_results.cal_status = status; + *pcal_status = pdev->xtalk_results.cal_status; + + + status = VL53LX_enable_xtalk_compensation(); + if (smudge_corr_en == 1) { + status = VL53LX_dynamic_xtalk_correction_enable(); + } + /* + #ifdef VL53LX_LOG_ENABLE + + + + VL53LX_print_customer_nvm_managed( + &(pdev->customer), + "run_xtalk_extraction():pdev->lldata.customer.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + VL53LX_print_xtalk_config( + &(pdev->xtalk_cfg), + "run_xtalk_extraction():pdev->lldata.xtalk_cfg.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + VL53LX_print_xtalk_histogram_data( + &(pdev->xtalk_shapes), + "pdev->lldata.xtalk_shapes.", + VL53LX_TRACE_MODULE_XTALK_DATA); + + #endif + */ + + return status; +} + +/* vl53lx_api.c */ + +VL53LX_Error VL53LX::VL53LX_GetVersion(VL53LX_Version_t *pVersion) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + pVersion->major = VL53LX_IMPLEMENTATION_VER_MAJOR; + pVersion->minor = VL53LX_IMPLEMENTATION_VER_MINOR; + pVersion->build = VL53LX_IMPLEMENTATION_VER_SUB; + + pVersion->revision = VL53LX_IMPLEMENTATION_VER_REVISION; + + return Status; +} + + +VL53LX_Error VL53LX::VL53LX_GetProductRevision( + uint8_t *pProductRevisionMajor, uint8_t *pProductRevisionMinor) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint8_t revision_id; + VL53LX_LLDriverData_t *pLLData; + + + pLLData = VL53LXDevStructGetLLDriverHandle(Dev); + revision_id = pLLData->nvm_copy_data.identification__revision_id; + *pProductRevisionMajor = 1; + *pProductRevisionMinor = (revision_id & 0xF0) >> 4; + + return Status; + +} + +VL53LX_Error VL53LX::VL53LX_GetDeviceInfo( + VL53LX_DeviceInfo_t *pVL53LX_DeviceInfo) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint8_t revision_id; + VL53LX_LLDriverData_t *pLLData; + + pLLData = VL53LXDevStructGetLLDriverHandle(Dev); + + pVL53LX_DeviceInfo->ProductType = + pLLData->nvm_copy_data.identification__module_type; + + revision_id = pLLData->nvm_copy_data.identification__revision_id; + pVL53LX_DeviceInfo->ProductRevisionMajor = 1; + pVL53LX_DeviceInfo->ProductRevisionMinor = (revision_id & 0xF0) >> 4; + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_GetUID(uint64_t *pUid) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint8_t fmtdata[8]; + + Status = VL53LX_read_nvm_raw_data( + (uint8_t)(0x1F8 >> 2), + (uint8_t)(8 >> 2), + fmtdata); + memcpy(pUid, fmtdata, sizeof(uint64_t)); + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_SetDeviceAddress(uint8_t DeviceAddress) +{ + + VL53LX_Error Status = VL53LX_ERROR_NONE; + + Status = VL53LX_WrByte(Dev, VL53LX_I2C_SLAVE__DEVICE_ADDRESS, + DeviceAddress / 2); + + if (Status == VL53LX_ERROR_NONE) { + Dev->I2cDevAddr = DeviceAddress; + } + + return Status; +} + + +VL53LX_Error VL53LX::VL53LX_DataInit() +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev; + uint8_t measurement_mode; + + + +#ifdef USE_I2C_2V8 + Status = VL53LX_RdByte(Dev, VL53LX_PAD_I2C_HV__EXTSUP_CONFIG, &i); + if (Status == VL53LX_ERROR_NONE) { + i = (i & 0xfe) | 0x01; + Status = VL53LX_WrByte(Dev, VL53LX_PAD_I2C_HV__EXTSUP_CONFIG, + i); + } +#endif + + if (Status == VL53LX_ERROR_NONE) { + Status = VL53LX_data_init(1); + } + + Status = SetPresetModeL3CX( + VL53LX_DISTANCEMODE_LONG, + 1000); + + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_SetMeasurementTimingBudgetMicroSeconds( + 33333); + + if (Status == VL53LX_ERROR_NONE) { + Status = SetInterMeasurementPeriodMilliSeconds(1000); + } + + if (Status == VL53LX_ERROR_NONE) { + pdev = VL53LXDevStructGetLLDriverHandle(Dev); + memset(&pdev->per_vcsel_cal_data, 0, + sizeof(pdev->per_vcsel_cal_data)); + } + + if (Status == VL53LX_ERROR_NONE) { + Status = VL53LX_set_dmax_mode( + VL53LX_DEVICEDMAXMODE__CUST_CAL_DATA); + } + + + measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + VL53LXDevDataSet(Dev, LLData.measurement_mode, measurement_mode); + + VL53LXDevDataSet(Dev, CurrentParameters.DistanceMode, + VL53LX_DISTANCEMODE_LONG); + + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_WaitDeviceBooted() +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + Status = VL53LX_poll_for_boot_completion( + VL53LX_BOOT_COMPLETION_POLLING_TIMEOUT_MS); + + return Status; +} + +VL53LX_Error VL53LX::ComputeDevicePresetMode( + VL53LX_DistanceModes DistanceMode, + VL53LX_DevicePresetModes *pDevicePresetMode) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + uint8_t DistIdx; + VL53LX_DevicePresetModes RangingModes[3] = { + VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE, + VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE, + VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE + }; + + switch (DistanceMode) { + case VL53LX_DISTANCEMODE_SHORT: + DistIdx = 0; + break; + case VL53LX_DISTANCEMODE_MEDIUM: + DistIdx = 1; + break; + default: + DistIdx = 2; + } + + *pDevicePresetMode = RangingModes[DistIdx]; + + return Status; +} + +VL53LX_Error VL53LX::SetPresetModeL3CX( + VL53LX_DistanceModes DistanceMode, + uint32_t inter_measurement_period_ms) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_DevicePresetModes device_preset_mode; + uint8_t measurement_mode; + uint16_t dss_config__target_total_rate_mcps; + uint32_t phasecal_config_timeout_us; + uint32_t mm_config_timeout_us; + uint32_t lld_range_config_timeout_us; + + + measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + + Status = ComputeDevicePresetMode(DistanceMode, + &device_preset_mode); + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_get_preset_mode_timing_cfg( + device_preset_mode, + &dss_config__target_total_rate_mcps, + &phasecal_config_timeout_us, + &mm_config_timeout_us, + &lld_range_config_timeout_us); + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_set_preset_mode( + device_preset_mode, + dss_config__target_total_rate_mcps, + phasecal_config_timeout_us, + mm_config_timeout_us, + lld_range_config_timeout_us, + inter_measurement_period_ms); + + if (Status == VL53LX_ERROR_NONE) + VL53LXDevDataSet(Dev, LLData.measurement_mode, + measurement_mode); + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_SetDistanceMode( + VL53LX_DistanceModes DistanceMode) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint32_t inter_measurement_period_ms; + uint32_t TimingBudget; + uint32_t MmTimeoutUs; + uint32_t PhaseCalTimeoutUs; + + if ((DistanceMode != VL53LX_DISTANCEMODE_SHORT) && + (DistanceMode != VL53LX_DISTANCEMODE_MEDIUM) && + (DistanceMode != VL53LX_DISTANCEMODE_LONG)) { + return VL53LX_ERROR_INVALID_PARAMS; + } + + inter_measurement_period_ms = VL53LXDevDataGet(Dev, + LLData.inter_measurement_period_ms); + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_get_timeouts_us(&PhaseCalTimeoutUs, + &MmTimeoutUs, &TimingBudget); + + if (Status == VL53LX_ERROR_NONE) + Status = SetPresetModeL3CX( + DistanceMode, + inter_measurement_period_ms); + + if (Status == VL53LX_ERROR_NONE) { + VL53LXDevDataSet(Dev, CurrentParameters.DistanceMode, + DistanceMode); + } + + if (Status == VL53LX_ERROR_NONE) { + Status = VL53LX_set_timeouts_us(PhaseCalTimeoutUs, + MmTimeoutUs, TimingBudget); + + if (Status == VL53LX_ERROR_NONE) + VL53LXDevDataSet(Dev, LLData.range_config_timeout_us, + TimingBudget); + } + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_GetDistanceMode( + VL53LX_DistanceModes *pDistanceMode) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + + *pDistanceMode = VL53LXDevDataGet(Dev, CurrentParameters.DistanceMode); + + return Status; +} + + +VL53LX_Error VL53LX::VL53LX_SetMeasurementTimingBudgetMicroSeconds( + uint32_t MeasurementTimingBudgetMicroSeconds) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint32_t TimingGuard; + uint32_t divisor; + uint32_t TimingBudget; + uint32_t MmTimeoutUs; + uint32_t PhaseCalTimeoutUs; + uint32_t FDAMaxTimingBudgetUs = FDA_MAX_TIMING_BUDGET_US; + + if (MeasurementTimingBudgetMicroSeconds > 10000000) { + Status = VL53LX_ERROR_INVALID_PARAMS; + } + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_get_timeouts_us( + &PhaseCalTimeoutUs, + &MmTimeoutUs, + &TimingBudget); + + TimingGuard = 1700; + divisor = 6; + + if (MeasurementTimingBudgetMicroSeconds <= TimingGuard) { + Status = VL53LX_ERROR_INVALID_PARAMS; + } else { + TimingBudget = (MeasurementTimingBudgetMicroSeconds + - TimingGuard); + } + + if (Status == VL53LX_ERROR_NONE) { + if (TimingBudget > FDAMaxTimingBudgetUs) { + Status = VL53LX_ERROR_INVALID_PARAMS; + } else { + TimingBudget /= divisor; + Status = VL53LX_set_timeouts_us( + PhaseCalTimeoutUs, + MmTimeoutUs, + TimingBudget); + } + + if (Status == VL53LX_ERROR_NONE) + VL53LXDevDataSet(Dev, + LLData.range_config_timeout_us, + TimingBudget); + } + + if (Status == VL53LX_ERROR_NONE) { + VL53LXDevDataSet(Dev, + CurrentParameters.MeasurementTimingBudgetMicroSeconds, + MeasurementTimingBudgetMicroSeconds); + } + + return Status; +} + + +VL53LX_Error VL53LX::VL53LX_GetMeasurementTimingBudgetMicroSeconds( + uint32_t *pMeasurementTimingBudgetMicroSeconds) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint32_t MmTimeoutUs = 0; + uint32_t RangeTimeoutUs = 0; + uint32_t PhaseCalTimeoutUs = 0; + + *pMeasurementTimingBudgetMicroSeconds = 0; + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_get_timeouts_us( + &PhaseCalTimeoutUs, + &MmTimeoutUs, + &RangeTimeoutUs); + + if (Status == VL53LX_ERROR_NONE) + *pMeasurementTimingBudgetMicroSeconds = (6 * RangeTimeoutUs) + + 1700; + + return Status; +} + +VL53LX_Error VL53LX::SetInterMeasurementPeriodMilliSeconds( + uint32_t InterMeasurementPeriodMilliSeconds) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint32_t adjustedIMP; + + adjustedIMP = InterMeasurementPeriodMilliSeconds; + adjustedIMP += (adjustedIMP * 64) / 1000; + + Status = VL53LX_set_inter_measurement_period_ms( + adjustedIMP); + + return Status; +} + +VL53LX_Error VL53LX::GetInterMeasurementPeriodMilliSeconds( + uint32_t *pInterMeasurementPeriodMilliSeconds) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint32_t adjustedIMP; + + + Status = VL53LX_get_inter_measurement_period_ms(&adjustedIMP); + + adjustedIMP -= (adjustedIMP * 64) / 1000; + *pInterMeasurementPeriodMilliSeconds = adjustedIMP; + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_StartMeasurement() +{ +#define TIMED_MODE_TIMING_GUARD_MILLISECONDS 4 + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint8_t DeviceMeasurementMode; + VL53LX_Error lStatus; + uint32_t MTBus, IMPms; + + + VL53LX_load_patch(); + + DeviceMeasurementMode = VL53LXDevDataGet(Dev, LLData.measurement_mode); + + + if ((Status == VL53LX_ERROR_NONE) && + (DeviceMeasurementMode == VL53LX_DEVICEMEASUREMENTMODE_TIMED)) { + lStatus = VL53LX_GetMeasurementTimingBudgetMicroSeconds( + &MTBus); + + MTBus /= 1000; + lStatus = GetInterMeasurementPeriodMilliSeconds( + &IMPms); + + SUPPRESS_UNUSED_WARNING(lStatus); + if (IMPms < MTBus + TIMED_MODE_TIMING_GUARD_MILLISECONDS) { + Status = VL53LX_ERROR_INVALID_PARAMS; + } + } + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_init_and_start_range( + DeviceMeasurementMode, + VL53LX_DEVICECONFIGLEVEL_FULL); + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_StopMeasurement() +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + Status = VL53LX_stop_range(); + + VL53LX_unload_patch(); + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_ClearInterruptAndStartMeasurement() +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint8_t DeviceMeasurementMode; + + DeviceMeasurementMode = VL53LXDevDataGet(Dev, LLData.measurement_mode); + + Status = VL53LX_clear_interrupt_and_enable_next_range( + DeviceMeasurementMode); + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_GetMeasurementDataReady(uint8_t *pMeasurementDataReady) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + Status = VL53LX_is_new_data_ready(pMeasurementDataReady); + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_WaitMeasurementDataReady() +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + Status = VL53LX_poll_for_range_completion( + VL53LX_RANGE_COMPLETION_POLLING_TIMEOUT_MS); + + return Status; +} + +uint8_t VL53LX::ConvertStatusHisto(uint8_t FilteredRangeStatus) +{ + uint8_t RangeStatus; + + switch (FilteredRangeStatus) { + case VL53LX_DEVICEERROR_RANGEPHASECHECK: + RangeStatus = VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL; + break; + case VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK: + RangeStatus = VL53LX_RANGESTATUS_SIGMA_FAIL; + break; + case VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK: + RangeStatus = + VL53LX_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL; + break; + case VL53LX_DEVICEERROR_PHASECONSISTENCY: + RangeStatus = VL53LX_RANGESTATUS_WRAP_TARGET_FAIL; + break; + case VL53LX_DEVICEERROR_PREV_RANGE_NO_TARGETS: + RangeStatus = VL53LX_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL; + break; + case VL53LX_DEVICEERROR_EVENTCONSISTENCY: + RangeStatus = VL53LX_RANGESTATUS_WRAP_TARGET_FAIL; + break; + case VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE: + RangeStatus = VL53LX_RANGESTATUS_RANGE_VALID_MERGED_PULSE; + break; + case VL53LX_DEVICEERROR_RANGECOMPLETE: + RangeStatus = VL53LX_RANGESTATUS_RANGE_VALID; + break; + default: + RangeStatus = VL53LX_RANGESTATUS_NONE; + } + + return RangeStatus; +} + +VL53LX_Error VL53LX::SetTargetData( + uint8_t active_results, uint8_t device_status, + VL53LX_range_data_t *presults_data, + VL53LX_TargetRangeData_t *pRangeData) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint8_t FilteredRangeStatus; + FixPoint1616_t AmbientRate; + FixPoint1616_t SignalRate; + FixPoint1616_t TempFix1616; + int16_t Range; + + SUPPRESS_UNUSED_WARNING(Dev); + + FilteredRangeStatus = presults_data->range_status & 0x1F; + + SignalRate = VL53LX_FIXPOINT97TOFIXPOINT1616( + presults_data->peak_signal_count_rate_mcps); + pRangeData->SignalRateRtnMegaCps + = SignalRate; + + AmbientRate = VL53LX_FIXPOINT97TOFIXPOINT1616( + presults_data->ambient_count_rate_mcps); + pRangeData->AmbientRateRtnMegaCps = AmbientRate; + + TempFix1616 = VL53LX_FIXPOINT97TOFIXPOINT1616( + presults_data->VL53LX_p_002); + + pRangeData->SigmaMilliMeter = TempFix1616; + + pRangeData->RangeMilliMeter = presults_data->median_range_mm; + pRangeData->RangeMaxMilliMeter = presults_data->max_range_mm; + pRangeData->RangeMinMilliMeter = presults_data->min_range_mm; + + + switch (device_status) { + case VL53LX_DEVICEERROR_MULTCLIPFAIL: + case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE: + case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE: + case VL53LX_DEVICEERROR_NOVHVVALUEFOUND: + pRangeData->RangeStatus = VL53LX_RANGESTATUS_HARDWARE_FAIL; + break; + case VL53LX_DEVICEERROR_USERROICLIP: + pRangeData->RangeStatus = VL53LX_RANGESTATUS_MIN_RANGE_FAIL; + break; + default: + pRangeData->RangeStatus = VL53LX_RANGESTATUS_RANGE_VALID; + } + + + if ((pRangeData->RangeStatus == VL53LX_RANGESTATUS_RANGE_VALID) && + (active_results == 0)) { + pRangeData->RangeStatus = VL53LX_RANGESTATUS_NONE; + pRangeData->SignalRateRtnMegaCps = 0; + pRangeData->SigmaMilliMeter = 0; + pRangeData->RangeMilliMeter = 8191; + pRangeData->RangeMaxMilliMeter = 8191; + pRangeData->RangeMinMilliMeter = 8191; + } + + + if (pRangeData->RangeStatus == VL53LX_RANGESTATUS_RANGE_VALID) + pRangeData->RangeStatus = + ConvertStatusHisto(FilteredRangeStatus); + + Range = pRangeData->RangeMilliMeter; + if ((pRangeData->RangeStatus == VL53LX_RANGESTATUS_RANGE_VALID) && + (Range < 0)) { + if (Range < BDTable[VL53LX_TUNING_PROXY_MIN]) + pRangeData->RangeStatus = + VL53LX_RANGESTATUS_RANGE_INVALID; + else { + pRangeData->RangeMilliMeter = 0; + } + } + + return Status; +} + +VL53LX_Error VL53LX::SetMeasurementData( + VL53LX_range_results_t *presults, + VL53LX_MultiRangingData_t *pMultiRangingData) +{ + uint8_t i; + uint8_t iteration; + VL53LX_TargetRangeData_t *pRangeData; + VL53LX_range_data_t *presults_data; + VL53LX_Error Status = VL53LX_ERROR_NONE; + uint8_t ActiveResults; + + pMultiRangingData->NumberOfObjectsFound = presults->active_results; + pMultiRangingData->HasXtalkValueChanged = + presults->smudge_corrector_data.new_xtalk_applied_flag; + + + pMultiRangingData->TimeStamp = 0; + + pMultiRangingData->StreamCount = presults->stream_count; + + ActiveResults = presults->active_results; + if (ActiveResults < 1) + + { + iteration = 1; + } else { + iteration = ActiveResults; + } + for (i = 0; i < iteration; i++) { + pRangeData = &(pMultiRangingData->RangeData[i]); + + presults_data = &(presults->VL53LX_p_003[i]); + if (Status == VL53LX_ERROR_NONE) + Status = SetTargetData(ActiveResults, + presults->device_status, + presults_data, + pRangeData); + + pMultiRangingData->EffectiveSpadRtnCount = + presults_data->VL53LX_p_004; + + } + return Status; +} + +VL53LX_Error VL53LX::VL53LX_GetMultiRangingData( + VL53LX_MultiRangingData_t *pMultiRangingData) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev = + VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_range_results_t *presults = + (VL53LX_range_results_t *) pdev->wArea1; + + memset(pMultiRangingData, 0xFF, + sizeof(VL53LX_MultiRangingData_t)); + + + Status = VL53LX_get_device_results( + VL53LX_DEVICERESULTSLEVEL_FULL, + presults); + + Status = SetMeasurementData( + presults, + pMultiRangingData); + + return Status; +} +/* +VL53LX_Error VL53LX::VL53LX_GetAdditionalData() +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + + return Status; +} +*/ +VL53LX_Error VL53LX::VL53LX_SetTuningParameter( + uint16_t TuningParameterId, int32_t TuningParameterValue) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + if (TuningParameterId == + VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS) { + return VL53LX_ERROR_INVALID_PARAMS; + } + + if (TuningParameterId >= 32768) + Status = VL53LX_set_tuning_parm( + TuningParameterId, + TuningParameterValue); + else { + if (TuningParameterId < VL53LX_TUNING_MAX_TUNABLE_KEY) { + BDTable[TuningParameterId] = TuningParameterValue; + } else { + Status = VL53LX_ERROR_INVALID_PARAMS; + } + } + + return Status; +} +VL53LX_Error VL53LX::VL53LX_GetTuningParameter( + uint16_t TuningParameterId, int32_t *pTuningParameterValue) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + + if (TuningParameterId >= 32768) + Status = VL53LX_get_tuning_parm( + TuningParameterId, + pTuningParameterValue); + else { + if (TuningParameterId < VL53LX_TUNING_MAX_TUNABLE_KEY) { + *pTuningParameterValue = BDTable[TuningParameterId]; + } else { + Status = VL53LX_ERROR_INVALID_PARAMS; + } + } + + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_PerformRefSpadManagement() +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_Error RawStatus; + uint8_t dcrbuffer[24]; + uint8_t *commbuf; + uint8_t numloc[2] = {5, 3}; + VL53LX_LLDriverData_t *pdev; + VL53LX_customer_nvm_managed_t *pc; + VL53LX_DistanceModes DistanceMode; + + pdev = VL53LXDevStructGetLLDriverHandle(Dev); + pc = &pdev->customer; + + if (Status == VL53LX_ERROR_NONE) { + DistanceMode = VL53LXDevDataGet(Dev, + CurrentParameters.DistanceMode); + Status = VL53LX_run_ref_spad_char(&RawStatus); + + if (Status == VL53LX_ERROR_NONE) { + Status = VL53LX_SetDistanceMode(DistanceMode); + } + } + + if (Status == VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH) { + + Status = VL53LX_read_nvm_raw_data( + (uint8_t)(0xA0 >> 2), + (uint8_t)(24 >> 2), + dcrbuffer); + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_WriteMulti(Dev, + VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS, + numloc, 2); + + if (Status == VL53LX_ERROR_NONE) { + pc->ref_spad_man__num_requested_ref_spads = numloc[0]; + pc->ref_spad_man__ref_location = numloc[1]; + } + + if (Status == VL53LX_ERROR_NONE) { + commbuf = &dcrbuffer[16]; + } + + + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_WriteMulti(Dev, + VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, + commbuf, 6); + + if (Status == VL53LX_ERROR_NONE) { + pc->global_config__spad_enables_ref_0 = commbuf[0]; + pc->global_config__spad_enables_ref_1 = commbuf[1]; + pc->global_config__spad_enables_ref_2 = commbuf[2]; + pc->global_config__spad_enables_ref_3 = commbuf[3]; + pc->global_config__spad_enables_ref_4 = commbuf[4]; + pc->global_config__spad_enables_ref_5 = commbuf[5]; + } + + } + + return Status; +} + + +VL53LX_Error VL53LX::VL53LX_SmudgeCorrectionEnable( + VL53LX_SmudgeCorrectionModes Mode) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_Error s1 = VL53LX_ERROR_NONE; + VL53LX_Error s2 = VL53LX_ERROR_NONE; + VL53LX_Error s3 = VL53LX_ERROR_NONE; + + switch (Mode) { + case VL53LX_SMUDGE_CORRECTION_NONE: + s1 = VL53LX_dynamic_xtalk_correction_disable(); + s2 = VL53LX_dynamic_xtalk_correction_apply_disable(); + s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable(); + break; + case VL53LX_SMUDGE_CORRECTION_CONTINUOUS: + s1 = VL53LX_dynamic_xtalk_correction_enable(); + s2 = VL53LX_dynamic_xtalk_correction_apply_enable(); + s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable(); + break; + case VL53LX_SMUDGE_CORRECTION_SINGLE: + s1 = VL53LX_dynamic_xtalk_correction_enable(); + s2 = VL53LX_dynamic_xtalk_correction_apply_enable(); + s3 = VL53LX_dynamic_xtalk_correction_single_apply_enable(); + break; + case VL53LX_SMUDGE_CORRECTION_DEBUG: + s1 = VL53LX_dynamic_xtalk_correction_enable(); + s2 = VL53LX_dynamic_xtalk_correction_apply_disable(); + s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable(); + break; + default: + Status = VL53LX_ERROR_INVALID_PARAMS; + break; + } + + if (Status == VL53LX_ERROR_NONE) { + Status = s1; + if (Status == VL53LX_ERROR_NONE) { + Status = s2; + } + if (Status == VL53LX_ERROR_NONE) { + Status = s3; + } + } + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_SetXTalkCompensationEnable( + uint8_t XTalkCompensationEnable) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + if (XTalkCompensationEnable == 0) { + Status = VL53LX_disable_xtalk_compensation(); + } else { + Status = VL53LX_enable_xtalk_compensation(); + } + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_GetXTalkCompensationEnable( + uint8_t *pXTalkCompensationEnable) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + + VL53LX_get_xtalk_compensation_enable( + pXTalkCompensationEnable); + + return Status; +} + + +VL53LX_Error VL53LX::VL53LX_PerformXTalkCalibration() +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_Error UStatus; + int16_t CalDistanceMm; + VL53LX_xtalk_calibration_results_t xtalk; + + VL53LX_CalibrationData_t caldata; + VL53LX_LLDriverData_t *pLLData; + int i; + uint32_t *pPlaneOffsetKcps; + uint32_t Margin = + BDTable[VL53LX_TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN]; + uint32_t DefaultOffset = + BDTable[VL53LX_TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET]; + uint32_t *pLLDataPlaneOffsetKcps; + uint32_t sum = 0; + uint8_t binok = 0; + + pPlaneOffsetKcps = + &caldata.customer.algo__crosstalk_compensation_plane_offset_kcps; + pLLData = VL53LXDevStructGetLLDriverHandle(Dev); + pLLDataPlaneOffsetKcps = + &pLLData->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps; + + CalDistanceMm = (int16_t) + BDTable[VL53LX_TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM]; + Status = VL53LX_run_hist_xtalk_extraction(CalDistanceMm, + &UStatus); + + + VL53LX_GetCalibrationData(&caldata); + for (i = 0; i < VL53LX_XTALK_HISTO_BINS; i++) { + sum += caldata.xtalkhisto.xtalk_shape.bin_data[i]; + if (caldata.xtalkhisto.xtalk_shape.bin_data[i] > 0) { + binok++; + } + } + + if ((UStatus == + VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL) || + (sum > (1024 + Margin)) || (sum < (1024 - Margin)) || + (binok < 3)) { + *pPlaneOffsetKcps = DefaultOffset; + *pLLDataPlaneOffsetKcps = DefaultOffset; + caldata.xtalkhisto.xtalk_shape.bin_data[0] = 307; + caldata.xtalkhisto.xtalk_shape.bin_data[1] = 410; + caldata.xtalkhisto.xtalk_shape.bin_data[2] = 410; + caldata.xtalkhisto.xtalk_shape.bin_data[3] = 307; + for (i = 4; i < VL53LX_XTALK_HISTO_BINS; i++) { + caldata.xtalkhisto.xtalk_shape.bin_data[i] = 0; + } + for (i = 0; i < VL53LX_BIN_REC_SIZE; i++) + caldata.algo__xtalk_cpo_HistoMerge_kcps[i] = + DefaultOffset + DefaultOffset * i; + VL53LX_SetCalibrationData(&caldata); + } + + if (Status == VL53LX_ERROR_NONE) { + Status = VL53LX_get_current_xtalk_settings(&xtalk); + Status = VL53LX_set_tuning_parm( + VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS, + xtalk.algo__crosstalk_compensation_plane_offset_kcps); + } + + return Status; +} +VL53LX_Error VL53LX::VL53LX_SetOffsetCorrectionMode( + VL53LX_OffsetCorrectionModes OffsetCorrectionMode) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_OffsetCorrectionMode offset_cor_mode; + + if (OffsetCorrectionMode == VL53LX_OFFSETCORRECTIONMODE_STANDARD) { + offset_cor_mode = + VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS; + } else if (OffsetCorrectionMode == + VL53LX_OFFSETCORRECTIONMODE_PERVCSEL) { + offset_cor_mode = + VL53LX_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS; + } else { + Status = VL53LX_ERROR_INVALID_PARAMS; + } + + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_set_offset_correction_mode( + offset_cor_mode); + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_PerformOffsetSimpleCalibration( + int32_t CalDistanceMilliMeter) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + int32_t sum_ranging; + uint8_t offset_meas; + int16_t Max, UnderMax, OverMax, Repeat; + int32_t total_count, inloopcount; + int32_t IncRounding; + int16_t meanDistance_mm; + int16_t offset; + VL53LX_MultiRangingData_t RangingMeasurementData; + VL53LX_LLDriverData_t *pdev; + uint8_t goodmeas; + VL53LX_Error SmudgeStatus = VL53LX_ERROR_NONE; + uint8_t smudge_corr_en; + VL53LX_TargetRangeData_t *pRange; + + pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled; + SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable(); + + pdev->customer.algo__part_to_part_range_offset_mm = 0; + pdev->customer.mm_config__inner_offset_mm = 0; + pdev->customer.mm_config__outer_offset_mm = 0; + memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data)); + Repeat = BDTable[VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT]; + Max = BDTable[ + VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER]; + UnderMax = 1 + (Max / 2); + OverMax = Max + (Max / 2); + sum_ranging = 0; + total_count = 0; + + while ((Repeat > 0) && (Status == VL53LX_ERROR_NONE)) { + Status = VL53LX_StartMeasurement(); + + if (Status == VL53LX_ERROR_NONE) { + VL53LX_WaitMeasurementDataReady(); + VL53LX_GetMultiRangingData( + &RangingMeasurementData); + VL53LX_ClearInterruptAndStartMeasurement(); + } + + inloopcount = 0; + offset_meas = 0; + while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) && + (offset_meas < OverMax)) { + Status = VL53LX_WaitMeasurementDataReady(); + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_GetMultiRangingData( + &RangingMeasurementData); + pRange = &(RangingMeasurementData.RangeData[0]); + goodmeas = (pRange->RangeStatus == + VL53LX_RANGESTATUS_RANGE_VALID); + if ((Status == VL53LX_ERROR_NONE) && goodmeas) { + sum_ranging += pRange->RangeMilliMeter; + inloopcount++; + } + Status = VL53LX_ClearInterruptAndStartMeasurement(); + offset_meas++; + } + total_count += inloopcount; + + + if (inloopcount < UnderMax) { + Status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL; + } + + VL53LX_StopMeasurement(); + + Repeat--; + + } + + if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1)) { + SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable(); + } + + if ((sum_ranging < 0) || + (sum_ranging > ((int32_t) total_count * 0xffff))) { + Status = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH; + } + + if ((Status == VL53LX_ERROR_NONE) && (total_count > 0)) { + IncRounding = total_count / 2; + meanDistance_mm = (int16_t)((sum_ranging + IncRounding) + / total_count); + offset = (int16_t)CalDistanceMilliMeter - meanDistance_mm; + pdev->customer.algo__part_to_part_range_offset_mm = 0; + pdev->customer.mm_config__inner_offset_mm = offset; + pdev->customer.mm_config__outer_offset_mm = offset; + + Status = VL53LX_set_customer_nvm_managed( + &(pdev->customer)); + } + + return Status; +} + + +VL53LX_Error VL53LX::VL53LX_PerformOffsetZeroDistanceCalibration() +{ +#define START_OFFSET 50 + VL53LX_Error Status = VL53LX_ERROR_NONE; + int32_t sum_ranging; + uint8_t offset_meas; + int16_t Max, UnderMax, OverMax, Repeat; + int32_t total_count, inloopcount; + int32_t IncRounding; + int16_t meanDistance_mm; + int16_t offset, ZeroDistanceOffset; + VL53LX_MultiRangingData_t RangingMeasurementData; + VL53LX_LLDriverData_t *pdev; + uint8_t goodmeas; + VL53LX_Error SmudgeStatus = VL53LX_ERROR_NONE; + uint8_t smudge_corr_en; + VL53LX_TargetRangeData_t *pRange; + + pdev = VL53LXDevStructGetLLDriverHandle(Dev); + smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled; + SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable(); + pdev->customer.algo__part_to_part_range_offset_mm = 0; + pdev->customer.mm_config__inner_offset_mm = START_OFFSET; + pdev->customer.mm_config__outer_offset_mm = START_OFFSET; + memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data)); + ZeroDistanceOffset = BDTable[ + VL53LX_TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR]; + Repeat = BDTable[VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT]; + Max = + BDTable[VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER]; + UnderMax = 1 + (Max / 2); + OverMax = Max + (Max / 2); + sum_ranging = 0; + total_count = 0; + + while ((Repeat > 0) && (Status == VL53LX_ERROR_NONE)) { + Status = VL53LX_StartMeasurement(); + if (Status == VL53LX_ERROR_NONE) { + VL53LX_WaitMeasurementDataReady(); + VL53LX_GetMultiRangingData( + &RangingMeasurementData); + VL53LX_ClearInterruptAndStartMeasurement(); + } + inloopcount = 0; + offset_meas = 0; + while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) && + (offset_meas < OverMax)) { + Status = VL53LX_WaitMeasurementDataReady(); + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_GetMultiRangingData( + &RangingMeasurementData); + pRange = &(RangingMeasurementData.RangeData[0]); + goodmeas = (pRange->RangeStatus == + VL53LX_RANGESTATUS_RANGE_VALID); + if ((Status == VL53LX_ERROR_NONE) && goodmeas) { + sum_ranging = sum_ranging + + pRange->RangeMilliMeter; + inloopcount++; + } + Status = VL53LX_ClearInterruptAndStartMeasurement(); + offset_meas++; + } + total_count += inloopcount; + if (inloopcount < UnderMax) { + Status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL; + } + VL53LX_StopMeasurement(); + Repeat--; + } + if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1)) { + SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable(); + } + if ((sum_ranging < 0) || + (sum_ranging > ((int32_t) total_count * 0xffff))) { + Status = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH; + } + + if ((Status == VL53LX_ERROR_NONE) && (total_count > 0)) { + IncRounding = total_count / 2; + meanDistance_mm = (int16_t) + ((sum_ranging + IncRounding) / total_count); + offset = START_OFFSET - meanDistance_mm + ZeroDistanceOffset; + pdev->customer.algo__part_to_part_range_offset_mm = 0; + pdev->customer.mm_config__inner_offset_mm = offset; + pdev->customer.mm_config__outer_offset_mm = offset; + Status = VL53LX_set_customer_nvm_managed( + &(pdev->customer)); + } + + return Status; +} + +VL53LX_Error VL53LX::VL53LX_SetCalibrationData( + VL53LX_CalibrationData_t *pCalibrationData) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_CustomerNvmManaged_t *pC; + VL53LX_calibration_data_t cal_data; + uint32_t x; + VL53LX_xtalk_calibration_results_t xtalk; + + cal_data.struct_version = pCalibrationData->struct_version - + VL53LX_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION; + + + memcpy( + &(cal_data.add_off_cal_data), + &(pCalibrationData->add_off_cal_data), + sizeof(VL53LX_additional_offset_cal_data_t)); + + + memcpy( + &(cal_data.optical_centre), + &(pCalibrationData->optical_centre), + sizeof(VL53LX_optical_centre_t)); + + + memcpy( + &(cal_data.xtalkhisto), + &(pCalibrationData->xtalkhisto), + sizeof(VL53LX_xtalk_histogram_data_t)); + + + memcpy( + &(cal_data.gain_cal), + &(pCalibrationData->gain_cal), + sizeof(VL53LX_gain_calibration_data_t)); + + + memcpy( + &(cal_data.cal_peak_rate_map), + &(pCalibrationData->cal_peak_rate_map), + sizeof(VL53LX_cal_peak_rate_map_t)); + + + memcpy( + &(cal_data.per_vcsel_cal_data), + &(pCalibrationData->per_vcsel_cal_data), + sizeof(VL53LX_per_vcsel_period_offset_cal_data_t)); + + pC = &pCalibrationData->customer; + x = pC->algo__crosstalk_compensation_plane_offset_kcps; + cal_data.customer.algo__crosstalk_compensation_plane_offset_kcps = + (uint16_t)(x & 0x0000FFFF); + + cal_data.customer.global_config__spad_enables_ref_0 = + pC->global_config__spad_enables_ref_0; + cal_data.customer.global_config__spad_enables_ref_1 = + pC->global_config__spad_enables_ref_1; + cal_data.customer.global_config__spad_enables_ref_2 = + pC->global_config__spad_enables_ref_2; + cal_data.customer.global_config__spad_enables_ref_3 = + pC->global_config__spad_enables_ref_3; + cal_data.customer.global_config__spad_enables_ref_4 = + pC->global_config__spad_enables_ref_4; + cal_data.customer.global_config__spad_enables_ref_5 = + pC->global_config__spad_enables_ref_5; + cal_data.customer.global_config__ref_en_start_select = + pC->global_config__ref_en_start_select; + cal_data.customer.ref_spad_man__num_requested_ref_spads = + pC->ref_spad_man__num_requested_ref_spads; + cal_data.customer.ref_spad_man__ref_location = + pC->ref_spad_man__ref_location; + cal_data.customer.algo__crosstalk_compensation_x_plane_gradient_kcps = + pC->algo__crosstalk_compensation_x_plane_gradient_kcps; + cal_data.customer.algo__crosstalk_compensation_y_plane_gradient_kcps = + pC->algo__crosstalk_compensation_y_plane_gradient_kcps; + cal_data.customer.ref_spad_char__total_rate_target_mcps = + pC->ref_spad_char__total_rate_target_mcps; + cal_data.customer.algo__part_to_part_range_offset_mm = + pC->algo__part_to_part_range_offset_mm; + cal_data.customer.mm_config__inner_offset_mm = + pC->mm_config__inner_offset_mm; + cal_data.customer.mm_config__outer_offset_mm = + pC->mm_config__outer_offset_mm; + + Status = VL53LX_set_part_to_part_data(&cal_data); + + if (Status != VL53LX_ERROR_NONE) { + goto ENDFUNC; + } + + Status = VL53LX_get_current_xtalk_settings(&xtalk); + + if (Status != VL53LX_ERROR_NONE) { + goto ENDFUNC; + } + + xtalk.algo__crosstalk_compensation_plane_offset_kcps = x; + + Status = VL53LX_set_tuning_parm( + VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS, + x); + + + memcpy( + &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]), + &(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]), + sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps)); + + Status = VL53LX_set_current_xtalk_settings(&xtalk); +ENDFUNC: + return Status; + +} + +VL53LX_Error VL53LX::VL53LX_GetCalibrationData( + VL53LX_CalibrationData_t *pCalibrationData) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + VL53LX_calibration_data_t cal_data; + VL53LX_CustomerNvmManaged_t *pC; + VL53LX_customer_nvm_managed_t *pC2; + VL53LX_xtalk_calibration_results_t xtalk; + uint32_t tmp; + + Status = VL53LX_get_part_to_part_data(&cal_data); + + pCalibrationData->struct_version = cal_data.struct_version + + VL53LX_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION; + + + memcpy( + &(pCalibrationData->add_off_cal_data), + &(cal_data.add_off_cal_data), + sizeof(VL53LX_additional_offset_cal_data_t)); + + + memcpy( + &(pCalibrationData->optical_centre), + &(cal_data.optical_centre), + sizeof(VL53LX_optical_centre_t)); + + + memcpy( + &(pCalibrationData->xtalkhisto), + &(cal_data.xtalkhisto), + sizeof(VL53LX_xtalk_histogram_data_t)); + + memcpy( + &(pCalibrationData->gain_cal), + &(cal_data.gain_cal), + sizeof(VL53LX_gain_calibration_data_t)); + + + memcpy( + &(pCalibrationData->cal_peak_rate_map), + &(cal_data.cal_peak_rate_map), + sizeof(VL53LX_cal_peak_rate_map_t)); + + + memcpy( + &(pCalibrationData->per_vcsel_cal_data), + &(cal_data.per_vcsel_cal_data), + sizeof(VL53LX_per_vcsel_period_offset_cal_data_t)); + + pC = &pCalibrationData->customer; + pC2 = &cal_data.customer; + pC->global_config__spad_enables_ref_0 = + pC2->global_config__spad_enables_ref_0; + pC->global_config__spad_enables_ref_1 = + pC2->global_config__spad_enables_ref_1; + pC->global_config__spad_enables_ref_2 = + pC2->global_config__spad_enables_ref_2; + pC->global_config__spad_enables_ref_3 = + pC2->global_config__spad_enables_ref_3; + pC->global_config__spad_enables_ref_4 = + pC2->global_config__spad_enables_ref_4; + pC->global_config__spad_enables_ref_5 = + pC2->global_config__spad_enables_ref_5; + pC->global_config__ref_en_start_select = + pC2->global_config__ref_en_start_select; + pC->ref_spad_man__num_requested_ref_spads = + pC2->ref_spad_man__num_requested_ref_spads; + pC->ref_spad_man__ref_location = + pC2->ref_spad_man__ref_location; + pC->algo__crosstalk_compensation_x_plane_gradient_kcps = + pC2->algo__crosstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps = + pC2->algo__crosstalk_compensation_y_plane_gradient_kcps; + pC->ref_spad_char__total_rate_target_mcps = + pC2->ref_spad_char__total_rate_target_mcps; + pC->algo__part_to_part_range_offset_mm = + pC2->algo__part_to_part_range_offset_mm; + pC->mm_config__inner_offset_mm = + pC2->mm_config__inner_offset_mm; + pC->mm_config__outer_offset_mm = + pC2->mm_config__outer_offset_mm; + + pC->algo__crosstalk_compensation_plane_offset_kcps = + (uint32_t)( + pC2->algo__crosstalk_compensation_plane_offset_kcps); + + Status = VL53LX_get_current_xtalk_settings(&xtalk); + + if (Status != VL53LX_ERROR_NONE) { + goto ENDFUNC; + } + + tmp = xtalk.algo__crosstalk_compensation_plane_offset_kcps; + pC->algo__crosstalk_compensation_plane_offset_kcps = tmp; + tmp = xtalk.algo__crosstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_x_plane_gradient_kcps = tmp; + tmp = xtalk.algo__crosstalk_compensation_y_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps = tmp; + + memcpy(&(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]), + &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]), + sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps)); +ENDFUNC: + return Status; +} + + +VL53LX_Error VL53LX::VL53LX_PerformOffsetPerVcselCalibration( + int32_t CalDistanceMilliMeter) +{ + VL53LX_Error Status = VL53LX_ERROR_NONE; + int32_t sum_ranging_range_A, sum_ranging_range_B; + uint8_t offset_meas_range_A, offset_meas_range_B; + int16_t Max, UnderMax, OverMax, Repeat; + int32_t inloopcount; + int32_t IncRounding; + int16_t meanDistance_mm; + VL53LX_MultiRangingData_t RangingMeasurementData; + VL53LX_LLDriverData_t *pdev; + uint8_t goodmeas; + VL53LX_DistanceModes currentDist; + VL53LX_DistanceModes DistMode[3] = {VL53LX_DISTANCEMODE_SHORT, + VL53LX_DISTANCEMODE_MEDIUM, VL53LX_DISTANCEMODE_LONG + }; + int16_t offsetA[3]; + int16_t offsetB[3]; + + VL53LX_Error SmudgeStatus = VL53LX_ERROR_NONE; + uint8_t smudge_corr_en, ics; + VL53LX_TargetRangeData_t *pRange; + + pdev = VL53LXDevStructGetLLDriverHandle(Dev); + + smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled; + SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable(); + + pdev->customer.algo__part_to_part_range_offset_mm = 0; + pdev->customer.mm_config__inner_offset_mm = 0; + pdev->customer.mm_config__outer_offset_mm = 0; + pdev->customer.mm_config__outer_offset_mm = 0; + memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data)); + + Repeat = 0; + Max = 2 * BDTable[ + VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER]; + UnderMax = 1 + (Max / 2); + OverMax = Max + (Max / 2); + + Status = VL53LX_GetDistanceMode(¤tDist); + + while ((Repeat < 3) && (Status == VL53LX_ERROR_NONE)) { + Status = VL53LX_SetDistanceMode(DistMode[Repeat]); + Status = VL53LX_StartMeasurement(); + + if (Status == VL53LX_ERROR_NONE) { + VL53LX_WaitMeasurementDataReady(); + VL53LX_GetMultiRangingData( + &RangingMeasurementData); + VL53LX_ClearInterruptAndStartMeasurement(); + } + + inloopcount = 0; + offset_meas_range_A = 0; + sum_ranging_range_A = 0; + offset_meas_range_B = 0; + sum_ranging_range_B = 0; + while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) && + (inloopcount < OverMax)) { + Status = VL53LX_WaitMeasurementDataReady(); + if (Status == VL53LX_ERROR_NONE) + Status = VL53LX_GetMultiRangingData( + &RangingMeasurementData); + pRange = &(RangingMeasurementData.RangeData[0]); + goodmeas = (pRange->RangeStatus == + VL53LX_RANGESTATUS_RANGE_VALID); + ics = pdev->ll_state.cfg_internal_stream_count; + if ((Status == VL53LX_ERROR_NONE) && goodmeas) { + if (ics & 0x01) { + sum_ranging_range_A += + pRange->RangeMilliMeter; + offset_meas_range_A++; + } else { + sum_ranging_range_B += + pRange->RangeMilliMeter; + offset_meas_range_B++; + } + inloopcount = offset_meas_range_A + + offset_meas_range_B; + } + Status = VL53LX_ClearInterruptAndStartMeasurement(); + } + + + if (inloopcount < UnderMax) { + Status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL; + } + + VL53LX_StopMeasurement(); + + + if ((sum_ranging_range_A < 0) || + (sum_ranging_range_B < 0) || + (sum_ranging_range_A > + ((int32_t) offset_meas_range_A * 0xffff)) || + (sum_ranging_range_B > + ((int32_t) offset_meas_range_B * 0xffff))) { + Status = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH; + } + + if ((Status == VL53LX_ERROR_NONE) && + (offset_meas_range_A > 0)) { + IncRounding = offset_meas_range_A / 2; + meanDistance_mm = (int16_t) + ((sum_ranging_range_A + IncRounding) + / offset_meas_range_A); + offsetA[Repeat] = (int16_t) + CalDistanceMilliMeter - meanDistance_mm; + } + + if ((Status == VL53LX_ERROR_NONE) && + (offset_meas_range_B > 0)) { + IncRounding = offset_meas_range_B / 2; + meanDistance_mm = (int16_t) + ((sum_ranging_range_B + IncRounding) + / offset_meas_range_B); + offsetB[Repeat] = (int16_t) + CalDistanceMilliMeter - meanDistance_mm; + } + Repeat++; + } + + if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1)) { + SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable(); + } + + if (Status == VL53LX_ERROR_NONE) { + pdev->per_vcsel_cal_data.short_a_offset_mm = offsetA[0]; + pdev->per_vcsel_cal_data.short_b_offset_mm = offsetB[0]; + pdev->per_vcsel_cal_data.medium_a_offset_mm = offsetA[1]; + pdev->per_vcsel_cal_data.medium_b_offset_mm = offsetB[1]; + pdev->per_vcsel_cal_data.long_a_offset_mm = offsetA[2]; + pdev->per_vcsel_cal_data.long_b_offset_mm = offsetB[2]; + } + + VL53LX_SetDistanceMode(currentDist); + + return Status; +} +