Fork Charles's library
Dependencies: X_NUCLEO_COMMON ST_INTERFACES
Dependents: VL53L3ExpansionBoard
vl53lx_class.cpp
- Committer:
- johnAlexander
- Date:
- 2020-11-03
- Revision:
- 3:316175f392f7
- Parent:
- VL53L3SRC/vl53lx_class.cpp@ 2:ad33ff89d2cf
File content as of revision 3:316175f392f7:
/**
******************************************************************************
* @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 dev_i2c->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 dev_i2c->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;
}