VL53L0X World smallest Time-of-Flight (ToF) ranging sensor
Dependencies: X_NUCLEO_COMMON ST_INTERFACES
Dependents: HelloWorld_ST_Sensors mbed-os-mqtt-client Multi_VL53L0X DISCO-IOT01_HomeEnv ... more
Fork of VL53L0X by
Revision 6:8ac15bf6d635, committed 2019-06-06
- Comitter:
- johnAlexander
- Date:
- Thu Jun 06 09:21:39 2019 +0000
- Parent:
- 5:f16727052990
- Commit message:
- Publish mbed-certified sensor class.
Changed in this revision
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X.cpp Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,5512 @@ +/** + ****************************************************************************** + * @file VL53L0X_class.cpp + * @author IMG + * @version V0.0.1 + * @date 28-June-2016 + * @brief Implementation file for the VL53L0X driver class + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2016 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 "VL53L0X.h" + +//#include "VL53L0X_api_core.h" +//#include "VL53L0X_api_calibration.h" +//#include "VL53L0X_api_strings.h" +#include "VL53L0X_interrupt_threshold_settings.h" +#include "VL53L0X_tuning.h" +#include "VL53L0X_types.h" + + +/****************** define for i2c configuration *******************************/ + +#define TEMP_BUF_SIZE 64 + +/** Maximum buffer size to be used in i2c */ +#define VL53L0X_MAX_I2C_XFER_SIZE 64 /* Maximum buffer size to be used in i2c */ +#define VL53L0X_I2C_USER_VAR /* none but could be for a flag var to get/pass to mutex interruptible return flags and try again */ + + +#define LOG_FUNCTION_START(fmt, ...) \ + _LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__) +#define LOG_FUNCTION_END(status, ...) \ + _LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__) +#define LOG_FUNCTION_END_FMT(status, fmt, ...) \ + _LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__) + +#ifdef VL53L0X_LOG_ENABLE +#define trace_print(level, ...) trace_print_module_function(TRACE_MODULE_API, \ + level, TRACE_FUNCTION_NONE, ##__VA_ARGS__) +#endif + +#define REF_ARRAY_SPAD_0 0 +#define REF_ARRAY_SPAD_5 5 +#define REF_ARRAY_SPAD_10 10 + +uint32_t refArrayQuadrants[4] = {REF_ARRAY_SPAD_10, REF_ARRAY_SPAD_5, + REF_ARRAY_SPAD_0, REF_ARRAY_SPAD_5 + }; + + + + +VL53L0X_Error VL53L0X::VL53L0X_device_read_strobe(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t strobe; + uint32_t loop_nb; + LOG_FUNCTION_START(""); + + status |= VL53L0X_write_byte(dev, 0x83, 0x00); + + /* polling + * use timeout to avoid deadlock*/ + if (status == VL53L0X_ERROR_NONE) { + loop_nb = 0; + do { + status = VL53L0X_read_byte(dev, 0x83, &strobe); + if ((strobe != 0x00) || status != VL53L0X_ERROR_NONE) { + break; + } + + loop_nb = loop_nb + 1; + } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP); + + if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) { + status = VL53L0X_ERROR_TIME_OUT; + } + } + + status |= VL53L0X_write_byte(dev, 0x83, 0x01); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_info_from_device(VL53L0X_DEV dev, uint8_t option) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t byte; + uint32_t tmp_dword; + uint8_t module_id; + uint8_t revision; + uint8_t reference_spad_count = 0; + uint8_t reference_spad_type = 0; + uint32_t part_uid_upper = 0; + uint32_t part_uid_lower = 0; + uint32_t offset_fixed1104_mm = 0; + int16_t offset_micro_meters = 0; + uint32_t dist_meas_tgt_fixed1104_mm = 400 << 4; + uint32_t dist_meas_fixed1104_400_mm = 0; + uint32_t signal_rate_meas_fixed1104_400_mm = 0; + char product_id[19]; + char *product_id_tmp; + uint8_t read_data_from_device_done; + FixPoint1616_t signal_rate_meas_fixed400_mm_fix = 0; + uint8_t nvm_ref_good_spad_map[VL53L0X_REF_SPAD_BUFFER_SIZE]; + int i; + + + LOG_FUNCTION_START(""); + + read_data_from_device_done = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, + ReadDataFromDeviceDone); + + /* This access is done only once after that a GetDeviceInfo or + * datainit is done*/ + if (read_data_from_device_done != 7) { + + status |= VL53L0X_write_byte(dev, 0x80, 0x01); + status |= VL53L0X_write_byte(dev, 0xFF, 0x01); + status |= VL53L0X_write_byte(dev, 0x00, 0x00); + + status |= VL53L0X_write_byte(dev, 0xFF, 0x06); + status |= VL53L0X_read_byte(dev, 0x83, &byte); + status |= VL53L0X_write_byte(dev, 0x83, byte | 4); + status |= VL53L0X_write_byte(dev, 0xFF, 0x07); + status |= VL53L0X_write_byte(dev, 0x81, 0x01); + + status |= VL53L0X_polling_delay(dev); + + status |= VL53L0X_write_byte(dev, 0x80, 0x01); + + if (((option & 1) == 1) && + ((read_data_from_device_done & 1) == 0)) { + status |= VL53L0X_write_byte(dev, 0x94, 0x6b); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + reference_spad_count = (uint8_t)((tmp_dword >> 8) & 0x07f); + reference_spad_type = (uint8_t)((tmp_dword >> 15) & 0x01); + + status |= VL53L0X_write_byte(dev, 0x94, 0x24); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + + nvm_ref_good_spad_map[0] = (uint8_t)((tmp_dword >> 24) + & 0xff); + nvm_ref_good_spad_map[1] = (uint8_t)((tmp_dword >> 16) + & 0xff); + nvm_ref_good_spad_map[2] = (uint8_t)((tmp_dword >> 8) + & 0xff); + nvm_ref_good_spad_map[3] = (uint8_t)(tmp_dword & 0xff); + + status |= VL53L0X_write_byte(dev, 0x94, 0x25); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + nvm_ref_good_spad_map[4] = (uint8_t)((tmp_dword >> 24) + & 0xff); + nvm_ref_good_spad_map[5] = (uint8_t)((tmp_dword >> 16) + & 0xff); + } + + if (((option & 2) == 2) && + ((read_data_from_device_done & 2) == 0)) { + + status |= VL53L0X_write_byte(dev, 0x94, 0x02); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_byte(dev, 0x90, &module_id); + + status |= VL53L0X_write_byte(dev, 0x94, 0x7B); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_byte(dev, 0x90, &revision); + + status |= VL53L0X_write_byte(dev, 0x94, 0x77); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + product_id[0] = (char)((tmp_dword >> 25) & 0x07f); + product_id[1] = (char)((tmp_dword >> 18) & 0x07f); + product_id[2] = (char)((tmp_dword >> 11) & 0x07f); + product_id[3] = (char)((tmp_dword >> 4) & 0x07f); + + byte = (uint8_t)((tmp_dword & 0x00f) << 3); + + status |= VL53L0X_write_byte(dev, 0x94, 0x78); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + product_id[4] = (char)(byte + + ((tmp_dword >> 29) & 0x07f)); + product_id[5] = (char)((tmp_dword >> 22) & 0x07f); + product_id[6] = (char)((tmp_dword >> 15) & 0x07f); + product_id[7] = (char)((tmp_dword >> 8) & 0x07f); + product_id[8] = (char)((tmp_dword >> 1) & 0x07f); + + byte = (uint8_t)((tmp_dword & 0x001) << 6); + + status |= VL53L0X_write_byte(dev, 0x94, 0x79); + + status |= VL53L0X_device_read_strobe(dev); + + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + product_id[9] = (char)(byte + + ((tmp_dword >> 26) & 0x07f)); + product_id[10] = (char)((tmp_dword >> 19) & 0x07f); + product_id[11] = (char)((tmp_dword >> 12) & 0x07f); + product_id[12] = (char)((tmp_dword >> 5) & 0x07f); + + byte = (uint8_t)((tmp_dword & 0x01f) << 2); + + status |= VL53L0X_write_byte(dev, 0x94, 0x7A); + + status |= VL53L0X_device_read_strobe(dev); + + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + product_id[13] = (char)(byte + + ((tmp_dword >> 30) & 0x07f)); + product_id[14] = (char)((tmp_dword >> 23) & 0x07f); + product_id[15] = (char)((tmp_dword >> 16) & 0x07f); + product_id[16] = (char)((tmp_dword >> 9) & 0x07f); + product_id[17] = (char)((tmp_dword >> 2) & 0x07f); + product_id[18] = '\0'; + + } + + if (((option & 4) == 4) && + ((read_data_from_device_done & 4) == 0)) { + + status |= VL53L0X_write_byte(dev, 0x94, 0x7B); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &part_uid_upper); + + status |= VL53L0X_write_byte(dev, 0x94, 0x7C); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &part_uid_lower); + + status |= VL53L0X_write_byte(dev, 0x94, 0x73); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + signal_rate_meas_fixed1104_400_mm = (tmp_dword & + 0x0000000ff) << 8; + + status |= VL53L0X_write_byte(dev, 0x94, 0x74); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + signal_rate_meas_fixed1104_400_mm |= ((tmp_dword & + 0xff000000) >> 24); + + status |= VL53L0X_write_byte(dev, 0x94, 0x75); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + dist_meas_fixed1104_400_mm = (tmp_dword & 0x0000000ff) + << 8; + + status |= VL53L0X_write_byte(dev, 0x94, 0x76); + status |= VL53L0X_device_read_strobe(dev); + status |= VL53L0X_read_dword(dev, 0x90, &tmp_dword); + + dist_meas_fixed1104_400_mm |= ((tmp_dword & 0xff000000) + >> 24); + } + + status |= VL53L0X_write_byte(dev, 0x81, 0x00); + status |= VL53L0X_write_byte(dev, 0xFF, 0x06); + status |= VL53L0X_read_byte(dev, 0x83, &byte); + status |= VL53L0X_write_byte(dev, 0x83, byte & 0xfb); + status |= VL53L0X_write_byte(dev, 0xFF, 0x01); + status |= VL53L0X_write_byte(dev, 0x00, 0x01); + + status |= VL53L0X_write_byte(dev, 0xFF, 0x00); + status |= VL53L0X_write_byte(dev, 0x80, 0x00); + } + + if ((status == VL53L0X_ERROR_NONE) && + (read_data_from_device_done != 7)) { + /* Assign to variable if status is ok */ + if (((option & 1) == 1) && + ((read_data_from_device_done & 1) == 0)) { + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + ReferenceSpadCount, reference_spad_count); + + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + ReferenceSpadType, reference_spad_type); + + for (i = 0; i < VL53L0X_REF_SPAD_BUFFER_SIZE; i++) { + dev->Data.SpadData.RefGoodSpadMap[i] = + nvm_ref_good_spad_map[i]; + } + } + + if (((option & 2) == 2) && + ((read_data_from_device_done & 2) == 0)) { + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + ModuleId, module_id); + + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + Revision, revision); + + product_id_tmp = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, + ProductId); + VL53L0X_COPYSTRING(product_id_tmp, product_id); + + } + + if (((option & 4) == 4) && + ((read_data_from_device_done & 4) == 0)) { + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + PartUIDUpper, part_uid_upper); + + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + PartUIDLower, part_uid_lower); + + signal_rate_meas_fixed400_mm_fix = + VL53L0X_FIXPOINT97TOFIXPOINT1616( + signal_rate_meas_fixed1104_400_mm); + + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + SignalRateMeasFixed400mm, + signal_rate_meas_fixed400_mm_fix); + + offset_micro_meters = 0; + if (dist_meas_fixed1104_400_mm != 0) { + offset_fixed1104_mm = + dist_meas_fixed1104_400_mm - + dist_meas_tgt_fixed1104_mm; + offset_micro_meters = (offset_fixed1104_mm + * 1000) >> 4; + offset_micro_meters *= -1; + } + + PALDevDataSet(dev, + Part2PartOffsetAdjustmentNVMMicroMeter, + offset_micro_meters); + } + byte = (uint8_t)(read_data_from_device_done | option); + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, ReadDataFromDeviceDone, + byte); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::wrapped_VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV dev, + int32_t *p_offset_calibration_data_micro_meter) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint16_t range_offset_register; + int16_t c_max_offset = 2047; + int16_t c_offset_range = 4096; + + /* Note that offset has 10.2 format */ + + status = VL53L0X_read_word(dev, + VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM, + &range_offset_register); + + if (status == VL53L0X_ERROR_NONE) { + range_offset_register = (range_offset_register & 0x0fff); + + /* Apply 12 bit 2's compliment conversion */ + if (range_offset_register > c_max_offset) { + *p_offset_calibration_data_micro_meter = + (int16_t)(range_offset_register - c_offset_range) + * 250; + } else { + *p_offset_calibration_data_micro_meter = + (int16_t)range_offset_register * 250; + } + + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV dev, + int32_t *p_offset_calibration_data_micro_meter) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = wrapped_VL53L0X_get_offset_calibration_data_micro_meter(dev, + p_offset_calibration_data_micro_meter); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::wrapped_VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV dev, + int32_t offset_calibration_data_micro_meter) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + int32_t c_max_offset_micro_meter = 511000; + int32_t c_min_offset_micro_meter = -512000; + int16_t c_offset_range = 4096; + uint32_t encoded_offset_val; + + LOG_FUNCTION_START(""); + + if (offset_calibration_data_micro_meter > c_max_offset_micro_meter) { + offset_calibration_data_micro_meter = c_max_offset_micro_meter; + } else { + if (offset_calibration_data_micro_meter < c_min_offset_micro_meter) { + offset_calibration_data_micro_meter = c_min_offset_micro_meter; + } + } + + /* The offset register is 10.2 format and units are mm + * therefore conversion is applied by a division of + * 250. + */ + if (offset_calibration_data_micro_meter >= 0) { + encoded_offset_val = + offset_calibration_data_micro_meter / 250; + } else { + encoded_offset_val = + c_offset_range + + offset_calibration_data_micro_meter / 250; + } + + status = VL53L0X_write_word(dev, + VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM, + encoded_offset_val); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV dev, + int32_t offset_calibration_data_micro_meter) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = wrapped_VL53L0X_set_offset_calibration_data_micro_meter(dev, + offset_calibration_data_micro_meter); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_apply_offset_adjustment(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + int32_t corrected_offset_micro_meters; + int32_t current_offset_micro_meters; + + /* if we run on this function we can read all the NVM info + * used by the API */ + status = VL53L0X_get_info_from_device(dev, 7); + + /* Read back current device offset */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_offset_calibration_data_micro_meter(dev, + ¤t_offset_micro_meters); + } + + /* Apply Offset Adjustment derived from 400mm measurements */ + if (status == VL53L0X_ERROR_NONE) { + + /* Store initial device offset */ + PALDevDataSet(dev, Part2PartOffsetNVMMicroMeter, + current_offset_micro_meters); + + corrected_offset_micro_meters = current_offset_micro_meters + + (int32_t)PALDevDataGet(dev, + Part2PartOffsetAdjustmentNVMMicroMeter); + + status = VL53L0X_set_offset_calibration_data_micro_meter(dev, + corrected_offset_micro_meters); + + /* store current, adjusted offset */ + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(dev, RangeOffsetMicroMeters, + corrected_offset_micro_meters); + } + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_device_mode(VL53L0X_DEV dev, + VL53L0X_DeviceModes *p_device_mode) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + VL53L0X_GETPARAMETERFIELD(dev, DeviceMode, *p_device_mode); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_inter_measurement_period_milli_seconds(VL53L0X_DEV dev, + uint32_t *p_inter_measurement_period_milli_seconds) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint16_t osc_calibrate_val; + uint32_t im_period_milli_seconds; + + LOG_FUNCTION_START(""); + + status = VL53L0X_read_word(dev, VL53L0X_REG_OSC_CALIBRATE_VAL, + &osc_calibrate_val); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_dword(dev, + VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD, + &im_period_milli_seconds); + } + + if (status == VL53L0X_ERROR_NONE) { + if (osc_calibrate_val != 0) { + *p_inter_measurement_period_milli_seconds = + im_period_milli_seconds / osc_calibrate_val; + } + VL53L0X_SETPARAMETERFIELD(dev, + InterMeasurementPeriodMilliSeconds, + *p_inter_measurement_period_milli_seconds); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_x_talk_compensation_rate_mega_cps(VL53L0X_DEV dev, + FixPoint1616_t *p_xtalk_compensation_rate_mega_cps) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint16_t value; + FixPoint1616_t temp_fix1616; + + LOG_FUNCTION_START(""); + + status = VL53L0X_read_word(dev, + VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, (uint16_t *)&value); + if (status == VL53L0X_ERROR_NONE) { + if (value == 0) { + /* the Xtalk is disabled return value from memory */ + VL53L0X_GETPARAMETERFIELD(dev, + XTalkCompensationRateMegaCps, temp_fix1616); + *p_xtalk_compensation_rate_mega_cps = temp_fix1616; + VL53L0X_SETPARAMETERFIELD(dev, XTalkCompensationEnable, + 0); + } else { + temp_fix1616 = VL53L0X_FIXPOINT313TOFIXPOINT1616(value); + *p_xtalk_compensation_rate_mega_cps = temp_fix1616; + VL53L0X_SETPARAMETERFIELD(dev, + XTalkCompensationRateMegaCps, temp_fix1616); + VL53L0X_SETPARAMETERFIELD(dev, XTalkCompensationEnable, + 1); + } + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_limit_check_value(VL53L0X_DEV dev, uint16_t limit_check_id, + FixPoint1616_t *p_limit_check_value) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t enable_zero_value = 0; + uint16_t temp16; + FixPoint1616_t temp_fix1616; + + LOG_FUNCTION_START(""); + + switch (limit_check_id) { + + case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE: + /* internal computation: */ + VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksValue, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, temp_fix1616); + enable_zero_value = 0; + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE: + status = VL53L0X_read_word(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, + &temp16); + if (status == VL53L0X_ERROR_NONE) { + temp_fix1616 = VL53L0X_FIXPOINT97TOFIXPOINT1616(temp16); + } + + + enable_zero_value = 1; + break; + + case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP: + /* internal computation: */ + VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksValue, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, temp_fix1616); + enable_zero_value = 0; + break; + + case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD: + /* internal computation: */ + VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksValue, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, temp_fix1616); + enable_zero_value = 0; + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC: + case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE: + status = VL53L0X_read_word(dev, + VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT, + &temp16); + if (status == VL53L0X_ERROR_NONE) { + temp_fix1616 = VL53L0X_FIXPOINT97TOFIXPOINT1616(temp16); + } + + + enable_zero_value = 0; + break; + + default: + status = VL53L0X_ERROR_INVALID_PARAMS; + + } + + if (status == VL53L0X_ERROR_NONE) { + + if (enable_zero_value == 1) { + + if (temp_fix1616 == 0) { + /* disabled: return value from memory */ + VL53L0X_GETARRAYPARAMETERFIELD(dev, + LimitChecksValue, limit_check_id, + temp_fix1616); + *p_limit_check_value = temp_fix1616; + VL53L0X_SETARRAYPARAMETERFIELD(dev, + LimitChecksEnable, limit_check_id, 0); + } else { + *p_limit_check_value = temp_fix1616; + VL53L0X_SETARRAYPARAMETERFIELD(dev, + LimitChecksValue, limit_check_id, + temp_fix1616); + VL53L0X_SETARRAYPARAMETERFIELD(dev, + LimitChecksEnable, limit_check_id, 1); + } + } else { + *p_limit_check_value = temp_fix1616; + } + } + + LOG_FUNCTION_END(status); + return status; + +} + +VL53L0X_Error VL53L0X::VL53L0X_get_limit_check_enable(VL53L0X_DEV dev, uint16_t limit_check_id, + uint8_t *p_limit_check_enable) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t temp8; + + LOG_FUNCTION_START(""); + + if (limit_check_id >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) { + status = VL53L0X_ERROR_INVALID_PARAMS; + *p_limit_check_enable = 0; + } else { + VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksEnable, + limit_check_id, temp8); + *p_limit_check_enable = temp8; + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_wrap_around_check_enable(VL53L0X_DEV dev, + uint8_t *p_wrap_around_check_enable) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t data; + + LOG_FUNCTION_START(""); + + status = VL53L0X_read_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &data); + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, SequenceConfig, data); + if (data & (0x01 << 7)) { + *p_wrap_around_check_enable = 0x01; + } else { + *p_wrap_around_check_enable = 0x00; + } + } + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(dev, WrapAroundCheckEnable, + *p_wrap_around_check_enable); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::sequence_step_enabled(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_config, + uint8_t *p_sequence_step_enabled) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + *p_sequence_step_enabled = 0; + LOG_FUNCTION_START(""); + + switch (sequence_step_id) { + case VL53L0X_SEQUENCESTEP_TCC: + *p_sequence_step_enabled = (sequence_config & 0x10) >> 4; + break; + case VL53L0X_SEQUENCESTEP_DSS: + *p_sequence_step_enabled = (sequence_config & 0x08) >> 3; + break; + case VL53L0X_SEQUENCESTEP_MSRC: + *p_sequence_step_enabled = (sequence_config & 0x04) >> 2; + break; + case VL53L0X_SEQUENCESTEP_PRE_RANGE: + *p_sequence_step_enabled = (sequence_config & 0x40) >> 6; + break; + case VL53L0X_SEQUENCESTEP_FINAL_RANGE: + *p_sequence_step_enabled = (sequence_config & 0x80) >> 7; + break; + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + + LOG_FUNCTION_END(status); + return Status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_sequence_step_enables(VL53L0X_DEV dev, + VL53L0X_SchedulerSequenceSteps_t *p_scheduler_sequence_steps) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t sequence_config = 0; + LOG_FUNCTION_START(""); + + status = VL53L0X_read_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + &sequence_config); + + if (status == VL53L0X_ERROR_NONE) { + status = sequence_step_enabled(dev, + VL53L0X_SEQUENCESTEP_TCC, sequence_config, + &p_scheduler_sequence_steps->TccOn); + } + if (status == VL53L0X_ERROR_NONE) { + status = sequence_step_enabled(dev, + VL53L0X_SEQUENCESTEP_DSS, sequence_config, + &p_scheduler_sequence_steps->DssOn); + } + if (status == VL53L0X_ERROR_NONE) { + status = sequence_step_enabled(dev, + VL53L0X_SEQUENCESTEP_MSRC, sequence_config, + &p_scheduler_sequence_steps->MsrcOn); + } + if (status == VL53L0X_ERROR_NONE) { + status = sequence_step_enabled(dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, sequence_config, + &p_scheduler_sequence_steps->PreRangeOn); + } + if (status == VL53L0X_ERROR_NONE) { + status = sequence_step_enabled(dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, sequence_config, + &p_scheduler_sequence_steps->FinalRangeOn); + } + + LOG_FUNCTION_END(status); + return status; +} + +uint8_t VL53L0X::VL53L0X_decode_vcsel_period(uint8_t vcsel_period_reg) +{ + /*! + * Converts the encoded VCSEL period register value into the real + * period in PLL clocks + */ + + uint8_t vcsel_period_pclks = 0; + + vcsel_period_pclks = (vcsel_period_reg + 1) << 1; + + return vcsel_period_pclks; +} + +uint8_t VL53L0X::lv53l0x_encode_vcsel_period(uint8_t vcsel_period_pclks) +{ + /*! + * Converts the encoded VCSEL period register value into the real period + * in PLL clocks + */ + + uint8_t vcsel_period_reg = 0; + + vcsel_period_reg = (vcsel_period_pclks >> 1) - 1; + + return vcsel_period_reg; +} + + +VL53L0X_Error VL53L0X::wrapped_VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV dev, + VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period_pclk) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t vcsel_period_reg; + uint8_t min_pre_vcsel_period_pclk = 12; + uint8_t max_pre_vcsel_period_pclk = 18; + uint8_t min_final_vcsel_period_pclk = 8; + uint8_t max_final_vcsel_period_pclk = 14; + uint32_t measurement_timing_budget_micro_seconds; + uint32_t final_range_timeout_micro_seconds; + uint32_t pre_range_timeout_micro_seconds; + uint32_t msrc_timeout_micro_seconds; + uint8_t phase_cal_int = 0; + + /* Check if valid clock period requested */ + + if ((vcsel_pulse_period_pclk % 2) != 0) { + /* Value must be an even number */ + status = VL53L0X_ERROR_INVALID_PARAMS; + } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_PRE_RANGE && + (vcsel_pulse_period_pclk < min_pre_vcsel_period_pclk || + vcsel_pulse_period_pclk > max_pre_vcsel_period_pclk)) { + status = VL53L0X_ERROR_INVALID_PARAMS; + } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_FINAL_RANGE && + (vcsel_pulse_period_pclk < min_final_vcsel_period_pclk || + vcsel_pulse_period_pclk > max_final_vcsel_period_pclk)) { + + status = VL53L0X_ERROR_INVALID_PARAMS; + } + + /* Apply specific settings for the requested clock period */ + + if (status != VL53L0X_ERROR_NONE) { + return status; + } + + + if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_PRE_RANGE) { + + /* Set phase check limits */ + if (vcsel_pulse_period_pclk == 12) { + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x18); + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + } else if (vcsel_pulse_period_pclk == 14) { + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x30); + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + } else if (vcsel_pulse_period_pclk == 16) { + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x40); + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + } else if (vcsel_pulse_period_pclk == 18) { + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x50); + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + } + } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_FINAL_RANGE) { + + if (vcsel_pulse_period_pclk == 8) { + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x10); + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x02); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x0C); + + status |= VL53L0X_write_byte(dev, 0xff, 0x01); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_ALGO_PHASECAL_LIM, + 0x30); + status |= VL53L0X_write_byte(dev, 0xff, 0x00); + } else if (vcsel_pulse_period_pclk == 10) { + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x28); + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x09); + + status |= VL53L0X_write_byte(dev, 0xff, 0x01); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_ALGO_PHASECAL_LIM, + 0x20); + status |= VL53L0X_write_byte(dev, 0xff, 0x00); + } else if (vcsel_pulse_period_pclk == 12) { + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x38); + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x08); + + status |= VL53L0X_write_byte(dev, 0xff, 0x01); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_ALGO_PHASECAL_LIM, + 0x20); + status |= VL53L0X_write_byte(dev, 0xff, 0x00); + } else if (vcsel_pulse_period_pclk == 14) { + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x048); + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x07); + + status |= VL53L0X_write_byte(dev, 0xff, 0x01); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_ALGO_PHASECAL_LIM, + 0x20); + status |= VL53L0X_write_byte(dev, 0xff, 0x00); + } + } + + + /* Re-calculate and apply timeouts, in macro periods */ + + if (status == VL53L0X_ERROR_NONE) { + vcsel_period_reg = lv53l0x_encode_vcsel_period((uint8_t) + vcsel_pulse_period_pclk); + + /* When the VCSEL period for the pre or final range is changed, + * the corresponding timeout must be read from the device using + * the current VCSEL period, then the new VCSEL period can be + * applied. The timeout then must be written back to the device + * using the new VCSEL period. + * + * For the MSRC timeout, the same applies - this timeout being + * dependant on the pre-range vcsel period. + */ + switch (vcsel_period_type) { + case VL53L0X_VCSEL_PERIOD_PRE_RANGE: + status = get_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + &pre_range_timeout_micro_seconds); + + if (status == VL53L0X_ERROR_NONE) + status = get_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_MSRC, + &msrc_timeout_micro_seconds); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_write_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD, + vcsel_period_reg); + + + if (status == VL53L0X_ERROR_NONE) + status = set_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + pre_range_timeout_micro_seconds); + + + if (status == VL53L0X_ERROR_NONE) + status = set_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_MSRC, + msrc_timeout_micro_seconds); + + VL53L0X_SETDEVICESPECIFICPARAMETER( + dev, + PreRangeVcselPulsePeriod, + vcsel_pulse_period_pclk); + break; + case VL53L0X_VCSEL_PERIOD_FINAL_RANGE: + status = get_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + &final_range_timeout_micro_seconds); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_write_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD, + vcsel_period_reg); + + + if (status == VL53L0X_ERROR_NONE) + status = set_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + final_range_timeout_micro_seconds); + + VL53L0X_SETDEVICESPECIFICPARAMETER( + dev, + FinalRangeVcselPulsePeriod, + vcsel_pulse_period_pclk); + break; + default: + status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + /* Finally, the timing budget must be re-applied */ + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_GETPARAMETERFIELD(dev, + MeasurementTimingBudgetMicroSeconds, + measurement_timing_budget_micro_seconds); + + status = VL53L0X_set_measurement_timing_budget_micro_seconds(dev, + measurement_timing_budget_micro_seconds); + } + + /* Perform the phase calibration. This is needed after changing on + * vcsel period. + * get_data_enable = 0, restore_config = 1 */ + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_perform_phase_calibration( + dev, &phase_cal_int, 0, 1); + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV dev, + VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = wrapped_VL53L0X_set_vcsel_pulse_period(dev, vcsel_period_type, + vcsel_pulse_period); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::wrapped_VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV dev, + VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t vcsel_period_reg; + + switch (vcsel_period_type) { + case VL53L0X_VCSEL_PERIOD_PRE_RANGE: + status = VL53L0X_read_byte(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD, + &vcsel_period_reg); + break; + case VL53L0X_VCSEL_PERIOD_FINAL_RANGE: + status = VL53L0X_read_byte(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD, + &vcsel_period_reg); + break; + default: + status = VL53L0X_ERROR_INVALID_PARAMS; + } + + if (status == VL53L0X_ERROR_NONE) + *p_vcsel_pulse_period_pclk = + VL53L0X_decode_vcsel_period(vcsel_period_reg); + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV dev, + VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = wrapped_VL53L0X_get_vcsel_pulse_period(dev, vcsel_period_type, + p_vcsel_pulse_period_pclk); + + LOG_FUNCTION_END(status); + return status; +} + +uint32_t VL53L0X::VL53L0X_decode_timeout(uint16_t encoded_timeout) +{ + /*! + * Decode 16-bit timeout register value - format (LSByte * 2^MSByte) + 1 + */ + + 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; +} + +uint32_t VL53L0X::VL53L0X_calc_macro_period_ps(VL53L0X_DEV dev, uint8_t vcsel_period_pclks) +{ + uint64_t pll_period_ps; + uint32_t macro_period_vclks; + uint32_t macro_period_ps; + + LOG_FUNCTION_START(""); + + /* The above calculation will produce rounding errors, + therefore set fixed value + */ + pll_period_ps = 1655; + + macro_period_vclks = 2304; + macro_period_ps = (uint32_t)(macro_period_vclks + * vcsel_period_pclks * pll_period_ps); + + LOG_FUNCTION_END(""); + return macro_period_ps; +} + +/* To convert register value into us */ +uint32_t VL53L0X::VL53L0X_calc_timeout_us(VL53L0X_DEV dev, + uint16_t timeout_period_mclks, + uint8_t vcsel_period_pclks) +{ + uint32_t macro_period_ps; + uint32_t macro_period_ns; + uint32_t actual_timeout_period_us = 0; + + macro_period_ps = VL53L0X_calc_macro_period_ps(dev, vcsel_period_pclks); + macro_period_ns = (macro_period_ps + 500) / 1000; + + actual_timeout_period_us = + ((timeout_period_mclks * macro_period_ns) + 500) / 1000; + + return actual_timeout_period_us; +} + +VL53L0X_Error VL53L0X::get_sequence_step_timeout(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, + uint32_t *p_time_out_micro_secs) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t current_vcsel_pulse_period_p_clk; + uint8_t encoded_time_out_byte = 0; + uint32_t timeout_micro_seconds = 0; + uint16_t pre_range_encoded_time_out = 0; + uint16_t msrc_time_out_m_clks; + uint16_t pre_range_time_out_m_clks; + uint16_t final_range_time_out_m_clks = 0; + uint16_t final_range_encoded_time_out; + VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps; + + if ((sequence_step_id == VL53L0X_SEQUENCESTEP_TCC) || + (sequence_step_id == VL53L0X_SEQUENCESTEP_DSS) || + (sequence_step_id == VL53L0X_SEQUENCESTEP_MSRC)) { + + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + ¤t_vcsel_pulse_period_p_clk); + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_byte(dev, + VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP, + &encoded_time_out_byte); + } + msrc_time_out_m_clks = VL53L0X_decode_timeout(encoded_time_out_byte); + + timeout_micro_seconds = VL53L0X_calc_timeout_us(dev, + msrc_time_out_m_clks, + current_vcsel_pulse_period_p_clk); + } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_PRE_RANGE) { + /* Retrieve PRE-RANGE VCSEL Period */ + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + ¤t_vcsel_pulse_period_p_clk); + + /* Retrieve PRE-RANGE Timeout in Macro periods (MCLKS) */ + if (status == VL53L0X_ERROR_NONE) { + + /* Retrieve PRE-RANGE VCSEL Period */ + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + ¤t_vcsel_pulse_period_p_clk); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_word(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, + &pre_range_encoded_time_out); + } + + pre_range_time_out_m_clks = VL53L0X_decode_timeout( + pre_range_encoded_time_out); + + timeout_micro_seconds = VL53L0X_calc_timeout_us(dev, + pre_range_time_out_m_clks, + current_vcsel_pulse_period_p_clk); + } + } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_FINAL_RANGE) { + + VL53L0X_get_sequence_step_enables(dev, &scheduler_sequence_steps); + pre_range_time_out_m_clks = 0; + + if (scheduler_sequence_steps.PreRangeOn) { + /* Retrieve PRE-RANGE VCSEL Period */ + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + ¤t_vcsel_pulse_period_p_clk); + + /* Retrieve PRE-RANGE Timeout in Macro periods + * (MCLKS) */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_word(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, + &pre_range_encoded_time_out); + pre_range_time_out_m_clks = VL53L0X_decode_timeout( + pre_range_encoded_time_out); + } + } + + if (status == VL53L0X_ERROR_NONE) { + /* Retrieve FINAL-RANGE VCSEL Period */ + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_FINAL_RANGE, + ¤t_vcsel_pulse_period_p_clk); + } + + /* Retrieve FINAL-RANGE Timeout in Macro periods (MCLKS) */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_word(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, + &final_range_encoded_time_out); + final_range_time_out_m_clks = VL53L0X_decode_timeout( + final_range_encoded_time_out); + } + + final_range_time_out_m_clks -= pre_range_time_out_m_clks; + timeout_micro_seconds = VL53L0X_calc_timeout_us(dev, + final_range_time_out_m_clks, + current_vcsel_pulse_period_p_clk); + } + + *p_time_out_micro_secs = timeout_micro_seconds; + + return status; +} + +VL53L0X_Error VL53L0X::wrapped_VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev, + uint32_t *p_measurement_timing_budget_micro_seconds) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps; + uint32_t final_range_timeout_micro_seconds; + uint32_t msrc_dcc_tcc_timeout_micro_seconds = 2000; + uint32_t start_overhead_micro_seconds = 1910; + uint32_t end_overhead_micro_seconds = 960; + uint32_t msrc_overhead_micro_seconds = 660; + uint32_t tcc_overhead_micro_seconds = 590; + uint32_t dss_overhead_micro_seconds = 690; + uint32_t pre_range_overhead_micro_seconds = 660; + uint32_t final_range_overhead_micro_seconds = 550; + uint32_t pre_range_timeout_micro_seconds = 0; + + LOG_FUNCTION_START(""); + + /* Start and end overhead times always present */ + *p_measurement_timing_budget_micro_seconds + = start_overhead_micro_seconds + end_overhead_micro_seconds; + + status = VL53L0X_get_sequence_step_enables(dev, &scheduler_sequence_steps); + + if (status != VL53L0X_ERROR_NONE) { + LOG_FUNCTION_END(status); + return status; + } + + + if (scheduler_sequence_steps.TccOn || + scheduler_sequence_steps.MsrcOn || + scheduler_sequence_steps.DssOn) { + + status = get_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_MSRC, + &msrc_dcc_tcc_timeout_micro_seconds); + + if (status == VL53L0X_ERROR_NONE) { + if (scheduler_sequence_steps.TccOn) { + *p_measurement_timing_budget_micro_seconds += + msrc_dcc_tcc_timeout_micro_seconds + + tcc_overhead_micro_seconds; + } + + if (scheduler_sequence_steps.DssOn) { + *p_measurement_timing_budget_micro_seconds += + 2 * (msrc_dcc_tcc_timeout_micro_seconds + + dss_overhead_micro_seconds); + } else if (scheduler_sequence_steps.MsrcOn) { + *p_measurement_timing_budget_micro_seconds += + msrc_dcc_tcc_timeout_micro_seconds + + msrc_overhead_micro_seconds; + } + } + } + + if (status == VL53L0X_ERROR_NONE) { + if (scheduler_sequence_steps.PreRangeOn) { + status = get_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + &pre_range_timeout_micro_seconds); + *p_measurement_timing_budget_micro_seconds += + pre_range_timeout_micro_seconds + + pre_range_overhead_micro_seconds; + } + } + + if (status == VL53L0X_ERROR_NONE) { + if (scheduler_sequence_steps.FinalRangeOn) { + status = get_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + &final_range_timeout_micro_seconds); + *p_measurement_timing_budget_micro_seconds += + (final_range_timeout_micro_seconds + + final_range_overhead_micro_seconds); + } + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(dev, + MeasurementTimingBudgetMicroSeconds, + *p_measurement_timing_budget_micro_seconds); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev, + uint32_t *p_measurement_timing_budget_micro_seconds) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = wrapped_VL53L0X_get_measurement_timing_budget_micro_seconds(dev, + p_measurement_timing_budget_micro_seconds); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_device_parameters(VL53L0X_DEV dev, + VL53L0X_DeviceParameters_t *p_device_parameters) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + int i; + + LOG_FUNCTION_START(""); + + status = VL53L0X_get_device_mode(dev, &(p_device_parameters->DeviceMode)); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_get_inter_measurement_period_milli_seconds(dev, + &(p_device_parameters->InterMeasurementPeriodMilliSeconds)); + + + if (status == VL53L0X_ERROR_NONE) { + p_device_parameters->XTalkCompensationEnable = 0; + } + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_get_x_talk_compensation_rate_mega_cps(dev, + &(p_device_parameters->XTalkCompensationRateMegaCps)); + + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_get_offset_calibration_data_micro_meter(dev, + &(p_device_parameters->RangeOffsetMicroMeters)); + + + if (status == VL53L0X_ERROR_NONE) { + for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) { + /* get first the values, then the enables. + * VL53L0X_GetLimitCheckValue will modify the enable + * flags + */ + if (status == VL53L0X_ERROR_NONE) { + status |= VL53L0X_get_limit_check_value(dev, i, + &(p_device_parameters->LimitChecksValue[i])); + } else { + break; + } + if (status == VL53L0X_ERROR_NONE) { + status |= VL53L0X_get_limit_check_enable(dev, i, + &(p_device_parameters->LimitChecksEnable[i])); + } else { + break; + } + } + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_wrap_around_check_enable(dev, + &(p_device_parameters->WrapAroundCheckEnable)); + } + + /* Need to be done at the end as it uses VCSELPulsePeriod */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_measurement_timing_budget_micro_seconds(dev, + &(p_device_parameters->MeasurementTimingBudgetMicroSeconds)); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_limit_check_value(VL53L0X_DEV dev, uint16_t limit_check_id, + FixPoint1616_t limit_check_value) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t temp8; + + LOG_FUNCTION_START(""); + + VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksEnable, limit_check_id, + temp8); + + if (temp8 == 0) { /* disabled write only internal value */ + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue, + limit_check_id, limit_check_value); + } else { + + switch (limit_check_id) { + + case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE: + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + limit_check_value); + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE: + + status = VL53L0X_write_word(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, + VL53L0X_FIXPOINT1616TOFIXPOINT97( + limit_check_value)); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP: + + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + limit_check_value); + + break; + + case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD: + + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + limit_check_value); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC: + case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE: + + status = VL53L0X_write_word(dev, + VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT, + VL53L0X_FIXPOINT1616TOFIXPOINT97( + limit_check_value)); + + break; + + default: + status = VL53L0X_ERROR_INVALID_PARAMS; + + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksValue, + limit_check_id, limit_check_value); + } + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_data_init(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + VL53L0X_DeviceParameters_t CurrentParameters; + int i; + uint8_t StopVariable; + + LOG_FUNCTION_START(""); + + /* by default the I2C is running at 1V8 if you want to change it you + * need to include this define at compilation level. */ +#ifdef USE_I2C_2V8 + Status = VL53L0X_UpdateByte(Dev, + VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV, + 0xFE, + 0x01); +#endif + + /* Set I2C standard mode */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0x88, 0x00); + } + + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, ReadDataFromDeviceDone, 0); + +#ifdef USE_IQC_STATION + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_apply_offset_adjustment(Dev); + } +#endif + + /* Default value is 1000 for Linearity Corrective Gain */ + PALDevDataSet(dev, LinearityCorrectiveGain, 1000); + + /* Dmax default Parameter */ + PALDevDataSet(dev, DmaxCalRangeMilliMeter, 400); + PALDevDataSet(dev, DmaxCalSignalRateRtnMegaCps, + (FixPoint1616_t)((0x00016B85))); /* 1.42 No Cover Glass*/ + + /* Set Default static parameters + *set first temporary values 9.44MHz * 65536 = 618660 */ + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, OscFrequencyMHz, 618660); + + /* Set Default XTalkCompensationRateMegaCps to 0 */ + VL53L0X_SETPARAMETERFIELD(dev, XTalkCompensationRateMegaCps, 0); + + /* Get default parameters */ + status = VL53L0X_get_device_parameters(dev, &CurrentParameters); + if (status == VL53L0X_ERROR_NONE) { + /* initialize PAL values */ + CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_SINGLE_RANGING; + CurrentParameters.HistogramMode = VL53L0X_HISTOGRAMMODE_DISABLED; + PALDevDataSet(dev, CurrentParameters, CurrentParameters); + } + + /* Sigma estimator variable */ + PALDevDataSet(dev, SigmaEstRefArray, 100); + PALDevDataSet(dev, SigmaEstEffPulseWidth, 900); + PALDevDataSet(dev, SigmaEstEffAmbWidth, 500); + PALDevDataSet(dev, targetRefRate, 0x0A00); /* 20 MCPS in 9:7 format */ + + /* Use internal default settings */ + PALDevDataSet(dev, UseInternalTuningSettings, 1); + + status |= VL53L0X_write_byte(dev, 0x80, 0x01); + status |= VL53L0X_write_byte(dev, 0xFF, 0x01); + status |= VL53L0X_write_byte(dev, 0x00, 0x00); + status |= VL53L0X_read_byte(dev, 0x91, &StopVariable); + PALDevDataSet(dev, StopVariable, StopVariable); + status |= VL53L0X_write_byte(dev, 0x00, 0x01); + status |= VL53L0X_write_byte(dev, 0xFF, 0x00); + status |= VL53L0X_write_byte(dev, 0x80, 0x00); + + /* Enable all check */ + for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) { + if (status == VL53L0X_ERROR_NONE) { + status |= VL53L0X_set_limit_check_enable(dev, i, 1); + } else { + break; + } + + } + + /* Disable the following checks */ + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_set_limit_check_enable(dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, 0); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_set_limit_check_enable(dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 0); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_set_limit_check_enable(dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC, 0); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_set_limit_check_enable(dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE, 0); + + /* Limit default values */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_set_limit_check_value(dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + (FixPoint1616_t)(18 * 65536)); + } + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_set_limit_check_value(dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + (FixPoint1616_t)(25 * 65536 / 100)); + /* 0.25 * 65536 */ + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_set_limit_check_value(dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + (FixPoint1616_t)(35 * 65536)); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_set_limit_check_value(dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + (FixPoint1616_t)(0 * 65536)); + } + + if (status == VL53L0X_ERROR_NONE) { + + PALDevDataSet(dev, SequenceConfig, 0xFF); + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + 0xFF); + + /* Set PAL state to tell that we are waiting for call to + * VL53L0X_StaticInit */ + PALDevDataSet(dev, PalState, VL53L0X_STATE_WAIT_STATICINIT); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, RefSpadsInitialised, 0); + } + + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_check_part_used(VL53L0X_DEV dev, + uint8_t *revision, + VL53L0X_DeviceInfo_t *p_VL53L0X_device_info) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t module_id_int; + char *product_id_tmp; + + LOG_FUNCTION_START(""); + + status = VL53L0X_get_info_from_device(dev, 2); + + if (status == VL53L0X_ERROR_NONE) { + module_id_int = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, ModuleId); + + if (module_id_int == 0) { + *revision = 0; + VL53L0X_COPYSTRING(p_VL53L0X_device_info->ProductId, ""); + } else { + *revision = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, Revision); + product_id_tmp = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, + ProductId); + VL53L0X_COPYSTRING(p_VL53L0X_device_info->ProductId, product_id_tmp); + } + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::wrapped_VL53L0X_get_device_info(VL53L0X_DEV dev, + VL53L0X_DeviceInfo_t *p_VL53L0X_device_info) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t revision_id; + uint8_t revision; + + status = VL53L0X_check_part_used(dev, &revision, p_VL53L0X_device_info); + + if (status == VL53L0X_ERROR_NONE) { + if (revision == 0) { + VL53L0X_COPYSTRING(p_VL53L0X_device_info->Name, + VL53L0X_STRING_DEVICE_INFO_NAME_TS0); + } else if ((revision <= 34) && (revision != 32)) { + VL53L0X_COPYSTRING(p_VL53L0X_device_info->Name, + VL53L0X_STRING_DEVICE_INFO_NAME_TS1); + } else if (revision < 39) { + VL53L0X_COPYSTRING(p_VL53L0X_device_info->Name, + VL53L0X_STRING_DEVICE_INFO_NAME_TS2); + } else { + VL53L0X_COPYSTRING(p_VL53L0X_device_info->Name, + VL53L0X_STRING_DEVICE_INFO_NAME_ES1); + } + + VL53L0X_COPYSTRING(p_VL53L0X_device_info->Type, + VL53L0X_STRING_DEVICE_INFO_TYPE); + + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_byte(dev, VL53L0X_REG_IDENTIFICATION_MODEL_ID, + &p_VL53L0X_device_info->ProductType); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_byte(dev, + VL53L0X_REG_IDENTIFICATION_REVISION_ID, + &revision_id); + p_VL53L0X_device_info->ProductRevisionMajor = 1; + p_VL53L0X_device_info->ProductRevisionMinor = + (revision_id & 0xF0) >> 4; + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_device_info(VL53L0X_DEV dev, + VL53L0X_DeviceInfo_t *p_VL53L0X_device_info) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = wrapped_VL53L0X_get_device_info(dev, p_VL53L0X_device_info); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_interrupt_mask_status(VL53L0X_DEV dev, + uint32_t *p_interrupt_mask_status) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t byte; + LOG_FUNCTION_START(""); + + status = VL53L0X_read_byte(dev, VL53L0X_REG_RESULT_INTERRUPT_STATUS, &byte); + *p_interrupt_mask_status = byte & 0x07; + + if (byte & 0x18) { + status = VL53L0X_ERROR_RANGE_ERROR; + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_measurement_data_ready(VL53L0X_DEV dev, + uint8_t *p_measurement_data_ready) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t sys_range_status_register; + uint8_t interrupt_config; + uint32_t interrupt_mask; + LOG_FUNCTION_START(""); + + interrupt_config = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, + Pin0GpioFunctionality); + + if (interrupt_config == + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) { + status = VL53L0X_get_interrupt_mask_status(dev, &interrupt_mask); + if (interrupt_mask == + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) { + *p_measurement_data_ready = 1; + } else { + *p_measurement_data_ready = 0; + } + } else { + status = VL53L0X_read_byte(dev, VL53L0X_REG_RESULT_RANGE_STATUS, + &sys_range_status_register); + if (status == VL53L0X_ERROR_NONE) { + if (sys_range_status_register & 0x01) { + *p_measurement_data_ready = 1; + } else { + *p_measurement_data_ready = 0; + } + } + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_polling_delay(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + + // do nothing + VL53L0X_OsDelay(); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_measurement_poll_for_completion(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t new_data_ready = 0; + uint32_t loop_nb; + + LOG_FUNCTION_START(""); + + loop_nb = 0; + + do { + status = VL53L0X_get_measurement_data_ready(dev, &new_data_ready); + if (status != 0) { + break; /* the error is set */ + } + + if (new_data_ready == 1) { + break; /* done note that status == 0 */ + } + + loop_nb++; + if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) { + status = VL53L0X_ERROR_TIME_OUT; + break; + } + + VL53L0X_polling_delay(dev); + } while (1); + + LOG_FUNCTION_END(status); + + return status; +} + +/* Group PAL Interrupt Functions */ +VL53L0X_Error VL53L0X::VL53L0X_clear_interrupt_mask(VL53L0X_DEV dev, uint32_t interrupt_mask) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t loop_count; + uint8_t byte; + LOG_FUNCTION_START(""); + + /* clear bit 0 range interrupt, bit 1 error interrupt */ + loop_count = 0; + do { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x01); + status |= VL53L0X_write_byte(dev, + VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x00); + status |= VL53L0X_read_byte(dev, + VL53L0X_REG_RESULT_INTERRUPT_STATUS, &byte); + loop_count++; + } while (((byte & 0x07) != 0x00) + && (loop_count < 3) + && (status == VL53L0X_ERROR_NONE)); + + + if (loop_count >= 3) { + status = VL53L0X_ERROR_INTERRUPT_NOT_CLEARED; + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_perform_single_ref_calibration(VL53L0X_DEV dev, + uint8_t vhv_init_byte) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSRANGE_START, + VL53L0X_REG_SYSRANGE_MODE_START_STOP | + vhv_init_byte); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_measurement_poll_for_completion(dev); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_clear_interrupt_mask(dev, 0); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSRANGE_START, 0x00); + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_ref_calibration_io(VL53L0X_DEV dev, uint8_t read_not_write, + uint8_t vhv_settings, uint8_t phase_cal, + uint8_t *p_vhv_settings, uint8_t *p_phase_cal, + const uint8_t vhv_enable, const uint8_t phase_enable) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t phase_calint = 0; + + /* Read VHV from device */ + status |= VL53L0X_write_byte(dev, 0xFF, 0x01); + status |= VL53L0X_write_byte(dev, 0x00, 0x00); + status |= VL53L0X_write_byte(dev, 0xFF, 0x00); + + if (read_not_write) { + if (vhv_enable) { + status |= VL53L0X_read_byte(dev, 0xCB, p_vhv_settings); + } + if (phase_enable) { + status |= VL53L0X_read_byte(dev, 0xEE, &phase_calint); + } + } else { + if (vhv_enable) { + status |= VL53L0X_write_byte(dev, 0xCB, vhv_settings); + } + if (phase_enable) { + status |= VL53L0X_update_byte(dev, 0xEE, 0x80, phase_cal); + } + } + + status |= VL53L0X_write_byte(dev, 0xFF, 0x01); + status |= VL53L0X_write_byte(dev, 0x00, 0x01); + status |= VL53L0X_write_byte(dev, 0xFF, 0x00); + + *p_phase_cal = (uint8_t)(phase_calint & 0xEF); + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_perform_vhv_calibration(VL53L0X_DEV dev, + uint8_t *p_vhv_settings, const uint8_t get_data_enable, + const uint8_t restore_config) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t sequence_config = 0; + uint8_t vhv_settings = 0; + uint8_t phase_cal = 0; + uint8_t phase_cal_int = 0; + + /* store the value of the sequence config, + * this will be reset before the end of the function + */ + + if (restore_config) { + sequence_config = PALDevDataGet(dev, SequenceConfig); + } + + /* Run VHV */ + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0x01); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_perform_single_ref_calibration(dev, 0x40); + } + + /* Read VHV from device */ + if ((status == VL53L0X_ERROR_NONE) && (get_data_enable == 1)) { + status = VL53L0X_ref_calibration_io(dev, 1, + vhv_settings, phase_cal, /* Not used here */ + p_vhv_settings, &phase_cal_int, + 1, 0); + } else { + *p_vhv_settings = 0; + } + + + if ((status == VL53L0X_ERROR_NONE) && restore_config) { + /* restore the previous Sequence Config */ + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + sequence_config); + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, SequenceConfig, sequence_config); + } + + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_perform_phase_calibration(VL53L0X_DEV dev, + uint8_t *p_phase_cal, const uint8_t get_data_enable, + const uint8_t restore_config) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t sequence_config = 0; + uint8_t vhv_settings = 0; + uint8_t phase_cal = 0; + uint8_t vhv_settingsint; + + /* store the value of the sequence config, + * this will be reset before the end of the function + */ + + if (restore_config) { + sequence_config = PALDevDataGet(dev, SequenceConfig); + } + + /* Run PhaseCal */ + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0x02); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_perform_single_ref_calibration(dev, 0x0); + } + + /* Read PhaseCal from device */ + if ((status == VL53L0X_ERROR_NONE) && (get_data_enable == 1)) { + status = VL53L0X_ref_calibration_io(dev, 1, + vhv_settings, phase_cal, /* Not used here */ + &vhv_settingsint, p_phase_cal, + 0, 1); + } else { + *p_phase_cal = 0; + } + + + if ((status == VL53L0X_ERROR_NONE) && restore_config) { + /* restore the previous Sequence Config */ + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + sequence_config); + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, SequenceConfig, sequence_config); + } + + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_perform_ref_calibration(VL53L0X_DEV dev, + uint8_t *p_vhv_settings, uint8_t *p_phase_cal, uint8_t get_data_enable) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t sequence_config = 0; + + /* store the value of the sequence config, + * this will be reset before the end of the function + */ + + sequence_config = PALDevDataGet(dev, SequenceConfig); + + /* In the following function we don't save the config to optimize + * writes on device. Config is saved and restored only once. */ + status = VL53L0X_perform_vhv_calibration( + dev, p_vhv_settings, get_data_enable, 0); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_perform_phase_calibration( + dev, p_phase_cal, get_data_enable, 0); + } + + + if (status == VL53L0X_ERROR_NONE) { + /* restore the previous Sequence Config */ + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + sequence_config); + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, SequenceConfig, sequence_config); + } + + } + + return status; +} + +void VL53L0X::get_next_good_spad(uint8_t good_spad_array[], uint32_t size, + uint32_t curr, int32_t *p_next) +{ + uint32_t start_index; + uint32_t fine_offset; + uint32_t c_spads_per_byte = 8; + uint32_t coarse_index; + uint32_t fine_index; + uint8_t data_byte; + uint8_t success = 0; + + /* + * Starting with the current good spad, loop through the array to find + * the next. i.e. the next bit set in the sequence. + * + * The coarse index is the byte index of the array and the fine index is + * the index of the bit within each byte. + */ + + *p_next = -1; + + start_index = curr / c_spads_per_byte; + fine_offset = curr % c_spads_per_byte; + + for (coarse_index = start_index; ((coarse_index < size) && !success); + coarse_index++) { + fine_index = 0; + data_byte = good_spad_array[coarse_index]; + + if (coarse_index == start_index) { + /* locate the bit position of the provided current + * spad bit before iterating */ + data_byte >>= fine_offset; + fine_index = fine_offset; + } + + while (fine_index < c_spads_per_byte) { + if ((data_byte & 0x1) == 1) { + success = 1; + *p_next = coarse_index * c_spads_per_byte + fine_index; + break; + } + data_byte >>= 1; + fine_index++; + } + } +} + +uint8_t VL53L0X::is_aperture(uint32_t spad_index) +{ + /* + * This function reports if a given spad index is an aperture SPAD by + * deriving the quadrant. + */ + uint32_t quadrant; + uint8_t is_aperture = 1; + quadrant = spad_index >> 6; + if (refArrayQuadrants[quadrant] == REF_ARRAY_SPAD_0) { + is_aperture = 0; + } + + return is_aperture; +} + +VL53L0X_Error VL53L0X::enable_spad_bit(uint8_t spad_array[], uint32_t size, + uint32_t spad_index) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t c_spads_per_byte = 8; + uint32_t coarse_index; + uint32_t fine_index; + + coarse_index = spad_index / c_spads_per_byte; + fine_index = spad_index % c_spads_per_byte; + if (coarse_index >= size) { + status = VL53L0X_ERROR_REF_SPAD_INIT; + } else { + spad_array[coarse_index] |= (1 << fine_index); + } + + return status; +} + +VL53L0X_Error VL53L0X::set_ref_spad_map(VL53L0X_DEV dev, uint8_t *p_ref_spad_array) +{ + VL53L0X_Error status = VL53L0X_write_multi(dev, + VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, + p_ref_spad_array, 6); + + return status; +} + +VL53L0X_Error VL53L0X::get_ref_spad_map(VL53L0X_DEV dev, uint8_t *p_ref_spad_array) +{ + VL53L0X_Error status = VL53L0X_read_multi(dev, + VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, + p_ref_spad_array, + 6); +// VL53L0X_Error status = VL53L0X_ERROR_NONE; +// uint8_t count=0; + +// for (count = 0; count < 6; count++) +// status = VL53L0X_RdByte(Dev, (VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0 + count), &refSpadArray[count]); + return status; +} + +VL53L0X_Error VL53L0X::enable_ref_spads(VL53L0X_DEV dev, + uint8_t aperture_spads, + uint8_t good_spad_array[], + uint8_t spad_array[], + uint32_t size, + uint32_t start, + uint32_t offset, + uint32_t spad_count, + uint32_t *p_last_spad) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t index; + uint32_t i; + int32_t next_good_spad = offset; + uint32_t current_spad; + uint8_t check_spad_array[6]; + + /* + * This function takes in a spad array which may or may not have SPADS + * already enabled and appends from a given offset a requested number + * of new SPAD enables. The 'good spad map' is applied to + * determine the next SPADs to enable. + * + * This function applies to only aperture or only non-aperture spads. + * Checks are performed to ensure this. + */ + + current_spad = offset; + for (index = 0; index < spad_count; index++) { + get_next_good_spad(good_spad_array, size, current_spad, + &next_good_spad); + + if (next_good_spad == -1) { + status = VL53L0X_ERROR_REF_SPAD_INIT; + break; + } + + /* Confirm that the next good SPAD is non-aperture */ + if (is_aperture(start + next_good_spad) != aperture_spads) { + /* if we can't get the required number of good aperture + * spads from the current quadrant then this is an error + */ + status = VL53L0X_ERROR_REF_SPAD_INIT; + break; + } + current_spad = (uint32_t)next_good_spad; + enable_spad_bit(spad_array, size, current_spad); + current_spad++; + } + *p_last_spad = current_spad; + + if (status == VL53L0X_ERROR_NONE) { + status = set_ref_spad_map(dev, spad_array); + } + + + if (status == VL53L0X_ERROR_NONE) { + status = get_ref_spad_map(dev, check_spad_array); + + i = 0; + + /* Compare spad maps. If not equal report error. */ + while (i < size) { + if (spad_array[i] != check_spad_array[i]) { + status = VL53L0X_ERROR_REF_SPAD_INIT; + break; + } + i++; + } + } + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_device_mode(VL53L0X_DEV dev, VL53L0X_DeviceModes device_mode) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START("%d", (int)DeviceMode); + + switch (device_mode) { + case VL53L0X_DEVICEMODE_SINGLE_RANGING: + case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING: + case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING: + case VL53L0X_DEVICEMODE_GPIO_DRIVE: + case VL53L0X_DEVICEMODE_GPIO_OSC: + /* Supported modes */ + VL53L0X_SETPARAMETERFIELD(dev, DeviceMode, device_mode); + break; + default: + /* Unsupported mode */ + status = VL53L0X_ERROR_MODE_NOT_SUPPORTED; + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_interrupt_thresholds(VL53L0X_DEV dev, + VL53L0X_DeviceModes device_mode, FixPoint1616_t threshold_low, + FixPoint1616_t threshold_high) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint16_t threshold16; + LOG_FUNCTION_START(""); + + /* no dependency on DeviceMode for Ewok */ + /* Need to divide by 2 because the FW will apply a x2 */ + threshold16 = (uint16_t)((threshold_low >> 17) & 0x00fff); + status = VL53L0X_write_word(dev, VL53L0X_REG_SYSTEM_THRESH_LOW, threshold16); + + if (status == VL53L0X_ERROR_NONE) { + /* Need to divide by 2 because the FW will apply a x2 */ + threshold16 = (uint16_t)((threshold_high >> 17) & 0x00fff); + status = VL53L0X_write_word(dev, VL53L0X_REG_SYSTEM_THRESH_HIGH, + threshold16); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_interrupt_thresholds(VL53L0X_DEV dev, + VL53L0X_DeviceModes device_mode, FixPoint1616_t *p_threshold_low, + FixPoint1616_t *p_threshold_high) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint16_t threshold16; + LOG_FUNCTION_START(""); + + /* no dependency on DeviceMode for Ewok */ + + status = VL53L0X_read_word(dev, VL53L0X_REG_SYSTEM_THRESH_LOW, &threshold16); + /* Need to multiply by 2 because the FW will apply a x2 */ + *p_threshold_low = (FixPoint1616_t)((0x00fff & threshold16) << 17); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_word(dev, VL53L0X_REG_SYSTEM_THRESH_HIGH, + &threshold16); + /* Need to multiply by 2 because the FW will apply a x2 */ + *p_threshold_high = + (FixPoint1616_t)((0x00fff & threshold16) << 17); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_load_tuning_settings(VL53L0X_DEV dev, + uint8_t *p_tuning_setting_buffer) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + int i; + int index; + uint8_t msb; + uint8_t lsb; + uint8_t select_param; + uint8_t number_of_writes; + uint8_t address; + uint8_t local_buffer[4]; /* max */ + uint16_t temp16; + + LOG_FUNCTION_START(""); + + index = 0; + + while ((*(p_tuning_setting_buffer + index) != 0) && + (status == VL53L0X_ERROR_NONE)) { + number_of_writes = *(p_tuning_setting_buffer + index); + index++; + if (number_of_writes == 0xFF) { + /* internal parameters */ + select_param = *(p_tuning_setting_buffer + index); + index++; + switch (select_param) { + case 0: /* uint16_t SigmaEstRefArray -> 2 bytes */ + msb = *(p_tuning_setting_buffer + index); + index++; + lsb = *(p_tuning_setting_buffer + index); + index++; + temp16 = VL53L0X_MAKEUINT16(lsb, msb); + PALDevDataSet(dev, SigmaEstRefArray, temp16); + break; + case 1: /* uint16_t SigmaEstEffPulseWidth -> 2 bytes */ + msb = *(p_tuning_setting_buffer + index); + index++; + lsb = *(p_tuning_setting_buffer + index); + index++; + temp16 = VL53L0X_MAKEUINT16(lsb, msb); + PALDevDataSet(dev, SigmaEstEffPulseWidth, + temp16); + break; + case 2: /* uint16_t SigmaEstEffAmbWidth -> 2 bytes */ + msb = *(p_tuning_setting_buffer + index); + index++; + lsb = *(p_tuning_setting_buffer + index); + index++; + temp16 = VL53L0X_MAKEUINT16(lsb, msb); + PALDevDataSet(dev, SigmaEstEffAmbWidth, temp16); + break; + case 3: /* uint16_t targetRefRate -> 2 bytes */ + msb = *(p_tuning_setting_buffer + index); + index++; + lsb = *(p_tuning_setting_buffer + index); + index++; + temp16 = VL53L0X_MAKEUINT16(lsb, msb); + PALDevDataSet(dev, targetRefRate, temp16); + break; + default: /* invalid parameter */ + status = VL53L0X_ERROR_INVALID_PARAMS; + } + + } else if (number_of_writes <= 4) { + address = *(p_tuning_setting_buffer + index); + index++; + + for (i = 0; i < number_of_writes; i++) { + local_buffer[i] = *(p_tuning_setting_buffer + + index); + index++; + } + + status = VL53L0X_write_multi(dev, address, local_buffer, + number_of_writes); + + } else { + status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_check_and_load_interrupt_settings(VL53L0X_DEV dev, + uint8_t start_not_stopflag) +{ + uint8_t interrupt_config; + FixPoint1616_t threshold_low; + FixPoint1616_t threshold_high; + VL53L0X_Error status = VL53L0X_ERROR_NONE; + + interrupt_config = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, + Pin0GpioFunctionality); + + if ((interrupt_config == + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW) || + (interrupt_config == + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH) || + (interrupt_config == + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT)) { + + status = VL53L0X_get_interrupt_thresholds(dev, + VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, + &threshold_low, &threshold_high); + + if (((threshold_low > 255 * 65536) || + (threshold_high > 255 * 65536)) && + (status == VL53L0X_ERROR_NONE)) { + + if (start_not_stopflag != 0) { + status = VL53L0X_load_tuning_settings(dev, + InterruptThresholdSettings); + } else { + status |= VL53L0X_write_byte(dev, 0xFF, 0x04); + status |= VL53L0X_write_byte(dev, 0x70, 0x00); + status |= VL53L0X_write_byte(dev, 0xFF, 0x00); + status |= VL53L0X_write_byte(dev, 0x80, 0x00); + } + + } + + + } + + return status; + +} + +VL53L0X_Error VL53L0X::VL53L0X_start_measurement(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + VL53L0X_DeviceModes device_mode; + uint8_t byte; + uint8_t start_stop_byte = VL53L0X_REG_SYSRANGE_MODE_START_STOP; + uint32_t loop_nb; + LOG_FUNCTION_START(""); + + /* Get Current DeviceMode */ + VL53L0X_get_device_mode(dev, &device_mode); + + status = VL53L0X_write_byte(dev, 0x80, 0x01); + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + status = VL53L0X_write_byte(dev, 0x00, 0x00); + status = VL53L0X_write_byte(dev, 0x91, PALDevDataGet(dev, StopVariable)); + status = VL53L0X_write_byte(dev, 0x00, 0x01); + status = VL53L0X_write_byte(dev, 0xFF, 0x00); + status = VL53L0X_write_byte(dev, 0x80, 0x00); + + switch (device_mode) { + case VL53L0X_DEVICEMODE_SINGLE_RANGING: + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSRANGE_START, 0x01); + + byte = start_stop_byte; + if (status == VL53L0X_ERROR_NONE) { + /* Wait until start bit has been cleared */ + loop_nb = 0; + do { + if (loop_nb > 0) + status = VL53L0X_read_byte(dev, + VL53L0X_REG_SYSRANGE_START, &byte); + loop_nb = loop_nb + 1; + } while (((byte & start_stop_byte) == start_stop_byte) + && (status == VL53L0X_ERROR_NONE) + && (loop_nb < VL53L0X_DEFAULT_MAX_LOOP)); + + if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) { + status = VL53L0X_ERROR_TIME_OUT; + } + + } + + break; + case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING: + /* Back-to-back mode */ + + /* Check if need to apply interrupt settings */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_check_and_load_interrupt_settings(dev, 1); + } + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_SYSRANGE_START, + VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK); + if (status == VL53L0X_ERROR_NONE) { + /* Set PAL State to Running */ + PALDevDataSet(dev, PalState, VL53L0X_STATE_RUNNING); + } + break; + case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING: + /* Continuous mode */ + /* Check if need to apply interrupt settings */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_check_and_load_interrupt_settings(dev, 1); + } + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_SYSRANGE_START, + VL53L0X_REG_SYSRANGE_MODE_TIMED); + + if (status == VL53L0X_ERROR_NONE) { + /* Set PAL State to Running */ + PALDevDataSet(dev, PalState, VL53L0X_STATE_RUNNING); + } + break; + default: + /* Selected mode not supported */ + status = VL53L0X_ERROR_MODE_NOT_SUPPORTED; + } + + + LOG_FUNCTION_END(status); + return status; +} + +/* Group PAL Measurement Functions */ +VL53L0X_Error VL53L0X::VL53L0X_perform_single_measurement(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + VL53L0X_DeviceModes device_mode; + + LOG_FUNCTION_START(""); + + /* Get Current DeviceMode */ + status = VL53L0X_get_device_mode(dev, &device_mode); + + /* Start immediately to run a single ranging measurement in case of + * single ranging or single histogram */ + if (status == VL53L0X_ERROR_NONE + && device_mode == VL53L0X_DEVICEMODE_SINGLE_RANGING) { + status = VL53L0X_start_measurement(dev); + } + + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_measurement_poll_for_completion(dev); + } + + + /* Change PAL State in case of single ranging or single histogram */ + if (status == VL53L0X_ERROR_NONE + && device_mode == VL53L0X_DEVICEMODE_SINGLE_RANGING) { + PALDevDataSet(dev, PalState, VL53L0X_STATE_IDLE); + } + + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_x_talk_compensation_enable(VL53L0X_DEV dev, + uint8_t *p_x_talk_compensation_enable) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t temp8; + LOG_FUNCTION_START(""); + + VL53L0X_GETPARAMETERFIELD(dev, XTalkCompensationEnable, temp8); + *p_x_talk_compensation_enable = temp8; + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_total_xtalk_rate(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data, + FixPoint1616_t *p_total_xtalk_rate_mcps) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + + uint8_t xtalk_comp_enable; + FixPoint1616_t total_xtalk_mega_cps; + FixPoint1616_t xtalk_per_spad_mega_cps; + + *p_total_xtalk_rate_mcps = 0; + + status = VL53L0X_get_x_talk_compensation_enable(dev, &xtalk_comp_enable); + if (status == VL53L0X_ERROR_NONE) { + + if (xtalk_comp_enable) { + + VL53L0X_GETPARAMETERFIELD( + dev, + XTalkCompensationRateMegaCps, + xtalk_per_spad_mega_cps); + + /* FixPoint1616 * FixPoint 8:8 = FixPoint0824 */ + total_xtalk_mega_cps = + p_ranging_measurement_data->EffectiveSpadRtnCount * + xtalk_per_spad_mega_cps; + + /* FixPoint0824 >> 8 = FixPoint1616 */ + *p_total_xtalk_rate_mcps = + (total_xtalk_mega_cps + 0x80) >> 8; + } + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_total_signal_rate(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data, + FixPoint1616_t *p_total_signal_rate_mcps) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + FixPoint1616_t total_xtalk_mega_cps; + + LOG_FUNCTION_START(""); + + *p_total_signal_rate_mcps = + p_ranging_measurement_data->SignalRateRtnMegaCps; + + status = VL53L0X_get_total_xtalk_rate( + dev, p_ranging_measurement_data, &total_xtalk_mega_cps); + + if (status == VL53L0X_ERROR_NONE) { + *p_total_signal_rate_mcps += total_xtalk_mega_cps; + } + + return status; +} + +/* To convert ms into register value */ +uint32_t VL53L0X::VL53L0X_calc_timeout_mclks(VL53L0X_DEV dev, + uint32_t timeout_period_us, + uint8_t vcsel_period_pclks) +{ + uint32_t macro_period_ps; + uint32_t macro_period_ns; + uint32_t timeout_period_mclks = 0; + + macro_period_ps = VL53L0X_calc_macro_period_ps(dev, vcsel_period_pclks); + macro_period_ns = (macro_period_ps + 500) / 1000; + + timeout_period_mclks = + (uint32_t)(((timeout_period_us * 1000) + + (macro_period_ns / 2)) / macro_period_ns); + + return timeout_period_mclks; +} + +uint32_t VL53L0X::VL53L0X_isqrt(uint32_t num) +{ + /* + * Implements an integer square root + * + * From: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots + */ + + uint32_t res = 0; + uint32_t bit = 1 << 30; + /* The second-to-top bit is set: + * 1 << 14 for 16-bits, 1 << 30 for 32 bits */ + + /* "bit" starts at the highest power of four <= the argument. */ + 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; +} + +VL53L0X_Error VL53L0X::VL53L0X_calc_dmax( + VL53L0X_DEV dev, + FixPoint1616_t total_signal_rate_mcps, + FixPoint1616_t total_corr_signal_rate_mcps, + FixPoint1616_t pw_mult, + uint32_t sigma_estimate_p1, + FixPoint1616_t sigma_estimate_p2, + uint32_t peak_vcsel_duration_us, + uint32_t *pd_max_mm) +{ + const uint32_t c_sigma_limit = 18; + const FixPoint1616_t c_signal_limit = 0x4000; /* 0.25 */ + const FixPoint1616_t c_sigma_est_ref = 0x00000042; /* 0.001 */ + const uint32_t c_amb_eff_width_sigma_est_ns = 6; + const uint32_t c_amb_eff_width_d_max_ns = 7; + uint32_t dmax_cal_range_mm; + FixPoint1616_t dmax_cal_signal_rate_rtn_mcps; + FixPoint1616_t min_signal_needed; + FixPoint1616_t min_signal_needed_p1; + FixPoint1616_t min_signal_needed_p2; + FixPoint1616_t min_signal_needed_p3; + FixPoint1616_t min_signal_needed_p4; + FixPoint1616_t sigma_limit_tmp; + FixPoint1616_t sigma_est_sq_tmp; + FixPoint1616_t signal_limit_tmp; + FixPoint1616_t signal_at0_mm; + FixPoint1616_t dmax_dark; + FixPoint1616_t dmax_ambient; + FixPoint1616_t dmax_dark_tmp; + FixPoint1616_t sigma_est_p2_tmp; + uint32_t signal_rate_temp_mcps; + + VL53L0X_Error status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + dmax_cal_range_mm = + PALDevDataGet(dev, DmaxCalRangeMilliMeter); + + dmax_cal_signal_rate_rtn_mcps = + PALDevDataGet(dev, DmaxCalSignalRateRtnMegaCps); + + /* uint32 * FixPoint1616 = FixPoint1616 */ + signal_at0_mm = dmax_cal_range_mm * dmax_cal_signal_rate_rtn_mcps; + + /* FixPoint1616 >> 8 = FixPoint2408 */ + signal_at0_mm = (signal_at0_mm + 0x80) >> 8; + signal_at0_mm *= dmax_cal_range_mm; + + min_signal_needed_p1 = 0; + if (total_corr_signal_rate_mcps > 0) { + + /* Shift by 10 bits to increase resolution prior to the + * division */ + signal_rate_temp_mcps = total_signal_rate_mcps << 10; + + /* Add rounding value prior to division */ + min_signal_needed_p1 = signal_rate_temp_mcps + + (total_corr_signal_rate_mcps / 2); + + /* FixPoint0626/FixPoint1616 = FixPoint2210 */ + min_signal_needed_p1 /= total_corr_signal_rate_mcps; + + /* Apply a factored version of the speed of light. + Correction to be applied at the end */ + min_signal_needed_p1 *= 3; + + /* FixPoint2210 * FixPoint2210 = FixPoint1220 */ + min_signal_needed_p1 *= min_signal_needed_p1; + + /* FixPoint1220 >> 16 = FixPoint2804 */ + min_signal_needed_p1 = (min_signal_needed_p1 + 0x8000) >> 16; + } + + min_signal_needed_p2 = pw_mult * sigma_estimate_p1; + + /* FixPoint1616 >> 16 = uint32 */ + min_signal_needed_p2 = (min_signal_needed_p2 + 0x8000) >> 16; + + /* uint32 * uint32 = uint32 */ + min_signal_needed_p2 *= min_signal_needed_p2; + + /* Check sigmaEstimateP2 + * If this value is too high there is not enough signal rate + * to calculate dmax value so set a suitable value to ensure + * a very small dmax. + */ + sigma_est_p2_tmp = (sigma_estimate_p2 + 0x8000) >> 16; + sigma_est_p2_tmp = (sigma_est_p2_tmp + c_amb_eff_width_sigma_est_ns / 2) / + c_amb_eff_width_sigma_est_ns; + sigma_est_p2_tmp *= c_amb_eff_width_d_max_ns; + + if (sigma_est_p2_tmp > 0xffff) { + min_signal_needed_p3 = 0xfff00000; + } else { + + /* DMAX uses a different ambient width from sigma, so apply + * correction. + * Perform division before multiplication to prevent overflow. + */ + sigma_estimate_p2 = (sigma_estimate_p2 + c_amb_eff_width_sigma_est_ns / 2) / + c_amb_eff_width_sigma_est_ns; + sigma_estimate_p2 *= c_amb_eff_width_d_max_ns; + + /* FixPoint1616 >> 16 = uint32 */ + min_signal_needed_p3 = (sigma_estimate_p2 + 0x8000) >> 16; + + min_signal_needed_p3 *= min_signal_needed_p3; + + } + + /* FixPoint1814 / uint32 = FixPoint1814 */ + sigma_limit_tmp = ((c_sigma_limit << 14) + 500) / 1000; + + /* FixPoint1814 * FixPoint1814 = FixPoint3628 := FixPoint0428 */ + sigma_limit_tmp *= sigma_limit_tmp; + + /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ + sigma_est_sq_tmp = c_sigma_est_ref * c_sigma_est_ref; + + /* FixPoint3232 >> 4 = FixPoint0428 */ + sigma_est_sq_tmp = (sigma_est_sq_tmp + 0x08) >> 4; + + /* FixPoint0428 - FixPoint0428 = FixPoint0428 */ + sigma_limit_tmp -= sigma_est_sq_tmp; + + /* uint32_t * FixPoint0428 = FixPoint0428 */ + min_signal_needed_p4 = 4 * 12 * sigma_limit_tmp; + + /* FixPoint0428 >> 14 = FixPoint1814 */ + min_signal_needed_p4 = (min_signal_needed_p4 + 0x2000) >> 14; + + /* uint32 + uint32 = uint32 */ + min_signal_needed = (min_signal_needed_p2 + min_signal_needed_p3); + + /* uint32 / uint32 = uint32 */ + min_signal_needed += (peak_vcsel_duration_us / 2); + min_signal_needed /= peak_vcsel_duration_us; + + /* uint32 << 14 = FixPoint1814 */ + min_signal_needed <<= 14; + + /* FixPoint1814 / FixPoint1814 = uint32 */ + min_signal_needed += (min_signal_needed_p4 / 2); + min_signal_needed /= min_signal_needed_p4; + + /* FixPoint3200 * FixPoint2804 := FixPoint2804*/ + min_signal_needed *= min_signal_needed_p1; + + /* Apply correction by dividing by 1000000. + * This assumes 10E16 on the numerator of the equation + * and 10E-22 on the denominator. + * We do this because 32bit fix point calculation can't + * handle the larger and smaller elements of this equation, + * i.e. speed of light and pulse widths. + */ + min_signal_needed = (min_signal_needed + 500) / 1000; + min_signal_needed <<= 4; + + min_signal_needed = (min_signal_needed + 500) / 1000; + + /* FixPoint1616 >> 8 = FixPoint2408 */ + signal_limit_tmp = (c_signal_limit + 0x80) >> 8; + + /* FixPoint2408/FixPoint2408 = uint32 */ + if (signal_limit_tmp != 0) { + dmax_dark_tmp = (signal_at0_mm + (signal_limit_tmp / 2)) + / signal_limit_tmp; + } else { + dmax_dark_tmp = 0; + } + + dmax_dark = VL53L0X_isqrt(dmax_dark_tmp); + + /* FixPoint2408/FixPoint2408 = uint32 */ + if (min_signal_needed != 0) { + dmax_ambient = (signal_at0_mm + min_signal_needed / 2) + / min_signal_needed; + } else { + dmax_ambient = 0; + } + + dmax_ambient = VL53L0X_isqrt(dmax_ambient); + + *pd_max_mm = dmax_dark; + if (dmax_dark > dmax_ambient) { + *pd_max_mm = dmax_ambient; + } + + LOG_FUNCTION_END(status); + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_calc_sigma_estimate(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data, + FixPoint1616_t *p_sigma_estimate, + uint32_t *p_dmax_mm) +{ + /* Expressed in 100ths of a ns, i.e. centi-ns */ + const uint32_t c_pulse_effective_width_centi_ns = 800; + /* Expressed in 100ths of a ns, i.e. centi-ns */ + const uint32_t c_ambient_effective_width_centi_ns = 600; + const FixPoint1616_t c_dflt_final_range_integration_time_milli_secs = 0x00190000; /* 25ms */ + const uint32_t c_vcsel_pulse_width_ps = 4700; /* pico secs */ + const FixPoint1616_t c_sigma_est_max = 0x028F87AE; + const FixPoint1616_t c_sigma_est_rtn_max = 0xF000; + const FixPoint1616_t c_amb_to_signal_ratio_max = 0xF0000000 / + c_ambient_effective_width_centi_ns; + /* Time Of Flight per mm (6.6 pico secs) */ + const FixPoint1616_t c_tof_per_mm_ps = 0x0006999A; + const uint32_t c_16bit_rounding_param = 0x00008000; + const FixPoint1616_t c_max_x_talk_kcps = 0x00320000; + const uint32_t c_pll_period_ps = 1655; + + uint32_t vcsel_total_events_rtn; + uint32_t final_range_timeout_micro_secs; + uint32_t pre_range_timeout_micro_secs; + uint32_t final_range_integration_time_milli_secs; + FixPoint1616_t sigma_estimate_p1; + FixPoint1616_t sigma_estimate_p2; + FixPoint1616_t sigma_estimate_p3; + FixPoint1616_t delta_t_ps; + FixPoint1616_t pw_mult; + FixPoint1616_t sigma_est_rtn; + FixPoint1616_t sigma_estimate; + FixPoint1616_t x_talk_correction; + FixPoint1616_t ambient_rate_kcps; + FixPoint1616_t peak_signal_rate_kcps; + FixPoint1616_t x_talk_comp_rate_mcps; + uint32_t x_talk_comp_rate_kcps; + VL53L0X_Error status = VL53L0X_ERROR_NONE; + FixPoint1616_t diff1_mcps; + FixPoint1616_t diff2_mcps; + FixPoint1616_t sqr1; + FixPoint1616_t sqr2; + FixPoint1616_t sqr_sum; + FixPoint1616_t sqrt_result_centi_ns; + FixPoint1616_t sqrt_result; + FixPoint1616_t total_signal_rate_mcps; + FixPoint1616_t corrected_signal_rate_mcps; + FixPoint1616_t sigma_est_ref; + uint32_t vcsel_width; + uint32_t final_range_macro_pclks; + uint32_t pre_range_macro_pclks; + uint32_t peak_vcsel_duration_us; + uint8_t final_range_vcsel_pclks; + uint8_t pre_range_vcsel_pclks; + /*! \addtogroup calc_sigma_estimate + * @{ + * + * Estimates the range sigma + */ + + LOG_FUNCTION_START(""); + + VL53L0X_GETPARAMETERFIELD(dev, XTalkCompensationRateMegaCps, + x_talk_comp_rate_mcps); + + /* + * We work in kcps rather than mcps as this helps keep within the + * confines of the 32 Fix1616 type. + */ + + ambient_rate_kcps = + (p_ranging_measurement_data->AmbientRateRtnMegaCps * 1000) >> 16; + + corrected_signal_rate_mcps = + p_ranging_measurement_data->SignalRateRtnMegaCps; + + + status = VL53L0X_get_total_signal_rate( + dev, p_ranging_measurement_data, &total_signal_rate_mcps); + status = VL53L0X_get_total_xtalk_rate( + dev, p_ranging_measurement_data, &x_talk_comp_rate_mcps); + + + /* Signal rate measurement provided by device is the + * peak signal rate, not average. + */ + peak_signal_rate_kcps = (total_signal_rate_mcps * 1000); + peak_signal_rate_kcps = (peak_signal_rate_kcps + 0x8000) >> 16; + + x_talk_comp_rate_kcps = x_talk_comp_rate_mcps * 1000; + + if (x_talk_comp_rate_kcps > c_max_x_talk_kcps) { + x_talk_comp_rate_kcps = c_max_x_talk_kcps; + } + + if (status == VL53L0X_ERROR_NONE) { + + /* Calculate final range macro periods */ + final_range_timeout_micro_secs = VL53L0X_GETDEVICESPECIFICPARAMETER( + dev, FinalRangeTimeoutMicroSecs); + + final_range_vcsel_pclks = VL53L0X_GETDEVICESPECIFICPARAMETER( + dev, FinalRangeVcselPulsePeriod); + + final_range_macro_pclks = VL53L0X_calc_timeout_mclks( + dev, final_range_timeout_micro_secs, final_range_vcsel_pclks); + + /* Calculate pre-range macro periods */ + pre_range_timeout_micro_secs = VL53L0X_GETDEVICESPECIFICPARAMETER( + dev, PreRangeTimeoutMicroSecs); + + pre_range_vcsel_pclks = VL53L0X_GETDEVICESPECIFICPARAMETER( + dev, PreRangeVcselPulsePeriod); + + pre_range_macro_pclks = VL53L0X_calc_timeout_mclks( + dev, pre_range_timeout_micro_secs, pre_range_vcsel_pclks); + + vcsel_width = 3; + if (final_range_vcsel_pclks == 8) { + vcsel_width = 2; + } + + + peak_vcsel_duration_us = vcsel_width * 2048 * + (pre_range_macro_pclks + final_range_macro_pclks); + peak_vcsel_duration_us = (peak_vcsel_duration_us + 500) / 1000; + peak_vcsel_duration_us *= c_pll_period_ps; + peak_vcsel_duration_us = (peak_vcsel_duration_us + 500) / 1000; + + /* Fix1616 >> 8 = Fix2408 */ + total_signal_rate_mcps = (total_signal_rate_mcps + 0x80) >> 8; + + /* Fix2408 * uint32 = Fix2408 */ + vcsel_total_events_rtn = total_signal_rate_mcps * + peak_vcsel_duration_us; + + /* Fix2408 >> 8 = uint32 */ + vcsel_total_events_rtn = (vcsel_total_events_rtn + 0x80) >> 8; + + /* Fix2408 << 8 = Fix1616 = */ + total_signal_rate_mcps <<= 8; + } + + if (status != VL53L0X_ERROR_NONE) { + LOG_FUNCTION_END(status); + return status; + } + + if (peak_signal_rate_kcps == 0) { + *p_sigma_estimate = c_sigma_est_max; + PALDevDataSet(dev, SigmaEstimate, c_sigma_est_max); + *p_dmax_mm = 0; + } else { + if (vcsel_total_events_rtn < 1) { + vcsel_total_events_rtn = 1; + } + + sigma_estimate_p1 = c_pulse_effective_width_centi_ns; + + /* ((FixPoint1616 << 16)* uint32)/uint32 = FixPoint1616 */ + sigma_estimate_p2 = (ambient_rate_kcps << 16) / peak_signal_rate_kcps; + if (sigma_estimate_p2 > c_amb_to_signal_ratio_max) { + /* Clip to prevent overflow. Will ensure safe + * max result. */ + sigma_estimate_p2 = c_amb_to_signal_ratio_max; + } + sigma_estimate_p2 *= c_ambient_effective_width_centi_ns; + + sigma_estimate_p3 = 2 * VL53L0X_isqrt(vcsel_total_events_rtn * 12); + + /* uint32 * FixPoint1616 = FixPoint1616 */ + delta_t_ps = p_ranging_measurement_data->RangeMilliMeter * + c_tof_per_mm_ps; + + /* + * vcselRate - xtalkCompRate + * (uint32 << 16) - FixPoint1616 = FixPoint1616. + * Divide result by 1000 to convert to mcps. + * 500 is added to ensure rounding when integer division + * truncates. + */ + diff1_mcps = (((peak_signal_rate_kcps << 16) - + 2 * x_talk_comp_rate_kcps) + 500) / 1000; + + /* vcselRate + xtalkCompRate */ + diff2_mcps = ((peak_signal_rate_kcps << 16) + 500) / 1000; + + /* Shift by 8 bits to increase resolution prior to the + * division */ + diff1_mcps <<= 8; + + /* FixPoint0824/FixPoint1616 = FixPoint2408 */ +// xTalkCorrection = abs(diff1_mcps/diff2_mcps); +// abs is causing compiler overloading isue in C++, but unsigned types. So, redundant call anyway! + x_talk_correction = diff1_mcps / diff2_mcps; + + /* FixPoint2408 << 8 = FixPoint1616 */ + x_talk_correction <<= 8; + + if (p_ranging_measurement_data->RangeStatus != 0) { + pw_mult = 1 << 16; + } else { + /* FixPoint1616/uint32 = FixPoint1616 */ + pw_mult = delta_t_ps / c_vcsel_pulse_width_ps; /* smaller than 1.0f */ + + /* + * FixPoint1616 * FixPoint1616 = FixPoint3232, however both + * values are small enough such that32 bits will not be + * exceeded. + */ + pw_mult *= ((1 << 16) - x_talk_correction); + + /* (FixPoint3232 >> 16) = FixPoint1616 */ + pw_mult = (pw_mult + c_16bit_rounding_param) >> 16; + + /* FixPoint1616 + FixPoint1616 = FixPoint1616 */ + pw_mult += (1 << 16); + + /* + * At this point the value will be 1.xx, therefore if we square + * the value this will exceed 32 bits. To address this perform + * a single shift to the right before the multiplication. + */ + pw_mult >>= 1; + /* FixPoint1715 * FixPoint1715 = FixPoint3430 */ + pw_mult = pw_mult * pw_mult; + + /* (FixPoint3430 >> 14) = Fix1616 */ + pw_mult >>= 14; + } + + /* FixPoint1616 * uint32 = FixPoint1616 */ + sqr1 = pw_mult * sigma_estimate_p1; + + /* (FixPoint1616 >> 16) = FixPoint3200 */ + sqr1 = (sqr1 + 0x8000) >> 16; + + /* FixPoint3200 * FixPoint3200 = FixPoint6400 */ + sqr1 *= sqr1; + + sqr2 = sigma_estimate_p2; + + /* (FixPoint1616 >> 16) = FixPoint3200 */ + sqr2 = (sqr2 + 0x8000) >> 16; + + /* FixPoint3200 * FixPoint3200 = FixPoint6400 */ + sqr2 *= sqr2; + + /* FixPoint64000 + FixPoint6400 = FixPoint6400 */ + sqr_sum = sqr1 + sqr2; + + /* SQRT(FixPoin6400) = FixPoint3200 */ + sqrt_result_centi_ns = VL53L0X_isqrt(sqr_sum); + + /* (FixPoint3200 << 16) = FixPoint1616 */ + sqrt_result_centi_ns <<= 16; + + /* + * Note that the Speed Of Light is expressed in um per 1E-10 + * seconds (2997) Therefore to get mm/ns we have to divide by + * 10000 + */ + sigma_est_rtn = (((sqrt_result_centi_ns + 50) / 100) / + sigma_estimate_p3); + sigma_est_rtn *= VL53L0X_SPEED_OF_LIGHT_IN_AIR; + + /* Add 5000 before dividing by 10000 to ensure rounding. */ + sigma_est_rtn += 5000; + sigma_est_rtn /= 10000; + + if (sigma_est_rtn > c_sigma_est_rtn_max) { + /* Clip to prevent overflow. Will ensure safe + * max result. */ + sigma_est_rtn = c_sigma_est_rtn_max; + } + final_range_integration_time_milli_secs = + (final_range_timeout_micro_secs + pre_range_timeout_micro_secs + 500) / 1000; + + /* sigmaEstRef = 1mm * 25ms/final range integration time (inc pre-range) + * sqrt(FixPoint1616/int) = FixPoint2408) + */ + sigma_est_ref = + VL53L0X_isqrt((c_dflt_final_range_integration_time_milli_secs + + final_range_integration_time_milli_secs / 2) / + final_range_integration_time_milli_secs); + + /* FixPoint2408 << 8 = FixPoint1616 */ + sigma_est_ref <<= 8; + sigma_est_ref = (sigma_est_ref + 500) / 1000; + + /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ + sqr1 = sigma_est_rtn * sigma_est_rtn; + /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ + sqr2 = sigma_est_ref * sigma_est_ref; + + /* sqrt(FixPoint3232) = FixPoint1616 */ + sqrt_result = VL53L0X_isqrt((sqr1 + sqr2)); + /* + * Note that the Shift by 4 bits increases resolution prior to + * the sqrt, therefore the result must be shifted by 2 bits to + * the right to revert back to the FixPoint1616 format. + */ + + sigma_estimate = 1000 * sqrt_result; + + if ((peak_signal_rate_kcps < 1) || (vcsel_total_events_rtn < 1) || + (sigma_estimate > c_sigma_est_max)) { + sigma_estimate = c_sigma_est_max; + } + + *p_sigma_estimate = (uint32_t)(sigma_estimate); + PALDevDataSet(dev, SigmaEstimate, *p_sigma_estimate); + status = VL53L0X_calc_dmax( + dev, + total_signal_rate_mcps, + corrected_signal_rate_mcps, + pw_mult, + sigma_estimate_p1, + sigma_estimate_p2, + peak_vcsel_duration_us, + p_dmax_mm); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_pal_range_status(VL53L0X_DEV dev, + uint8_t device_range_status, + FixPoint1616_t signal_rate, + uint16_t effective_spad_rtn_count, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data, + uint8_t *p_pal_range_status) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t none_flag; + uint8_t sigma_limitflag = 0; + uint8_t signal_ref_clipflag = 0; + uint8_t range_ignore_thresholdflag = 0; + uint8_t sigma_limit_check_enable = 0; + uint8_t signal_rate_final_range_limit_check_enable = 0; + uint8_t signal_ref_clip_limit_check_enable = 0; + uint8_t range_ignore_threshold_limit_check_enable = 0; + FixPoint1616_t sigma_estimate; + FixPoint1616_t sigma_limit_value; + FixPoint1616_t signal_ref_clip_value; + FixPoint1616_t range_ignore_threshold_value; + FixPoint1616_t signal_rate_per_spad; + uint8_t device_range_status_internal = 0; + uint16_t tmp_word = 0; + uint8_t temp8; + uint32_t dmax_mm = 0; + FixPoint1616_t last_signal_ref_mcps; + + LOG_FUNCTION_START(""); + + + /* + * VL53L0X has a good ranging when the value of the + * DeviceRangeStatus = 11. This function will replace the value 0 with + * the value 11 in the DeviceRangeStatus. + * In addition, the SigmaEstimator is not included in the VL53L0X + * DeviceRangeStatus, this will be added in the PalRangeStatus. + */ + + device_range_status_internal = ((device_range_status & 0x78) >> 3); + + if (device_range_status_internal == 0 || + device_range_status_internal == 5 || + device_range_status_internal == 7 || + device_range_status_internal == 12 || + device_range_status_internal == 13 || + device_range_status_internal == 14 || + device_range_status_internal == 15 + ) { + none_flag = 1; + } else { + none_flag = 0; + } + + /* + * Check if Sigma limit is enabled, if yes then do comparison with limit + * value and put the result back into pPalRangeStatus. + */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_limit_check_enable(dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + &sigma_limit_check_enable); + } + + if ((sigma_limit_check_enable != 0) && (status == VL53L0X_ERROR_NONE)) { + /* + * compute the Sigma and check with limit + */ + status = VL53L0X_calc_sigma_estimate( + dev, + p_ranging_measurement_data, + &sigma_estimate, + &dmax_mm); + if (status == VL53L0X_ERROR_NONE) { + p_ranging_measurement_data->RangeDMaxMilliMeter = dmax_mm; + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_limit_check_value(dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + &sigma_limit_value); + + if ((sigma_limit_value > 0) && + (sigma_estimate > sigma_limit_value)) { + /* Limit Fail */ + sigma_limitflag = 1; + } + } + } + + /* + * Check if Signal ref clip limit is enabled, if yes then do comparison + * with limit value and put the result back into pPalRangeStatus. + */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_limit_check_enable(dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + &signal_ref_clip_limit_check_enable); + } + + if ((signal_ref_clip_limit_check_enable != 0) && + (status == VL53L0X_ERROR_NONE)) { + + status = VL53L0X_get_limit_check_value(dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + &signal_ref_clip_value); + + /* Read LastSignalRefMcps from device */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_word(dev, + VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF, + &tmp_word); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0xFF, 0x00); + } + + last_signal_ref_mcps = VL53L0X_FIXPOINT97TOFIXPOINT1616(tmp_word); + PALDevDataSet(dev, LastSignalRefMcps, last_signal_ref_mcps); + + if ((signal_ref_clip_value > 0) && + (last_signal_ref_mcps > signal_ref_clip_value)) { + /* Limit Fail */ + signal_ref_clipflag = 1; + } + } + + /* + * Check if Signal ref clip limit is enabled, if yes then do comparison + * with limit value and put the result back into pPalRangeStatus. + * EffectiveSpadRtnCount has a format 8.8 + * If (Return signal rate < (1.5 x Xtalk x number of Spads)) : FAIL + */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_limit_check_enable(dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + &range_ignore_threshold_limit_check_enable); + } + + if ((range_ignore_threshold_limit_check_enable != 0) && + (status == VL53L0X_ERROR_NONE)) { + + /* Compute the signal rate per spad */ + if (effective_spad_rtn_count == 0) { + signal_rate_per_spad = 0; + } else { + signal_rate_per_spad = (FixPoint1616_t)((256 * signal_rate) + / effective_spad_rtn_count); + } + + status = VL53L0X_get_limit_check_value(dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + &range_ignore_threshold_value); + + if ((range_ignore_threshold_value > 0) && + (signal_rate_per_spad < range_ignore_threshold_value)) { + /* Limit Fail add 2^6 to range status */ + range_ignore_thresholdflag = 1; + } + } + + if (status == VL53L0X_ERROR_NONE) { + if (none_flag == 1) { + *p_pal_range_status = 255; /* NONE */ + } else if (device_range_status_internal == 1 || + device_range_status_internal == 2 || + device_range_status_internal == 3) { + *p_pal_range_status = 5; /* HW fail */ + } else if (device_range_status_internal == 6 || + device_range_status_internal == 9) { + *p_pal_range_status = 4; /* Phase fail */ + } else if (device_range_status_internal == 8 || + device_range_status_internal == 10 || + signal_ref_clipflag == 1) { + *p_pal_range_status = 3; /* Min range */ + } else if (device_range_status_internal == 4 || + range_ignore_thresholdflag == 1) { + *p_pal_range_status = 2; /* Signal Fail */ + } else if (sigma_limitflag == 1) { + *p_pal_range_status = 1; /* Sigma Fail */ + } else { + *p_pal_range_status = 0; /* Range Valid */ + } + } + + /* DMAX only relevant during range error */ + if (*p_pal_range_status == 0) { + p_ranging_measurement_data->RangeDMaxMilliMeter = 0; + } + + /* fill the Limit Check Status */ + + status = VL53L0X_get_limit_check_enable(dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + &signal_rate_final_range_limit_check_enable); + + if (status == VL53L0X_ERROR_NONE) { + if ((sigma_limit_check_enable == 0) || (sigma_limitflag == 1)) { + temp8 = 1; + } else { + temp8 = 0; + } + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksStatus, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, temp8); + + if ((device_range_status_internal == 4) || + (signal_rate_final_range_limit_check_enable == 0)) { + temp8 = 1; + } else { + temp8 = 0; + } + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksStatus, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + temp8); + + if ((signal_ref_clip_limit_check_enable == 0) || + (signal_ref_clipflag == 1)) { + temp8 = 1; + } else { + temp8 = 0; + } + + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksStatus, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, temp8); + + if ((range_ignore_threshold_limit_check_enable == 0) || + (range_ignore_thresholdflag == 1)) { + temp8 = 1; + } else { + temp8 = 0; + } + + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksStatus, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + temp8); + } + + LOG_FUNCTION_END(status); + return status; + +} + +VL53L0X_Error VL53L0X::VL53L0X_get_ranging_measurement_data(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t device_range_status; + uint8_t range_fractional_enable; + uint8_t pal_range_status; + uint8_t x_talk_compensation_enable; + uint16_t ambient_rate; + FixPoint1616_t signal_rate; + uint16_t x_talk_compensation_rate_mega_cps; + uint16_t effective_spad_rtn_count; + uint16_t tmpuint16; + uint16_t xtalk_range_milli_meter; + uint16_t linearity_corrective_gain; + uint8_t localBuffer[12]; + VL53L0X_RangingMeasurementData_t last_range_data_buffer; + + LOG_FUNCTION_START(""); + + /* + * use multi read even if some registers are not useful, result will + * be more efficient + * start reading at 0x14 dec20 + * end reading at 0x21 dec33 total 14 bytes to read + */ + status = VL53L0X_read_multi(dev, 0x14, localBuffer, 12); + + if (status == VL53L0X_ERROR_NONE) { + + p_ranging_measurement_data->ZoneId = 0; /* Only one zone */ + p_ranging_measurement_data->TimeStamp = 0; /* Not Implemented */ + + tmpuint16 = VL53L0X_MAKEUINT16(localBuffer[11], localBuffer[10]); + /* cut1.1 if SYSTEM__RANGE_CONFIG if 1 range is 2bits fractional + *(format 11.2) else no fractional + */ + + p_ranging_measurement_data->MeasurementTimeUsec = 0; + + signal_rate = VL53L0X_FIXPOINT97TOFIXPOINT1616( + VL53L0X_MAKEUINT16(localBuffer[7], localBuffer[6])); + /* peak_signal_count_rate_rtn_mcps */ + p_ranging_measurement_data->SignalRateRtnMegaCps = signal_rate; + + ambient_rate = VL53L0X_MAKEUINT16(localBuffer[9], localBuffer[8]); + p_ranging_measurement_data->AmbientRateRtnMegaCps = + VL53L0X_FIXPOINT97TOFIXPOINT1616(ambient_rate); + + effective_spad_rtn_count = VL53L0X_MAKEUINT16(localBuffer[3], + localBuffer[2]); + /* EffectiveSpadRtnCount is 8.8 format */ + p_ranging_measurement_data->EffectiveSpadRtnCount = + effective_spad_rtn_count; + + device_range_status = localBuffer[0]; + + /* Get Linearity Corrective Gain */ + linearity_corrective_gain = PALDevDataGet(dev, + LinearityCorrectiveGain); + + /* Get ranging configuration */ + range_fractional_enable = PALDevDataGet(dev, + RangeFractionalEnable); + + if (linearity_corrective_gain != 1000) { + + tmpuint16 = (uint16_t)((linearity_corrective_gain + * tmpuint16 + 500) / 1000); + + /* Implement Xtalk */ + VL53L0X_GETPARAMETERFIELD(dev, + XTalkCompensationRateMegaCps, + x_talk_compensation_rate_mega_cps); + VL53L0X_GETPARAMETERFIELD(dev, XTalkCompensationEnable, + x_talk_compensation_enable); + + if (x_talk_compensation_enable) { + + if ((signal_rate + - ((x_talk_compensation_rate_mega_cps + * effective_spad_rtn_count) >> 8)) + <= 0) { + if (range_fractional_enable) { + xtalk_range_milli_meter = 8888; + } else { + xtalk_range_milli_meter = 8888 << 2; + } + } else { + xtalk_range_milli_meter = + (tmpuint16 * signal_rate) + / (signal_rate + - ((x_talk_compensation_rate_mega_cps + * effective_spad_rtn_count) + >> 8)); + } + + tmpuint16 = xtalk_range_milli_meter; + } + + } + + if (range_fractional_enable) { + p_ranging_measurement_data->RangeMilliMeter = + (uint16_t)((tmpuint16) >> 2); + p_ranging_measurement_data->RangeFractionalPart = + (uint8_t)((tmpuint16 & 0x03) << 6); + } else { + p_ranging_measurement_data->RangeMilliMeter = tmpuint16; + p_ranging_measurement_data->RangeFractionalPart = 0; + } + + /* + * For a standard definition of RangeStatus, this should + * return 0 in case of good result after a ranging + * The range status depends on the device so call a device + * specific function to obtain the right Status. + */ + status |= VL53L0X_get_pal_range_status(dev, device_range_status, + signal_rate, effective_spad_rtn_count, + p_ranging_measurement_data, &pal_range_status); + + if (status == VL53L0X_ERROR_NONE) { + p_ranging_measurement_data->RangeStatus = pal_range_status; + } + + } + + if (status == VL53L0X_ERROR_NONE) { + /* Copy last read data into Dev buffer */ + last_range_data_buffer = PALDevDataGet(dev, LastRangeMeasure); + + last_range_data_buffer.RangeMilliMeter = + p_ranging_measurement_data->RangeMilliMeter; + last_range_data_buffer.RangeFractionalPart = + p_ranging_measurement_data->RangeFractionalPart; + last_range_data_buffer.RangeDMaxMilliMeter = + p_ranging_measurement_data->RangeDMaxMilliMeter; + last_range_data_buffer.MeasurementTimeUsec = + p_ranging_measurement_data->MeasurementTimeUsec; + last_range_data_buffer.SignalRateRtnMegaCps = + p_ranging_measurement_data->SignalRateRtnMegaCps; + last_range_data_buffer.AmbientRateRtnMegaCps = + p_ranging_measurement_data->AmbientRateRtnMegaCps; + last_range_data_buffer.EffectiveSpadRtnCount = + p_ranging_measurement_data->EffectiveSpadRtnCount; + last_range_data_buffer.RangeStatus = + p_ranging_measurement_data->RangeStatus; + + PALDevDataSet(dev, LastRangeMeasure, last_range_data_buffer); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_perform_single_ranging_measurement(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + /* This function will do a complete single ranging + * Here we fix the mode! */ + status = VL53L0X_set_device_mode(dev, VL53L0X_DEVICEMODE_SINGLE_RANGING); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_perform_single_measurement(dev); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_ranging_measurement_data(dev, + p_ranging_measurement_data); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_clear_interrupt_mask(dev, 0); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::perform_ref_signal_measurement(VL53L0X_DEV dev, + uint16_t *p_ref_signal_rate) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + VL53L0X_RangingMeasurementData_t ranging_measurement_data; + + uint8_t sequence_config = 0; + + /* store the value of the sequence config, + * this will be reset before the end of the function + */ + + sequence_config = PALDevDataGet(dev, SequenceConfig); + + /* + * This function performs a reference signal rate measurement. + */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0xC0); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_perform_single_ranging_measurement(dev, + &ranging_measurement_data); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_word(dev, + VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF, + p_ref_signal_rate); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0xFF, 0x00); + } + + if (status == VL53L0X_ERROR_NONE) { + /* restore the previous Sequence Config */ + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + sequence_config); + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, SequenceConfig, sequence_config); + } + } + + return status; +} + +VL53L0X_Error VL53L0X::wrapped_VL53L0X_perform_ref_spad_management(VL53L0X_DEV dev, + uint32_t *ref_spad_count, + uint8_t *is_aperture_spads) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t last_spad_array[6]; + uint8_t start_select = 0xB4; + uint32_t minimum_spad_count = 3; + uint32_t max_spad_count = 44; + uint32_t current_spad_index = 0; + uint32_t last_spad_index = 0; + int32_t next_good_spad = 0; + uint16_t target_ref_rate = 0x0A00; /* 20 MCPS in 9:7 format */ + uint16_t peak_signal_rate_ref; + uint32_t need_apt_spads = 0; + uint32_t index = 0; + uint32_t spad_array_size = 6; + uint32_t signal_rate_diff = 0; + uint32_t last_signal_rate_diff = 0; + uint8_t complete = 0; + uint8_t vhv_settings = 0; + uint8_t phase_cal = 0; + uint32_t ref_spad_count_int = 0; + uint8_t is_aperture_spads_int = 0; + + /* + * The reference SPAD initialization procedure determines the minimum + * amount of reference spads to be enables to achieve a target reference + * signal rate and should be performed once during initialization. + * + * Either aperture or non-aperture spads are applied but never both. + * Firstly non-aperture spads are set, begining with 5 spads, and + * increased one spad at a time until the closest measurement to the + * target rate is achieved. + * + * If the target rate is exceeded when 5 non-aperture spads are enabled, + * initialization is performed instead with aperture spads. + * + * When setting spads, a 'Good Spad Map' is applied. + * + * This procedure operates within a SPAD window of interest of a maximum + * 44 spads. + * The start point is currently fixed to 180, which lies towards the end + * of the non-aperture quadrant and runs in to the adjacent aperture + * quadrant. + */ + target_ref_rate = PALDevDataGet(dev, targetRefRate); + + /* + * Initialize Spad arrays. + * Currently the good spad map is initialised to 'All good'. + * This is a short term implementation. The good spad map will be + * provided as an input. + * Note that there are 6 bytes. Only the first 44 bits will be used to + * represent spads. + */ + for (index = 0; index < spad_array_size; index++) { + dev->Data.SpadData.RefSpadEnables[index] = 0; + } + + + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0xFF, 0x00); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT, + start_select); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_POWER_MANAGEMENT_GO1_POWER_FORCE, 0); + } + + /* Perform ref calibration */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_perform_ref_calibration(dev, &vhv_settings, + &phase_cal, 0); + } + + if (status == VL53L0X_ERROR_NONE) { + /* Enable Minimum NON-APERTURE Spads */ + current_spad_index = 0; + last_spad_index = current_spad_index; + need_apt_spads = 0; + status = enable_ref_spads(dev, + need_apt_spads, + dev->Data.SpadData.RefGoodSpadMap, + dev->Data.SpadData.RefSpadEnables, + spad_array_size, + start_select, + current_spad_index, + minimum_spad_count, + &last_spad_index); + } + + if (status == VL53L0X_ERROR_NONE) { + current_spad_index = last_spad_index; + + status = perform_ref_signal_measurement(dev, + &peak_signal_rate_ref); + if ((status == VL53L0X_ERROR_NONE) && + (peak_signal_rate_ref > target_ref_rate)) { + /* Signal rate measurement too high, + * switch to APERTURE SPADs */ + + for (index = 0; index < spad_array_size; index++) { + dev->Data.SpadData.RefSpadEnables[index] = 0; + } + + + /* Increment to the first APERTURE spad */ + while ((is_aperture(start_select + current_spad_index) + == 0) && (current_spad_index < max_spad_count)) { + current_spad_index++; + } + + need_apt_spads = 1; + + status = enable_ref_spads(dev, + need_apt_spads, + dev->Data.SpadData.RefGoodSpadMap, + dev->Data.SpadData.RefSpadEnables, + spad_array_size, + start_select, + current_spad_index, + minimum_spad_count, + &last_spad_index); + + if (status == VL53L0X_ERROR_NONE) { + current_spad_index = last_spad_index; + status = perform_ref_signal_measurement(dev, + &peak_signal_rate_ref); + + if ((status == VL53L0X_ERROR_NONE) && + (peak_signal_rate_ref > target_ref_rate)) { + /* Signal rate still too high after + * setting the minimum number of + * APERTURE spads. Can do no more + * therefore set the min number of + * aperture spads as the result. + */ + is_aperture_spads_int = 1; + ref_spad_count_int = minimum_spad_count; + } + } + } else { + need_apt_spads = 0; + } + } + + if ((status == VL53L0X_ERROR_NONE) && + (peak_signal_rate_ref < target_ref_rate)) { + /* At this point, the minimum number of either aperture + * or non-aperture spads have been set. Proceed to add + * spads and perform measurements until the target + * reference is reached. + */ + is_aperture_spads_int = need_apt_spads; + ref_spad_count_int = minimum_spad_count; + + memcpy(last_spad_array, dev->Data.SpadData.RefSpadEnables, + spad_array_size); + last_signal_rate_diff = abs(peak_signal_rate_ref - + target_ref_rate); + complete = 0; + + while (!complete) { + get_next_good_spad( + dev->Data.SpadData.RefGoodSpadMap, + spad_array_size, current_spad_index, + &next_good_spad); + + if (next_good_spad == -1) { + status = VL53L0X_ERROR_REF_SPAD_INIT; + break; + } + + /* Cannot combine Aperture and Non-Aperture spads, so + * ensure the current spad is of the correct type. + */ + if (is_aperture((uint32_t)start_select + next_good_spad) != + need_apt_spads) { + /* At this point we have enabled the maximum + * number of Aperture spads. + */ + complete = 1; + break; + } + + (ref_spad_count_int)++; + + current_spad_index = next_good_spad; + status = enable_spad_bit( + dev->Data.SpadData.RefSpadEnables, + spad_array_size, current_spad_index); + + if (status == VL53L0X_ERROR_NONE) { + current_spad_index++; + /* Proceed to apply the additional spad and + * perform measurement. */ + status = set_ref_spad_map(dev, + dev->Data.SpadData.RefSpadEnables); + } + + if (status != VL53L0X_ERROR_NONE) { + break; + } + + status = perform_ref_signal_measurement(dev, + &peak_signal_rate_ref); + + if (status != VL53L0X_ERROR_NONE) { + break; + } + + signal_rate_diff = abs(peak_signal_rate_ref - target_ref_rate); + + if (peak_signal_rate_ref > target_ref_rate) { + /* Select the spad map that provides the + * measurement closest to the target rate, + * either above or below it. + */ + if (signal_rate_diff > last_signal_rate_diff) { + /* Previous spad map produced a closer + * measurement, so choose this. */ + status = set_ref_spad_map(dev, + last_spad_array); + memcpy( + dev->Data.SpadData.RefSpadEnables, + last_spad_array, spad_array_size); + + (ref_spad_count_int)--; + } + complete = 1; + } else { + /* Continue to add spads */ + last_signal_rate_diff = signal_rate_diff; + memcpy(last_spad_array, + dev->Data.SpadData.RefSpadEnables, + spad_array_size); + } + + } /* while */ + } + + if (status == VL53L0X_ERROR_NONE) { + *ref_spad_count = ref_spad_count_int; + *is_aperture_spads = is_aperture_spads_int; + + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, RefSpadsInitialised, 1); + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + ReferenceSpadCount, (uint8_t)(*ref_spad_count)); + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + ReferenceSpadType, *is_aperture_spads); + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_reference_spads(VL53L0X_DEV dev, + uint32_t count, uint8_t is_aperture_spads) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t current_spad_index = 0; + uint8_t start_select = 0xB4; + uint32_t spad_array_size = 6; + uint32_t max_spad_count = 44; + uint32_t last_spad_index; + uint32_t index; + + /* + * This function applies a requested number of reference spads, either + * aperture or + * non-aperture, as requested. + * The good spad map will be applied. + */ + + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0xFF, 0x00); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT, + start_select); + } + + for (index = 0; index < spad_array_size; index++) { + dev->Data.SpadData.RefSpadEnables[index] = 0; + } + + if (is_aperture_spads) { + /* Increment to the first APERTURE spad */ + while ((is_aperture(start_select + current_spad_index) == 0) && + (current_spad_index < max_spad_count)) { + current_spad_index++; + } + } + status = enable_ref_spads(dev, + is_aperture_spads, + dev->Data.SpadData.RefGoodSpadMap, + dev->Data.SpadData.RefSpadEnables, + spad_array_size, + start_select, + current_spad_index, + count, + &last_spad_index); + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, RefSpadsInitialised, 1); + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + ReferenceSpadCount, (uint8_t)(count)); + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + ReferenceSpadType, is_aperture_spads); + } + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_wait_device_booted(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented on VL53L0X */ + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_perform_ref_calibration(VL53L0X_DEV dev, uint8_t *p_vhv_settings, + uint8_t *p_phase_cal) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = VL53L0X_perform_ref_calibration(dev, p_vhv_settings, + p_phase_cal, 1); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_perform_ref_spad_management(VL53L0X_DEV dev, + uint32_t *ref_spad_count, uint8_t *is_aperture_spads) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = wrapped_VL53L0X_perform_ref_spad_management(dev, ref_spad_count, + is_aperture_spads); + + LOG_FUNCTION_END(status); + + return status; +} + +/* Group PAL Init Functions */ +VL53L0X_Error VL53L0X::VL53L0X_set_device_address(VL53L0X_DEV dev, uint8_t device_address) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = VL53L0X_write_byte(dev, VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS, + device_address / 2); + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_gpio_config(VL53L0X_DEV dev, uint8_t pin, + VL53L0X_DeviceModes device_mode, VL53L0X_GpioFunctionality functionality, + VL53L0X_InterruptPolarity polarity) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t data; + + LOG_FUNCTION_START(""); + + if (pin != 0) { + status = VL53L0X_ERROR_GPIO_NOT_EXISTING; + } else if (device_mode == VL53L0X_DEVICEMODE_GPIO_DRIVE) { + if (polarity == VL53L0X_INTERRUPTPOLARITY_LOW) { + data = 0x10; + } else { + data = 1; + } + + status = VL53L0X_write_byte(dev, + VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, data); + + } else { + if (device_mode == VL53L0X_DEVICEMODE_GPIO_OSC) { + + status |= VL53L0X_write_byte(dev, 0xff, 0x01); + status |= VL53L0X_write_byte(dev, 0x00, 0x00); + + status |= VL53L0X_write_byte(dev, 0xff, 0x00); + status |= VL53L0X_write_byte(dev, 0x80, 0x01); + status |= VL53L0X_write_byte(dev, 0x85, 0x02); + + status |= VL53L0X_write_byte(dev, 0xff, 0x04); + status |= VL53L0X_write_byte(dev, 0xcd, 0x00); + status |= VL53L0X_write_byte(dev, 0xcc, 0x11); + + status |= VL53L0X_write_byte(dev, 0xff, 0x07); + status |= VL53L0X_write_byte(dev, 0xbe, 0x00); + + status |= VL53L0X_write_byte(dev, 0xff, 0x06); + status |= VL53L0X_write_byte(dev, 0xcc, 0x09); + + status |= VL53L0X_write_byte(dev, 0xff, 0x00); + status |= VL53L0X_write_byte(dev, 0xff, 0x01); + status |= VL53L0X_write_byte(dev, 0x00, 0x00); + + } else { + + if (status == VL53L0X_ERROR_NONE) { + switch (functionality) { + case VL53L0X_GPIOFUNCTIONALITY_OFF: + data = 0x00; + break; + case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW: + data = 0x01; + break; + case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH: + data = 0x02; + break; + case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT: + data = 0x03; + break; + case VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY: + data = 0x04; + break; + default: + status = + VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED; + } + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, data); + } + + if (status == VL53L0X_ERROR_NONE) { + if (polarity == VL53L0X_INTERRUPTPOLARITY_LOW) { + data = 0; + } else { + data = (uint8_t)(1 << 4); + } + status = VL53L0X_update_byte(dev, + VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, 0xEF, data); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + Pin0GpioFunctionality, functionality); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_clear_interrupt_mask(dev, 0); + } + } + } + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_fraction_enable(VL53L0X_DEV dev, uint8_t *p_enabled) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = VL53L0X_read_byte(dev, VL53L0X_REG_SYSTEM_RANGE_CONFIG, p_enabled); + + if (status == VL53L0X_ERROR_NONE) { + *p_enabled = (*p_enabled & 1); + } + + LOG_FUNCTION_END(status); + return status; +} + +uint16_t VL53L0X::VL53L0X_encode_timeout(uint32_t timeout_macro_clks) +{ + /*! + * Encode timeout in macro periods in (LSByte * 2^MSByte) + 1 format + */ + + uint16_t encoded_timeout = 0; + uint32_t ls_byte = 0; + uint16_t ms_byte = 0; + + if (timeout_macro_clks > 0) { + ls_byte = timeout_macro_clks - 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; + +} + +VL53L0X_Error VL53L0X::set_sequence_step_timeout(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, + uint32_t timeout_micro_secs) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t current_vcsel_pulse_period_p_clk; + uint8_t msrc_encoded_time_out; + uint16_t pre_range_encoded_time_out; + uint16_t pre_range_time_out_m_clks; + uint16_t msrc_range_time_out_m_clks; + uint32_t final_range_time_out_m_clks; + uint16_t final_range_encoded_time_out; + VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps; + + if ((sequence_step_id == VL53L0X_SEQUENCESTEP_TCC) || + (sequence_step_id == VL53L0X_SEQUENCESTEP_DSS) || + (sequence_step_id == VL53L0X_SEQUENCESTEP_MSRC)) { + + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + ¤t_vcsel_pulse_period_p_clk); + + if (status == VL53L0X_ERROR_NONE) { + msrc_range_time_out_m_clks = VL53L0X_calc_timeout_mclks(dev, + timeout_micro_secs, + (uint8_t)current_vcsel_pulse_period_p_clk); + + if (msrc_range_time_out_m_clks > 256) { + msrc_encoded_time_out = 255; + } else { + msrc_encoded_time_out = + (uint8_t)msrc_range_time_out_m_clks - 1; + } + + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + LastEncodedTimeout, + msrc_encoded_time_out); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP, + msrc_encoded_time_out); + } + } else { + + if (sequence_step_id == VL53L0X_SEQUENCESTEP_PRE_RANGE) { + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + ¤t_vcsel_pulse_period_p_clk); + pre_range_time_out_m_clks = + VL53L0X_calc_timeout_mclks(dev, + timeout_micro_secs, + (uint8_t)current_vcsel_pulse_period_p_clk); + pre_range_encoded_time_out = VL53L0X_encode_timeout( + pre_range_time_out_m_clks); + + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, + LastEncodedTimeout, + pre_range_encoded_time_out); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_word(dev, + VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, + pre_range_encoded_time_out); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + dev, + PreRangeTimeoutMicroSecs, + timeout_micro_secs); + } + } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_FINAL_RANGE) { + + /* For the final range timeout, the pre-range timeout + * must be added. To do this both final and pre-range + * timeouts must be expressed in macro periods MClks + * because they have different vcsel periods. + */ + + VL53L0X_get_sequence_step_enables(dev, + &scheduler_sequence_steps); + pre_range_time_out_m_clks = 0; + if (scheduler_sequence_steps.PreRangeOn) { + + /* Retrieve PRE-RANGE VCSEL Period */ + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + ¤t_vcsel_pulse_period_p_clk); + + /* Retrieve PRE-RANGE Timeout in Macro periods + * (MCLKS) */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_word(dev, 0x51, + &pre_range_encoded_time_out); + pre_range_time_out_m_clks = + VL53L0X_decode_timeout( + pre_range_encoded_time_out); + } + } + + /* Calculate FINAL RANGE Timeout in Macro Periods + * (MCLKS) and add PRE-RANGE value + */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_vcsel_pulse_period(dev, + VL53L0X_VCSEL_PERIOD_FINAL_RANGE, + ¤t_vcsel_pulse_period_p_clk); + } + if (status == VL53L0X_ERROR_NONE) { + final_range_time_out_m_clks = + VL53L0X_calc_timeout_mclks(dev, + timeout_micro_secs, + (uint8_t) current_vcsel_pulse_period_p_clk); + + final_range_time_out_m_clks += pre_range_time_out_m_clks; + + final_range_encoded_time_out = + VL53L0X_encode_timeout(final_range_time_out_m_clks); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_word(dev, 0x71, + final_range_encoded_time_out); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + dev, + FinalRangeTimeoutMicroSecs, + timeout_micro_secs); + } + } + } else { + status = VL53L0X_ERROR_INVALID_PARAMS; + } + + } + return status; +} + +VL53L0X_Error VL53L0X::wrapped_VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev, + uint32_t measurement_timing_budget_micro_seconds) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t final_range_timing_budget_micro_seconds; + VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps; + uint32_t msrc_dcc_tcc_timeout_micro_seconds = 2000; + uint32_t start_overhead_micro_seconds = 1910; + uint32_t end_overhead_micro_seconds = 960; + uint32_t msrc_overhead_micro_seconds = 660; + uint32_t tcc_overhead_micro_seconds = 590; + uint32_t dss_overhead_micro_seconds = 690; + uint32_t pre_range_overhead_micro_seconds = 660; + uint32_t final_range_overhead_micro_seconds = 550; + uint32_t pre_range_timeout_micro_seconds = 0; + uint32_t c_min_timing_budget_micro_seconds = 20000; + uint32_t sub_timeout = 0; + + LOG_FUNCTION_START(""); + + if (measurement_timing_budget_micro_seconds + < c_min_timing_budget_micro_seconds) { + status = VL53L0X_ERROR_INVALID_PARAMS; + return status; + } + + final_range_timing_budget_micro_seconds = + measurement_timing_budget_micro_seconds - + (start_overhead_micro_seconds + end_overhead_micro_seconds); + + status = VL53L0X_get_sequence_step_enables(dev, &scheduler_sequence_steps); + + if (status == VL53L0X_ERROR_NONE && + (scheduler_sequence_steps.TccOn || + scheduler_sequence_steps.MsrcOn || + scheduler_sequence_steps.DssOn)) { + + /* TCC, MSRC and DSS all share the same timeout */ + status = get_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_MSRC, + &msrc_dcc_tcc_timeout_micro_seconds); + + /* Subtract the TCC, MSRC and DSS timeouts if they are + * enabled. */ + + if (status != VL53L0X_ERROR_NONE) { + return status; + } + + /* TCC */ + if (scheduler_sequence_steps.TccOn) { + + sub_timeout = msrc_dcc_tcc_timeout_micro_seconds + + tcc_overhead_micro_seconds; + + if (sub_timeout < + final_range_timing_budget_micro_seconds) { + final_range_timing_budget_micro_seconds -= + sub_timeout; + } else { + /* Requested timeout too big. */ + status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + if (status != VL53L0X_ERROR_NONE) { + LOG_FUNCTION_END(status); + return status; + } + + /* DSS */ + if (scheduler_sequence_steps.DssOn) { + + sub_timeout = 2 * (msrc_dcc_tcc_timeout_micro_seconds + + dss_overhead_micro_seconds); + + if (sub_timeout < final_range_timing_budget_micro_seconds) { + final_range_timing_budget_micro_seconds + -= sub_timeout; + } else { + /* Requested timeout too big. */ + status = VL53L0X_ERROR_INVALID_PARAMS; + } + } else if (scheduler_sequence_steps.MsrcOn) { + /* MSRC */ + sub_timeout = msrc_dcc_tcc_timeout_micro_seconds + + msrc_overhead_micro_seconds; + + if (sub_timeout < final_range_timing_budget_micro_seconds) { + final_range_timing_budget_micro_seconds + -= sub_timeout; + } else { + /* Requested timeout too big. */ + status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + } + + if (status != VL53L0X_ERROR_NONE) { + LOG_FUNCTION_END(status); + return status; + } + + if (scheduler_sequence_steps.PreRangeOn) { + + /* Subtract the Pre-range timeout if enabled. */ + + status = get_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + &pre_range_timeout_micro_seconds); + + sub_timeout = pre_range_timeout_micro_seconds + + pre_range_overhead_micro_seconds; + + if (sub_timeout < final_range_timing_budget_micro_seconds) { + final_range_timing_budget_micro_seconds -= sub_timeout; + } else { + /* Requested timeout too big. */ + status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + + if (status == VL53L0X_ERROR_NONE && + scheduler_sequence_steps.FinalRangeOn) { + + final_range_timing_budget_micro_seconds -= + final_range_overhead_micro_seconds; + + /* Final Range Timeout + * Note that the final range timeout is determined by the timing + * budget and the sum of all other timeouts within the sequence. + * If there is no room for the final range timeout, then an error + * will be set. Otherwise the remaining time will be applied to + * the final range. + */ + status = set_sequence_step_timeout(dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + final_range_timing_budget_micro_seconds); + + VL53L0X_SETPARAMETERFIELD(dev, + MeasurementTimingBudgetMicroSeconds, + measurement_timing_budget_micro_seconds); + } + + LOG_FUNCTION_END(status); + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev, + uint32_t measurement_timing_budget_micro_seconds) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = wrapped_VL53L0X_set_measurement_timing_budget_micro_seconds(dev, + measurement_timing_budget_micro_seconds); + + LOG_FUNCTION_END(status); + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_sequence_step_enable(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_step_enabled) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t sequence_config = 0; + uint8_t sequence_config_new = 0; + uint32_t measurement_timing_budget_micro_seconds; + LOG_FUNCTION_START(""); + + status = VL53L0X_read_byte(dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + &sequence_config); + + sequence_config_new = sequence_config; + + if (status == VL53L0X_ERROR_NONE) { + if (sequence_step_enabled == 1) { + + /* Enable requested sequence step + */ + switch (sequence_step_id) { + case VL53L0X_SEQUENCESTEP_TCC: + sequence_config_new |= 0x10; + break; + case VL53L0X_SEQUENCESTEP_DSS: + sequence_config_new |= 0x28; + break; + case VL53L0X_SEQUENCESTEP_MSRC: + sequence_config_new |= 0x04; + break; + case VL53L0X_SEQUENCESTEP_PRE_RANGE: + sequence_config_new |= 0x40; + break; + case VL53L0X_SEQUENCESTEP_FINAL_RANGE: + sequence_config_new |= 0x80; + break; + default: + status = VL53L0X_ERROR_INVALID_PARAMS; + } + } else { + /* Disable requested sequence step + */ + switch (sequence_step_id) { + case VL53L0X_SEQUENCESTEP_TCC: + sequence_config_new &= 0xef; + break; + case VL53L0X_SEQUENCESTEP_DSS: + sequence_config_new &= 0xd7; + break; + case VL53L0X_SEQUENCESTEP_MSRC: + sequence_config_new &= 0xfb; + break; + case VL53L0X_SEQUENCESTEP_PRE_RANGE: + sequence_config_new &= 0xbf; + break; + case VL53L0X_SEQUENCESTEP_FINAL_RANGE: + sequence_config_new &= 0x7f; + break; + default: + status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + } + + if (sequence_config_new != sequence_config) { + /* Apply New Setting */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, + VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, sequence_config_new); + } + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, SequenceConfig, sequence_config_new); + } + + + /* Recalculate timing budget */ + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_GETPARAMETERFIELD(dev, + MeasurementTimingBudgetMicroSeconds, + measurement_timing_budget_micro_seconds); + + VL53L0X_set_measurement_timing_budget_micro_seconds(dev, + measurement_timing_budget_micro_seconds); + } + } + + LOG_FUNCTION_END(status); + + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_set_limit_check_enable(VL53L0X_DEV dev, uint16_t limit_check_id, + uint8_t limit_check_enable) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + FixPoint1616_t temp_fix1616 = 0; + uint8_t limit_check_enable_int = 0; + uint8_t limit_check_disable = 0; + uint8_t temp8; + + LOG_FUNCTION_START(""); + + if (limit_check_id >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) { + status = VL53L0X_ERROR_INVALID_PARAMS; + } else { + if (limit_check_enable == 0) { + temp_fix1616 = 0; + limit_check_enable_int = 0; + limit_check_disable = 1; + + } else { + VL53L0X_GETARRAYPARAMETERFIELD(dev, LimitChecksValue, + limit_check_id, temp_fix1616); + limit_check_disable = 0; + /* this to be sure to have either 0 or 1 */ + limit_check_enable_int = 1; + } + + switch (limit_check_id) { + + case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE: + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + limit_check_enable_int); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE: + + status = VL53L0X_write_word(dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, + VL53L0X_FIXPOINT1616TOFIXPOINT97(temp_fix1616)); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP: + + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + limit_check_enable_int); + + break; + + case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD: + + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + limit_check_enable_int); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC: + + temp8 = (uint8_t)(limit_check_disable << 1); + status = VL53L0X_update_byte(dev, + VL53L0X_REG_MSRC_CONFIG_CONTROL, + 0xFE, temp8); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE: + + temp8 = (uint8_t)(limit_check_disable << 4); + status = VL53L0X_update_byte(dev, + VL53L0X_REG_MSRC_CONFIG_CONTROL, + 0xEF, temp8); + + break; + + + default: + status = VL53L0X_ERROR_INVALID_PARAMS; + + } + + } + + if (status == VL53L0X_ERROR_NONE) { + if (limit_check_enable == 0) { + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable, + limit_check_id, 0); + } else { + VL53L0X_SETARRAYPARAMETERFIELD(dev, LimitChecksEnable, + limit_check_id, 1); + } + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_static_init(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + VL53L0X_DeviceParameters_t current_parameters = {0}; + uint8_t *p_tuning_setting_buffer; + uint16_t tempword = 0; + uint8_t tempbyte = 0; + uint8_t use_internal_tuning_settings = 0; + uint32_t count = 0; + uint8_t is_aperture_spads = 0; + uint32_t ref_spad_count = 0; + uint8_t aperture_spads = 0; + uint8_t vcsel_pulse_period_pclk; + uint32_t seq_timeout_micro_secs; + + LOG_FUNCTION_START(""); + + status = VL53L0X_get_info_from_device(dev, 1); + + /* set the ref spad from NVM */ + count = (uint32_t)VL53L0X_GETDEVICESPECIFICPARAMETER(dev, + ReferenceSpadCount); + aperture_spads = VL53L0X_GETDEVICESPECIFICPARAMETER(dev, + ReferenceSpadType); + + /* NVM value invalid */ + if ((aperture_spads > 1) || + ((aperture_spads == 1) && (count > 32)) || + ((aperture_spads == 0) && (count > 12))) { + status = wrapped_VL53L0X_perform_ref_spad_management(dev, &ref_spad_count, + &is_aperture_spads); + } else { + status = VL53L0X_set_reference_spads(dev, count, aperture_spads); + } + + + /* Initialize tuning settings buffer to prevent compiler warning. */ + p_tuning_setting_buffer = DefaultTuningSettings; + + if (status == VL53L0X_ERROR_NONE) { + use_internal_tuning_settings = PALDevDataGet(dev, + UseInternalTuningSettings); + + if (use_internal_tuning_settings == 0) { + p_tuning_setting_buffer = PALDevDataGet(dev, + pTuningSettingsPointer); + } else { + p_tuning_setting_buffer = DefaultTuningSettings; + } + + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_load_tuning_settings(dev, p_tuning_setting_buffer); + } + + + /* Set interrupt config to new sample ready */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_set_gpio_config(dev, 0, 0, + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY, + VL53L0X_INTERRUPTPOLARITY_LOW); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + status |= VL53L0X_read_word(dev, 0x84, &tempword); + status |= VL53L0X_write_byte(dev, 0xFF, 0x00); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER(dev, OscFrequencyMHz, + VL53L0X_FIXPOINT412TOFIXPOINT1616(tempword)); + } + + /* After static init, some device parameters may be changed, + * so update them */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_device_parameters(dev, ¤t_parameters); + } + + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_fraction_enable(dev, &tempbyte); + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, RangeFractionalEnable, tempbyte); + } + + } + + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, CurrentParameters, current_parameters); + } + + + /* read the sequence config and save it */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_byte(dev, + VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &tempbyte); + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, SequenceConfig, tempbyte); + } + } + + /* Disable MSRC and TCC by default */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_set_sequence_step_enable(dev, + VL53L0X_SEQUENCESTEP_TCC, 0); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_set_sequence_step_enable(dev, + VL53L0X_SEQUENCESTEP_MSRC, 0); + } + + /* Set PAL State to standby */ + if (status == VL53L0X_ERROR_NONE) { + PALDevDataSet(dev, PalState, VL53L0X_STATE_IDLE); + } + + /* Store pre-range vcsel period */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_vcsel_pulse_period( + dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &vcsel_pulse_period_pclk); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + dev, + PreRangeVcselPulsePeriod, + vcsel_pulse_period_pclk); + } + + /* Store final-range vcsel period */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_get_vcsel_pulse_period( + dev, + VL53L0X_VCSEL_PERIOD_FINAL_RANGE, + &vcsel_pulse_period_pclk); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + dev, + FinalRangeVcselPulsePeriod, + vcsel_pulse_period_pclk); + } + + /* Store pre-range timeout */ + if (status == VL53L0X_ERROR_NONE) { + status = get_sequence_step_timeout( + dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + &seq_timeout_micro_secs); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + dev, + PreRangeTimeoutMicroSecs, + seq_timeout_micro_secs); + } + + /* Store final-range timeout */ + if (status == VL53L0X_ERROR_NONE) { + status = get_sequence_step_timeout( + dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + &seq_timeout_micro_secs); + } + + if (status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + dev, + FinalRangeTimeoutMicroSecs, + seq_timeout_micro_secs); + } + + LOG_FUNCTION_END(status); + return status; +} + + +VL53L0X_Error VL53L0X::VL53L0X_stop_measurement(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + status = VL53L0X_write_byte(dev, VL53L0X_REG_SYSRANGE_START, + VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT); + + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + status = VL53L0X_write_byte(dev, 0x00, 0x00); + status = VL53L0X_write_byte(dev, 0x91, 0x00); + status = VL53L0X_write_byte(dev, 0x00, 0x01); + status = VL53L0X_write_byte(dev, 0xFF, 0x00); + + if (status == VL53L0X_ERROR_NONE) { + /* Set PAL State to Idle */ + PALDevDataSet(dev, PalState, VL53L0X_STATE_IDLE); + } + + /* Check if need to apply interrupt settings */ + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_check_and_load_interrupt_settings(dev, 0); + } + + LOG_FUNCTION_END(status); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_get_stop_completed_status(VL53L0X_DEV dev, + uint32_t *p_stop_status) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t byte = 0; + LOG_FUNCTION_START(""); + + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_read_byte(dev, 0x04, &byte); + } + + if (status == VL53L0X_ERROR_NONE) { + status = VL53L0X_write_byte(dev, 0xFF, 0x0); + } + + *p_stop_status = byte; + + if (byte == 0) { + status = VL53L0X_write_byte(dev, 0x80, 0x01); + status = VL53L0X_write_byte(dev, 0xFF, 0x01); + status = VL53L0X_write_byte(dev, 0x00, 0x00); + status = VL53L0X_write_byte(dev, 0x91, + PALDevDataGet(dev, StopVariable)); + status = VL53L0X_write_byte(dev, 0x00, 0x01); + status = VL53L0X_write_byte(dev, 0xFF, 0x00); + status = VL53L0X_write_byte(dev, 0x80, 0x00); + } + + LOG_FUNCTION_END(status); + return status; +} + +/****************** Write and read functions from I2C *************************/ + +VL53L0X_Error VL53L0X::VL53L0X_write_multi(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data, uint32_t count) +{ + int status; + + status = VL53L0X_i2c_write(dev->I2cDevAddr, index, p_data, (uint16_t)count); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_read_multi(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data, uint32_t count) +{ + int status; + + if (count >= VL53L0X_MAX_I2C_XFER_SIZE) { + status = VL53L0X_ERROR_INVALID_PARAMS; + } + + status = VL53L0X_i2c_read(dev->I2cDevAddr, index, p_data, (uint16_t)count); + + return status; +} + + +VL53L0X_Error VL53L0X::VL53L0X_write_byte(VL53L0X_DEV Dev, uint8_t index, uint8_t data) +{ + int status; + + status = VL53L0X_i2c_write(Dev->I2cDevAddr, index, &data, 1); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_write_word(VL53L0X_DEV dev, uint8_t index, uint16_t data) +{ + int status; + uint8_t buffer[2]; + + buffer[0] = data >> 8; + buffer[1] = data & 0x00FF; + status = VL53L0X_i2c_write(dev->I2cDevAddr, index, (uint8_t *)buffer, 2); + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_write_dword(VL53L0X_DEV Dev, uint8_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 = VL53L0X_i2c_write(Dev->I2cDevAddr, index, (uint8_t *)buffer, 4); + return status; +} + + +VL53L0X_Error VL53L0X::VL53L0X_read_byte(VL53L0X_DEV Dev, uint8_t index, uint8_t *p_data) +{ + int status; + + status = VL53L0X_i2c_read(Dev->I2cDevAddr, index, p_data, 1); + + if (status) { + return -1; + } + + return 0; +} + +VL53L0X_Error VL53L0X::VL53L0X_read_word(VL53L0X_DEV Dev, uint8_t index, uint16_t *p_data) +{ + int status; + uint8_t buffer[2] = {0, 0}; + + status = VL53L0X_i2c_read(Dev->I2cDevAddr, index, buffer, 2); + if (!status) { + *p_data = (buffer[0] << 8) + buffer[1]; + } + return status; + +} + +VL53L0X_Error VL53L0X::VL53L0X_read_dword(VL53L0X_DEV Dev, uint8_t index, uint32_t *p_data) +{ + int status; + uint8_t buffer[4] = {0, 0, 0, 0}; + + status = VL53L0X_i2c_read(Dev->I2cDevAddr, index, buffer, 4); + if (!status) { + *p_data = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]; + } + return status; + +} + +VL53L0X_Error VL53L0X::VL53L0X_update_byte(VL53L0X_DEV Dev, uint8_t index, uint8_t and_data, uint8_t or_data) +{ + int status; + uint8_t buffer = 0; + + /* read data direct onto buffer */ + status = VL53L0X_i2c_read(Dev->I2cDevAddr, index, &buffer, 1); + if (!status) { + buffer = (buffer & and_data) | or_data; + status = VL53L0X_i2c_write(Dev->I2cDevAddr, index, &buffer, (uint8_t)1); + } + return status; +} + +VL53L0X_Error VL53L0X::VL53L0X_i2c_write(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t *p_data, + uint16_t NumByteToWrite) +{ + int ret; + + ret = _dev_i2c->i2c_write(p_data, DeviceAddr, RegisterAddr, NumByteToWrite); + + if (ret) { + return -1; + } + return 0; +} + +VL53L0X_Error VL53L0X::VL53L0X_i2c_read(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t *p_data, + uint16_t NumByteToRead) +{ + int ret; + + ret = _dev_i2c->i2c_read(p_data, DeviceAddr, RegisterAddr, NumByteToRead); + + if (ret) { + return -1; + } + return 0; +} + +int VL53L0X::read_id(uint8_t *id) +{ + int status = 0; + uint16_t rl_id = 0; + + status = VL53L0X_read_word(_device, VL53L0X_REG_IDENTIFICATION_MODEL_ID, &rl_id); + if (rl_id == 0xEEAA) { + return status; + } + + return -1; +} + + +VL53L0X_Error VL53L0X::wait_measurement_data_ready(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t new_dat_ready = 0; + uint32_t loop_nb; + + // Wait until it finished + // use timeout to avoid deadlock + if (status == VL53L0X_ERROR_NONE) { + loop_nb = 0; + do { + status = VL53L0X_get_measurement_data_ready(dev, &new_dat_ready); + if ((new_dat_ready == 0x01) || status != VL53L0X_ERROR_NONE) { + break; + } + loop_nb = loop_nb + 1; + VL53L0X_polling_delay(dev); + } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP); + + if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) { + status = VL53L0X_ERROR_TIME_OUT; + } + } + + return status; +} + +VL53L0X_Error VL53L0X::wait_stop_completed(VL53L0X_DEV dev) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t stop_completed = 0; + uint32_t loop_nb; + + // Wait until it finished + // use timeout to avoid deadlock + if (status == VL53L0X_ERROR_NONE) { + loop_nb = 0; + do { + status = VL53L0X_get_stop_completed_status(dev, &stop_completed); + if ((stop_completed == 0x00) || status != VL53L0X_ERROR_NONE) { + break; + } + loop_nb = loop_nb + 1; + VL53L0X_polling_delay(dev); + } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP); + + if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) { + status = VL53L0X_ERROR_TIME_OUT; + } + + } + + return status; +} + + +int VL53L0X::init_sensor(uint8_t new_addr) +{ + int status; + + VL53L0X_off(); + VL53L0X_on(); + +// status=VL53L0X_WaitDeviceBooted(Device); +// if(status) +// printf("WaitDeviceBooted fail\n\r"); + status = is_present(); + if (!status) { + status = init(&_my_device); + if (status != VL53L0X_ERROR_NONE) { + printf("Failed to init VL53L0X sensor!\n\r"); + return status; + } + + // deduce silicon version + status = VL53L0X_get_device_info(&_my_device, &_device_info); + + status = prepare(); + if (status != VL53L0X_ERROR_NONE) { + printf("Failed to prepare VL53L0X!\n\r"); + return status; + } + + if (new_addr != VL53L0X_DEFAULT_ADDRESS) { + status = set_device_address(new_addr); + if (status) { + printf("Failed to change I2C address!\n\r"); + return status; + } + } else { + printf("Invalid new address!\n\r"); + return VL53L0X_ERROR_INVALID_PARAMS; + } + } + return status; +} + +int VL53L0X::range_meas_int_continuous_mode(void (*fptr)(void)) +{ + int status, clr_status; + + status = VL53L0X_stop_measurement(_device); // it is safer to do this while sensor is stopped + +// status = VL53L0X_SetInterruptThresholds(Device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, 0, 300); + + status = VL53L0X_set_gpio_config(_device, 0, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY, + VL53L0X_INTERRUPTPOLARITY_HIGH); + + if (!status) { + attach_interrupt_measure_detection_irq(fptr); + enable_interrupt_measure_detection_irq(); + } + + clr_status = clear_interrupt(VL53L0X_REG_RESULT_INTERRUPT_STATUS | VL53L0X_REG_RESULT_RANGE_STATUS); + if (clr_status) { + VL53L0X_ErrLog("VL53L0X_ClearErrorInterrupt fail\r\n"); + } + + if (!status) { + status = range_start_continuous_mode(); + } + return status; +} + + +int VL53L0X::start_measurement(OperatingMode operating_mode, void (*fptr)(void)) +{ + int Status = VL53L0X_ERROR_NONE; + int ClrStatus; + + uint8_t VhvSettings; + uint8_t PhaseCal; + // *** from mass market cube expansion v1.1, ranging with satellites. + // default settings, for normal range. + FixPoint1616_t signalLimit = (FixPoint1616_t)(0.25 * 65536); + FixPoint1616_t sigmaLimit = (FixPoint1616_t)(18 * 65536); + uint32_t timingBudget = 33000; + uint8_t preRangeVcselPeriod = 14; + uint8_t finalRangeVcselPeriod = 10; + + if (operating_mode == range_continuous_interrupt) { + if (_gpio1Int == NULL) { + printf("GPIO1 Error\r\n"); + return 1; + } + + Status = VL53L0X_stop_measurement(_device); // it is safer to do this while sensor is stopped + +// Status = VL53L0X_SetInterruptThresholds(Device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, 0, 300); + + Status = VL53L0X_set_gpio_config(_device, 0, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY, + VL53L0X_INTERRUPTPOLARITY_HIGH); + + if (Status == VL53L0X_ERROR_NONE) { + attach_interrupt_measure_detection_irq(fptr); + enable_interrupt_measure_detection_irq(); + } + + ClrStatus = clear_interrupt(VL53L0X_REG_RESULT_INTERRUPT_STATUS | VL53L0X_REG_RESULT_RANGE_STATUS); + if (ClrStatus) { + VL53L0X_ErrLog("VL53L0X_ClearErrorInterrupt fail\r\n"); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_set_device_mode(_device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); // Setup in continuous ranging mode + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_start_measurement(_device); + } + } + + if (operating_mode == range_single_shot_polling) { + // singelshot, polled ranging + if (Status == VL53L0X_ERROR_NONE) { + // no need to do this when we use VL53L0X_PerformSingleRangingMeasurement + Status = VL53L0X_set_device_mode(_device, VL53L0X_DEVICEMODE_SINGLE_RANGING); // Setup in single ranging mode + } + + // Enable/Disable Sigma and Signal check + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_set_limit_check_enable(_device, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, 1); + } + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_set_limit_check_enable(_device, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1); + } + +// *** from mass market cube expansion v1.1, ranging with satellites. + /* Ranging configuration */ +//* +// switch(rangingConfig) { +// case LONG_RANGE: + signalLimit = (FixPoint1616_t)(0.1 * 65536); + sigmaLimit = (FixPoint1616_t)(60 * 65536); + timingBudget = 33000; + preRangeVcselPeriod = 18; + finalRangeVcselPeriod = 14; + /* break; + case HIGH_ACCURACY: + signalLimit = (FixPoint1616_t)(0.25*65536); + sigmaLimit = (FixPoint1616_t)(18*65536); + timingBudget = 200000; + preRangeVcselPeriod = 14; + finalRangeVcselPeriod = 10; + break; + case HIGH_SPEED: + signalLimit = (FixPoint1616_t)(0.25*65536); + sigmaLimit = (FixPoint1616_t)(32*65536); + timingBudget = 20000; + preRangeVcselPeriod = 14; + finalRangeVcselPeriod = 10; + break; + default: + debug_printf("Not Supported"); + } + */ + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_set_limit_check_value(_device, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, signalLimit); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_set_limit_check_value(_device, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, sigmaLimit); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_set_measurement_timing_budget_micro_seconds(_device, timingBudget); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_set_vcsel_pulse_period(_device, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, preRangeVcselPeriod); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_set_vcsel_pulse_period(_device, + VL53L0X_VCSEL_PERIOD_FINAL_RANGE, finalRangeVcselPeriod); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_perform_ref_calibration(_device, &VhvSettings, &PhaseCal); + } + + } + + if (operating_mode == range_continuous_polling) { + if (Status == VL53L0X_ERROR_NONE) { + //printf("Call of VL53L0X_SetDeviceMode\n"); + Status = VL53L0X_set_device_mode(_device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); // Setup in continuous ranging mode + } + + if (Status == VL53L0X_ERROR_NONE) { + //printf("Call of VL53L0X_StartMeasurement\n"); + Status = VL53L0X_start_measurement(_device); + } + } + + return Status; +} + + +int VL53L0X::get_measurement(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *p_data) +{ + int Status = VL53L0X_ERROR_NONE; + + if (operating_mode == range_single_shot_polling) { + Status = VL53L0X_perform_single_ranging_measurement(_device, p_data); + } + + if (operating_mode == range_continuous_polling) { + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_measurement_poll_for_completion(_device); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_get_ranging_measurement_data(_device, p_data); + + // Clear the interrupt + VL53L0X_clear_interrupt_mask(_device, VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); + VL53L0X_polling_delay(_device); + } + } + + if (operating_mode == range_continuous_interrupt) { + Status = VL53L0X_get_ranging_measurement_data(_device, p_data); + VL53L0X_clear_interrupt_mask(_device, VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR | VL53L0X_REG_RESULT_INTERRUPT_STATUS); + } + + return Status; +} + + +int VL53L0X::stop_measurement(OperatingMode operating_mode) +{ + int status = VL53L0X_ERROR_NONE; + + + // don't need to stop for a singleshot range! + if (operating_mode == range_single_shot_polling) { + } + + if (operating_mode == range_continuous_interrupt || operating_mode == range_continuous_polling) { + // continuous mode + if (status == VL53L0X_ERROR_NONE) { + //printf("Call of VL53L0X_StopMeasurement\n"); + status = VL53L0X_stop_measurement(_device); + } + + if (status == VL53L0X_ERROR_NONE) { + //printf("Wait Stop to be competed\n"); + status = wait_stop_completed(_device); + } + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_clear_interrupt_mask(_device, + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); + } + + return status; +} + + +int VL53L0X::handle_irq(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *data) +{ + int status; + status = get_measurement(operating_mode, data); + enable_interrupt_measure_detection_irq(); + return status; +} + + +/******************************************************************************/
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,2797 @@ +/******************************************************************************* + Copyright © 2016, STMicroelectronics International N.V. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * 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, FITNESS FOR A PARTICULAR PURPOSE, AND + NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. + IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. + *****************************************************************************/ + +#ifndef __VL53L0X_CLASS_H +#define __VL53L0X_CLASS_H + + +#ifdef _MSC_VER +# ifdef VL53L0X_API_EXPORTS +# define VL53L0X_API __declspec(dllexport) +# else +# define VL53L0X_API +# endif +#else +# define VL53L0X_API +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "mbed.h" +#include "RangeSensor.h" +#include "DevI2C.h" +#include "PinNames.h" +#include "VL53L0X_def.h" +#include "VL53L0X_platform.h" +#include "Stmpe1600.h" + + +/** + * The device model ID + */ +#define IDENTIFICATION_MODEL_ID 0x000 + + +#define STATUS_OK 0x00 +#define STATUS_FAIL 0x01 + +#define VL53L0X_OsDelay(...) wait_ms(2) // 2 msec delay. can also use wait(float secs)/wait_us(int) + +#ifdef USE_EMPTY_STRING +#define VL53L0X_STRING_DEVICE_INFO_NAME "" +#define VL53L0X_STRING_DEVICE_INFO_NAME_TS0 "" +#define VL53L0X_STRING_DEVICE_INFO_NAME_TS1 "" +#define VL53L0X_STRING_DEVICE_INFO_NAME_TS2 "" +#define VL53L0X_STRING_DEVICE_INFO_NAME_ES1 "" +#define VL53L0X_STRING_DEVICE_INFO_TYPE "" + +/* PAL ERROR strings */ +#define VL53L0X_STRING_ERROR_NONE "" +#define VL53L0X_STRING_ERROR_CALIBRATION_WARNING "" +#define VL53L0X_STRING_ERROR_MIN_CLIPPED "" +#define VL53L0X_STRING_ERROR_UNDEFINED "" +#define VL53L0X_STRING_ERROR_INVALID_PARAMS "" +#define VL53L0X_STRING_ERROR_NOT_SUPPORTED "" +#define VL53L0X_STRING_ERROR_RANGE_ERROR "" +#define VL53L0X_STRING_ERROR_TIME_OUT "" +#define VL53L0X_STRING_ERROR_MODE_NOT_SUPPORTED "" +#define VL53L0X_STRING_ERROR_BUFFER_TOO_SMALL "" +#define VL53L0X_STRING_ERROR_GPIO_NOT_EXISTING "" +#define VL53L0X_STRING_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED "" +#define VL53L0X_STRING_ERROR_CONTROL_INTERFACE "" +#define VL53L0X_STRING_ERROR_INVALID_COMMAND "" +#define VL53L0X_STRING_ERROR_DIVISION_BY_ZERO "" +#define VL53L0X_STRING_ERROR_REF_SPAD_INIT "" +#define VL53L0X_STRING_ERROR_NOT_IMPLEMENTED "" + +#define VL53L0X_STRING_UNKNOW_ERROR_CODE "" + + + +/* Range Status */ +#define VL53L0X_STRING_RANGESTATUS_NONE "" +#define VL53L0X_STRING_RANGESTATUS_RANGEVALID "" +#define VL53L0X_STRING_RANGESTATUS_SIGMA "" +#define VL53L0X_STRING_RANGESTATUS_SIGNAL "" +#define VL53L0X_STRING_RANGESTATUS_MINRANGE "" +#define VL53L0X_STRING_RANGESTATUS_PHASE "" +#define VL53L0X_STRING_RANGESTATUS_HW "" + + +/* Range Status */ +#define VL53L0X_STRING_STATE_POWERDOWN "" +#define VL53L0X_STRING_STATE_WAIT_STATICINIT "" +#define VL53L0X_STRING_STATE_STANDBY "" +#define VL53L0X_STRING_STATE_IDLE "" +#define VL53L0X_STRING_STATE_RUNNING "" +#define VL53L0X_STRING_STATE_UNKNOWN "" +#define VL53L0X_STRING_STATE_ERROR "" + + +/* Device Specific */ +#define VL53L0X_STRING_DEVICEERROR_NONE "" +#define VL53L0X_STRING_DEVICEERROR_VCSELCONTINUITYTESTFAILURE "" +#define VL53L0X_STRING_DEVICEERROR_VCSELWATCHDOGTESTFAILURE "" +#define VL53L0X_STRING_DEVICEERROR_NOVHVVALUEFOUND "" +#define VL53L0X_STRING_DEVICEERROR_MSRCNOTARGET "" +#define VL53L0X_STRING_DEVICEERROR_SNRCHECK "" +#define VL53L0X_STRING_DEVICEERROR_RANGEPHASECHECK "" +#define VL53L0X_STRING_DEVICEERROR_SIGMATHRESHOLDCHECK "" +#define VL53L0X_STRING_DEVICEERROR_TCC "" +#define VL53L0X_STRING_DEVICEERROR_PHASECONSISTENCY "" +#define VL53L0X_STRING_DEVICEERROR_MINCLIP "" +#define VL53L0X_STRING_DEVICEERROR_RANGECOMPLETE "" +#define VL53L0X_STRING_DEVICEERROR_ALGOUNDERFLOW "" +#define VL53L0X_STRING_DEVICEERROR_ALGOOVERFLOW "" +#define VL53L0X_STRING_DEVICEERROR_RANGEIGNORETHRESHOLD "" +#define VL53L0X_STRING_DEVICEERROR_UNKNOWN "" + +/* Check Enable */ +#define VL53L0X_STRING_CHECKENABLE_SIGMA_FINAL_RANGE "" +#define VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE "" +#define VL53L0X_STRING_CHECKENABLE_SIGNAL_REF_CLIP "" +#define VL53L0X_STRING_CHECKENABLE_RANGE_IGNORE_THRESHOLD "" + +/* Sequence Step */ +#define VL53L0X_STRING_SEQUENCESTEP_TCC "" +#define VL53L0X_STRING_SEQUENCESTEP_DSS "" +#define VL53L0X_STRING_SEQUENCESTEP_MSRC "" +#define VL53L0X_STRING_SEQUENCESTEP_PRE_RANGE "" +#define VL53L0X_STRING_SEQUENCESTEP_FINAL_RANGE "" +#else +#define VL53L0X_STRING_DEVICE_INFO_NAME "VL53L0X cut1.0" +#define VL53L0X_STRING_DEVICE_INFO_NAME_TS0 "VL53L0X TS0" +#define VL53L0X_STRING_DEVICE_INFO_NAME_TS1 "VL53L0X TS1" +#define VL53L0X_STRING_DEVICE_INFO_NAME_TS2 "VL53L0X TS2" +#define VL53L0X_STRING_DEVICE_INFO_NAME_ES1 "VL53L0X ES1 or later" +#define VL53L0X_STRING_DEVICE_INFO_TYPE "VL53L0X" + +/* PAL ERROR strings */ +#define VL53L0X_STRING_ERROR_NONE \ + "No Error" +#define VL53L0X_STRING_ERROR_CALIBRATION_WARNING \ + "Calibration Warning Error" +#define VL53L0X_STRING_ERROR_MIN_CLIPPED \ + "Min clipped error" +#define VL53L0X_STRING_ERROR_UNDEFINED \ + "Undefined error" +#define VL53L0X_STRING_ERROR_INVALID_PARAMS \ + "Invalid parameters error" +#define VL53L0X_STRING_ERROR_NOT_SUPPORTED \ + "Not supported error" +#define VL53L0X_STRING_ERROR_RANGE_ERROR \ + "Range error" +#define VL53L0X_STRING_ERROR_TIME_OUT \ + "Time out error" +#define VL53L0X_STRING_ERROR_MODE_NOT_SUPPORTED \ + "Mode not supported error" +#define VL53L0X_STRING_ERROR_BUFFER_TOO_SMALL \ + "Buffer too small" +#define VL53L0X_STRING_ERROR_GPIO_NOT_EXISTING \ + "GPIO not existing" +#define VL53L0X_STRING_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED \ + "GPIO funct not supported" +#define VL53L0X_STRING_ERROR_INTERRUPT_NOT_CLEARED \ + "Interrupt not Cleared" +#define VL53L0X_STRING_ERROR_CONTROL_INTERFACE \ + "Control Interface Error" +#define VL53L0X_STRING_ERROR_INVALID_COMMAND \ + "Invalid Command Error" +#define VL53L0X_STRING_ERROR_DIVISION_BY_ZERO \ + "Division by zero Error" +#define VL53L0X_STRING_ERROR_REF_SPAD_INIT \ + "Reference Spad Init Error" +#define VL53L0X_STRING_ERROR_NOT_IMPLEMENTED \ + "Not implemented error" + +#define VL53L0X_STRING_UNKNOW_ERROR_CODE \ + "Unknown Error Code" + + + +/* Range Status */ +#define VL53L0X_STRING_RANGESTATUS_NONE "No Update" +#define VL53L0X_STRING_RANGESTATUS_RANGEVALID "Range Valid" +#define VL53L0X_STRING_RANGESTATUS_SIGMA "Sigma Fail" +#define VL53L0X_STRING_RANGESTATUS_SIGNAL "Signal Fail" +#define VL53L0X_STRING_RANGESTATUS_MINRANGE "Min Range Fail" +#define VL53L0X_STRING_RANGESTATUS_PHASE "Phase Fail" +#define VL53L0X_STRING_RANGESTATUS_HW "Hardware Fail" + + +/* Range Status */ +#define VL53L0X_STRING_STATE_POWERDOWN "POWERDOWN State" +#define VL53L0X_STRING_STATE_WAIT_STATICINIT \ + "Wait for staticinit State" +#define VL53L0X_STRING_STATE_STANDBY "STANDBY State" +#define VL53L0X_STRING_STATE_IDLE "IDLE State" +#define VL53L0X_STRING_STATE_RUNNING "RUNNING State" +#define VL53L0X_STRING_STATE_UNKNOWN "UNKNOWN State" +#define VL53L0X_STRING_STATE_ERROR "ERROR State" + + +/* Device Specific */ +#define VL53L0X_STRING_DEVICEERROR_NONE "No Update" +#define VL53L0X_STRING_DEVICEERROR_VCSELCONTINUITYTESTFAILURE \ + "VCSEL Continuity Test Failure" +#define VL53L0X_STRING_DEVICEERROR_VCSELWATCHDOGTESTFAILURE \ + "VCSEL Watchdog Test Failure" +#define VL53L0X_STRING_DEVICEERROR_NOVHVVALUEFOUND \ + "No VHV Value found" +#define VL53L0X_STRING_DEVICEERROR_MSRCNOTARGET \ + "MSRC No Target Error" +#define VL53L0X_STRING_DEVICEERROR_SNRCHECK \ + "SNR Check Exit" +#define VL53L0X_STRING_DEVICEERROR_RANGEPHASECHECK \ + "Range Phase Check Error" +#define VL53L0X_STRING_DEVICEERROR_SIGMATHRESHOLDCHECK \ + "Sigma Threshold Check Error" +#define VL53L0X_STRING_DEVICEERROR_TCC \ + "TCC Error" +#define VL53L0X_STRING_DEVICEERROR_PHASECONSISTENCY \ + "Phase Consistency Error" +#define VL53L0X_STRING_DEVICEERROR_MINCLIP \ + "Min Clip Error" +#define VL53L0X_STRING_DEVICEERROR_RANGECOMPLETE \ + "Range Complete" +#define VL53L0X_STRING_DEVICEERROR_ALGOUNDERFLOW \ + "Range Algo Underflow Error" +#define VL53L0X_STRING_DEVICEERROR_ALGOOVERFLOW \ + "Range Algo Overlow Error" +#define VL53L0X_STRING_DEVICEERROR_RANGEIGNORETHRESHOLD \ + "Range Ignore Threshold Error" +#define VL53L0X_STRING_DEVICEERROR_UNKNOWN \ + "Unknown error code" + +/* Check Enable */ +#define VL53L0X_STRING_CHECKENABLE_SIGMA_FINAL_RANGE \ + "SIGMA FINAL RANGE" +#define VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE \ + "SIGNAL RATE FINAL RANGE" +#define VL53L0X_STRING_CHECKENABLE_SIGNAL_REF_CLIP \ + "SIGNAL REF CLIP" +#define VL53L0X_STRING_CHECKENABLE_RANGE_IGNORE_THRESHOLD \ + "RANGE IGNORE THRESHOLD" +#define VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_MSRC \ + "SIGNAL RATE MSRC" +#define VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_PRE_RANGE \ + "SIGNAL RATE PRE RANGE" + +/* Sequence Step */ +#define VL53L0X_STRING_SEQUENCESTEP_TCC "TCC" +#define VL53L0X_STRING_SEQUENCESTEP_DSS "DSS" +#define VL53L0X_STRING_SEQUENCESTEP_MSRC "MSRC" +#define VL53L0X_STRING_SEQUENCESTEP_PRE_RANGE "PRE RANGE" +#define VL53L0X_STRING_SEQUENCESTEP_FINAL_RANGE "FINAL RANGE" +#endif /* USE_EMPTY_STRING */ + +/* sensor operating modes */ +typedef enum { + range_single_shot_polling = 1, + range_continuous_polling, + range_continuous_interrupt, + range_continuous_polling_low_threshold, + range_continuous_polling_high_threshold, + range_continuous_polling_out_of_window, + range_continuous_interrupt_low_threshold, + range_continuous_interrupt_high_threshold, + range_continuous_interrupt_out_of_window, +} OperatingMode; + +/** default device address */ +#define VL53L0X_DEFAULT_ADDRESS 0x52 /* (8-bit) */ + +/* Classes -------------------------------------------------------------------*/ +/** Class representing a VL53L0 sensor component + */ +class VL53L0X : public RangeSensor +{ +public: + /** Constructor + * @param[in] &i2c device I2C to be used for communication + * @param[in] &pin_gpio1 pin Mbed InterruptIn PinName to be used as component GPIO_1 INT + * @param[in] dev_addr device address, 0x29 by default + */ + VL53L0X(DevI2C *i2c, DigitalOut *pin, PinName pin_gpio1, uint8_t dev_addr = VL53L0X_DEFAULT_ADDRESS) : _dev_i2c(i2c), + _gpio0(pin) + { + _my_device.I2cDevAddr = dev_addr; + _my_device.comms_type = 1; // VL53L0X_COMMS_I2C + _my_device.comms_speed_khz = 400; + _device = &_my_device; + _expgpio0 = NULL; + if (pin_gpio1 != NC) { + _gpio1Int = new InterruptIn(pin_gpio1); + } else { + _gpio1Int = NULL; + } + } + + /** Constructor 2 (STMPE1600DigiOut) + * @param[in] i2c device I2C to be used for communication + * @param[in] &pin Gpio Expander STMPE1600DigiOut pin to be used as component GPIO_0 CE + * @param[in] pin_gpio1 pin Mbed InterruptIn PinName to be used as component GPIO_1 INT + * @param[in] device address, 0x29 by default + */ + VL53L0X(DevI2C *i2c, Stmpe1600DigiOut *pin, PinName pin_gpio1, + uint8_t dev_addr = VL53L0X_DEFAULT_ADDRESS) : _dev_i2c(i2c), _expgpio0(pin) + { + _my_device.I2cDevAddr = dev_addr; + _my_device.comms_type = 1; // VL53L0X_COMMS_I2C + _my_device.comms_speed_khz = 400; + _device = &_my_device; + _gpio0 = NULL; + if (pin_gpio1 != NC) { + _gpio1Int = new InterruptIn(pin_gpio1); + } else { + _gpio1Int = NULL; + } + } + + /** Destructor + */ + virtual ~VL53L0X() + { + if (_gpio1Int != NULL) { + delete _gpio1Int; + } + } + + /*** Interface Methods ***/ + /*** High level API ***/ + /** + * @brief PowerOn the sensor + * @return void + */ + /* turns on the sensor */ + void VL53L0X_on(void) + { + if (_gpio0) { + *_gpio0 = 1; + } else { + if (_expgpio0) { + *_expgpio0 = 1; + } + } + wait_ms(10); + } + + /** + * @brief PowerOff the sensor + * @return void + */ + /* turns off the sensor */ + void VL53L0X_off(void) + { + if (_gpio0) { + *_gpio0 = 0; + } else { + if (_expgpio0) { + *_expgpio0 = 0; + } + } + wait_ms(10); + } + + + /** + * @brief Initialize the sensor with default values + * @return "0" on success + */ + int init_sensor(uint8_t new_addr); + + /** + * @brief Start the measure indicated by operating mode + * @param[in] operating_mode specifies requested measure + * @param[in] fptr specifies call back function must be !NULL in case of interrupt measure + * @return "0" on success + */ + int start_measurement(OperatingMode operating_mode, void (*fptr)(void)); + + /** + * @brief Get results for the measure indicated by operating mode + * @param[in] operating_mode specifies requested measure results + * @param[out] p_data pointer to the MeasureData_t structure to read data in to + * @return "0" on success + */ + int get_measurement(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *p_data); + + /** + * @brief Stop the currently running measure indicate by operating_mode + * @param[in] operating_mode specifies requested measure to stop + * @return "0" on success + */ + int stop_measurement(OperatingMode operating_mode); + + /** + * @brief Interrupt handling func to be called by user after an INT is occourred + * @param[in] opeating_mode indicating the in progress measure + * @param[out] Data pointer to the MeasureData_t structure to read data in to + * @return "0" on success + */ + int handle_irq(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *data); + + /** + * @brief Enable interrupt measure IRQ + * @return "0" on success + */ + void enable_interrupt_measure_detection_irq(void) + { + if (_gpio1Int != NULL) { + _gpio1Int->enable_irq(); + } + } + + /** + * @brief Disable interrupt measure IRQ + * @return "0" on success + */ + void disable_interrupt_measure_detection_irq(void) + { + if (_gpio1Int != NULL) { + _gpio1Int->disable_irq(); + } + } + + /** + * @brief Attach a function to call when an interrupt is detected, i.e. measurement is ready + * @param[in] fptr pointer to call back function to be called whenever an interrupt occours + * @return "0" on success + */ + void attach_interrupt_measure_detection_irq(void (*fptr)(void)) + { + if (_gpio1Int != NULL) { + _gpio1Int->rise(fptr); + } + } + + /** Wrapper functions */ + /** @defgroup api_init Init functions + * @brief API init functions + * @ingroup api_hl + * @{ + */ + + /** + * + * @brief One time device initialization + * + * To be called once and only once after device is brought out of reset (Chip enable) and booted. + * + * @par Function Description + * When not used after a fresh device "power up" or reset, it may return @a #CALIBRATION_WARNING + * meaning wrong calibration data may have been fetched from device that can result in ranging offset error\n + * If application cannot execute device reset or need to run VL53L0X_data_init multiple time + * then it must ensure proper offset calibration saving and restore on its own + * by using @a VL53L0X_get_offset_calibration_data_micro_meter() on first power up and then @a VL53L0X_set_offset_calibration_data_micro_meter() all all subsequent init + * + * @param void + * @return "0" on success, @a #CALIBRATION_WARNING if failed + */ + virtual int init(void *init) + { + return VL53L0X_data_init(_device); + } + + /** + * @brief Prepare device for operation + * @par Function Description + * Does static initialization and reprogram common default settings \n + * Device is prepared for new measure, ready single shot ranging or ALS typical polling operation\n + * After prepare user can : \n + * @li Call other API function to set other settings\n + * @li Configure the interrupt pins, etc... \n + * @li Then start ranging or ALS operations in single shot or continuous mode + * + * @param void + * @return "0" on success + */ + int prepare() + { + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t ref_spad_count; + uint8_t is_aperture_spads; + uint8_t vhv_settings; + uint8_t phase_cal; + + if (status == VL53L0X_ERROR_NONE) { + //printf("Call of VL53L0X_StaticInit\r\n"); + status = VL53L0X_static_init(_device); // Device Initialization + } + + if (status == VL53L0X_ERROR_NONE) { + //printf("Call of VL53L0X_PerformRefCalibration\r\n"); + status = VL53L0X_perform_ref_calibration(_device, + &vhv_settings, &phase_cal); // Device Initialization + } + + if (status == VL53L0X_ERROR_NONE) { + //printf("Call of VL53L0X_PerformRefSpadManagement\r\n"); + status = VL53L0X_perform_ref_spad_management(_device, + &ref_spad_count, &is_aperture_spads); // Device Initialization +// printf ("refSpadCount = %d, isApertureSpads = %d\r\n", refSpadCount, isApertureSpads); + } + + return status; + } + + /** + * @brief Start continuous ranging mode + * + * @details End user should ensure device is in idle state and not already running + * @return "0" on success + */ + int range_start_continuous_mode() + { + int status; + status = VL53L0X_set_device_mode(_device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); + + if (status == VL53L0X_ERROR_NONE) { + //printf ("Call of VL53L0X_StartMeasurement\r\n"); + status = VL53L0X_start_measurement(_device); + } + + return status; + } + + /** + * @brief Get ranging result and only that + * + * @par Function Description + * Unlike @a VL53L0X_get_ranging_measurement_data() this function only retrieves the range in millimeter \n + * It does any required up-scale translation\n + * It can be called after success status polling or in interrupt mode \n + * @warning these function is not doing wrap around filtering \n + * This function doesn't perform any data ready check! + * + * @param p_data Pointer to range distance + * @return "0" on success + */ + virtual int get_distance(uint32_t *p_data) + { + int status = 0; + VL53L0X_RangingMeasurementData_t p_ranging_measurement_data; + + status = start_measurement(range_single_shot_polling, NULL); + if (!status) { + status = get_measurement(range_single_shot_polling, &p_ranging_measurement_data); + } + if (p_ranging_measurement_data.RangeStatus == 0) { + // we have a valid range. + *p_data = p_ranging_measurement_data.RangeMilliMeter; + } else { + *p_data = 0; + status = VL53L0X_ERROR_RANGE_ERROR; + } + stop_measurement(range_single_shot_polling); + return status; + } + + /** @} */ + + /** + * @brief Set new device i2c address + * + * After completion the device will answer to the new address programmed. + * + * @param new_addr The new i2c address (7bit) + * @return "0" on success + */ + int set_device_address(int new_addr) + { + int status; + + status = VL53L0X_set_device_address(_device, new_addr); + if (!status) { + _device->I2cDevAddr = new_addr; + } + return status; + + } + + /** + * @brief Clear given system interrupt condition + * + * @par Function Description + * Clear given interrupt cause by writing into register #SYSTEM_INTERRUPT_CLEAR register. + * @param dev The device + * @param int_clear Which interrupt source to clear. Use any combinations of #INTERRUPT_CLEAR_RANGING , #INTERRUPT_CLEAR_ALS , #INTERRUPT_CLEAR_ERROR. + * @return "0" on success + */ + int clear_interrupt(uint8_t int_clear) + { + return VL53L0X_clear_interrupt_mask(_device, int_clear); + } + + /** + * + * @brief Get the 53L0 device + * + * To be called to retrive the internal device descriptor to allow usage of + * low level API having device as parameter. To be called after set_device_address() + * (if any). + * + * @par Function Description + * To be called if low level API usage is needed as those functions requires + * device as a parameter.TICINIT. + * + * @note This function return a pointer to an object internal structure + * + * @param dev ptr to ptr to Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error vl53l0x_get_device(VL53L0X_DEV *dev) +{ + *dev = _device; + return VL53L0X_ERROR_NONE; +} + + /** + * + * @brief One time device initialization + * + * To be called once and only once after device is brought out of reset + * (Chip enable) and booted see @a VL53L0X_WaitDeviceBooted() + * + * @par Function Description + * When not used after a fresh device "power up" or reset, it may return + * @a #VL53L0X_ERROR_CALIBRATION_WARNING meaning wrong calibration data + * may have been fetched from device that can result in ranging offset error\n + * If application cannot execute device reset or need to run VL53L0X_DataInit + * multiple time then it must ensure proper offset calibration saving and + * restore on its own by using @a VL53L0X_GetOffsetCalibrationData() on first + * power up and then @a VL53L0X_SetOffsetCalibrationData() in all subsequent init + * This function will change the VL53L0X_State from VL53L0X_STATE_POWERDOWN to + * VL53L0X_STATE_WAIT_STATICINIT. + * + * @note This function accesses to the device + * + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_data_init(VL53L0X_DEV dev); + + /** + * @brief Do basic device init (and eventually patch loading) + * This function will change the VL53L0X_State from + * VL53L0X_STATE_WAIT_STATICINIT to VL53L0X_STATE_IDLE. + * In this stage all default setting will be applied. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_static_init(VL53L0X_DEV dev); + + /** + * @brief Perform Reference Calibration + * + * @details Perform a reference calibration of the Device. + * This function should be run from time to time before doing + * a ranging measurement. + * This function will launch a special ranging measurement, so + * if interrupt are enable an interrupt will be done. + * This function will clear the interrupt generated automatically. + * + * @warning This function is a blocking function + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_vhv_settings Pointer to vhv settings parameter. + * @param p_phase_cal Pointer to PhaseCal parameter. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_perform_ref_calibration(VL53L0X_DEV dev, uint8_t *p_vhv_settings, + uint8_t *p_phase_cal); + + /** + * @brief Get Reference Calibration Parameters + * + * @par Function Description + * Get Reference Calibration Parameters. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_vhv_settings Pointer to VHV parameter + * @param p_phase_cal Pointer to PhaseCal Parameter + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_ref_calibration(VL53L0X_DEV dev, + uint8_t *p_vhv_settings, uint8_t *p_phase_cal); + + VL53L0X_Error VL53L0X_set_ref_calibration(VL53L0X_DEV dev, + uint8_t vhv_settings, uint8_t phase_cal); + + /** + * @brief Performs Reference Spad Management + * + * @par Function Description + * The reference SPAD initialization procedure determines the minimum amount + * of reference spads to be enables to achieve a target reference signal rate + * and should be performed once during initialization. + * + * @note This function Access to the device + * + * @note This function change the device mode to + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * + * @param dev Device Handle + * @param ref_spad_count Reports ref Spad Count + * @param is_aperture_spads Reports if spads are of type + * aperture or non-aperture. + * 1:=aperture, 0:=Non-Aperture + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_REF_SPAD_INIT Error in the Ref Spad procedure. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_perform_ref_spad_management(VL53L0X_DEV dev, + uint32_t *ref_spad_count, uint8_t *is_aperture_spads); + + /** + * @brief Applies Reference SPAD configuration + * + * @par Function Description + * This function applies a given number of reference spads, identified as + * either Aperture or Non-Aperture. + * The requested spad count and type are stored within the device specific + * parameters data for access by the host. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param refSpadCount Number of ref spads. + * @param is_aperture_spads Defines if spads are of type + * aperture or non-aperture. + * 1:=aperture, 0:=Non-Aperture + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_REF_SPAD_INIT Error in the in the reference + * spad configuration. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_reference_spads(VL53L0X_DEV dev, + uint32_t refSpadCount, uint8_t is_aperture_spads); + + /** + * @brief Retrieves SPAD configuration + * + * @par Function Description + * This function retrieves the current number of applied reference spads + * and also their type : Aperture or Non-Aperture. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_spad_count Number ref Spad Count + * @param p_is_aperture_spads Reports if spads are of type + * aperture or non-aperture. + * 1:=aperture, 0:=Non-Aperture + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_REF_SPAD_INIT Error in the in the reference + * spad configuration. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_reference_spads(VL53L0X_DEV dev, + uint32_t *p_spad_count, uint8_t *p_is_aperture_spads); + + /** + * @brief Get part to part calibration offset + * + * @par Function Description + * Should only be used after a successful call to @a VL53L0X_DataInit to backup + * device NVM value + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_offset_calibration_data_micro_meter Return part to part + * calibration offset from device (microns) + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV dev, + int32_t *p_offset_calibration_data_micro_meter); + /** + * Set or over-hide part to part calibration offset + * \sa VL53L0X_DataInit() VL53L0X_GetOffsetCalibrationDataMicroMeter() + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_offset_calibration_data_micro_meter Offset (microns) + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV dev, + int32_t offset_calibration_data_micro_meter); + + VL53L0X_Error VL53L0X_perform_offset_calibration(VL53L0X_DEV dev, + FixPoint1616_t cal_distance_milli_meter, + int32_t *p_offset_micro_meter); + + VL53L0X_Error VL53L0X_perform_xtalk_calibration(VL53L0X_DEV dev, + FixPoint1616_t xtalk_cal_distance, + FixPoint1616_t *p_xtalk_compensation_rate_mega_cps); + + /** + * @brief Perform XTalk Measurement + * + * @details Measures the current cross talk from glass in front + * of the sensor. + * This functions performs a histogram measurement and uses the results + * to measure the crosstalk. For the function to be successful, there + * must be no target in front of the sensor. + * + * @warning This function is a blocking function + * + * @warning This function is not supported when the final range + * vcsel clock period is set below 10 PCLKS. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param timeout_ms Histogram measurement duration. + * @param p_xtalk_per_spad Output parameter containing the crosstalk + * measurement result, in MCPS/Spad. + * Format fixpoint 16:16. + * @param p_ambient_too_high Output parameter which indicate that + * pXtalkPerSpad is not good if the Ambient + * is too high. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS vcsel clock period not supported + * for this operation. + * Must not be less than 10PCLKS. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_perform_xtalk_measurement(VL53L0X_DEV dev, + uint32_t timeout_ms, FixPoint1616_t *p_xtalk_per_spad, + uint8_t *p_ambient_too_high); + + /** + * @brief Enable/Disable Cross talk compensation feature + * + * @note This function is not Implemented. + * Enable/Disable Cross Talk by set to zero the Cross Talk value + * by using @a VL53L0X_SetXTalkCompensationRateMegaCps(). + * + * @param dev Device Handle + * @param x_talk_compensation_enable Cross talk compensation + * to be set 0=disabled else = enabled + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ + VL53L0X_Error VL53L0X_set_x_talk_compensation_enable(VL53L0X_DEV dev, + uint8_t x_talk_compensation_enable); + + /** + * @brief Get Cross talk compensation rate + * + * @note This function is not Implemented. + * Enable/Disable Cross Talk by set to zero the Cross Talk value by + * using @a VL53L0X_SetXTalkCompensationRateMegaCps(). + * + * @param dev Device Handle + * @param p_x_talk_compensation_enable Pointer to the Cross talk compensation + * state 0=disabled or 1 = enabled + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ + VL53L0X_Error VL53L0X_get_x_talk_compensation_enable(VL53L0X_DEV dev, + uint8_t *p_x_talk_compensation_enable); + /** + * @brief Set Cross talk compensation rate + * + * @par Function Description + * Set Cross talk compensation rate. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param x_talk_compensation_rate_mega_cps Compensation rate in + * Mega counts per second + * (16.16 fix point) see + * datasheet for details + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_x_talk_compensation_rate_mega_cps(VL53L0X_DEV dev, + FixPoint1616_t x_talk_compensation_rate_mega_cps); + + /** + * @brief Get Cross talk compensation rate + * + * @par Function Description + * Get Cross talk compensation rate. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_xtalk_compensation_rate_mega_cps Pointer to Compensation rate + * in Mega counts per second + * (16.16 fix point) see + * datasheet for details + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_x_talk_compensation_rate_mega_cps(VL53L0X_DEV dev, + FixPoint1616_t *p_xtalk_compensation_rate_mega_cps); + + /** + * @brief Set a new device mode + * @par Function Description + * Set device to a new mode (ranging, histogram ...) + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param device_mode New device mode to apply + * Valid values are: + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * VL53L0X_DEVICEMODE_CONTINUOUS_RANGING + * VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING + * VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM + * VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY + * VL53L0X_HISTOGRAMMODE_RETURN_ONLY + * VL53L0X_HISTOGRAMMODE_BOTH + * + * + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when + * DeviceMode is not in the + * supported list + */ + VL53L0X_Error VL53L0X_set_device_mode(VL53L0X_DEV dev, VL53L0X_DeviceModes device_mode); + + /** + * @brief Get current new device mode + * @par Function Description + * Get actual mode of the device(ranging, histogram ...) + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param p_device_mode Pointer to current apply mode value + * Valid values are: + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * VL53L0X_DEVICEMODE_CONTINUOUS_RANGING + * VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING + * VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM + * VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY + * VL53L0X_HISTOGRAMMODE_RETURN_ONLY + * VL53L0X_HISTOGRAMMODE_BOTH + * + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when + * DeviceMode is not in the + * supported list + */ + VL53L0X_Error VL53L0X_get_device_mode(VL53L0X_DEV dev, + VL53L0X_DeviceModes *p_device_mode); + + /** + * @brief Get current configuration for GPIO pin for a given device + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param pin ID of the GPIO Pin + * @param p_device_mode Pointer to Device Mode associated to the Gpio. + * @param p_functionality Pointer to Pin functionality. + * Refer to ::VL53L0X_GpioFunctionality + * @param p_polarity Pointer to interrupt polarity. + * Active high or active low see + * ::VL53L0X_InterruptPolarity + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_GPIO_NOT_EXISTING Only Pin=0 is accepted. + * @return VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED + * This error occurs + * when Funcionality programmed is not in the supported list: + * Supported value are: + * VL53L0X_GPIOFUNCTIONALITY_OFF, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT, + * VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_gpio_config(VL53L0X_DEV dev, uint8_t pin, + VL53L0X_DeviceModes *p_device_mode, + VL53L0X_GpioFunctionality *p_functionality, + VL53L0X_InterruptPolarity *p_polarity); + + /** + * @brief Set the configuration of GPIO pin for a given device + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param pin ID of the GPIO Pin + * @param functionality Select Pin functionality. + * Refer to ::VL53L0X_GpioFunctionality + * @param device_mode Device Mode associated to the Gpio. + * @param polarity Set interrupt polarity. Active high + * or active low see ::VL53L0X_InterruptPolarity + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_GPIO_NOT_EXISTING Only Pin=0 is accepted. + * @return VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED This error occurs + * when Functionality programmed is not in the supported list: + * Supported value are: + * VL53L0X_GPIOFUNCTIONALITY_OFF, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH, + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT, + * VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_gpio_config(VL53L0X_DEV dev, uint8_t pin, + VL53L0X_DeviceModes device_mode, VL53L0X_GpioFunctionality functionality, + VL53L0X_InterruptPolarity polarity); + + /** + * @brief Start device measurement + * + * @details Started measurement will depend on device parameters set through + * @a VL53L0X_SetParameters() + * This is a non-blocking function. + * This function will change the VL53L0X_State from VL53L0X_STATE_IDLE to + * VL53L0X_STATE_RUNNING. + * + * @note This function Access to the device + * + + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when + * DeviceMode programmed with @a VL53L0X_SetDeviceMode is not in the supported + * list: + * Supported mode are: + * VL53L0X_DEVICEMODE_SINGLE_RANGING, + * VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, + * VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING + * @return VL53L0X_ERROR_TIME_OUT Time out on start measurement + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_start_measurement(VL53L0X_DEV dev); + + /** + * @brief Stop device measurement + * + * @details Will set the device in standby mode at end of current measurement\n + * Not necessary in single mode as device shall return automatically + * in standby mode at end of measurement. + * This function will change the VL53L0X_State from VL53L0X_STATE_RUNNING + * to VL53L0X_STATE_IDLE. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_stop_measurement(VL53L0X_DEV dev); + + /** + * @brief Return device stop completion status + * + * @par Function Description + * Returns stop completiob status. + * User shall call this function after a stop command + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_stop_status Pointer to status variable to update + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_stop_completed_status(VL53L0X_DEV dev, + uint32_t *p_stop_status); + + /** + * @brief Return Measurement Data Ready + * + * @par Function Description + * This function indicate that a measurement data is ready. + * This function check if interrupt mode is used then check is done accordingly. + * If perform function clear the interrupt, this function will not work, + * like in case of @a VL53L0X_PerformSingleRangingMeasurement(). + * The previous function is blocking function, VL53L0X_GetMeasurementDataReady + * is used for non-blocking capture. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_measurement_data_ready Pointer to Measurement Data Ready. + * 0=data not ready, 1 = data ready + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_measurement_data_ready(VL53L0X_DEV dev, + uint8_t *p_measurement_data_ready); + + /** + * @brief Retrieve the measurements from device for a given setup + * + * @par Function Description + * Get data from last successful Ranging measurement + * @warning USER should take care about @a VL53L0X_GetNumberOfROIZones() + * before get data. + * PAL will fill a NumberOfROIZones times the corresponding data + * structure used in the measurement function. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_ranging_measurement_data Pointer to the data structure to fill up. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_ranging_measurement_data(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data); + + /** + * @brief Clear given system interrupt condition + * + * @par Function Description + * Clear given interrupt(s). + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param interrupt_mask Mask of interrupts to clear + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INTERRUPT_NOT_CLEARED Cannot clear interrupts + * + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_clear_interrupt_mask(VL53L0X_DEV dev, uint32_t interrupt_mask); + + /** + * @brief Return device interrupt status + * + * @par Function Description + * Returns currently raised interrupts by the device. + * User shall be able to activate/deactivate interrupts through + * @a VL53L0X_SetGpioConfig() + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_interrupt_mask_status Pointer to status variable to update + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_interrupt_mask_status(VL53L0X_DEV dev, + uint32_t *p_interrupt_mask_status); + + /** + * @brief Performs a single ranging measurement and retrieve the ranging + * measurement data + * + * @par Function Description + * This function will change the device mode to VL53L0X_DEVICEMODE_SINGLE_RANGING + * with @a VL53L0X_SetDeviceMode(), + * It performs measurement with @a VL53L0X_PerformSingleMeasurement() + * It get data from last successful Ranging measurement with + * @a VL53L0X_GetRangingMeasurementData. + * Finally it clear the interrupt with @a VL53L0X_ClearInterruptMask(). + * + * @note This function Access to the device + * + * @note This function change the device mode to + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * + * @param dev Device Handle + * @param p_ranging_measurement_data Pointer to the data structure to fill up. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_perform_single_ranging_measurement(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data); + + /** + * @brief Single shot measurement. + * + * @par Function Description + * Perform simple measurement sequence (Start measure, Wait measure to end, + * and returns when measurement is done). + * Once function returns, user can get valid data by calling + * VL53L0X_GetRangingMeasurement or VL53L0X_GetHistogramMeasurement + * depending on defined measurement mode + * User should Clear the interrupt in case this are enabled by using the + * function VL53L0X_ClearInterruptMask(). + * + * @warning This function is a blocking function + * + * @note This function Access to the device + * + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_perform_single_measurement(VL53L0X_DEV dev); + + /** + * @brief Read current status of the error register for the selected device + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_device_error_status Pointer to current error code of the device + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_device_error_status(VL53L0X_DEV dev, + VL53L0X_DeviceError *p_device_error_status); + + /** + * @brief Human readable error string for a given Error Code + * + * @note This function doesn't access to the device + * + * @param error_code The error code as stored on ::VL53L0X_DeviceError + * @param p_device_error_string The error string corresponding to the ErrorCode + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_device_error_string( + VL53L0X_DeviceError error_code, char *p_device_error_string); + + /** + * @brief Human readable Range Status string for a given RangeStatus + * + * @note This function doesn't access to the device + * + * @param range_status The RangeStatus code as stored on + * @a VL53L0X_RangingMeasurementData_t + * @param p_range_status_string The returned RangeStatus string. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_range_status_string(uint8_t range_status, + char *p_range_status_string); + + VL53L0X_Error VL53L0X_get_total_signal_rate(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data, + FixPoint1616_t *p_total_signal_rate_mcps); + + VL53L0X_Error VL53L0X_get_total_xtalk_rate(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data, + FixPoint1616_t *p_total_xtalk_rate_mcps); + + /** + * @brief Get Ranging Timing Budget in microseconds + * + * @par Function Description + * Returns the programmed the maximum time allowed by the user to the + * device to run a full ranging sequence for the current mode + * (ranging, histogram, ASL ...) + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_measurement_timing_budget_micro_seconds Max measurement time in + * microseconds. + * Valid values are: + * >= 17000 microsecs when wraparound enabled + * >= 12000 microsecs when wraparound disabled + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev, + uint32_t *p_measurement_timing_budget_micro_seconds); + + /** + * @brief Set Ranging Timing Budget in microseconds + * + * @par Function Description + * Defines the maximum time allowed by the user to the device to run a + * full ranging sequence for the current mode (ranging, histogram, ASL ...) + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param measurement_timing_budget_micro_seconds Max measurement time in + * microseconds. + * Valid values are: + * >= 17000 microsecs when wraparound enabled + * >= 12000 microsecs when wraparound disabled + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned if + MeasurementTimingBudgetMicroSeconds out of range + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev, + uint32_t measurement_timing_budget_micro_seconds); + + /** + * @brief Get specific limit check enable state + * + * @par Function Description + * This function get the enable state of a specific limit check. + * The limit check is identified with the LimitCheckId. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param limit_check_id Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param p_limit_check_enable Pointer to the check limit enable + * value. + * if 1 the check limit + * corresponding to LimitCheckId is Enabled + * if 0 the check limit + * corresponding to LimitCheckId is disabled + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned + * when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_limit_check_enable(VL53L0X_DEV dev, uint16_t limit_check_id, + uint8_t *p_limit_check_enable); + + /** + * @brief Enable/Disable a specific limit check + * + * @par Function Description + * This function Enable/Disable a specific limit check. + * The limit check is identified with the LimitCheckId. + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param limit_check_id Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param limit_check_enable if 1 the check limit + * corresponding to LimitCheckId is Enabled + * if 0 the check limit + * corresponding to LimitCheckId is disabled + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned + * when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_limit_check_enable(VL53L0X_DEV dev, uint16_t limit_check_id, + uint8_t limit_check_enable); + + /** + * @brief Get a specific limit check value + * + * @par Function Description + * This function get a specific limit check value from device then it updates + * internal values and check enables. + * The limit check is identified with the LimitCheckId. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param limit_check_id Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param p_limit_check_value Pointer to Limit + * check Value for a given LimitCheckId. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned + * when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_limit_check_value(VL53L0X_DEV dev, uint16_t limit_check_id, + FixPoint1616_t *p_limit_check_value); + + /** + * @brief Set a specific limit check value + * + * @par Function Description + * This function set a specific limit check value. + * The limit check is identified with the LimitCheckId. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param limit_check_id Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param limit_check_value Limit check Value for a given + * LimitCheckId + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned when either + * LimitCheckId or LimitCheckValue value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_limit_check_value(VL53L0X_DEV dev, uint16_t limit_check_id, + FixPoint1616_t limit_check_value); + + /** + * @brief Get the current value of the signal used for the limit check + * + * @par Function Description + * This function get a the current value of the signal used for the limit check. + * To obtain the latest value you should run a ranging before. + * The value reported is linked to the limit check identified with the + * LimitCheckId. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param limit_check_id Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param p_limit_check_current Pointer to current Value for a + * given LimitCheckId. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned when + * LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_limit_check_current(VL53L0X_DEV dev, uint16_t limit_check_id, + FixPoint1616_t *p_limit_check_current); + + /** + * @brief Return a the Status of the specified check limit + * + * @par Function Description + * This function returns the Status of the specified check limit. + * The value indicate if the check is fail or not. + * The limit check is identified with the LimitCheckId. + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param limit_check_id Limit Check ID + (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param p_limit_check_status Pointer to the + Limit Check Status of the given check limit. + * LimitCheckStatus : + * 0 the check is not fail + * 1 the check if fail or not enabled + * + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is + returned when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_limit_check_status(VL53L0X_DEV dev, + uint16_t limit_check_id, uint8_t *p_limit_check_status); + + /** + * Get continuous mode Inter-Measurement period in milliseconds + * + * @par Function Description + * When trying to set too short time return INVALID_PARAMS minimal value + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_inter_measurement_period_milli_seconds Pointer to programmed + * Inter-Measurement Period in milliseconds. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_inter_measurement_period_milli_seconds(VL53L0X_DEV dev, + uint32_t *p_inter_measurement_period_milli_seconds); + + /** + * Program continuous mode Inter-Measurement period in milliseconds + * + * @par Function Description + * When trying to set too short time return INVALID_PARAMS minimal value + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param inter_measurement_period_milli_seconds Inter-Measurement Period in ms. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_inter_measurement_period_milli_seconds( + VL53L0X_DEV dev, uint32_t inter_measurement_period_milli_seconds); + + /** + * @brief Set new device address + * + * After completion the device will answer to the new address programmed. + * This function should be called when several devices are used in parallel + * before start programming the sensor. + * When a single device us used, there is no need to call this function. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param device_address The new Device address + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_device_address(VL53L0X_DEV dev, uint8_t device_address); + + /** + * @brief Do an hard reset or soft reset (depending on implementation) of the + * device \nAfter call of this function, device must be in same state as right + * after a power-up sequence.This function will change the VL53L0X_State to + * VL53L0X_STATE_POWERDOWN. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_reset_device(VL53L0X_DEV dev); + + /** + * @brief Get setup of Wrap around Check + * + * @par Function Description + * This function get the wrapAround check enable parameters + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_wrap_around_check_enable Pointer to the Wrap around Check state + * 0=disabled or 1 = enabled + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_wrap_around_check_enable(VL53L0X_DEV dev, + uint8_t *p_wrap_around_check_enable); + + /** + * @brief Enable (or disable) Wrap around Check + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param wrap_around_check_enable Wrap around Check to be set + * 0=disabled, other = enabled + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_wrap_around_check_enable(VL53L0X_DEV dev, + uint8_t wrap_around_check_enable); + + /** + * @brief Gets the VCSEL pulse period. + * + * @par Function Description + * This function retrieves the VCSEL pulse period for the given period type. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param vcsel_period_type VCSEL period identifier (pre-range|final). + * @param p_vcsel_pulse_period_pclk Pointer to VCSEL period value. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error VcselPeriodType parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV dev, + VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk); + + /** + * @brief Sets the VCSEL pulse period. + * + * @par Function Description + * This function retrieves the VCSEL pulse period for the given period type. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param vcsel_period_type VCSEL period identifier (pre-range|final). + * @param vcsel_pulse_period VCSEL period value + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error VcselPeriodType parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV dev, + VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period); + + /** + * @brief Set low and high Interrupt thresholds for a given mode + * (ranging, ALS, ...) for a given device + * + * @par Function Description + * Set low and high Interrupt thresholds for a given mode (ranging, ALS, ...) + * for a given device + * + * @note This function Access to the device + * + * @note DeviceMode is ignored for the current device + * + * @param dev Device Handle + * @param device_mode Device Mode for which change thresholds + * @param threshold_low Low threshold (mm, lux ..., depending on the mode) + * @param threshold_high High threshold (mm, lux ..., depending on the mode) + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_interrupt_thresholds(VL53L0X_DEV dev, + VL53L0X_DeviceModes device_mode, FixPoint1616_t threshold_low, + FixPoint1616_t threshold_high); + + /** + * @brief Get high and low Interrupt thresholds for a given mode + * (ranging, ALS, ...) for a given device + * + * @par Function Description + * Get high and low Interrupt thresholds for a given mode (ranging, ALS, ...) + * for a given device + * + * @note This function Access to the device + * + * @note DeviceMode is ignored for the current device + * + * @param dev Device Handle + * @param device_mode Device Mode from which read thresholds + * @param p_threshold_low Low threshold (mm, lux ..., depending on the mode) + * @param p_threshold_high High threshold (mm, lux ..., depending on the mode) + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_interrupt_thresholds(VL53L0X_DEV dev, + VL53L0X_DeviceModes device_mode, FixPoint1616_t *p_threshold_low, + FixPoint1616_t *p_threshold_high); + + /** + * @brief Reads the Device information for given Device + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_VL53L0X_device_info Pointer to current device info for a given + * Device + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_device_info(VL53L0X_DEV dev, + VL53L0X_DeviceInfo_t *p_VL53L0X_device_info); + + /** + * @brief Gets the (on/off) state of all sequence steps. + * + * @par Function Description + * This function retrieves the state of all sequence step in the scheduler. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param p_scheduler_sequence_steps Pointer to struct containing result. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_sequence_step_enables(VL53L0X_DEV dev, + VL53L0X_SchedulerSequenceSteps_t *p_scheduler_sequence_steps); + + /** + * @brief Sets the (on/off) state of a requested sequence step. + * + * @par Function Description + * This function enables/disables a requested sequence step. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param sequence_step_id Sequence step identifier. + * @param sequence_step_enabled Demanded state {0=Off,1=On} + * is enabled. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error SequenceStepId parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_sequence_step_enable(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_step_enabled); + + /** + * @brief Gets the fraction enable parameter indicating the resolution of + * range measurements. + * + * @par Function Description + * Gets the fraction enable state, which translates to the resolution of + * range measurements as follows :Enabled:=0.25mm resolution, + * Not Enabled:=1mm resolution. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param p_enabled Output Parameter reporting the fraction enable state. + * + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_fraction_enable(VL53L0X_DEV dev, uint8_t *p_enabled); + + /** + * @brief Sets the resolution of range measurements. + * @par Function Description + * Set resolution of range measurements to either 0.25mm if + * fraction enabled or 1mm if not enabled. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param enable Enable high resolution + * + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_range_fraction_enable(VL53L0X_DEV dev, + uint8_t enable); + + /** + * @brief Return the VL53L0X PAL Implementation Version + * + * @note This function doesn't access to the device + * + * @param p_version Pointer to current PAL Implementation Version + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_version(VL53L0X_Version_t *p_version); + + /** + * @brief Reads the Product Revision for a for given Device + * This function can be used to distinguish cut1.0 from cut1.1. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_product_revision_major Pointer to Product Revision Major + * for a given Device + * @param p_product_revision_minor Pointer to Product Revision Minor + * for a given Device + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_product_revision(VL53L0X_DEV dev, + uint8_t *p_product_revision_major, uint8_t *p_product_revision_minor); + + /** + * @brief Retrieve current device parameters + * @par Function Description + * Get actual parameters of the device + * @li Then start ranging operation. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_device_parameters Pointer to store current device parameters. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_device_parameters(VL53L0X_DEV dev, + VL53L0X_DeviceParameters_t *p_device_parameters); + + /** + * @brief Human readable error string for current PAL error status + * + * @note This function doesn't access to the device + * + * @param pal_error_code The error code as stored on @a VL53L0X_Error + * @param p_pal_error_string The error string corresponding to the + * PalErrorCode + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_pal_error_string(VL53L0X_Error pal_error_code, + char *p_pal_error_string); + + /** + * @brief Return the PAL Specification Version used for the current + * implementation. + * + * @note This function doesn't access to the device + * + * @param p_pal_spec_version Pointer to current PAL Specification Version + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_pal_spec_version( + VL53L0X_Version_t *p_pal_spec_version); + + /** + * @brief Reads the internal state of the PAL for a given Device + * + * @note This function doesn't access to the device + * + * @param dev Device Handle + * @param p_pal_state Pointer to current state of the PAL for a + * given Device + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_pal_state(VL53L0X_DEV dev, + VL53L0X_State *p_pal_state); + + /** + * @brief Human readable PAL State string + * + * @note This function doesn't access to the device + * + * @param pal_state_code The State code as stored on @a VL53L0X_State + * @param p_pal_state_string The State string corresponding to the + * PalStateCode + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_pal_state_string(VL53L0X_State pal_state_code, + char *p_pal_state_string); + + /*** End High level API ***/ +private: + /* api.h functions */ + + /** + * @brief Wait for device booted after chip enable (hardware standby) + * This function can be run only when VL53L0X_State is VL53L0X_STATE_POWERDOWN. + * + * @note This function is not Implemented + * + * @param dev Device Handle + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + * + */ + VL53L0X_Error VL53L0X_wait_device_booted(VL53L0X_DEV dev); + + + VL53L0X_Error sequence_step_enabled(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_config, + uint8_t *p_sequence_step_enabled); + + VL53L0X_Error VL53L0X_check_and_load_interrupt_settings(VL53L0X_DEV dev, + uint8_t start_not_stopflag); + + + /* api_core.h functions */ + + VL53L0X_Error VL53L0X_get_info_from_device(VL53L0X_DEV dev, uint8_t option); + + VL53L0X_Error VL53L0X_device_read_strobe(VL53L0X_DEV dev); + + VL53L0X_Error wrapped_VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev, + uint32_t *p_measurement_timing_budget_micro_seconds); + + VL53L0X_Error wrapped_VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV dev, + VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk); + + uint8_t VL53L0X_decode_vcsel_period(uint8_t vcsel_period_reg); + + uint32_t VL53L0X_decode_timeout(uint16_t encoded_timeout); + + uint32_t VL53L0X_calc_timeout_us(VL53L0X_DEV dev, + uint16_t timeout_period_mclks, + uint8_t vcsel_period_pclks); + + uint32_t VL53L0X_calc_macro_period_ps(VL53L0X_DEV dev, uint8_t vcsel_period_pclks); + + VL53L0X_Error VL53L0X_measurement_poll_for_completion(VL53L0X_DEV dev); + + VL53L0X_Error VL53L0X_load_tuning_settings(VL53L0X_DEV dev, + uint8_t *p_tuning_setting_buffer); + + VL53L0X_Error VL53L0X_get_pal_range_status(VL53L0X_DEV dev, + uint8_t device_range_status, + FixPoint1616_t signal_rate, + uint16_t effective_spad_rtn_count, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data, + uint8_t *p_pal_range_status); + VL53L0X_Error VL53L0X_calc_sigma_estimate(VL53L0X_DEV dev, + VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data, + FixPoint1616_t *p_sigma_estimate, + uint32_t *p_dmax_mm); + uint32_t VL53L0X_calc_timeout_mclks(VL53L0X_DEV dev, + uint32_t timeout_period_us, + uint8_t vcsel_period_pclks); + uint32_t VL53L0X_isqrt(uint32_t num); + + uint32_t VL53L0X_quadrature_sum(uint32_t a, uint32_t b); + + VL53L0X_Error VL53L0X_calc_dmax( + VL53L0X_DEV dev, + FixPoint1616_t total_signal_rate_mcps, + FixPoint1616_t total_corr_signal_rate_mcps, + FixPoint1616_t pw_mult, + uint32_t sigma_estimate_p1, + FixPoint1616_t sigma_estimate_p2, + uint32_t peak_vcsel_duration_us, + uint32_t *pd_max_mm); + VL53L0X_Error wrapped_VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV dev, + uint32_t measurement_timing_budget_micro_seconds); + VL53L0X_Error get_sequence_step_timeout(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, + uint32_t *p_time_out_micro_secs); + VL53L0X_Error set_sequence_step_timeout(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, + uint32_t timeout_micro_secs); + uint16_t VL53L0X_encode_timeout(uint32_t timeout_macro_clks); + VL53L0X_Error wrapped_VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV dev, + VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period_pclk); + uint8_t lv53l0x_encode_vcsel_period(uint8_t vcsel_period_pclks); + + /* api_calibration.h functions */ + VL53L0X_Error VL53L0X_apply_offset_adjustment(VL53L0X_DEV dev); + VL53L0X_Error wrapped_VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV dev, + int32_t *p_offset_calibration_data_micro_meter); + VL53L0X_Error wrapped_VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV dev, + int32_t offset_calibration_data_micro_meter); + VL53L0X_Error wrapped_VL53L0X_perform_ref_spad_management(VL53L0X_DEV dev, + uint32_t *ref_spad_count, + uint8_t *is_aperture_spads); + VL53L0X_Error VL53L0X_perform_ref_calibration(VL53L0X_DEV dev, + uint8_t *p_vhv_settings, uint8_t *p_phase_cal, uint8_t get_data_enable); + VL53L0X_Error VL53L0X_perform_vhv_calibration(VL53L0X_DEV dev, + uint8_t *p_vhv_settings, const uint8_t get_data_enable, + const uint8_t restore_config); + VL53L0X_Error VL53L0X_perform_single_ref_calibration(VL53L0X_DEV dev, + uint8_t vhv_init_byte); + VL53L0X_Error VL53L0X_ref_calibration_io(VL53L0X_DEV dev, uint8_t read_not_write, + uint8_t vhv_settings, uint8_t phase_cal, + uint8_t *p_vhv_settings, uint8_t *p_phase_cal, + const uint8_t vhv_enable, const uint8_t phase_enable); + VL53L0X_Error VL53L0X_perform_phase_calibration(VL53L0X_DEV dev, + uint8_t *p_phase_cal, const uint8_t get_data_enable, + const uint8_t restore_config); + VL53L0X_Error enable_ref_spads(VL53L0X_DEV dev, + uint8_t aperture_spads, + uint8_t good_spad_array[], + uint8_t spad_array[], + uint32_t size, + uint32_t start, + uint32_t offset, + uint32_t spad_count, + uint32_t *p_last_spad); + void get_next_good_spad(uint8_t good_spad_array[], uint32_t size, + uint32_t curr, int32_t *p_next); + uint8_t is_aperture(uint32_t spad_index); + VL53L0X_Error enable_spad_bit(uint8_t spad_array[], uint32_t size, + uint32_t spad_index); + VL53L0X_Error set_ref_spad_map(VL53L0X_DEV dev, uint8_t *p_ref_spad_array); + VL53L0X_Error get_ref_spad_map(VL53L0X_DEV dev, uint8_t *p_ref_spad_array); + VL53L0X_Error perform_ref_signal_measurement(VL53L0X_DEV dev, + uint16_t *p_ref_signal_rate); + VL53L0X_Error wrapped_VL53L0X_set_reference_spads(VL53L0X_DEV dev, + uint32_t count, uint8_t is_aperture_spads); + + /* api_strings.h functions */ + VL53L0X_Error wrapped_VL53L0X_get_device_info(VL53L0X_DEV dev, + VL53L0X_DeviceInfo_t *p_VL53L0X_device_info); + VL53L0X_Error VL53L0X_check_part_used(VL53L0X_DEV dev, + uint8_t *revision, + VL53L0X_DeviceInfo_t *p_VL53L0X_device_info); + + /* Read function of the ID device */ + // virtual int read_id(); + virtual int read_id(uint8_t *id); + + VL53L0X_Error wait_measurement_data_ready(VL53L0X_DEV dev); + + VL53L0X_Error wait_stop_completed(VL53L0X_DEV dev); + + /* Write and read functions from I2C */ + /** + * Write single byte register + * @param dev Device Handle + * @param index The register index + * @param data 8 bit register data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_write_byte(VL53L0X_DEV dev, uint8_t index, uint8_t data); + /** + * Write word register + * @param dev Device Handle + * @param index The register index + * @param data 16 bit register data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_write_word(VL53L0X_DEV dev, uint8_t index, uint16_t data); + /** + * Write double word (4 byte) register + * @param dev Device Handle + * @param index The register index + * @param data 32 bit register data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_write_dword(VL53L0X_DEV dev, uint8_t index, uint32_t data); + /** + * Read single byte register + * @param dev Device Handle + * @param index The register index + * @param data pointer to 8 bit data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_read_byte(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data); + /** + * Read word (2byte) register + * @param dev Device Handle + * @param index The register index + * @param data pointer to 16 bit data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_read_word(VL53L0X_DEV dev, uint8_t index, uint16_t *p_data); + /** + * Read dword (4byte) register + * @param dev Device Handle + * @param index The register index + * @param data pointer to 32 bit data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_read_dword(VL53L0X_DEV dev, uint8_t index, uint32_t *p_data); + /** + * Threat safe Update (read/modify/write) single byte register + * + * Final_reg = (Initial_reg & and_data) |or_data + * + * @param dev Device Handle + * @param index The register index + * @param and_data 8 bit and data + * @param or_data 8 bit or data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_update_byte(VL53L0X_DEV dev, uint8_t index, uint8_t and_data, uint8_t or_data); + /** + * Writes the supplied byte buffer to the device + * @param dev Device Handle + * @param index The register index + * @param p_data Pointer to uint8_t buffer containing the data to be written + * @param count Number of bytes in the supplied byte buffer + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_write_multi(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data, uint32_t count); + /** + * Reads the requested number of bytes from the device + * @param dev Device Handle + * @param index The register index + * @param p_data Pointer to the uint8_t buffer to store read data + * @param count Number of uint8_t's to read + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_read_multi(VL53L0X_DEV dev, uint8_t index, uint8_t *p_data, uint32_t count); + + /** + * @brief Writes a buffer towards the I2C peripheral device. + * @param dev Device Handle + * @param p_data pointer to the byte-array data to send + * @param number_of_bytes number of bytes to be written. + * @retval 0 if ok, + * @retval -1 if an I2C error has occured + * @note On some devices if NumByteToWrite is greater + * than one, the RegisterAddr must be masked correctly! + */ + VL53L0X_Error VL53L0X_i2c_write(uint8_t dev, uint8_t index, uint8_t *p_data, uint16_t number_of_bytes); + + /** + * @brief Reads a buffer from the I2C peripheral device. + * @param dev Device Handle + * @param p_data pointer to the byte-array to read data in to + * @param number_of_bytes number of bytes to be read. + * @retval 0 if ok, + * @retval -1 if an I2C error has occured + * @note On some devices if NumByteToWrite is greater + * than one, the RegisterAddr must be masked correctly! + */ + VL53L0X_Error VL53L0X_i2c_read(uint8_t dev, uint8_t index, uint8_t *p_data, uint16_t number_of_bytes); + + /** + * @brief execute delay in all polling API call + * + * A typical multi-thread or RTOs implementation is to sleep the task for some 5ms (with 100Hz max rate faster polling is not needed) + * if nothing specific is need you can define it as an empty/void macro + * @code + * #define VL53L0X_PollingDelay(...) (void)0 + * @endcode + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_polling_delay(VL53L0X_DEV dev); /* usually best implemented as a real function */ + + int is_present() + { + int status; + uint8_t id = 0; + + status = read_id(&id); + if (status) { + VL53L0X_ErrLog("Failed to read ID device. Device not present!\n\r"); + } + return status; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////// + //Added functions // + /////////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * @brief Cycle Power to Device + * + * @return status - status 0 = ok, 1 = error + * + */ + int32_t VL53L0X_cycle_power(void); + + uint8_t VL53L0X_encode_vcsel_period(uint8_t vcsel_period_pclks); + + VL53L0X_Error wrapped_VL53L0X_get_device_error_string(VL53L0X_DeviceError error_code, + char *p_device_error_string); + + VL53L0X_Error wrapped_VL53L0X_get_limit_check_info(VL53L0X_DEV dev, uint16_t limit_check_id, + char *p_limit_check_string); + + VL53L0X_Error wrapped_VL53L0X_get_pal_error_string(VL53L0X_Error pal_error_code, + char *p_pal_error_string); + + VL53L0X_Error wrapped_VL53L0X_get_pal_state_string(VL53L0X_State pal_state_code, + char *p_pal_state_string); + + VL53L0X_Error wrapped_VL53L0X_get_range_status_string(uint8_t range_status, + char *p_range_status_string); + + VL53L0X_Error wrapped_VL53L0X_get_ref_calibration(VL53L0X_DEV dev, + uint8_t *p_vhv_settings, uint8_t *p_phase_cal); + + + VL53L0X_Error count_enabled_spads(uint8_t spad_array[], + uint32_t byte_count, uint32_t max_spads, + uint32_t *p_total_spads_enabled, uint8_t *p_is_aperture); + + VL53L0X_Error wrapped_VL53L0X_get_sequence_steps_info(VL53L0X_SequenceStepId sequence_step_id, + char *p_sequence_steps_string); + + + /** + * @brief Gets the name of a given sequence step. + * + * @par Function Description + * This function retrieves the name of sequence steps corresponding to + * SequenceStepId. + * + * @note This function doesn't Accesses the device + * + * @param sequence_step_id Sequence step identifier. + * @param p_sequence_steps_string Pointer to Info string + * + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_sequence_steps_info(VL53L0X_SequenceStepId sequence_step_id, + char *p_sequence_steps_string); + + /** + * @brief Get the frequency of the timer used for ranging results time stamps + * + * @param[out] p_timer_freq_hz : pointer for timer frequency + * + * @return status : 0 = ok, 1 = error + * + */ + int32_t VL53L0X_get_timer_frequency(int32_t *p_timer_freq_hz); + + /** + * @brief Get the timer value in units of timer_freq_hz (see VL53L0X_get_timestamp_frequency()) + * + * @param[out] p_timer_count : pointer for timer count value + * + * @return status : 0 = ok, 1 = error + * + */ + int32_t VL53L0X_get_timer_value(int32_t *p_timer_count); + + /** + * @brief Configure ranging interrupt reported to system + * + * @note This function is not Implemented + * + * @param dev Device Handle + * @param interrupt_mask Mask of interrupt to Enable/disable + * (0:interrupt disabled or 1: interrupt enabled) + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ + VL53L0X_Error VL53L0X_enable_interrupt_mask(VL53L0X_DEV dev, + uint32_t interrupt_mask); + + /** + * @brief Get Dmax Calibration Parameters for a given device + * + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_range_milli_meter Pointer to Calibration Distance + * @param p_signal_rate_rtn_mega_cps Pointer to Signal rate return + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_dmax_cal_parameters(VL53L0X_DEV dev, + uint16_t *p_range_milli_meter, FixPoint1616_t *p_signal_rate_rtn_mega_cps); + + /** + * @brief Set Dmax Calibration Parameters for a given device + * When one of the parameter is zero, this function will get parameter + * from NVM. + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param range_milli_meter Calibration Distance + * @param signal_rate_rtn_mega_cps Signal rate return read at CalDistance + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_dmax_cal_parameters(VL53L0X_DEV dev, + uint16_t range_milli_meter, FixPoint1616_t signal_rate_rtn_mega_cps); + + /** + * @brief Retrieve the measurements from device for a given setup + * + * @par Function Description + * Get data from last successful Histogram measurement + * @warning USER should take care about @a VL53L0X_GetNumberOfROIZones() + * before get data. + * PAL will fill a NumberOfROIZones times the corresponding data structure + * used in the measurement function. + * + * @note This function is not Implemented + * + * @param dev Device Handle + * @param p_histogram_measurement_data Pointer to the histogram data structure. + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ + VL53L0X_Error VL53L0X_get_histogram_measurement_data(VL53L0X_DEV dev, + VL53L0X_HistogramMeasurementData_t *p_histogram_measurement_data); + + /** + * @brief Get current new device mode + * @par Function Description + * Get current Histogram mode of a Device + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param p_histogram_mode Pointer to current Histogram Mode value + * Valid values are: + * VL53L0X_HISTOGRAMMODE_DISABLED + * VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM + * VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY + * VL53L0X_HISTOGRAMMODE_RETURN_ONLY + * VL53L0X_HISTOGRAMMODE_BOTH + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_histogram_mode(VL53L0X_DEV dev, + VL53L0X_HistogramModes *p_histogram_mode); + + /** + * @brief Set a new Histogram mode + * @par Function Description + * Set device to a new Histogram mode + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param histogram_mode New device mode to apply + * Valid values are: + * VL53L0X_HISTOGRAMMODE_DISABLED + * VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM + * VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY + * VL53L0X_HISTOGRAMMODE_RETURN_ONLY + * VL53L0X_HISTOGRAMMODE_BOTH + * + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when + * HistogramMode is not in the supported list + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_histogram_mode(VL53L0X_DEV dev, + VL53L0X_HistogramModes histogram_mode); + + /** + * @brief Return a description string for a given limit check number + * + * @par Function Description + * This function returns a description string for a given limit check number. + * The limit check is identified with the LimitCheckId. + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param limit_check_id Limit Check ID + (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param p_limit_check_string Pointer to the + description string of the given check limit. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is + returned when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_limit_check_info(VL53L0X_DEV dev, + uint16_t limit_check_id, char *p_limit_check_string); + + /** + * @brief Get the linearity corrective gain + * + * @par Function Description + * Should only be used after a successful call to @a VL53L0X_DataInit to backup + * device NVM value + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_linearity_corrective_gain Pointer to the linearity + * corrective gain in x1000 + * if value is 1000 then no modification is applied. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_linearity_corrective_gain(VL53L0X_DEV dev, + uint16_t *p_linearity_corrective_gain); + + /** + * Set the linearity corrective gain + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param linearity_corrective_gain Linearity corrective + * gain in x1000 + * if value is 1000 then no modification is applied. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_linearity_corrective_gain(VL53L0X_DEV dev, + int16_t linearity_corrective_gain); + + /** + * @brief Get the Maximum number of ROI Zones managed by the Device + * + * @par Function Description + * Get Maximum number of ROI Zones managed by the Device. + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param p_max_number_of_roi_zones Pointer to the Maximum Number + * of ROI Zones value. + * @return VL53L0X_ERROR_NONE Success + */ + VL53L0X_Error VL53L0X_get_max_number_of_roi_zones(VL53L0X_DEV dev, + uint8_t *p_max_number_of_roi_zones); + + /** + * @brief Retrieve the Reference Signal after a measurements + * + * @par Function Description + * Get Reference Signal from last successful Ranging measurement + * This function return a valid value after that you call the + * @a VL53L0X_GetRangingMeasurementData(). + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_measurement_ref_signal Pointer to the Ref Signal to fill up. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_measurement_ref_signal(VL53L0X_DEV dev, + FixPoint1616_t *p_measurement_ref_signal); + + /** + * @brief Get the number of the check limit managed by a given Device + * + * @par Function Description + * This function give the number of the check limit managed by the Device + * + * @note This function doesn't Access to the device + * + * @param p_number_of_limit_check Pointer to the number of check limit. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_number_of_limit_check( + uint16_t *p_number_of_limit_check); + + /** + * @brief Get the number of ROI Zones managed by the Device + * + * @par Function Description + * Get number of ROI Zones managed by the Device + * USER should take care about @a VL53L0X_GetNumberOfROIZones() + * before get data after a perform measurement. + * PAL will fill a NumberOfROIZones times the corresponding data + * structure used in the measurement function. + * + * @note This function doesn't Access to the device + * + * @param dev Device Handle + * @param p_number_of_roi_zones Pointer to the Number of ROI Zones value. + * @return VL53L0X_ERROR_NONE Success + */ + VL53L0X_Error VL53L0X_get_number_of_roi_zones(VL53L0X_DEV dev, + uint8_t *p_number_of_roi_zones); + + /** + * @brief Set the number of ROI Zones to be used for a specific Device + * + * @par Function Description + * Set the number of ROI Zones to be used for a specific Device. + * The programmed value should be less than the max number of ROI Zones given + * with @a VL53L0X_GetMaxNumberOfROIZones(). + * This version of API manage only one zone. + * + * @param dev Device Handle + * @param number_of_roi_zones Number of ROI Zones to be used for a + * specific Device. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned if + * NumberOfROIZones != 1 + */ + VL53L0X_Error VL53L0X_set_number_of_roi_zones(VL53L0X_DEV dev, + uint8_t number_of_roi_zones); + + /** + * @brief Gets number of sequence steps managed by the API. + * + * @par Function Description + * This function retrieves the number of sequence steps currently managed + * by the API + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param p_number_of_sequence_steps Out parameter reporting the number of + * sequence steps. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_number_of_sequence_steps(VL53L0X_DEV dev, + uint8_t *p_number_of_sequence_steps); + /** + * @brief Get the power mode for a given Device + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_power_mode Pointer to the current value of the power + * mode. see ::VL53L0X_PowerModes + * Valid values are: + * VL53L0X_POWERMODE_STANDBY_LEVEL1, + * VL53L0X_POWERMODE_IDLE_LEVEL1 + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_power_mode(VL53L0X_DEV dev, + VL53L0X_PowerModes *p_power_mode); + + /** + * @brief Set the power mode for a given Device + * The power mode can be Standby or Idle. Different level of both Standby and + * Idle can exists. + * This function should not be used when device is in Ranging state. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param power_mode The value of the power mode to set. + * see ::VL53L0X_PowerModes + * Valid values are: + * VL53L0X_POWERMODE_STANDBY_LEVEL1, + * VL53L0X_POWERMODE_IDLE_LEVEL1 + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when PowerMode + * is not in the supported list + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_power_mode(VL53L0X_DEV dev, + VL53L0X_PowerModes power_mode); + + /** + * @brief Retrieves SPAD configuration + * + * @par Function Description + * This function retrieves the current number of applied reference spads + * and also their type : Aperture or Non-Aperture. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_spad_count Number ref Spad Count + * @param p_is_aperture_spads Reports if spads are of type + * aperture or non-aperture. + * 1:=aperture, 0:=Non-Aperture + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_REF_SPAD_INIT Error in the in the reference + * spad configuration. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error wrapped_VL53L0X_get_reference_spads(VL53L0X_DEV dev, + uint32_t *p_spad_count, uint8_t *p_is_aperture_spads); + + /** + * @brief Gets the (on/off) state of a requested sequence step. + * + * @par Function Description + * This function retrieves the state of a requested sequence step, i.e. on/off. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param sequence_step_id Sequence step identifier. + * @param p_sequence_step_enabled Out parameter reporting if the sequence step + * is enabled {0=Off,1=On}. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error SequenceStepId parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_sequence_step_enable(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, uint8_t *p_sequence_step_enabled); + + + /** + * @brief Gets the timeout of a requested sequence step. + * + * @par Function Description + * This function retrieves the timeout of a requested sequence step. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param sequence_step_id Sequence step identifier. + * @param p_time_out_milli_secs Timeout value. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error SequenceStepId parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_sequence_step_timeout(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, + FixPoint1616_t *p_time_out_milli_secs); + + /** + * @brief Sets the timeout of a requested sequence step. + * + * @par Function Description + * This function sets the timeout of a requested sequence step. + * + * @note This function Accesses the device + * + * @param dev Device Handle + * @param sequence_step_id Sequence step identifier. + * @param time_out_milli_secs Demanded timeout + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error SequenceStepId parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_sequence_step_timeout(VL53L0X_DEV dev, + VL53L0X_SequenceStepId sequence_step_id, FixPoint1616_t time_out_milli_secs); + + /** + * @brief Get the current SPAD Ambient Damper Factor value + * + * @par Function Description + * This function get the SPAD Ambient Damper Factor value + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_spad_ambient_damper_factor Pointer to programmed SPAD Ambient + * Damper Factor value + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_spad_ambient_damper_factor(VL53L0X_DEV dev, + uint16_t *p_spad_ambient_damper_factor); + /** + * @brief Set the SPAD Ambient Damper Factor value + * + * @par Function Description + * This function set the SPAD Ambient Damper Factor value + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param spad_ambient_damper_factor SPAD Ambient Damper Factor value + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_spad_ambient_damper_factor(VL53L0X_DEV dev, + uint16_t spad_ambient_damper_factor); + + /** + * @brief Get the current SPAD Ambient Damper Threshold value + * + * @par Function Description + * This function get the SPAD Ambient Damper Threshold value + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_spad_ambient_damper_threshold Pointer to programmed + * SPAD Ambient Damper Threshold value + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_spad_ambient_damper_threshold(VL53L0X_DEV dev, + uint16_t *p_spad_ambient_damper_threshold); + + /** + * @brief Set the SPAD Ambient Damper Threshold value + * + * @par Function Description + * This function set the SPAD Ambient Damper Threshold value + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param spad_ambient_damper_threshold SPAD Ambient Damper Threshold value + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_spad_ambient_damper_threshold(VL53L0X_DEV dev, + uint16_t spad_ambient_damper_threshold); + + /** + * @brief Get the maximal distance for actual setup + * @par Function Description + * Device must be initialized through @a VL53L0X_SetParameters() prior calling + * this function. + * + * Any range value more than the value returned is to be considered as + * "no target detected" or + * "no target in detectable range"\n + * @warning The maximal distance depends on the setup + * + * @note This function is not Implemented + * + * @param dev Device Handle + * @param p_upper_limit_milli_meter The maximal range limit for actual setup + * (in millimeter) + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ + VL53L0X_Error VL53L0X_get_upper_limit_milli_meter(VL53L0X_DEV dev, + uint16_t *p_upper_limit_milli_meter); + + /** + * @brief Get the tuning settings pointer and the internal external switch + * value. + * + * This function is used to get the Tuning settings buffer pointer and the + * value. + * of the switch to select either external or internal tuning settings. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param pp_tuning_setting_buffer Pointer to tuning settings buffer. + * @param p_use_internal_tuning_settings Pointer to store Use internal tuning + * settings value. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_get_tuning_setting_buffer(VL53L0X_DEV dev, + uint8_t **pp_tuning_setting_buffer, uint8_t *p_use_internal_tuning_settings); + + /** + * @brief Set the tuning settings pointer + * + * This function is used to specify the Tuning settings buffer to be used + * for a given device. The buffer contains all the necessary data to permit + * the API to write tuning settings. + * This function permit to force the usage of either external or internal + * tuning settings. + * + * @note This function Access to the device + * + * @param dev Device Handle + * @param p_tuning_setting_buffer Pointer to tuning settings buffer. + * @param use_internal_tuning_settings Use internal tuning settings value. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_set_tuning_setting_buffer(VL53L0X_DEV dev, + uint8_t *p_tuning_setting_buffer, uint8_t use_internal_tuning_settings); + + /** + * @defgroup VL53L0X_registerAccess_group PAL Register Access Functions + * @brief PAL Register Access Functions + * @{ + */ + + /** + * Lock comms interface to serialize all commands to a shared I2C interface for a specific device + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_lock_sequence_access(VL53L0X_DEV dev); + + /** + * Unlock comms interface to serialize all commands to a shared I2C interface for a specific device + * @param dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error VL53L0X_unlock_sequence_access(VL53L0X_DEV dev); + + /** + * @brief Prepare device for operation + * @par Function Description + * Update device with provided parameters + * @li Then start ranging operation. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pDeviceParameters Pointer to store current device parameters. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ + VL53L0X_Error vl53L0x_set_device_parameters(VL53L0X_DEV Dev, + const VL53L0X_DeviceParameters_t *pDeviceParameters); + + /** + * Set Group parameter Hold state + * + * @par Function Description + * Set or remove device internal group parameter hold + * + * @note This function is not Implemented + * + * @param dev Device Handle + * @param group_param_hold Group parameter Hold state to be set (on/off) + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ + VL53L0X_Error VL53L0X_set_group_param_hold(VL53L0X_DEV dev, + uint8_t group_param_hold); + + + /** + * @brief Wait for device ready for a new measurement command. + * Blocking function. + * + * @note This function is not Implemented + * + * @param dev Device Handle + * @param max_loop Max Number of polling loop (timeout). + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ + VL53L0X_Error VL53L0X_wait_device_ready_for_new_measurement(VL53L0X_DEV dev, + uint32_t max_loop); + + VL53L0X_Error VL53L0X_reverse_bytes(uint8_t *data, uint32_t size); + + int range_meas_int_continuous_mode(void (*fptr)(void)); + + + VL53L0X_DeviceInfo_t _device_info; + + /* IO Device */ + DevI2C *_dev_i2c; + /* Digital out pin */ + DigitalOut *_gpio0; + /* GPIO expander */ + Stmpe1600DigiOut *_expgpio0; + /* Measure detection IRQ */ + InterruptIn *_gpio1Int; + /* Device data */ + VL53L0X_Dev_t _my_device; + VL53L0X_DEV _device; +}; + + +#endif /* _VL53L0X_CLASS_H_ */
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X_def.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X_def.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,640 @@ +/******************************************************************************* +Copyright © 2016, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * 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, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. +*******************************************************************************/ + +/** + * @file VL53L0X_def.h + * + * @brief Type definitions for VL53L0X API. + * + */ + + +#ifndef _VL53L0X_DEF_H_ +#define _VL53L0X_DEF_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup VL53L0X_globaldefine_group VL53L0X Defines + * @brief VL53L0X Defines + * @{ + */ + + +/** PAL SPECIFICATION major version */ +#define VL53L0X10_SPECIFICATION_VER_MAJOR 1 +/** PAL SPECIFICATION minor version */ +#define VL53L0X10_SPECIFICATION_VER_MINOR 2 +/** PAL SPECIFICATION sub version */ +#define VL53L0X10_SPECIFICATION_VER_SUB 7 +/** PAL SPECIFICATION sub version */ +#define VL53L0X10_SPECIFICATION_VER_REVISION 1440 + +/** VL53L0X PAL IMPLEMENTATION major version */ +#define VL53L0X10_IMPLEMENTATION_VER_MAJOR 1 +/** VL53L0X PAL IMPLEMENTATION minor version */ +#define VL53L0X10_IMPLEMENTATION_VER_MINOR 0 +/** VL53L0X PAL IMPLEMENTATION sub version */ +#define VL53L0X10_IMPLEMENTATION_VER_SUB 9 +/** VL53L0X PAL IMPLEMENTATION sub version */ +#define VL53L0X10_IMPLEMENTATION_VER_REVISION 3673 + +/** PAL SPECIFICATION major version */ +#define VL53L0X_SPECIFICATION_VER_MAJOR 1 +/** PAL SPECIFICATION minor version */ +#define VL53L0X_SPECIFICATION_VER_MINOR 2 +/** PAL SPECIFICATION sub version */ +#define VL53L0X_SPECIFICATION_VER_SUB 7 +/** PAL SPECIFICATION sub version */ +#define VL53L0X_SPECIFICATION_VER_REVISION 1440 + +/** VL53L0X PAL IMPLEMENTATION major version */ +#define VL53L0X_IMPLEMENTATION_VER_MAJOR 1 +/** VL53L0X PAL IMPLEMENTATION minor version */ +#define VL53L0X_IMPLEMENTATION_VER_MINOR 1 +/** VL53L0X PAL IMPLEMENTATION sub version */ +#define VL53L0X_IMPLEMENTATION_VER_SUB 21 +/** VL53L0X PAL IMPLEMENTATION sub version */ +#define VL53L0X_IMPLEMENTATION_VER_REVISION 4823 +#define VL53L0X_DEFAULT_MAX_LOOP 2000 +#define VL53L0X_MAX_STRING_LENGTH 32 + + +#include "VL53L0X_device.h" +#include "VL53L0X_types.h" + + +/**************************************** + * PRIVATE define do not edit + ****************************************/ + +/** @brief Defines the parameters of the Get Version Functions + */ +typedef struct { + uint32_t revision; /*!< revision number */ + uint8_t major; /*!< major number */ + uint8_t minor; /*!< minor number */ + uint8_t build; /*!< build number */ +} VL53L0X_Version_t; + + +/** @brief Defines the parameters of the Get Device Info Functions + */ +typedef struct { + char Name[VL53L0X_MAX_STRING_LENGTH]; + /*!< Name of the Device e.g. Left_Distance */ + char Type[VL53L0X_MAX_STRING_LENGTH]; + /*!< Type of the Device e.g VL53L0X */ + char ProductId[VL53L0X_MAX_STRING_LENGTH]; + /*!< Product Identifier String */ + uint8_t ProductType; + /*!< Product Type, VL53L0X = 1, VL53L1 = 2 */ + uint8_t ProductRevisionMajor; + /*!< Product revision major */ + uint8_t ProductRevisionMinor; + /*!< Product revision minor */ +} VL53L0X_DeviceInfo_t; + + +/** @defgroup VL53L0X_define_Error_group Error and Warning code returned by API + * The following DEFINE are used to identify the PAL ERROR + * @{ + */ + +typedef int8_t VL53L0X_Error; + +#define VL53L0X_ERROR_NONE ((VL53L0X_Error) 0) +#define VL53L0X_ERROR_CALIBRATION_WARNING ((VL53L0X_Error) -1) +/*!< Warning invalid calibration data may be in used + \a VL53L0X_InitData() + \a VL53L0X_GetOffsetCalibrationData + \a VL53L0X_SetOffsetCalibrationData */ +#define VL53L0X_ERROR_MIN_CLIPPED ((VL53L0X_Error) -2) +/*!< Warning parameter passed was clipped to min before to be applied */ + +#define VL53L0X_ERROR_UNDEFINED ((VL53L0X_Error) -3) +/*!< Unqualified error */ +#define VL53L0X_ERROR_INVALID_PARAMS ((VL53L0X_Error) -4) +/*!< Parameter passed is invalid or out of range */ +#define VL53L0X_ERROR_NOT_SUPPORTED ((VL53L0X_Error) -5) +/*!< Function is not supported in current mode or configuration */ +#define VL53L0X_ERROR_RANGE_ERROR ((VL53L0X_Error) -6) +/*!< Device report a ranging error interrupt status */ +#define VL53L0X_ERROR_TIME_OUT ((VL53L0X_Error) -7) +/*!< Aborted due to time out */ +#define VL53L0X_ERROR_MODE_NOT_SUPPORTED ((VL53L0X_Error) -8) +/*!< Asked mode is not supported by the device */ +#define VL53L0X_ERROR_BUFFER_TOO_SMALL ((VL53L0X_Error) -9) +/*!< ... */ +#define VL53L0X_ERROR_GPIO_NOT_EXISTING ((VL53L0X_Error) -10) +/*!< User tried to setup a non-existing GPIO pin */ +#define VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED ((VL53L0X_Error) -11) +/*!< unsupported GPIO functionality */ +#define VL53L0X_ERROR_INTERRUPT_NOT_CLEARED ((VL53L0X_Error) -12) +/*!< Error during interrupt clear */ +#define VL53L0X_ERROR_CONTROL_INTERFACE ((VL53L0X_Error) -20) +/*!< error reported from IO functions */ +#define VL53L0X_ERROR_INVALID_COMMAND ((VL53L0X_Error) -30) +/*!< The command is not allowed in the current device state + * (power down) */ +#define VL53L0X_ERROR_DIVISION_BY_ZERO ((VL53L0X_Error) -40) +/*!< In the function a division by zero occurs */ +#define VL53L0X_ERROR_REF_SPAD_INIT ((VL53L0X_Error) -50) +/*!< Error during reference SPAD initialization */ +#define VL53L0X_ERROR_NOT_IMPLEMENTED ((VL53L0X_Error) -99) +/*!< Tells requested functionality has not been implemented yet or + * not compatible with the device */ +/** @} VL53L0X_define_Error_group */ + + +/** @defgroup VL53L0X_define_DeviceModes_group Defines Device modes + * Defines all possible modes for the device + * @{ + */ +typedef uint8_t VL53L0X_DeviceModes; + +#define VL53L0X_DEVICEMODE_SINGLE_RANGING ((VL53L0X_DeviceModes) 0) +#define VL53L0X_DEVICEMODE_CONTINUOUS_RANGING ((VL53L0X_DeviceModes) 1) +#define VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM ((VL53L0X_DeviceModes) 2) +#define VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING ((VL53L0X_DeviceModes) 3) +#define VL53L0X_DEVICEMODE_SINGLE_ALS ((VL53L0X_DeviceModes) 10) +#define VL53L0X_DEVICEMODE_GPIO_DRIVE ((VL53L0X_DeviceModes) 20) +#define VL53L0X_DEVICEMODE_GPIO_OSC ((VL53L0X_DeviceModes) 21) +/* ... Modes to be added depending on device */ +/** @} VL53L0X_define_DeviceModes_group */ + + + +/** @defgroup VL53L0X_define_HistogramModes_group Defines Histogram modes + * Defines all possible Histogram modes for the device + * @{ + */ +typedef uint8_t VL53L0X_HistogramModes; + +#define VL53L0X_HISTOGRAMMODE_DISABLED ((VL53L0X_HistogramModes) 0) +/*!< Histogram Disabled */ +#define VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY ((VL53L0X_HistogramModes) 1) +/*!< Histogram Reference array only */ +#define VL53L0X_HISTOGRAMMODE_RETURN_ONLY ((VL53L0X_HistogramModes) 2) +/*!< Histogram Return array only */ +#define VL53L0X_HISTOGRAMMODE_BOTH ((VL53L0X_HistogramModes) 3) +/*!< Histogram both Reference and Return Arrays */ +/* ... Modes to be added depending on device */ +/** @} VL53L0X_define_HistogramModes_group */ + + +/** @defgroup VL53L0X_define_PowerModes_group List of available Power Modes + * List of available Power Modes + * @{ + */ + +typedef uint8_t VL53L0X_PowerModes; + +#define VL53L0X_POWERMODE_STANDBY_LEVEL1 ((VL53L0X_PowerModes) 0) +/*!< Standby level 1 */ +#define VL53L0X_POWERMODE_STANDBY_LEVEL2 ((VL53L0X_PowerModes) 1) +/*!< Standby level 2 */ +#define VL53L0X_POWERMODE_IDLE_LEVEL1 ((VL53L0X_PowerModes) 2) +/*!< Idle level 1 */ +#define VL53L0X_POWERMODE_IDLE_LEVEL2 ((VL53L0X_PowerModes) 3) +/*!< Idle level 2 */ + +/** @} VL53L0X_define_PowerModes_group */ + + +/** @brief Defines all parameters for the device + */ +typedef struct { + VL53L0X_DeviceModes DeviceMode; + /*!< Defines type of measurement to be done for the next measure */ + VL53L0X_HistogramModes HistogramMode; + /*!< Defines type of histogram measurement to be done for the next + * measure */ + uint32_t MeasurementTimingBudgetMicroSeconds; + /*!< Defines the allowed total time for a single measurement */ + uint32_t InterMeasurementPeriodMilliSeconds; + /*!< Defines time between two consecutive measurements (between two + * measurement starts). If set to 0 means back-to-back mode */ + uint8_t XTalkCompensationEnable; + /*!< Tells if Crosstalk compensation shall be enable or not */ + uint16_t XTalkCompensationRangeMilliMeter; + /*!< CrossTalk compensation range in millimeter */ + FixPoint1616_t XTalkCompensationRateMegaCps; + /*!< CrossTalk compensation rate in Mega counts per seconds. + * Expressed in 16.16 fixed point format. */ + int32_t RangeOffsetMicroMeters; + /*!< Range offset adjustment (mm). */ + + uint8_t LimitChecksEnable[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS]; + /*!< This Array store all the Limit Check enable for this device. */ + uint8_t LimitChecksStatus[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS]; + /*!< This Array store all the Status of the check linked to last + * measurement. */ + FixPoint1616_t LimitChecksValue[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS]; + /*!< This Array store all the Limit Check value for this device */ + + uint8_t WrapAroundCheckEnable; + /*!< Tells if Wrap Around Check shall be enable or not */ +} VL53L0X_DeviceParameters_t; + + +/** @defgroup VL53L0X_define_State_group Defines the current status of the device + * Defines the current status of the device + * @{ + */ + +typedef uint8_t VL53L0X_State; + +#define VL53L0X_STATE_POWERDOWN ((VL53L0X_State) 0) +/*!< Device is in HW reset */ +#define VL53L0X_STATE_WAIT_STATICINIT ((VL53L0X_State) 1) +/*!< Device is initialized and wait for static initialization */ +#define VL53L0X_STATE_STANDBY ((VL53L0X_State) 2) +/*!< Device is in Low power Standby mode */ +#define VL53L0X_STATE_IDLE ((VL53L0X_State) 3) +/*!< Device has been initialized and ready to do measurements */ +#define VL53L0X_STATE_RUNNING ((VL53L0X_State) 4) +/*!< Device is performing measurement */ +#define VL53L0X_STATE_UNKNOWN ((VL53L0X_State) 98) +/*!< Device is in unknown state and need to be rebooted */ +#define VL53L0X_STATE_ERROR ((VL53L0X_State) 99) +/*!< Device is in error state and need to be rebooted */ + +/** @} VL53L0X_define_State_group */ + + +/** @brief Structure containing the Dmax computation parameters and data + */ +typedef struct { + int32_t AmbTuningWindowFactor_K; + /*!< internal algo tuning (*1000) */ + int32_t RetSignalAt0mm; + /*!< intermediate dmax computation value caching */ +} VL53L0X_DMaxData_t; + +/** + * @struct VL53L0X_RangeData_t + * @brief Range measurement data. + */ +typedef struct { + uint32_t TimeStamp; /*!< 32-bit time stamp. */ + uint32_t MeasurementTimeUsec; + /*!< Give the Measurement time needed by the device to do the + * measurement.*/ + + + uint16_t RangeMilliMeter; /*!< range distance in millimeter. */ + + uint16_t RangeDMaxMilliMeter; + /*!< Tells what is the maximum detection distance of the device + * in current setup and environment conditions (Filled when + * applicable) */ + + FixPoint1616_t SignalRateRtnMegaCps; + /*!< Return signal rate (MCPS)\n these is a 16.16 fix point + * value, which is effectively a measure of target + * reflectance.*/ + FixPoint1616_t AmbientRateRtnMegaCps; + /*!< Return ambient rate (MCPS)\n these is a 16.16 fix point + * value, which is effectively a measure of the ambien + * t light.*/ + + uint16_t EffectiveSpadRtnCount; + /*!< Return the effective SPAD count for the return signal. + * To obtain Real value it should be divided by 256 */ + + uint8_t ZoneId; + /*!< Denotes which zone and range scheduler stage the range + * data relates to. */ + uint8_t RangeFractionalPart; + /*!< Fractional part of range distance. Final value is a + * FixPoint168 value. */ + uint8_t RangeStatus; + /*!< Range Status for the current measurement. This is device + * dependent. Value = 0 means value is valid. + * See \ref RangeStatusPage */ +} VL53L0X_RangingMeasurementData_t; + + +#define VL53L0X_HISTOGRAM_BUFFER_SIZE 24 + +/** + * @struct VL53L0X_HistogramData_t + * @brief Histogram measurement data. + */ +typedef struct { + /* Histogram Measurement data */ + uint32_t HistogramData[VL53L0X_HISTOGRAM_BUFFER_SIZE]; + /*!< Histogram data */ + uint8_t HistogramType; /*!< Indicate the types of histogram data : + Return only, Reference only, both Return and Reference */ + uint8_t FirstBin; /*!< First Bin value */ + uint8_t BufferSize; /*!< Buffer Size - Set by the user.*/ + uint8_t NumberOfBins; + /*!< Number of bins filled by the histogram measurement */ + + VL53L0X_DeviceError ErrorStatus; + /*!< Error status of the current measurement. \n + see @a ::VL53L0X_DeviceError @a VL53L0X_GetStatusErrorString() */ +} VL53L0X_HistogramMeasurementData_t; + +#define VL53L0X_REF_SPAD_BUFFER_SIZE 6 + +/** + * @struct VL53L0X_SpadData_t + * @brief Spad Configuration Data. + */ +typedef struct { + uint8_t RefSpadEnables[VL53L0X_REF_SPAD_BUFFER_SIZE]; + /*!< Reference Spad Enables */ + uint8_t RefGoodSpadMap[VL53L0X_REF_SPAD_BUFFER_SIZE]; + /*!< Reference Spad Good Spad Map */ +} VL53L0X_SpadData_t; + +typedef struct { + FixPoint1616_t OscFrequencyMHz; /* Frequency used */ + + uint16_t LastEncodedTimeout; + /* last encoded Time out used for timing budget*/ + + VL53L0X_GpioFunctionality Pin0GpioFunctionality; + /* store the functionality of the GPIO: pin0 */ + + uint32_t FinalRangeTimeoutMicroSecs; + /*!< Execution time of the final range*/ + uint8_t FinalRangeVcselPulsePeriod; + /*!< Vcsel pulse period (pll clocks) for the final range measurement*/ + uint32_t PreRangeTimeoutMicroSecs; + /*!< Execution time of the final range*/ + uint8_t PreRangeVcselPulsePeriod; + /*!< Vcsel pulse period (pll clocks) for the pre-range measurement*/ + + uint16_t SigmaEstRefArray; + /*!< Reference array sigma value in 1/100th of [mm] e.g. 100 = 1mm */ + uint16_t SigmaEstEffPulseWidth; + /*!< Effective Pulse width for sigma estimate in 1/100th + * of ns e.g. 900 = 9.0ns */ + uint16_t SigmaEstEffAmbWidth; + /*!< Effective Ambient width for sigma estimate in 1/100th of ns + * e.g. 500 = 5.0ns */ + + + uint8_t ReadDataFromDeviceDone; /* Indicate if read from device has + been done (==1) or not (==0) */ + uint8_t ModuleId; /* Module ID */ + uint8_t Revision; /* test Revision */ + char ProductId[VL53L0X_MAX_STRING_LENGTH]; + /* Product Identifier String */ + uint8_t ReferenceSpadCount; /* used for ref spad management */ + uint8_t ReferenceSpadType; /* used for ref spad management */ + uint8_t RefSpadsInitialised; /* reports if ref spads are initialised. */ + uint32_t PartUIDUpper; /*!< Unique Part ID Upper */ + uint32_t PartUIDLower; /*!< Unique Part ID Lower */ + FixPoint1616_t SignalRateMeasFixed400mm; /*!< Peek Signal rate + at 400 mm*/ + +} VL53L0X_DeviceSpecificParameters_t; + +/** + * @struct VL53L0X_DevData_t + * + * @brief VL53L0X PAL device ST private data structure \n + * End user should never access any of these field directly + * + * These must never access directly but only via macro + */ +typedef struct { + VL53L0X_DMaxData_t DMaxData; + /*!< Dmax Data */ + int32_t Part2PartOffsetNVMMicroMeter; + /*!< backed up NVM value */ + int32_t Part2PartOffsetAdjustmentNVMMicroMeter; + /*!< backed up NVM value representing additional offset adjustment */ + VL53L0X_DeviceParameters_t CurrentParameters; + /*!< Current Device Parameter */ + VL53L0X_RangingMeasurementData_t LastRangeMeasure; + /*!< Ranging Data */ + VL53L0X_HistogramMeasurementData_t LastHistogramMeasure; + /*!< Histogram Data */ + VL53L0X_DeviceSpecificParameters_t DeviceSpecificParameters; + /*!< Parameters specific to the device */ + VL53L0X_SpadData_t SpadData; + /*!< Spad Data */ + uint8_t SequenceConfig; + /*!< Internal value for the sequence config */ + uint8_t RangeFractionalEnable; + /*!< Enable/Disable fractional part of ranging data */ + VL53L0X_State PalState; + /*!< Current state of the PAL for this device */ + VL53L0X_PowerModes PowerMode; + /*!< Current Power Mode */ + uint16_t SigmaEstRefArray; + /*!< Reference array sigma value in 1/100th of [mm] e.g. 100 = 1mm */ + uint16_t SigmaEstEffPulseWidth; + /*!< Effective Pulse width for sigma estimate in 1/100th + * of ns e.g. 900 = 9.0ns */ + uint16_t SigmaEstEffAmbWidth; + /*!< Effective Ambient width for sigma estimate in 1/100th of ns + * e.g. 500 = 5.0ns */ + uint8_t StopVariable; + /*!< StopVariable used during the stop sequence */ + uint16_t targetRefRate; + /*!< Target Ambient Rate for Ref spad management */ + FixPoint1616_t SigmaEstimate; + /*!< Sigma Estimate - based on ambient & VCSEL rates and + * signal_total_events */ + FixPoint1616_t SignalEstimate; + /*!< Signal Estimate - based on ambient & VCSEL rates and cross talk */ + FixPoint1616_t LastSignalRefMcps; + /*!< Latest Signal ref in Mcps */ + uint8_t *pTuningSettingsPointer; + /*!< Pointer for Tuning Settings table */ + uint8_t UseInternalTuningSettings; + /*!< Indicate if we use Tuning Settings table */ + uint16_t LinearityCorrectiveGain; + /*!< Linearity Corrective Gain value in x1000 */ + uint16_t DmaxCalRangeMilliMeter; + /*!< Dmax Calibration Range millimeter */ + FixPoint1616_t DmaxCalSignalRateRtnMegaCps; + /*!< Dmax Calibration Signal Rate Return MegaCps */ + +} VL53L0X_DevData_t; + + +/** @defgroup VL53L0X_define_InterruptPolarity_group Defines the Polarity + * of the Interrupt + * Defines the Polarity of the Interrupt + * @{ + */ +typedef uint8_t VL53L0X_InterruptPolarity; + +#define VL53L0X_INTERRUPTPOLARITY_LOW ((VL53L0X_InterruptPolarity) 0) +/*!< Set active low polarity best setup for falling edge. */ +#define VL53L0X_INTERRUPTPOLARITY_HIGH ((VL53L0X_InterruptPolarity) 1) +/*!< Set active high polarity best setup for rising edge. */ + +/** @} VL53L0X_define_InterruptPolarity_group */ + + +/** @defgroup VL53L0X_define_VcselPeriod_group Vcsel Period Defines + * Defines the range measurement for which to access the vcsel period. + * @{ + */ +typedef uint8_t VL53L0X_VcselPeriod; + +#define VL53L0X_VCSEL_PERIOD_PRE_RANGE ((VL53L0X_VcselPeriod) 0) +/*!<Identifies the pre-range vcsel period. */ +#define VL53L0X_VCSEL_PERIOD_FINAL_RANGE ((VL53L0X_VcselPeriod) 1) +/*!<Identifies the final range vcsel period. */ + +/** @} VL53L0X_define_VcselPeriod_group */ + +/** @defgroup VL53L0X_define_SchedulerSequence_group Defines the steps + * carried out by the scheduler during a range measurement. + * @{ + * Defines the states of all the steps in the scheduler + * i.e. enabled/disabled. + */ +typedef struct { + uint8_t TccOn; /*!<Reports if Target Centre Check On */ + uint8_t MsrcOn; /*!<Reports if MSRC On */ + uint8_t DssOn; /*!<Reports if DSS On */ + uint8_t PreRangeOn; /*!<Reports if Pre-Range On */ + uint8_t FinalRangeOn; /*!<Reports if Final-Range On */ +} VL53L0X_SchedulerSequenceSteps_t; + +/** @} VL53L0X_define_SchedulerSequence_group */ + +/** @defgroup VL53L0X_define_SequenceStepId_group Defines the Polarity + * of the Interrupt + * Defines the the sequence steps performed during ranging.. + * @{ + */ +typedef uint8_t VL53L0X_SequenceStepId; + +#define VL53L0X_SEQUENCESTEP_TCC ((VL53L0X_VcselPeriod) 0) +/*!<Target CentreCheck identifier. */ +#define VL53L0X_SEQUENCESTEP_DSS ((VL53L0X_VcselPeriod) 1) +/*!<Dynamic Spad Selection function Identifier. */ +#define VL53L0X_SEQUENCESTEP_MSRC ((VL53L0X_VcselPeriod) 2) +/*!<Minimum Signal Rate Check function Identifier. */ +#define VL53L0X_SEQUENCESTEP_PRE_RANGE ((VL53L0X_VcselPeriod) 3) +/*!<Pre-Range check Identifier. */ +#define VL53L0X_SEQUENCESTEP_FINAL_RANGE ((VL53L0X_VcselPeriod) 4) +/*!<Final Range Check Identifier. */ + +#define VL53L0X_SEQUENCESTEP_NUMBER_OF_CHECKS 5 +/*!<Number of Sequence Step Managed by the API. */ + +/** @} VL53L0X_define_SequenceStepId_group */ + + +/* MACRO Definitions */ +/** @defgroup VL53L0X_define_GeneralMacro_group General Macro Defines + * General Macro Defines + * @{ + */ + +/* Defines */ +#define VL53L0X_SETPARAMETERFIELD(Dev, field, value) \ + PALDevDataSet(Dev, CurrentParameters.field, value) + +#define VL53L0X_GETPARAMETERFIELD(Dev, field, variable) \ + variable = PALDevDataGet(Dev, CurrentParameters).field + + +#define VL53L0X_SETARRAYPARAMETERFIELD(Dev, field, index, value) \ + PALDevDataSet(Dev, CurrentParameters.field[index], value) + +#define VL53L0X_GETARRAYPARAMETERFIELD(Dev, field, index, variable) \ + variable = PALDevDataGet(Dev, CurrentParameters).field[index] + + +#define VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, field, value) \ + PALDevDataSet(Dev, DeviceSpecificParameters.field, value) + +#define VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, field) \ + PALDevDataGet(Dev, DeviceSpecificParameters).field + + +#define VL53L0X_FIXPOINT1616TOFIXPOINT97(Value) \ + (uint16_t)((Value>>9)&0xFFFF) +#define VL53L0X_FIXPOINT97TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<9) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT88(Value) \ + (uint16_t)((Value>>8)&0xFFFF) +#define VL53L0X_FIXPOINT88TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<8) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT412(Value) \ + (uint16_t)((Value>>4)&0xFFFF) +#define VL53L0X_FIXPOINT412TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<4) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT313(Value) \ + (uint16_t)((Value>>3)&0xFFFF) +#define VL53L0X_FIXPOINT313TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<3) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT08(Value) \ + (uint8_t)((Value>>8)&0x00FF) +#define VL53L0X_FIXPOINT08TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<8) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT53(Value) \ + (uint8_t)((Value>>13)&0x00FF) +#define VL53L0X_FIXPOINT53TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<13) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT102(Value) \ + (uint16_t)((Value>>14)&0x0FFF) +#define VL53L0X_FIXPOINT102TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<12) + +#define VL53L0X_MAKEUINT16(lsb, msb) (uint16_t)((((uint16_t)msb)<<8) + \ + (uint16_t)lsb) + +/** @} VL53L0X_define_GeneralMacro_group */ + +/** @} VL53L0X_globaldefine_group */ + + + + + + + +#ifdef __cplusplus +} +#endif + + +#endif /* _VL53L0X_DEF_H_ */
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X_device.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X_device.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,257 @@ +/******************************************************************************* +Copyright © 2016, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * 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, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. +*******************************************************************************/ + +/** + * Device specific defines. To be adapted by implementer for the targeted + * device. + */ + +#ifndef _VL53L0X_DEVICE_H_ +#define _VL53L0X_DEVICE_H_ + +#include "VL53L0X_types.h" + + +/** @defgroup VL53L0X_DevSpecDefines_group VL53L0X cut1.1 Device Specific Defines + * @brief VL53L0X cut1.1 Device Specific Defines + * @{ + */ + + +/** @defgroup VL53L0X_DeviceError_group Device Error + * @brief Device Error code + * + * This enum is Device specific it should be updated in the implementation + * Use @a VL53L0X_GetStatusErrorString() to get the string. + * It is related to Status Register of the Device. + * @{ + */ +typedef uint8_t VL53L0X_DeviceError; + +#define VL53L0X_DEVICEERROR_NONE ((VL53L0X_DeviceError) 0) +/*!< 0 NoError */ +#define VL53L0X_DEVICEERROR_VCSELCONTINUITYTESTFAILURE ((VL53L0X_DeviceError) 1) +#define VL53L0X_DEVICEERROR_VCSELWATCHDOGTESTFAILURE ((VL53L0X_DeviceError) 2) +#define VL53L0X_DEVICEERROR_NOVHVVALUEFOUND ((VL53L0X_DeviceError) 3) +#define VL53L0X_DEVICEERROR_MSRCNOTARGET ((VL53L0X_DeviceError) 4) +#define VL53L0X_DEVICEERROR_SNRCHECK ((VL53L0X_DeviceError) 5) +#define VL53L0X_DEVICEERROR_RANGEPHASECHECK ((VL53L0X_DeviceError) 6) +#define VL53L0X_DEVICEERROR_SIGMATHRESHOLDCHECK ((VL53L0X_DeviceError) 7) +#define VL53L0X_DEVICEERROR_TCC ((VL53L0X_DeviceError) 8) +#define VL53L0X_DEVICEERROR_PHASECONSISTENCY ((VL53L0X_DeviceError) 9) +#define VL53L0X_DEVICEERROR_MINCLIP ((VL53L0X_DeviceError) 10) +#define VL53L0X_DEVICEERROR_RANGECOMPLETE ((VL53L0X_DeviceError) 11) +#define VL53L0X_DEVICEERROR_ALGOUNDERFLOW ((VL53L0X_DeviceError) 12) +#define VL53L0X_DEVICEERROR_ALGOOVERFLOW ((VL53L0X_DeviceError) 13) +#define VL53L0X_DEVICEERROR_RANGEIGNORETHRESHOLD ((VL53L0X_DeviceError) 14) + +/** @} end of VL53L0X_DeviceError_group */ + + +/** @defgroup VL53L0X_CheckEnable_group Check Enable list + * @brief Check Enable code + * + * Define used to specify the LimitCheckId. + * Use @a VL53L0X_GetLimitCheckInfo() to get the string. + * @{ + */ + +#define VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE 0 +#define VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE 1 +#define VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP 2 +#define VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD 3 +#define VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC 4 +#define VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE 5 + +#define VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS 6 + +/** @} end of VL53L0X_CheckEnable_group */ + + +/** @defgroup VL53L0X_GpioFunctionality_group Gpio Functionality + * @brief Defines the different functionalities for the device GPIO(s) + * @{ + */ +typedef uint8_t VL53L0X_GpioFunctionality; + +#define VL53L0X_GPIOFUNCTIONALITY_OFF \ + ((VL53L0X_GpioFunctionality) 0) /*!< NO Interrupt */ +#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW \ + ((VL53L0X_GpioFunctionality) 1) /*!< Level Low (value < thresh_low) */ +#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH \ + ((VL53L0X_GpioFunctionality) 2) /*!< Level High (value > thresh_high) */ +#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT \ + ((VL53L0X_GpioFunctionality) 3) +/*!< Out Of Window (value < thresh_low OR value > thresh_high) */ +#define VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY \ + ((VL53L0X_GpioFunctionality) 4) /*!< New Sample Ready */ + +/** @} end of VL53L0X_GpioFunctionality_group */ + + +/* Device register map */ + +/** @defgroup VL53L0X_DefineRegisters_group Define Registers + * @brief List of all the defined registers + * @{ + */ +#define VL53L0X_REG_SYSRANGE_START 0x000 +/** mask existing bit in #VL53L0X_REG_SYSRANGE_START*/ +#define VL53L0X_REG_SYSRANGE_MODE_MASK 0x0F +/** bit 0 in #VL53L0X_REG_SYSRANGE_START write 1 toggle state in + * continuous mode and arm next shot in single shot mode */ +#define VL53L0X_REG_SYSRANGE_MODE_START_STOP 0x01 +/** bit 1 write 0 in #VL53L0X_REG_SYSRANGE_START set single shot mode */ +#define VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT 0x00 +/** bit 1 write 1 in #VL53L0X_REG_SYSRANGE_START set back-to-back + * operation mode */ +#define VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK 0x02 +/** bit 2 write 1 in #VL53L0X_REG_SYSRANGE_START set timed operation + * mode */ +#define VL53L0X_REG_SYSRANGE_MODE_TIMED 0x04 +/** bit 3 write 1 in #VL53L0X_REG_SYSRANGE_START set histogram operation + * mode */ +#define VL53L0X_REG_SYSRANGE_MODE_HISTOGRAM 0x08 + + +#define VL53L0X_REG_SYSTEM_THRESH_HIGH 0x000C +#define VL53L0X_REG_SYSTEM_THRESH_LOW 0x000E + + +#define VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG 0x0001 +#define VL53L0X_REG_SYSTEM_RANGE_CONFIG 0x0009 +#define VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD 0x0004 + + +#define VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO 0x000A +#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_DISABLED 0x00 +#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_LEVEL_LOW 0x01 +#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_LEVEL_HIGH 0x02 +#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_OUT_OF_WINDOW 0x03 +#define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY 0x04 + +#define VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH 0x0084 + + +#define VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR 0x000B + +/* Result registers */ +#define VL53L0X_REG_RESULT_INTERRUPT_STATUS 0x0013 +#define VL53L0X_REG_RESULT_RANGE_STATUS 0x0014 + +#define VL53L0X_REG_RESULT_CORE_PAGE 1 +#define VL53L0X_REG_RESULT_CORE_AMBIENT_WINDOW_EVENTS_RTN 0x00BC +#define VL53L0X_REG_RESULT_CORE_RANGING_TOTAL_EVENTS_RTN 0x00C0 +#define VL53L0X_REG_RESULT_CORE_AMBIENT_WINDOW_EVENTS_REF 0x00D0 +#define VL53L0X_REG_RESULT_CORE_RANGING_TOTAL_EVENTS_REF 0x00D4 +#define VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF 0x00B6 + +/* Algo register */ + +#define VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM 0x0028 + +#define VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS 0x008a + +/* Check Limit registers */ +#define VL53L0X_REG_MSRC_CONFIG_CONTROL 0x0060 + +#define VL53L0X_REG_PRE_RANGE_CONFIG_MIN_SNR 0X0027 +#define VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW 0x0056 +#define VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH 0x0057 +#define VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT 0x0064 + +#define VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_SNR 0X0067 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW 0x0047 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH 0x0048 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT 0x0044 + + +#define VL53L0X_REG_PRE_RANGE_CONFIG_SIGMA_THRESH_HI 0X0061 +#define VL53L0X_REG_PRE_RANGE_CONFIG_SIGMA_THRESH_LO 0X0062 + +/* PRE RANGE registers */ +#define VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD 0x0050 +#define VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI 0x0051 +#define VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_LO 0x0052 + +#define VL53L0X_REG_SYSTEM_HISTOGRAM_BIN 0x0081 +#define VL53L0X_REG_HISTOGRAM_CONFIG_INITIAL_PHASE_SELECT 0x0033 +#define VL53L0X_REG_HISTOGRAM_CONFIG_READOUT_CTRL 0x0055 + +#define VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD 0x0070 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI 0x0071 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_LO 0x0072 +#define VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS 0x0020 + +#define VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP 0x0046 + + +#define VL53L0X_REG_SOFT_RESET_GO2_SOFT_RESET_N 0x00bf +#define VL53L0X_REG_IDENTIFICATION_MODEL_ID 0x00c0 +#define VL53L0X_REG_IDENTIFICATION_REVISION_ID 0x00c2 + +#define VL53L0X_REG_OSC_CALIBRATE_VAL 0x00f8 + + +#define VL53L0X_SIGMA_ESTIMATE_MAX_VALUE 65535 +/* equivalent to a range sigma of 655.35mm */ + +#define VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH 0x032 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0 0x0B0 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_1 0x0B1 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_2 0x0B2 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_3 0x0B3 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_4 0x0B4 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_5 0x0B5 + +#define VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT 0xB6 +#define VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD 0x4E /* 0x14E */ +#define VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET 0x4F /* 0x14F */ +#define VL53L0X_REG_POWER_MANAGEMENT_GO1_POWER_FORCE 0x80 + +/* + * Speed of light in um per 1E-10 Seconds + */ + +#define VL53L0X_SPEED_OF_LIGHT_IN_AIR 2997 + +#define VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV 0x0089 + +#define VL53L0X_REG_ALGO_PHASECAL_LIM 0x0030 /* 0x130 */ +#define VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT 0x0030 + +/** @} VL53L0X_DefineRegisters_group */ + +/** @} VL53L0X_DevSpecDefines_group */ + + +#endif + +/* _VL53L0X_DEVICE_H_ */ + +
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X_i2c_platform.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X_i2c_platform.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,417 @@ +/* + * COPYRIGHT (C) STMicroelectronics 2014. All rights reserved. + * + * This software is the confidential and proprietary information of + * STMicroelectronics ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with STMicroelectronics + * + * Programming Golden Rule: Keep it Simple! + * + */ + +/** + * @file VL53L0X_platform.h + * @brief Function prototype definitions for Ewok Platform layer. + * + */ + + +#ifndef _VL53L0X_I2C_PLATFORM_H_ +#define _VL53L0X_I2C_PLATFORM_H_ + +#include "VL53L0X_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Include uint8_t, unit16_t etc definitions + +#include <stdint.h> +#include <stdarg.h> + + +/** + * @brief Typedef defining .\n + * The developer shoud modify this to suit the platform being deployed. + * + */ + +// enum {TRUE = true, FALSE = false}; + +/** + * @brief Typedef defining 8 bit unsigned char type.\n + * The developer shoud modify this to suit the platform being deployed. + * + */ + +#ifndef bool_t +typedef unsigned char bool_t; +#endif + + +#define I2C 0x01 +#define SPI 0x00 + +#define COMMS_BUFFER_SIZE 64 // MUST be the same size as the SV task buffer + +#define BYTES_PER_WORD 2 +#define BYTES_PER_DWORD 4 + +#define VL53L0X_MAX_STRING_LENGTH_PLT 256 + +/** + * @brief Initialise platform comms. + * + * @param comms_type - selects between I2C and SPI + * @param comms_speed_khz - unsigned short containing the I2C speed in kHz + * + * @return status - status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_comms_initialise(uint8_t comms_type, + uint16_t comms_speed_khz); + +/** +* @brief Initialise platform serial comms. +* +* @param comPortStr - String to indicate the comm port +* @param baudRate - Bau rate +* +* @return status - status 0 = ok, 1 = error +* +*/ +int VL53L0_i2c_init(char *comPortStr, unsigned int baudRate); + + +/** + * @brief Close platform comms. + * + * @return status - status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_comms_close(void); + +/** + * @brief Cycle Power to Device + * + * @return status - status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_cycle_power(void); + + +/** + * @brief Writes the supplied byte buffer to the device + * + * Wrapper for SystemVerilog Write Multi task + * + * @code + * + * Example: + * + * uint8_t *spad_enables; + * + * int status = VL53L0X_write_multi(RET_SPAD_EN_0, spad_enables, 36); + * + * @endcode + * + * @param address - uint8_t device address value + * @param index - uint8_t register index value + * @param pdata - pointer to uint8_t buffer containing the data to be written + * @param count - number of bytes in the supplied byte buffer + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_write_multi(uint8_t address, uint8_t index, uint8_t *pdata, int32_t count); + + +/** + * @brief Reads the requested number of bytes from the device + * + * Wrapper for SystemVerilog Read Multi task + * + * @code + * + * Example: + * + * uint8_t buffer[COMMS_BUFFER_SIZE]; + * + * int status = status = VL53L0X_read_multi(DEVICE_ID, buffer, 2) + * + * @endcode + * + * @param address - uint8_t device address value + * @param index - uint8_t register index value + * @param pdata - pointer to the uint8_t buffer to store read data + * @param count - number of uint8_t's to read + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_read_multi(uint8_t address, uint8_t index, uint8_t *pdata, int32_t count); + + +/** + * @brief Writes a single byte to the device + * + * Wrapper for SystemVerilog Write Byte task + * + * @code + * + * Example: + * + * uint8_t page_number = MAIN_SELECT_PAGE; + * + * int status = VL53L0X_write_byte(PAGE_SELECT, page_number); + * + * @endcode + * + * @param address - uint8_t device address value + * @param index - uint8_t register index value + * @param data - uint8_t data value to write + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_write_byte(uint8_t address, uint8_t index, uint8_t data); + + +/** + * @brief Writes a single word (16-bit unsigned) to the device + * + * Manages the big-endian nature of the device (first byte written is the MS byte). + * Uses SystemVerilog Write Multi task. + * + * @code + * + * Example: + * + * uint16_t nvm_ctrl_pulse_width = 0x0004; + * + * int status = VL53L0X_write_word(NVM_CTRL__PULSE_WIDTH_MSB, nvm_ctrl_pulse_width); + * + * @endcode + * + * @param address - uint8_t device address value + * @param index - uint8_t register index value + * @param data - uin16_t data value write + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_write_word(uint8_t address, uint8_t index, uint16_t data); + + +/** + * @brief Writes a single dword (32-bit unsigned) to the device + * + * Manages the big-endian nature of the device (first byte written is the MS byte). + * Uses SystemVerilog Write Multi task. + * + * @code + * + * Example: + * + * uint32_t nvm_data = 0x0004; + * + * int status = VL53L0X_write_dword(NVM_CTRL__DATAIN_MMM, nvm_data); + * + * @endcode + * + * @param address - uint8_t device address value + * @param index - uint8_t register index value + * @param data - uint32_t data value to write + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_write_dword(uint8_t address, uint8_t index, uint32_t data); + + + +/** + * @brief Reads a single byte from the device + * + * Uses SystemVerilog Read Byte task. + * + * @code + * + * Example: + * + * uint8_t device_status = 0; + * + * int status = VL53L0X_read_byte(STATUS, &device_status); + * + * @endcode + * + * @param address - uint8_t device address value + * @param index - uint8_t register index value + * @param pdata - pointer to uint8_t data value + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_read_byte(uint8_t address, uint8_t index, uint8_t *pdata); + + +/** + * @brief Reads a single word (16-bit unsigned) from the device + * + * Manages the big-endian nature of the device (first byte read is the MS byte). + * Uses SystemVerilog Read Multi task. + * + * @code + * + * Example: + * + * uint16_t timeout = 0; + * + * int status = VL53L0X_read_word(TIMEOUT_OVERALL_PERIODS_MSB, &timeout); + * + * @endcode + * + * @param address - uint8_t device address value + * @param index - uint8_t register index value + * @param pdata - pointer to uint16_t data value + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_read_word(uint8_t address, uint8_t index, uint16_t *pdata); + + +/** + * @brief Reads a single dword (32-bit unsigned) from the device + * + * Manages the big-endian nature of the device (first byte read is the MS byte). + * Uses SystemVerilog Read Multi task. + * + * @code + * + * Example: + * + * uint32_t range_1 = 0; + * + * int status = VL53L0X_read_dword(RANGE_1_MMM, &range_1); + * + * @endcode + * + * @param address - uint8_t device address value + * @param index - uint8_t register index value + * @param pdata - pointer to uint32_t data value + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_read_dword(uint8_t address, uint8_t index, uint32_t *pdata); + + +/** + * @brief Implements a programmable wait in us + * + * Wrapper for SystemVerilog Wait in micro seconds task + * + * @param wait_us - integer wait in micro seconds + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_platform_wait_us(int32_t wait_us); + + +/** + * @brief Implements a programmable wait in ms + * + * Wrapper for SystemVerilog Wait in milli seconds task + * + * @param wait_ms - integer wait in milli seconds + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_wait_ms(int32_t wait_ms); + + +/** + * @brief Set GPIO value + * + * @param level - input level - either 0 or 1 + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_set_gpio(uint8_t level); + + +/** + * @brief Get GPIO value + * + * @param plevel - uint8_t pointer to store GPIO level (0 or 1) + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_get_gpio(uint8_t *plevel); + +/** + * @brief Release force on GPIO + * + * @return status - SystemVerilog status 0 = ok, 1 = error + * + */ + +int32_t VL53L0X_release_gpio(void); + + +/** +* @brief Get the frequency of the timer used for ranging results time stamps +* +* @param[out] ptimer_freq_hz : pointer for timer frequency +* +* @return status : 0 = ok, 1 = error +* +*/ + +int32_t VL53L0X_get_timer_frequency(int32_t *ptimer_freq_hz); + +/** +* @brief Get the timer value in units of timer_freq_hz (see VL53L0X_get_timestamp_frequency()) +* +* @param[out] ptimer_count : pointer for timer count value +* +* @return status : 0 = ok, 1 = error +* +*/ + +int32_t VL53L0X_get_timer_value(int32_t *ptimer_count); + + + + + +#ifdef __cplusplus +} +#endif + +#endif //_VL53L0X_I2C_PLATFORM_H_ + +
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X_interrupt_threshold_settings.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X_interrupt_threshold_settings.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,195 @@ +/******************************************************************************* +Copyright © 2016, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * 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, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. +*******************************************************************************/ + + +#ifndef _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_ +#define _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +uint8_t InterruptThresholdSettings[] = { + + /* Start of Interrupt Threshold Settings */ + 0x1, 0xff, 0x00, + 0x1, 0x80, 0x01, + 0x1, 0xff, 0x01, + 0x1, 0x00, 0x00, + 0x1, 0xff, 0x01, + 0x1, 0x4f, 0x02, + 0x1, 0xFF, 0x0E, + 0x1, 0x00, 0x03, + 0x1, 0x01, 0x84, + 0x1, 0x02, 0x0A, + 0x1, 0x03, 0x03, + 0x1, 0x04, 0x08, + 0x1, 0x05, 0xC8, + 0x1, 0x06, 0x03, + 0x1, 0x07, 0x8D, + 0x1, 0x08, 0x08, + 0x1, 0x09, 0xC6, + 0x1, 0x0A, 0x01, + 0x1, 0x0B, 0x02, + 0x1, 0x0C, 0x00, + 0x1, 0x0D, 0xD5, + 0x1, 0x0E, 0x18, + 0x1, 0x0F, 0x12, + 0x1, 0x10, 0x01, + 0x1, 0x11, 0x82, + 0x1, 0x12, 0x00, + 0x1, 0x13, 0xD5, + 0x1, 0x14, 0x18, + 0x1, 0x15, 0x13, + 0x1, 0x16, 0x03, + 0x1, 0x17, 0x86, + 0x1, 0x18, 0x0A, + 0x1, 0x19, 0x09, + 0x1, 0x1A, 0x08, + 0x1, 0x1B, 0xC2, + 0x1, 0x1C, 0x03, + 0x1, 0x1D, 0x8F, + 0x1, 0x1E, 0x0A, + 0x1, 0x1F, 0x06, + 0x1, 0x20, 0x01, + 0x1, 0x21, 0x02, + 0x1, 0x22, 0x00, + 0x1, 0x23, 0xD5, + 0x1, 0x24, 0x18, + 0x1, 0x25, 0x22, + 0x1, 0x26, 0x01, + 0x1, 0x27, 0x82, + 0x1, 0x28, 0x00, + 0x1, 0x29, 0xD5, + 0x1, 0x2A, 0x18, + 0x1, 0x2B, 0x0B, + 0x1, 0x2C, 0x28, + 0x1, 0x2D, 0x78, + 0x1, 0x2E, 0x28, + 0x1, 0x2F, 0x91, + 0x1, 0x30, 0x00, + 0x1, 0x31, 0x0B, + 0x1, 0x32, 0x00, + 0x1, 0x33, 0x0B, + 0x1, 0x34, 0x00, + 0x1, 0x35, 0xA1, + 0x1, 0x36, 0x00, + 0x1, 0x37, 0xA0, + 0x1, 0x38, 0x00, + 0x1, 0x39, 0x04, + 0x1, 0x3A, 0x28, + 0x1, 0x3B, 0x30, + 0x1, 0x3C, 0x0C, + 0x1, 0x3D, 0x04, + 0x1, 0x3E, 0x0F, + 0x1, 0x3F, 0x79, + 0x1, 0x40, 0x28, + 0x1, 0x41, 0x1E, + 0x1, 0x42, 0x2F, + 0x1, 0x43, 0x87, + 0x1, 0x44, 0x00, + 0x1, 0x45, 0x0B, + 0x1, 0x46, 0x00, + 0x1, 0x47, 0x0B, + 0x1, 0x48, 0x00, + 0x1, 0x49, 0xA7, + 0x1, 0x4A, 0x00, + 0x1, 0x4B, 0xA6, + 0x1, 0x4C, 0x00, + 0x1, 0x4D, 0x04, + 0x1, 0x4E, 0x01, + 0x1, 0x4F, 0x00, + 0x1, 0x50, 0x00, + 0x1, 0x51, 0x80, + 0x1, 0x52, 0x09, + 0x1, 0x53, 0x08, + 0x1, 0x54, 0x01, + 0x1, 0x55, 0x00, + 0x1, 0x56, 0x0F, + 0x1, 0x57, 0x79, + 0x1, 0x58, 0x09, + 0x1, 0x59, 0x05, + 0x1, 0x5A, 0x00, + 0x1, 0x5B, 0x60, + 0x1, 0x5C, 0x05, + 0x1, 0x5D, 0xD1, + 0x1, 0x5E, 0x0C, + 0x1, 0x5F, 0x3C, + 0x1, 0x60, 0x00, + 0x1, 0x61, 0xD0, + 0x1, 0x62, 0x0B, + 0x1, 0x63, 0x03, + 0x1, 0x64, 0x28, + 0x1, 0x65, 0x10, + 0x1, 0x66, 0x2A, + 0x1, 0x67, 0x39, + 0x1, 0x68, 0x0B, + 0x1, 0x69, 0x02, + 0x1, 0x6A, 0x28, + 0x1, 0x6B, 0x10, + 0x1, 0x6C, 0x2A, + 0x1, 0x6D, 0x61, + 0x1, 0x6E, 0x0C, + 0x1, 0x6F, 0x00, + 0x1, 0x70, 0x0F, + 0x1, 0x71, 0x79, + 0x1, 0x72, 0x00, + 0x1, 0x73, 0x0B, + 0x1, 0x74, 0x00, + 0x1, 0x75, 0x0B, + 0x1, 0x76, 0x00, + 0x1, 0x77, 0xA1, + 0x1, 0x78, 0x00, + 0x1, 0x79, 0xA0, + 0x1, 0x7A, 0x00, + 0x1, 0x7B, 0x04, + 0x1, 0xFF, 0x04, + 0x1, 0x79, 0x1D, + 0x1, 0x7B, 0x27, + 0x1, 0x96, 0x0E, + 0x1, 0x97, 0xFE, + 0x1, 0x98, 0x03, + 0x1, 0x99, 0xEF, + 0x1, 0x9A, 0x02, + 0x1, 0x9B, 0x44, + 0x1, 0x73, 0x07, + 0x1, 0x70, 0x01, + 0x1, 0xff, 0x01, + 0x1, 0x00, 0x01, + 0x1, 0xff, 0x00, + 0x00, 0x00, 0x00 +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_ */ +
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X_platform.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X_platform.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,242 @@ +/******************************************************************************* +Copyright © 2015, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * 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, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. +********************************************************************************/ + + +#ifndef _VL53L0X_PLATFORM_H_ +#define _VL53L0X_PLATFORM_H_ + +#include "VL53L0X_def.h" +#include "VL53L0X_platform_log.h" +#include "VL53L0X_i2c_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file vl53l0_platform.h + * + * @brief All end user OS/platform/application porting + */ + +/** + * @defgroup VL53L0X_platform_group VL53L0 Platform Functions + * @brief VL53L0 Platform Functions + * @{ + */ + +/** + * @struct VL53L0X_Dev_t + * @brief Generic PAL device type that does link between API and platform abstraction layer + * + */ +typedef struct { + VL53L0X_DevData_t Data; /*!< embed ST Ewok Dev data as "Data"*/ + + /*!< user specific field */ + uint8_t I2cDevAddr; /*!< i2c device address user specific field */ + uint8_t comms_type; /*!< Type of comms : VL53L0X_COMMS_I2C or VL53L0X_COMMS_SPI */ + uint16_t comms_speed_khz; /*!< Comms speed [kHz] : typically 400kHz for I2C */ + +} VL53L0X_Dev_t; + + +/** + * @brief Declare the device Handle as a pointer of the structure @a VL53L0X_Dev_t. + * + */ +typedef VL53L0X_Dev_t *VL53L0X_DEV; + +/** + * @def PALDevDataGet + * @brief Get ST private structure @a VL53L0X_DevData_t data access + * + * @param Dev Device Handle + * @param field ST structure field name + * It maybe used and as real data "ref" not just as "get" for sub-structure item + * like PALDevDataGet(FilterData.field)[i] or PALDevDataGet(FilterData.MeasurementIndex)++ + */ +#define PALDevDataGet(Dev, field) (Dev->Data.field) + +/** + * @def PALDevDataSet(Dev, field, data) + * @brief Set ST private structure @a VL53L0X_DevData_t data field + * @param Dev Device Handle + * @param field ST structure field name + * @param data Data to be set + */ +#define PALDevDataSet(Dev, field, data) (Dev->Data.field)=(data) + + +/** + * @defgroup VL53L0X_registerAccess_group PAL Register Access Functions + * @brief PAL Register Access Functions + * @{ + */ + +/** + * Lock comms interface to serialize all commands to a shared I2C interface for a specific device + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_LockSequenceAccess(VL53L0X_DEV Dev); + +/** + * Unlock comms interface to serialize all commands to a shared I2C interface for a specific device + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_UnlockSequenceAccess(VL53L0X_DEV Dev); + + +/** + * Writes the supplied byte buffer to the device + * @param Dev Device Handle + * @param index The register index + * @param pdata Pointer to uint8_t buffer containing the data to be written + * @param count Number of bytes in the supplied byte buffer + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_WriteMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata, uint32_t count); + +/** + * Reads the requested number of bytes from the device + * @param Dev Device Handle + * @param index The register index + * @param pdata Pointer to the uint8_t buffer to store read data + * @param count Number of uint8_t's to read + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_ReadMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata, uint32_t count); + +/** + * Write single byte register + * @param Dev Device Handle + * @param index The register index + * @param data 8 bit register data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_WrByte(VL53L0X_DEV Dev, uint8_t index, uint8_t data); + +/** + * Write word register + * @param Dev Device Handle + * @param index The register index + * @param data 16 bit register data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_WrWord(VL53L0X_DEV Dev, uint8_t index, uint16_t data); + +/** + * Write double word (4 byte) register + * @param Dev Device Handle + * @param index The register index + * @param data 32 bit register data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_WrDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t data); + +/** + * Read single byte register + * @param Dev Device Handle + * @param index The register index + * @param data pointer to 8 bit data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_RdByte(VL53L0X_DEV Dev, uint8_t index, uint8_t *data); + +/** + * Read word (2byte) register + * @param Dev Device Handle + * @param index The register index + * @param data pointer to 16 bit data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_RdWord(VL53L0X_DEV Dev, uint8_t index, uint16_t *data); + +/** + * Read dword (4byte) register + * @param Dev Device Handle + * @param index The register index + * @param data pointer to 32 bit data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_RdDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t *data); + +/** + * Threat safe Update (read/modify/write) single byte register + * + * Final_reg = (Initial_reg & and_data) |or_data + * + * @param Dev Device Handle + * @param index The register index + * @param AndData 8 bit and data + * @param OrData 8 bit or data + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_UpdateByte(VL53L0X_DEV Dev, uint8_t index, uint8_t AndData, uint8_t OrData); + +/** @} end of VL53L0X_registerAccess_group */ + + +/** + * @brief execute delay in all polling API call + * + * A typical multi-thread or RTOs implementation is to sleep the task for some 5ms (with 100Hz max rate faster polling is not needed) + * if nothing specific is need you can define it as an empty/void macro + * @code + * #define VL53L0X_PollingDelay(...) (void)0 + * @endcode + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_PollingDelay(VL53L0X_DEV Dev); /* usually best implemented as a real function */ + +/** @} end of VL53L0X_platform_group */ + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_PLATFORM_H_ */ + + + +
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X_platform_log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X_platform_log.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,119 @@ +/******************************************************************************* +Copyright © 2015, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * 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, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. +********************************************************************************/ + + +#ifndef _VL53L0X_PLATFORM_LOG_H_ +#define _VL53L0X_PLATFORM_LOG_H_ + +#include <stdio.h> +#include <string.h> +/* LOG Functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file vl53l0_platform_log.h + * + * @brief platform log function definition + */ + +//#define VL53L0X_LOG_ENABLE 0 + +enum { + TRACE_LEVEL_NONE, + TRACE_LEVEL_ERRORS, + TRACE_LEVEL_WARNING, + TRACE_LEVEL_INFO, + TRACE_LEVEL_DEBUG, + TRACE_LEVEL_ALL, + TRACE_LEVEL_IGNORE +}; + +enum { + TRACE_FUNCTION_NONE = 0, + TRACE_FUNCTION_I2C = 1, + TRACE_FUNCTION_ALL = 0x7fffffff //all bits except sign +}; + +enum { + TRACE_MODULE_NONE = 0x0, + TRACE_MODULE_API = 0x1, + TRACE_MODULE_PLATFORM = 0x2, + TRACE_MODULE_ALL = 0x7fffffff //all bits except sign +}; + + +#ifdef VL53L0X_LOG_ENABLE + +#include <sys/time.h> + +extern uint32_t _trace_level; + + + +int32_t VL53L0X_trace_config(char *filename, uint32_t modules, uint32_t level, uint32_t functions); + +void trace_print_module_function(uint32_t module, uint32_t level, uint32_t function, const char *format, ...); + + +//extern FILE * log_file; + +#define LOG_GET_TIME() (int)clock() + +#define _LOG_FUNCTION_START(module, fmt, ... ) \ + trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%ld <START> %s "fmt"\n", LOG_GET_TIME(), __FUNCTION__, ##__VA_ARGS__); + +#define _LOG_FUNCTION_END(module, status, ... )\ + trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%ld <END> %s %d\n", LOG_GET_TIME(), __FUNCTION__, (int)status, ##__VA_ARGS__) + +#define _LOG_FUNCTION_END_FMT(module, status, fmt, ... )\ + trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%ld <END> %s %d "fmt"\n", LOG_GET_TIME(), __FUNCTION__, (int)status,##__VA_ARGS__) + +// __func__ is gcc only +#define VL53L0X_ErrLog( fmt, ...) fprintf(stderr, "VL53L0X_ErrLog %s" fmt "\n", __func__, ##__VA_ARGS__) + +#else /* VL53L0X_LOG_ENABLE no logging */ +#define VL53L0X_ErrLog(...) (void)0 +#define _LOG_FUNCTION_START(module, fmt, ... ) (void)0 +#define _LOG_FUNCTION_END(module, status, ... ) (void)0 +#define _LOG_FUNCTION_END_FMT(module, status, fmt, ... ) (void)0 +#endif /* else */ + +#define VL53L0X_COPYSTRING(str, ...) strcpy(str, ##__VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_PLATFORM_LOG_H_ */ + + + +
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X_tuning.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X_tuning.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,147 @@ +/******************************************************************************* +Copyright © 2016, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * 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, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. +*******************************************************************************/ + + +#ifndef _VL53L0X_TUNING_H_ +#define _VL53L0X_TUNING_H_ + +#include "VL53L0X_def.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +uint8_t DefaultTuningSettings[] = { + + /* update 02/11/2015_v36 */ + 0x01, 0xFF, 0x01, + 0x01, 0x00, 0x00, + + 0x01, 0xFF, 0x00, + 0x01, 0x09, 0x00, + 0x01, 0x10, 0x00, + 0x01, 0x11, 0x00, + + 0x01, 0x24, 0x01, + 0x01, 0x25, 0xff, + 0x01, 0x75, 0x00, + + 0x01, 0xFF, 0x01, + 0x01, 0x4e, 0x2c, + 0x01, 0x48, 0x00, + 0x01, 0x30, 0x20, + + 0x01, 0xFF, 0x00, + 0x01, 0x30, 0x09, /* mja changed from 0x64. */ + 0x01, 0x54, 0x00, + 0x01, 0x31, 0x04, + 0x01, 0x32, 0x03, + 0x01, 0x40, 0x83, + 0x01, 0x46, 0x25, + 0x01, 0x60, 0x00, + 0x01, 0x27, 0x00, + 0x01, 0x50, 0x06, + 0x01, 0x51, 0x00, + 0x01, 0x52, 0x96, + 0x01, 0x56, 0x08, + 0x01, 0x57, 0x30, + 0x01, 0x61, 0x00, + 0x01, 0x62, 0x00, + 0x01, 0x64, 0x00, + 0x01, 0x65, 0x00, + 0x01, 0x66, 0xa0, + + 0x01, 0xFF, 0x01, + 0x01, 0x22, 0x32, + 0x01, 0x47, 0x14, + 0x01, 0x49, 0xff, + 0x01, 0x4a, 0x00, + + 0x01, 0xFF, 0x00, + 0x01, 0x7a, 0x0a, + 0x01, 0x7b, 0x00, + 0x01, 0x78, 0x21, + + 0x01, 0xFF, 0x01, + 0x01, 0x23, 0x34, + 0x01, 0x42, 0x00, + 0x01, 0x44, 0xff, + 0x01, 0x45, 0x26, + 0x01, 0x46, 0x05, + 0x01, 0x40, 0x40, + 0x01, 0x0E, 0x06, + 0x01, 0x20, 0x1a, + 0x01, 0x43, 0x40, + + 0x01, 0xFF, 0x00, + 0x01, 0x34, 0x03, + 0x01, 0x35, 0x44, + + 0x01, 0xFF, 0x01, + 0x01, 0x31, 0x04, + 0x01, 0x4b, 0x09, + 0x01, 0x4c, 0x05, + 0x01, 0x4d, 0x04, + + + 0x01, 0xFF, 0x00, + 0x01, 0x44, 0x00, + 0x01, 0x45, 0x20, + 0x01, 0x47, 0x08, + 0x01, 0x48, 0x28, + 0x01, 0x67, 0x00, + 0x01, 0x70, 0x04, + 0x01, 0x71, 0x01, + 0x01, 0x72, 0xfe, + 0x01, 0x76, 0x00, + 0x01, 0x77, 0x00, + + 0x01, 0xFF, 0x01, + 0x01, 0x0d, 0x01, + + 0x01, 0xFF, 0x00, + 0x01, 0x80, 0x01, + 0x01, 0x01, 0xF8, + + 0x01, 0xFF, 0x01, + 0x01, 0x8e, 0x01, + 0x01, 0x00, 0x01, + 0x01, 0xFF, 0x00, + 0x01, 0x80, 0x00, + + 0x00, 0x00, 0x00 +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_TUNING_H_ */ +
diff -r f16727052990 -r 8ac15bf6d635 VL53L0X_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VL53L0X_types.h Thu Jun 06 09:21:39 2019 +0000 @@ -0,0 +1,112 @@ +/******************************************************************************* +Copyright © 2015, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * 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, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. +********************************************************************************/ +/** + * @file vl53l0_types.h + * @brief VL53L0 types definition + */ + +#ifndef VL53L0X_TYPES_H_ +#define VL53L0X_TYPES_H_ + +/** @defgroup porting_type Basic type definition + * @ingroup VL53L0X_platform_group + * + * @brief file vl53l0_types.h files hold basic type definition that may requires porting + * + * contains type that must be defined for the platform\n + * when target platform and compiler provide stdint.h and stddef.h it is enough to include it.\n + * If stdint.h is not available review and adapt all signed and unsigned 8/16/32 bits basic types. \n + * If stddef.h is not available review and adapt NULL definition . + */ +#include <stdint.h> +#include <stddef.h> + +#ifndef NULL +#error "Error NULL definition should be done. Please add required include " +#endif + + +#if ! defined(STDINT_H) && !defined(_GCC_STDINT_H) &&!defined(__STDINT_DECLS) && !defined(_GCC_WRAP_STDINT_H) + +#pragma message("Please review type definition of STDINT define for your platform and add to list above ") + +/* + * target platform do not provide stdint or use a different #define than above + * to avoid seeing the message below addapt the #define list above or implement + * all type and delete these pragma + */ + +/** \ingroup VL53L0X_portingType_group + * @{ + */ + + +typedef unsigned long long uint64_t; + + +/** @brief Typedef defining 32 bit unsigned int type.\n + * The developer should modify this to suit the platform being deployed. + */ +typedef unsigned int uint32_t; + +/** @brief Typedef defining 32 bit int type.\n + * The developer should modify this to suit the platform being deployed. + */ +typedef int int32_t; + +/** @brief Typedef defining 16 bit unsigned short type.\n + * The developer should modify this to suit the platform being deployed. + */ +typedef unsigned short uint16_t; + +/** @brief Typedef defining 16 bit short type.\n + * The developer should modify this to suit the platform being deployed. + */ +typedef short int16_t; + +/** @brief Typedef defining 8 bit unsigned char type.\n + * The developer should modify this to suit the platform being deployed. + */ +typedef unsigned char uint8_t; + +/** @brief Typedef defining 8 bit char type.\n + * The developer should modify this to suit the platform being deployed. + */ +typedef signed char int8_t; + +/** @} */ +#endif /* _STDINT_H */ + + +/** use where fractional values are expected + * + * Given a floating point value f it's .16 bit point is (int)(f*(1<<16))*/ +typedef uint32_t FixPoint1616_t; + +#endif /* VL53L0X_TYPES_H_ */ +
diff -r f16727052990 -r 8ac15bf6d635 vl53L1x_I2c.h --- a/vl53L1x_I2c.h Mon Jan 28 10:14:03 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* Define to prevent from recursive inclusion --------------------------------*/ -#ifndef __DEV_53L1X_I2C_H -#define __DEV_53L1X_I2C_H - -/* Includes ------------------------------------------------------------------*/ -#include "mbed.h" -#include "pinmap.h" - -//Class replacing DevI2C class as it was not implementing a 16bit address registers -class vl53L1X_DevI2C : public I2C -{ -public: - /** Create a DevI2C Master interface, connected to the specified pins - * - * @param sda I2C data line pin - * @param scl I2C clock line pin - */ - vl53L1X_DevI2C(PinName sda, PinName scl) : I2C(sda, scl) {} - - /** - * @brief Writes a buffer towards the I2C peripheral device. - * @param pBuffer pointer to the byte-array data to send - * @param DeviceAddr specifies the peripheral device slave address. - * @param RegisterAddr specifies the internal address register - * where to start writing to (must be correctly masked). - * @param NumByteToWrite number of bytes to be written. - * @retval 0 if ok, - * @retval -1 if an I2C error has occured, or - * @retval -2 on temporary buffer overflow (i.e. NumByteToWrite was too high) - * @note On some devices if NumByteToWrite is greater - * than one, the RegisterAddr must be masked correctly! - */ - int v53l1x_i2c_write(uint8_t* pBuffer, uint8_t DeviceAddr, uint16_t RegisterAddr, - 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; - } - - /** - * @brief Reads a buffer from the I2C peripheral device. - * @param pBuffer pointer to the byte-array to read data in to - * @param DeviceAddr specifies the peripheral device slave address. - * @param RegisterAddr specifies the internal address register - * where to start reading from (must be correctly masked). - * @param NumByteToRead number of bytes to be read. - * @retval 0 if ok, - * @retval -1 if an I2C error has occured - * @note On some devices if NumByteToWrite is greater - * than one, the RegisterAddr must be masked correctly! - */ - int v53l1x_i2c_read(uint8_t* pBuffer, uint8_t DeviceAddr, uint16_t RegisterAddr, - uint16_t NumByteToRead) { - int ret; - uint8_t ExpanderData[2]; - ExpanderData[0] = RegisterAddr >> 8; - ExpanderData[1] = RegisterAddr & 0x0FF; - /* Send device address, with no STOP condition */ - ret = write(DeviceAddr, (const char*)ExpanderData, 2, true); - if(!ret) { - /* Read data, with STOP condition */ - ret = read(DeviceAddr, (char*)pBuffer, NumByteToRead, false); - } - - if(ret) return -1; - return 0; - } - -private: - static const unsigned int TEMP_BUF_SIZE = 32; -}; - -#endif /* __DEV_53L1X_I2C_H */ \ No newline at end of file
diff -r f16727052990 -r 8ac15bf6d635 vl53l1x_class.cpp --- a/vl53l1x_class.cpp Mon Jan 28 10:14:03 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1074 +0,0 @@ -/** - ****************************************************************************** - * @file vl53l1x_class.cpp - * @author JS - * @version V0.0.1 - * @date 15-January-2019 - * @brief Implementation file for the VL53L1 sensor component 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 "vl53l1x_class.h" - - -#define ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x001E -#define MM_CONFIG__INNER_OFFSET_MM 0x0020 -#define MM_CONFIG__OUTER_OFFSET_MM 0x0022 - -#include "vl53l1x_configuration.h" - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetSWVersion(VL53L1X_Version_t *pVersion) -{ - VL53L1X_ERROR Status = 0; - - pVersion->major = VL53L1X_IMPLEMENTATION_VER_MAJOR; - pVersion->minor = VL53L1X_IMPLEMENTATION_VER_MINOR; - pVersion->build = VL53L1X_IMPLEMENTATION_VER_SUB; - pVersion->revision = VL53L1X_IMPLEMENTATION_VER_REVISION; - return Status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_SetI2CAddress(uint8_t new_address) -{ - VL53L1X_ERROR status = 0; - - Device->I2cDevAddr = new_address; - status = VL53L1_WrByte(Device, VL53L1_I2C_SLAVE__DEVICE_ADDRESS, new_address >> 1); - return status; -} - -int VL53L1X::init_sensor(uint8_t new_addr) -{ - Device->I2cDevAddr = new_addr; - int status = 0; - VL53L1_Off(); - VL53L1_On(); - - status = is_present(); - if (!status) { - printf("Failed to init VL53L0X sensor!\n\r"); - return status; - } - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_SensorInit() -{ - VL53L1X_ERROR status = 0; - uint8_t Addr = 0x00; - - for (Addr = 0x2D; Addr <= 0x87; Addr++){ - status = VL53L1_WrByte(Device, Addr, VL51L1X_DEFAULT_CONFIGURATION[Addr - 0x2D]); - if (status != 0) - { - printf("Writing config failed - %d\r\n", status); - } - } - - uint16_t sensorID= 0; - status = VL53L1X_GetSensorId(&sensorID); - printf("Sensor id is - %d (%X)\r\n", sensorID, sensorID); - - status = VL53L1X_StartRanging(); - if (status != 0) - { - printf("start ranging failed - %d\r\n", status); - } - - status = VL53L1X_ClearInterrupt(); - status = VL53L1X_StopRanging(); - status = VL53L1_WrByte(Device, VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, 0x09); /* two bounds VHV */ - status = VL53L1_WrByte(Device, 0x0B, 0); /* start VHV from the previous temperature */ - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_ClearInterrupt() -{ - VL53L1X_ERROR status = 0; - - status = VL53L1_WrByte(Device, SYSTEM__INTERRUPT_CLEAR, 0x01); - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_SetInterruptPolarity(uint8_t NewPolarity) -{ - uint8_t Temp; - VL53L1X_ERROR status = 0; - - status = VL53L1_RdByte(Device, GPIO_HV_MUX__CTRL, &Temp); - Temp = Temp & 0xEF; - status = VL53L1_WrByte(Device, GPIO_HV_MUX__CTRL, Temp | (!(NewPolarity & 1)) << 4); - return status; -} - - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetInterruptPolarity(uint8_t *pInterruptPolarity) -{ - uint8_t Temp; - VL53L1X_ERROR status = 0; - - status = VL53L1_RdByte(Device, GPIO_HV_MUX__CTRL, &Temp); - Temp = Temp & 0x10; - *pInterruptPolarity = !(Temp>>4); - return status; -} - - - -VL53L1X_ERROR VL53L1X::VL53L1X_StartRanging() -{ - VL53L1X_ERROR status = 0; -/* - uint8_t Addr = 0x00; - - for (Addr = 0x2D; Addr <= 0x87; Addr++){ - status = VL53L1_WrByte(Device, Addr, VL51L1X_DEFAULT_CONFIGURATION[Addr - 0x2D]); - } -*/ - status = VL53L1_WrByte(Device, SYSTEM__MODE_START, 0x40); /* Enable VL53L1X */ - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_StopRanging() -{ - VL53L1X_ERROR status = 0; - - status = VL53L1_WrByte(Device, SYSTEM__MODE_START, 0x00); /* Disable VL53L1X */ - return status; -} - - - -VL53L1X_ERROR VL53L1X::VL53L1X_CheckForDataReady(uint8_t *isDataReady) -{ - uint8_t Temp; - uint8_t IntPol; - VL53L1X_ERROR status = 0; - - status = VL53L1X_GetInterruptPolarity(&IntPol); - status = VL53L1_RdByte(Device, GPIO__TIO_HV_STATUS, &Temp); - /* Read in the register to check if a new value is available */ - if (status == 0){ - if ((Temp & 1) == IntPol) - *isDataReady = 1; - else - *isDataReady = 0; - } - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_SetTimingBudgetInMs(uint16_t TimingBudgetInMs) -{ - uint16_t DM; - VL53L1X_ERROR status=0; - - status = VL53L1X_GetDistanceMode(&DM); - if (DM == 0) - return 1; - else if (DM == 1) { /* Short DistanceMode */ - switch (TimingBudgetInMs) { - case 15: /* only available in short distance mode */ - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x01D); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x0027); - break; - case 20: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x0051); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x006E); - break; - case 33: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x00D6); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x006E); - break; - case 50: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x1AE); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x01E8); - break; - case 100: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x02E1); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x0388); - break; - case 200: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x03E1); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x0496); - break; - case 500: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x0591); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x05C1); - break; - default: - status = 1; - break; - } - } else { - switch (TimingBudgetInMs) { - case 20: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x001E); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x0022); - break; - case 33: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x0060); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x006E); - break; - case 50: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x00AD); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x00C6); - break; - case 100: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x01CC); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x01EA); - break; - case 200: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x02D9); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x02F8); - break; - case 500: - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, - 0x048F); - VL53L1_WrWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_B_HI, - 0x04A4); - break; - default: - status = 1; - break; - } - } - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_GetTimingBudgetInMs(uint16_t *pTimingBudget) -{ - uint16_t Temp; - VL53L1X_ERROR status = 0; - - status = VL53L1_RdWord(Device, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, &Temp); - switch (Temp) { - case 0x001D : - *pTimingBudget = 15; - break; - case 0x0051 : - case 0x001E : - *pTimingBudget = 20; - break; - case 0x00D6 : - case 0x0060 : - *pTimingBudget = 33; - break; - case 0x1AE : - case 0x00AD : - *pTimingBudget = 50; - break; - case 0x02E1 : - case 0x01CC : - *pTimingBudget = 100; - break; - case 0x03E1 : - case 0x02D9 : - *pTimingBudget = 200; - break; - case 0x0591 : - case 0x048F : - *pTimingBudget = 500; - break; - default: - *pTimingBudget = 0; - break; - } - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_SetDistanceMode(uint16_t DM) -{ - uint16_t TB; - VL53L1X_ERROR status = 0; - - status = VL53L1X_GetTimingBudgetInMs(&TB); - - - switch (DM) { - case 1: - status = VL53L1_WrByte(Device, PHASECAL_CONFIG__TIMEOUT_MACROP, 0x14); - status = VL53L1_WrByte(Device, RANGE_CONFIG__VCSEL_PERIOD_A, 0x07); - status = VL53L1_WrByte(Device, RANGE_CONFIG__VCSEL_PERIOD_B, 0x05); - status = VL53L1_WrByte(Device, RANGE_CONFIG__VALID_PHASE_HIGH, 0x38); - status = VL53L1_WrWord(Device, SD_CONFIG__WOI_SD0, 0x0705); - status = VL53L1_WrWord(Device, SD_CONFIG__INITIAL_PHASE_SD0, 0x0606); - break; - case 2: - status = VL53L1_WrByte(Device, PHASECAL_CONFIG__TIMEOUT_MACROP, 0x0A); - status = VL53L1_WrByte(Device, RANGE_CONFIG__VCSEL_PERIOD_A, 0x0F); - status = VL53L1_WrByte(Device, RANGE_CONFIG__VCSEL_PERIOD_B, 0x0D); - status = VL53L1_WrByte(Device, RANGE_CONFIG__VALID_PHASE_HIGH, 0xB8); - status = VL53L1_WrWord(Device, SD_CONFIG__WOI_SD0, 0x0F0D); - status = VL53L1_WrWord(Device, SD_CONFIG__INITIAL_PHASE_SD0, 0x0E0E); - break; - default: - break; - } - status = VL53L1X_SetTimingBudgetInMs(TB); - return status; -} - - - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetDistanceMode(uint16_t *DM) -{ - uint8_t TempDM, status=0; - - status = VL53L1_RdByte(Device,PHASECAL_CONFIG__TIMEOUT_MACROP, &TempDM); - if (TempDM == 0x14) - *DM=1; - if(TempDM == 0x0A) - *DM=2; - return status; -} - - - -VL53L1X_ERROR VL53L1X::VL53L1X_SetInterMeasurementInMs(uint16_t InterMeasMs) -{ - uint16_t ClockPLL; - VL53L1X_ERROR status = 0; - - status = VL53L1_RdWord(Device, VL53L1_RESULT__OSC_CALIBRATE_VAL, &ClockPLL); - ClockPLL = ClockPLL&0x3FF; - VL53L1_WrDWord(Device, VL53L1_SYSTEM__INTERMEASUREMENT_PERIOD, - (uint32_t)(ClockPLL * InterMeasMs * 1.075)); - return status; - -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetInterMeasurementInMs(uint16_t *pIM) -{ - uint16_t ClockPLL; - VL53L1X_ERROR status = 0; - uint32_t tmp; - - status = VL53L1_RdDWord(Device,VL53L1_SYSTEM__INTERMEASUREMENT_PERIOD, &tmp); - *pIM = (uint16_t)tmp; - status = VL53L1_RdWord(Device, VL53L1_RESULT__OSC_CALIBRATE_VAL, &ClockPLL); - ClockPLL = ClockPLL&0x3FF; - *pIM= (uint16_t)(*pIM/(ClockPLL*1.065)); - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_BootState(uint8_t *state) -{ - VL53L1X_ERROR status = 0; - uint8_t tmp = 0; - - status = VL53L1_RdByte(Device,VL53L1_FIRMWARE__SYSTEM_STATUS, &tmp); - *state = tmp; - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetSensorId(uint16_t *sensorId) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp = 0; - - status = VL53L1_RdWord(Device, VL53L1_IDENTIFICATION__MODEL_ID, &tmp); - *sensorId = tmp; - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetDistance(uint16_t *distance) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = (VL53L1_RdWord(Device, - VL53L1_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0, &tmp)); - *distance = tmp; - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_GetSignalPerSpad(uint16_t *signalRate) -{ - VL53L1X_ERROR status = 0; - uint16_t SpNb=1, signal; - - status = VL53L1_RdWord(Device, - VL53L1_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0, &signal); - status = VL53L1_RdWord(Device, - VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0, &SpNb); - *signalRate = (uint16_t) (2000.0*signal/SpNb); - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetAmbientPerSpad(uint16_t *ambPerSp) -{ - VL53L1X_ERROR status=0; - uint16_t AmbientRate, SpNb=1; - - status = VL53L1_RdWord(Device, RESULT__AMBIENT_COUNT_RATE_MCPS_SD, &AmbientRate); - status = VL53L1_RdWord(Device, VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0, &SpNb); - *ambPerSp=(uint16_t) (2000.0 * AmbientRate / SpNb); - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetSignalRate(uint16_t *signal) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = VL53L1_RdWord(Device, - VL53L1_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0, &tmp); - *signal = tmp*8; - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetSpadNb(uint16_t *spNb) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = VL53L1_RdWord(Device, - VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0, &tmp); - *spNb = tmp >> 8; - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetAmbientRate(uint16_t *ambRate) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = VL53L1_RdWord(Device, RESULT__AMBIENT_COUNT_RATE_MCPS_SD, &tmp); - *ambRate = tmp*8; - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetRangeStatus(uint8_t *rangeStatus) -{ - VL53L1X_ERROR status = 0; - uint8_t RgSt; - - status = VL53L1_RdByte(Device, VL53L1_RESULT__RANGE_STATUS, &RgSt); - RgSt = RgSt&0x1F; - switch (RgSt) { - case 9: - RgSt = 0; - break; - case 6: - RgSt = 1; - break; - case 4: - RgSt = 2; - break; - case 8: - RgSt = 3; - break; - case 5: - RgSt = 4; - break; - case 3: - RgSt = 5; - break; - case 19: - RgSt = 6; - break; - case 7: - RgSt = 7; - break; - case 12: - RgSt = 9; - break; - case 18: - RgSt = 10; - break; - case 22: - RgSt = 11; - break; - case 23: - RgSt = 12; - break; - case 13: - RgSt = 13; - break; - default: - RgSt = 255; - break; - } - *rangeStatus = RgSt; - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_SetOffset(int16_t OffsetValue) -{ - VL53L1X_ERROR status = 0; - int16_t Temp; - - Temp = (OffsetValue*4); - VL53L1_WrWord(Device, ALGO__PART_TO_PART_RANGE_OFFSET_MM, - (uint16_t)Temp); - VL53L1_WrWord(Device, MM_CONFIG__INNER_OFFSET_MM, 0x0); - VL53L1_WrWord(Device, MM_CONFIG__OUTER_OFFSET_MM, 0x0); - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetOffset(int16_t *offset) -{ - VL53L1X_ERROR status = 0; - uint16_t Temp; - - status = VL53L1_RdWord(Device,ALGO__PART_TO_PART_RANGE_OFFSET_MM, &Temp); - Temp = Temp<<3; - Temp = Temp >>5; - *offset = (int16_t)(Temp); - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_SetXtalk(uint16_t XtalkValue) -{ -/* XTalkValue in count per second to avoid float type */ - VL53L1X_ERROR status = 0; - - status = VL53L1_WrWord(Device, - ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS, - 0x0000); - status = VL53L1_WrWord(Device, ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS, - 0x0000); - status = VL53L1_WrWord(Device, ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS, - (XtalkValue<<9)/1000); /* * << 9 (7.9 format) and /1000 to convert cps to kpcs */ - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetXtalk(uint16_t *xtalk ) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = VL53L1_RdWord(Device,ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS, &tmp); - *xtalk = (tmp*1000)>>9; /* * 1000 to convert kcps to cps and >> 9 (7.9 format) */ - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_SetDistanceThreshold(uint16_t ThreshLow, - uint16_t ThreshHigh, uint8_t Window, - uint8_t IntOnNoTarget) -{ - VL53L1X_ERROR status = 0; - uint8_t Temp = 0; - - status = VL53L1_RdByte(Device, SYSTEM__INTERRUPT_CONFIG_GPIO, &Temp); - Temp = Temp & 0x47; - if (IntOnNoTarget == 0) { - status = VL53L1_WrByte(Device, SYSTEM__INTERRUPT_CONFIG_GPIO, - (Temp | (Window & 0x07))); - } else { - status = VL53L1_WrByte(Device, SYSTEM__INTERRUPT_CONFIG_GPIO, - ((Temp | (Window & 0x07)) | 0x40)); - } - status = VL53L1_WrWord(Device, SYSTEM__THRESH_HIGH, ThreshHigh); - status = VL53L1_WrWord(Device, SYSTEM__THRESH_LOW, ThreshLow); - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetDistanceThresholdWindow(uint16_t *window) -{ - VL53L1X_ERROR status = 0; - uint8_t tmp; - status = VL53L1_RdByte(Device,SYSTEM__INTERRUPT_CONFIG_GPIO, &tmp); - *window = (uint16_t)(tmp & 0x7); - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_GetDistanceThresholdLow(uint16_t *low) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = VL53L1_RdWord(Device,SYSTEM__THRESH_LOW, &tmp); - *low = tmp; - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_GetDistanceThresholdHigh(uint16_t *high) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = VL53L1_RdWord(Device,SYSTEM__THRESH_HIGH, &tmp); - *high = tmp; - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_SetROI(uint16_t X, uint16_t Y) -{ - uint8_t OpticalCenter; - VL53L1X_ERROR status = 0; - - status =VL53L1_RdByte(Device, VL53L1_ROI_CONFIG__MODE_ROI_CENTRE_SPAD, &OpticalCenter); - if (X > 16) - X = 16; - if (Y > 16) - Y = 16; - if (X > 10 || Y > 10){ - OpticalCenter = 199; - } - status = VL53L1_WrByte(Device, ROI_CONFIG__USER_ROI_CENTRE_SPAD, OpticalCenter); - status = VL53L1_WrByte(Device, ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE, - (Y - 1) << 4 | (X - 1)); - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_GetROI_XY(uint16_t *ROI_X, uint16_t *ROI_Y) -{ - VL53L1X_ERROR status = 0; - uint8_t tmp; - - status = VL53L1_RdByte(Device,ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE, &tmp); - *ROI_X = ((uint16_t)tmp & 0x0F) + 1; - *ROI_Y = (((uint16_t)tmp & 0xF0) >> 4) + 1; - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_SetSignalThreshold(uint16_t Signal) -{ - VL53L1X_ERROR status = 0; - - VL53L1_WrWord(Device,RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS,Signal>>3); - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_GetSignalThreshold(uint16_t *signal) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = VL53L1_RdWord(Device, - RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS, &tmp); - *signal = tmp <<3; - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1X_SetSigmaThreshold(uint16_t Sigma) -{ - VL53L1X_ERROR status = 0; - - if(Sigma>(0xFFFF>>2)){ - return 1; - } - /* 16 bits register 14.2 format */ - status = VL53L1_WrWord(Device,RANGE_CONFIG__SIGMA_THRESH,Sigma<<2); - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1X_GetSigmaThreshold(uint16_t *sigma) -{ - VL53L1X_ERROR status = 0; - uint16_t tmp; - - status = VL53L1_RdWord(Device,RANGE_CONFIG__SIGMA_THRESH, &tmp); - *sigma = tmp >> 2; - return status; - -} - -VL53L1X_ERROR VL53L1X::VL53L1X_StartTemperatureUpdate() -{ - VL53L1X_ERROR status = 0; - uint8_t tmp=0; - - status = VL53L1_WrByte(Device,VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,0x81); /* full VHV */ - status = VL53L1_WrByte(Device,0x0B,0x92); - status = VL53L1X_StartRanging(); - while(tmp==0){ - status = VL53L1X_CheckForDataReady(&tmp); - } - tmp = 0; - status = VL53L1X_ClearInterrupt(); - status = VL53L1X_StopRanging(); - status = VL53L1_WrByte(Device, VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, 0x09); /* two bounds VHV */ - status = VL53L1_WrByte(Device, 0x0B, 0); /* start VHV from the previous temperature */ - return status; -} - - /* VL53L1X_calibration.h functions */ - -int8_t VL53L1X::VL53L1X_CalibrateOffset(uint16_t TargetDistInMm, int16_t *offset) -{ - uint8_t i = 0, tmp; - int16_t AverageDistance = 0; - uint16_t distance; - VL53L1X_ERROR status = 0; - - status = VL53L1_WrWord(Device, ALGO__PART_TO_PART_RANGE_OFFSET_MM, 0x0); - status = VL53L1_WrWord(Device, MM_CONFIG__INNER_OFFSET_MM, 0x0); - status = VL53L1_WrWord(Device, MM_CONFIG__OUTER_OFFSET_MM, 0x0); - status = VL53L1X_StartRanging(); /* Enable VL53L1X sensor */ - for (i = 0; i < 50; i++) { - while (tmp == 0){ - status = VL53L1X_CheckForDataReady(&tmp); - } - tmp = 0; - status = VL53L1X_GetDistance(&distance); - status = VL53L1X_ClearInterrupt(); - AverageDistance = AverageDistance + distance; - } - status = VL53L1X_StopRanging(); - AverageDistance = AverageDistance / 50; - *offset = TargetDistInMm - AverageDistance; - status = VL53L1_WrWord(Device, ALGO__PART_TO_PART_RANGE_OFFSET_MM, *offset*4); - return status; -} - - -int8_t VL53L1X::VL53L1X_CalibrateXtalk(uint16_t TargetDistInMm, uint16_t *xtalk) -{ - uint8_t i, tmp= 0; - float AverageSignalRate = 0; - float AverageDistance = 0; - float AverageSpadNb = 0; - uint16_t distance = 0, spadNum; - uint16_t sr; - VL53L1X_ERROR status = 0; - - status = VL53L1_WrWord(Device, 0x0016,0); - status = VL53L1X_StartRanging(); - for (i = 0; i < 50; i++) { - while (tmp == 0){ - status = VL53L1X_CheckForDataReady(&tmp); - } - tmp=0; - status= VL53L1X_GetSignalRate(&sr); - status= VL53L1X_GetDistance(&distance); - status = VL53L1X_ClearInterrupt(); - AverageDistance = AverageDistance + distance; - status = VL53L1X_GetSpadNb(&spadNum); - AverageSpadNb = AverageSpadNb + spadNum; - AverageSignalRate = - AverageSignalRate + sr; - } - status = VL53L1X_StopRanging(); - AverageDistance = AverageDistance / 50; - AverageSpadNb = AverageSpadNb / 50; - AverageSignalRate = AverageSignalRate / 50; - /* Calculate Xtalk value */ - *xtalk = (uint16_t)(512*(AverageSignalRate*(1-(AverageDistance/TargetDistInMm)))/AverageSpadNb); - status = VL53L1_WrWord(Device, 0x0016, *xtalk); - return status; -} - - - - - /* Write and read functions from I2C */ - - -VL53L1X_ERROR VL53L1X::VL53L1_WriteMulti(VL53L1_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count) -{ - int status; - - status = VL53L1_I2CWrite(Dev->I2cDevAddr, index, pdata, (uint16_t)count); - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1_ReadMulti(VL53L1_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count) -{ - int status; - - status = VL53L1_I2CRead(Dev->I2cDevAddr, index, pdata, (uint16_t)count); - - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1_WrByte(VL53L1_DEV Dev, uint16_t index, uint8_t data) -{ - int status; - - status=VL53L1_I2CWrite(Dev->I2cDevAddr, index, &data, 1); - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1_WrWord(VL53L1_DEV Dev, uint16_t index, uint16_t data) -{ - int status; - uint8_t buffer[2]; - - buffer[0] = data >> 8; - buffer[1] = data & 0x00FF; - status=VL53L1_I2CWrite(Dev->I2cDevAddr, index, (uint8_t *)buffer, 2); - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1_WrDWord(VL53L1_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=VL53L1_I2CWrite(Dev->I2cDevAddr, index, (uint8_t *)buffer, 4); - return status; -} - - -VL53L1X_ERROR VL53L1X::VL53L1_RdByte(VL53L1_DEV Dev, uint16_t index, uint8_t *data) -{ - int status; - - status = VL53L1_I2CRead(Dev->I2cDevAddr, index, data, 1); - - if(status) - return -1; - - return 0; -} - -VL53L1X_ERROR VL53L1X::VL53L1_RdWord(VL53L1_DEV Dev, uint16_t index, uint16_t *data) -{ - int status; - uint8_t buffer[2] = {0,0}; - - status = VL53L1_I2CRead(Dev->I2cDevAddr, index, buffer, 2); - if (!status) - { - *data = (buffer[0] << 8) + buffer[1]; - } - return status; - -} - -VL53L1X_ERROR VL53L1X::VL53L1_RdDWord(VL53L1_DEV Dev, uint16_t index, uint32_t *data) -{ - int status; - uint8_t buffer[4] = {0,0,0,0}; - - status = VL53L1_I2CRead(Dev->I2cDevAddr, index, buffer, 4); - if(!status) - { - *data = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]; - } - return status; - -} - -VL53L1X_ERROR VL53L1X::VL53L1_UpdateByte(VL53L1_DEV Dev, uint16_t index, uint8_t AndData, uint8_t OrData) -{ - int status; - uint8_t buffer = 0; - - /* read data direct onto buffer */ - status = VL53L1_I2CRead(Dev->I2cDevAddr, index, &buffer,1); - if (!status) - { - buffer = (buffer & AndData) | OrData; - status = VL53L1_I2CWrite(Dev->I2cDevAddr, index, &buffer, (uint16_t)1); - } - return status; -} - -VL53L1X_ERROR VL53L1X::VL53L1_I2CWrite(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t* pBuffer, uint16_t NumByteToWrite) -{ - int ret; - ret = dev_i2c->v53l1x_i2c_write(pBuffer, DeviceAddr, RegisterAddr, NumByteToWrite); - if (ret) { - return -1; - } - return 0; - -} - -VL53L1X_ERROR VL53L1X::VL53L1_I2CRead(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t* pBuffer, uint16_t NumByteToRead) -{ - int ret; - - ret = dev_i2c->v53l1x_i2c_read(pBuffer, DeviceAddr, RegisterAddr, NumByteToRead); - //ret = dev_i2c->i2c_read(pBuffer, DeviceAddr, RegisterAddr, NumByteToRead); - - if (ret) { - return -1; - } - return 0; -} - - -VL53L1X_ERROR VL53L1X::VL53L1_GetTickCount( - uint32_t *ptick_count_ms) -{ - - /* Returns current tick count in [ms] */ - - VL53L1X_ERROR status = VL53L1_ERROR_NONE; - - //*ptick_count_ms = timeGetTime(); - *ptick_count_ms = 0; - - return status; -} - - - -VL53L1X_ERROR VL53L1X::VL53L1_WaitUs(VL53L1_Dev_t *pdev, int32_t wait_us) -{ - //(void)pdev; - //wait_ms(wait_us/1000); - return VL53L1_ERROR_NONE; -} - - -VL53L1X_ERROR VL53L1X::VL53L1_WaitMs(VL53L1_Dev_t *pdev, int32_t wait_ms) -{ - //(void)pdev; - //wait_ms(wait_ms); - return VL53L1_ERROR_NONE; -} - - -VL53L1X_ERROR VL53L1X::VL53L1_WaitValueMaskEx( - VL53L1_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); - */ - - VL53L1_Error status = VL53L1_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 */ - - VL53L1_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 == VL53L1_ERROR_NONE) && - (polling_time_ms < timeout_ms) && - (found == 0)) { - - if (status == VL53L1_ERROR_NONE) - status = VL53L1_RdByte( - pdev, - index, - &byte_value); - - if ((byte_value & mask) == value) - found = 1; - - if (status == VL53L1_ERROR_NONE && - found == 0 && - poll_delay_ms > 0) - status = VL53L1_WaitMs( - pdev, - poll_delay_ms); - - /* Update polling time (Compare difference rather than absolute to - negate 32bit wrap around issue) */ - VL53L1_GetTickCount(¤t_time_ms); - polling_time_ms = current_time_ms - start_time_ms; - - } - - - if (found == 0 && status == VL53L1_ERROR_NONE) - status = VL53L1_ERROR_TIME_OUT; - - return status; -} - - -
diff -r f16727052990 -r 8ac15bf6d635 vl53l1x_class.h --- a/vl53l1x_class.h Mon Jan 28 10:14:03 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,640 +0,0 @@ -/******************************************************************************* - * @file vl53l1x_class.h - * @author JS - * @version V0.0.1 - * @date 15-January-2019 - * @brief Header file for VL53L1 sensor component - ****************************************************************************** - Copyright © 2019, STMicroelectronics International N.V. - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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. - * 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, FITNESS FOR A PARTICULAR PURPOSE, AND - NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. - IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. 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. - *****************************************************************************/ - -#ifndef __VL53L1X_CLASS_H -#define __VL53L1X_CLASS_H - - -#ifdef _MSC_VER -# ifdef VL53L1X_API_EXPORTS -# define VL53L1X_API __declspec(dllexport) -# else -# define VL53L1X_API -# endif -#else -# define VL53L1X_API -#endif - - -/* Includes ------------------------------------------------------------------*/ -#include "mbed.h" -#include "PinNames.h" -#include "RangeSensor.h" -#include "vl53l1x_error_codes.h" -//#include "DevI2C.h" -#include "vl53L1x_I2c.h" -#include "Stmpe1600.h" - - -#define VL53L1X_IMPLEMENTATION_VER_MAJOR 1 -#define VL53L1X_IMPLEMENTATION_VER_MINOR 0 -#define VL53L1X_IMPLEMENTATION_VER_SUB 1 -#define VL53L1X_IMPLEMENTATION_VER_REVISION 0000 - -typedef int8_t VL53L1X_ERROR; - -//#define SOFT_RESET 0x0000 -#define VL53L1_I2C_SLAVE__DEVICE_ADDRESS 0x0001 -#define VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND 0x0008 -#define ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS 0x0016 -#define ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS 0x0018 -#define ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS 0x001A -#define ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x001E -#define MM_CONFIG__INNER_OFFSET_MM 0x0020 -#define MM_CONFIG__OUTER_OFFSET_MM 0x0022 -#define GPIO_HV_MUX__CTRL 0x0030 -#define GPIO__TIO_HV_STATUS 0x0031 -#define SYSTEM__INTERRUPT_CONFIG_GPIO 0x0046 -#define PHASECAL_CONFIG__TIMEOUT_MACROP 0x004B -#define RANGE_CONFIG__TIMEOUT_MACROP_A_HI 0x005E -#define RANGE_CONFIG__VCSEL_PERIOD_A 0x0060 -#define RANGE_CONFIG__VCSEL_PERIOD_B 0x0063 -#define RANGE_CONFIG__TIMEOUT_MACROP_B_HI 0x0061 -#define RANGE_CONFIG__TIMEOUT_MACROP_B_LO 0x0062 -#define RANGE_CONFIG__SIGMA_THRESH 0x0064 -#define RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS 0x0066 -#define RANGE_CONFIG__VALID_PHASE_HIGH 0x0069 -#define VL53L1_SYSTEM__INTERMEASUREMENT_PERIOD 0x006C -#define SYSTEM__THRESH_HIGH 0x0072 -#define SYSTEM__THRESH_LOW 0x0074 -#define SD_CONFIG__WOI_SD0 0x0078 -#define SD_CONFIG__INITIAL_PHASE_SD0 0x007A -#define ROI_CONFIG__USER_ROI_CENTRE_SPAD 0x007F -#define ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE 0x0080 -#define SYSTEM__SEQUENCE_CONFIG 0x0081 -#define VL53L1_SYSTEM__GROUPED_PARAMETER_HOLD 0x0082 -#define SYSTEM__INTERRUPT_CLEAR 0x0086 -#define SYSTEM__MODE_START 0x0087 -#define VL53L1_RESULT__RANGE_STATUS 0x0089 -#define VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 0x008C -#define RESULT__AMBIENT_COUNT_RATE_MCPS_SD 0x0090 -#define VL53L1_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 0x0096 -#define VL53L1_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 0x0098 -#define VL53L1_RESULT__OSC_CALIBRATE_VAL 0x00DE -#define VL53L1_FIRMWARE__SYSTEM_STATUS 0x00E5 -#define VL53L1_IDENTIFICATION__MODEL_ID 0x010F -#define VL53L1_ROI_CONFIG__MODE_ROI_CENTRE_SPAD 0x013E - - -#define VL53L1X_DEFAULT_DEVICE_ADDRESS 0x52 - -#define VL53L1X_REG_IDENTIFICATION_MODEL_ID 0x010F -/**************************************** - * PRIVATE define do not edit - ****************************************/ - -/** - * @brief defines SW Version - */ -typedef struct { - uint8_t major; /*!< major number */ - uint8_t minor; /*!< minor number */ - uint8_t build; /*!< build number */ - uint32_t revision; /*!< revision number */ -} VL53L1X_Version_t; - - -typedef struct { - - uint8_t I2cDevAddr; - -} VL53L1_Dev_t; - -typedef VL53L1_Dev_t *VL53L1_DEV; - - -/* Classes -------------------------------------------------------------------*/ -/** Class representing a VL53L1 sensor component - */ -class VL53L1X : public RangeSensor -{ - public: - /** Constructor - * @param[in] &i2c device I2C to be used for communication - * @param[in] &pin_gpio1 pin Mbed InterruptIn PinName to be used as component GPIO_1 INT - * @param[in] DevAddr device address, 0x52 by default - */ - VL53L1X(vl53L1X_DevI2C *i2c, DigitalOut *pin, PinName pin_gpio1, uint8_t dev_addr = VL53L1X_DEFAULT_DEVICE_ADDRESS) - : RangeSensor(), dev_i2c(i2c), _gpio0(pin) - { - MyDevice.I2cDevAddr=dev_addr; - Device = &MyDevice; - - _expgpio0 = NULL; - if (pin_gpio1 != NC) { - _gpio1Int = new InterruptIn(pin_gpio1); - } else { - _gpio1Int = NULL; - } - } - - /** Constructor 2 (STMPE1600DigiOut) - * @param[in] i2c device I2C to be used for communication - * @param[in] &pin Gpio Expander STMPE1600DigiOut pin to be used as component GPIO_0 CE - * @param[in] pin_gpio1 pin Mbed InterruptIn PinName to be used as component GPIO_1 INT - * @param[in] device address, 0x29 by default - */ - VL53L1X(vl53L1X_DevI2C *i2c, Stmpe1600DigiOut *pin, PinName pin_gpio1, - uint8_t dev_addr = VL53L1X_DEFAULT_DEVICE_ADDRESS) - : dev_i2c(i2c), _expgpio0(pin) - { - MyDevice.I2cDevAddr=dev_addr; - Device = &MyDevice; - - _gpio0 = NULL; - if (pin_gpio1 != NC) { - _gpio1Int = new InterruptIn(pin_gpio1); - } else { - _gpio1Int = NULL; - } - } - - /** Destructor - */ - virtual ~VL53L1X() - { - if (_gpio1Int != NULL) { - delete _gpio1Int; - } - } - - - - VL53L1_DEV getDevicePtr() { return Device; } - - - /* warning: VL53L1 class inherits from GenericSensor, RangeSensor and LightSensor, that haven`t a destructor. - The warning should request to introduce a virtual destructor to make sure to delete the object */ - - /*** Interface Methods ***/ - /*** High level API ***/ - /** - * @brief PowerOn the sensor - * @return void - */ - /* turns on the sensor */ - virtual void VL53L1_On(void) - { - printf("VL53L1_On\r\n"); - if (_gpio0) { - *_gpio0 = 1; - } else { - if (_expgpio0) { - *_expgpio0 = 1; - } - } - wait_ms(10); - } - - /** - * @brief PowerOff the sensor - * @return void - */ - /* turns off the sensor */ - virtual void VL53L1_Off(void) - { - printf("VL53L1_Off\r\n"); - if (_gpio0) { - *_gpio0 = 0; - } else { - if (_expgpio0) { - *_expgpio0 = 0; - } - } - wait_ms(10); - } - - int is_present() - { - int status; - uint8_t id = 0; - - status = read_id(&id); - if (status) { - printf("Failed to read ID device. Device not present!\n\r"); - } - return status; - } - - /** - * @brief Initialize the sensor with default values - * @return 0 on Success - */ - - VL53L1X_ERROR InitSensor(uint8_t address){ - VL53L1X_ERROR status = 0; - uint8_t sensorState = 0; - VL53L1_Off(); - VL53L1_On(); - status = VL53L1X_SetI2CAddress(address); - - if(!status){ - status = VL53L1X_SensorInit(); - } - - while(!status && !sensorState) { - status = VL53L1X_BootState(&sensorState); - wait_ms(2); - } - - return status; - } - - - -/** - * - * @brief One time device initialization - * @param void - * @return 0 on success, @a #CALIBRATION_WARNING if failed - */ - virtual int init(void *init) - { - return VL53L1X_SensorInit(); - } - - - /** - * @brief Initialize the sensor with default values - * @return "0" on success - */ - int init_sensor(uint8_t new_addr); - - /* Read function of the ID device */ - virtual int read_id(uint8_t *id){ - int status = 0; - uint16_t rl_id = 0; - - uint8_t ExpanderData[2]; - - ExpanderData[0] = 0; - ExpanderData[1] = 0; - rl_id = 0; - dev_i2c->v53l1x_i2c_read(&ExpanderData[0], Device->I2cDevAddr, VL53L1X_REG_IDENTIFICATION_MODEL_ID, 2); - - rl_id = (ExpanderData[0] << 8) + ExpanderData[1]; - printf("Model ID is: %d (%X) \r\n",rl_id, rl_id); - - uint8_t tmp = 0; - ExpanderData[0] = VL53L1_FIRMWARE__SYSTEM_STATUS >> 8; - ExpanderData[1] = VL53L1_FIRMWARE__SYSTEM_STATUS & 0x0FF; - dev_i2c->v53l1x_i2c_read(&tmp, Device->I2cDevAddr, VL53L1_FIRMWARE__SYSTEM_STATUS, 1); - - printf("Firmware system is: %d\r\n",tmp); - - if (rl_id == 0xEACC) { - printf("Device is present %d:\r\n", rl_id); - return status; - } - return -1; - } - - - -/** - * @brief Get ranging result and only that - * @param pRange_mm Pointer to range distance - * @return 0 on success - */ - virtual int get_distance(uint32_t *piData) - { - int status; - uint16_t distance; - status = VL53L1X_GetDistance(&distance); - *piData = (uint32_t) distance; - return status; - } - - -/* VL53L1X_api.h functions */ - - - - /** - * @brief This function returns the SW driver version - */ - VL53L1X_ERROR VL53L1X_GetSWVersion(VL53L1X_Version_t *pVersion); - - /** - * @brief This function sets the sensor I2C address used in case multiple devices application, default address 0x52 - */ - VL53L1X_ERROR VL53L1X_SetI2CAddress(uint8_t new_address); - - /** - * @brief This function loads the 135 bytes default values to initialize the sensor. - * @param dev Device address - * @return 0:success, != 0:failed - */ - VL53L1X_ERROR VL53L1X_SensorInit(); - - /** - * @brief This function clears the interrupt, to be called after a ranging data reading - * to arm the interrupt for the next data ready event. - */ - VL53L1X_ERROR VL53L1X_ClearInterrupt(); - - /** - * @brief This function programs the interrupt polarity\n - * 1=active high (default), 0=active low - */ - VL53L1X_ERROR VL53L1X_SetInterruptPolarity(uint8_t IntPol); - - /** - * @brief This function returns the current interrupt polarity\n - * 1=active high (default), 0=active low - */ - VL53L1X_ERROR VL53L1X_GetInterruptPolarity(uint8_t *pIntPol); - - /** - * @brief This function starts the ranging distance operation\n - * The ranging operation is continuous. The clear interrupt has to be done after each get data to allow the interrupt to raise when the next data is ready\n - * 1=active high (default), 0=active low, use SetInterruptPolarity() to change the interrupt polarity if required. - */ - VL53L1X_ERROR VL53L1X_StartRanging(); - - /** - * @brief This function stops the ranging. - */ - VL53L1X_ERROR VL53L1X_StopRanging(); - - /** - * @brief This function checks if the new ranging data is available by polling the dedicated register. - * @param : isDataReady==0 -> not ready; isDataReady==1 -> ready - */ - VL53L1X_ERROR VL53L1X_CheckForDataReady(uint8_t *isDataReady); - - /** - * @brief This function programs the timing budget in ms. - * Predefined values = 15, 20, 33, 50, 100(default), 200, 500. - */ - VL53L1X_ERROR VL53L1X_SetTimingBudgetInMs(uint16_t TimingBudgetInMs); - - /** - * @brief This function returns the current timing budget in ms. - */ - VL53L1X_ERROR VL53L1X_GetTimingBudgetInMs(uint16_t *pTimingBudgetInMs); - - /** - * @brief This function programs the distance mode (1=short, 2=long(default)). - * Short mode max distance is limited to 1.3 m but better ambient immunity.\n - * Long mode can range up to 4 m in the dark with 200 ms timing budget. - */ - VL53L1X_ERROR VL53L1X_SetDistanceMode(uint16_t DistanceMode); - - /** - * @brief This function returns the current distance mode (1=short, 2=long). - */ - VL53L1X_ERROR VL53L1X_GetDistanceMode(uint16_t *pDistanceMode); - - /** - * @brief This function programs the Intermeasurement period in ms\n - * Intermeasurement period must be >/= timing budget. This condition is not checked by the API, - * the customer has the duty to check the condition. Default = 100 ms - */ - VL53L1X_ERROR VL53L1X_SetInterMeasurementInMs(uint16_t InterMeasurementInMs); - - /** - * @brief This function returns the Intermeasurement period in ms. - */ - VL53L1X_ERROR VL53L1X_GetInterMeasurementInMs(uint16_t * pIM); - - /** - * @brief This function returns the boot state of the device (1:booted, 0:not booted) - */ - VL53L1X_ERROR VL53L1X_BootState(uint8_t *state); - - /** - * @brief This function returns the sensor id, sensor Id must be 0xEEAC - */ - VL53L1X_ERROR VL53L1X_GetSensorId(uint16_t *id); - - /** - * @brief This function returns the distance measured by the sensor in mm - */ - VL53L1X_ERROR VL53L1X_GetDistance(uint16_t *distance); - - /** - * @brief This function returns the returned signal per SPAD in kcps/SPAD. - * With kcps stands for Kilo Count Per Second - */ - VL53L1X_ERROR VL53L1X_GetSignalPerSpad(uint16_t *signalPerSp); - - /** - * @brief This function returns the ambient per SPAD in kcps/SPAD - */ - VL53L1X_ERROR VL53L1X_GetAmbientPerSpad(uint16_t *amb); - - /** - * @brief This function returns the returned signal in kcps. - */ - VL53L1X_ERROR VL53L1X_GetSignalRate(uint16_t *signalRate); - - /** - * @brief This function returns the current number of enabled SPADs - */ - VL53L1X_ERROR VL53L1X_GetSpadNb(uint16_t *spNb); - - /** - * @brief This function returns the ambient rate in kcps - */ - VL53L1X_ERROR VL53L1X_GetAmbientRate(uint16_t *ambRate); - - /** - * @brief This function returns the ranging status error \n - * (0:no error, 1:sigma failed, 2:signal failed, ..., 7:wrap-around) - */ - VL53L1X_ERROR VL53L1X_GetRangeStatus(uint8_t *rangeStatus); - - /** - * @brief This function programs the offset correction in mm - * @param OffsetValue:the offset correction value to program in mm - */ - VL53L1X_ERROR VL53L1X_SetOffset(int16_t OffsetValue); - - /** - * @brief This function returns the programmed offset correction value in mm - */ - VL53L1X_ERROR VL53L1X_GetOffset(int16_t *Offset); - - /** - * @brief This function programs the xtalk correction value in cps (Count Per Second).\n - * This is the number of photons reflected back from the cover glass in cps. - */ - VL53L1X_ERROR VL53L1X_SetXtalk(uint16_t XtalkValue); - - /** - * @brief This function returns the current programmed xtalk correction value in cps - */ - VL53L1X_ERROR VL53L1X_GetXtalk(uint16_t *Xtalk); - - /** - * @brief This function programs the threshold detection mode\n - * Example:\n - * VL53L1X_SetDistanceThreshold(dev,100,300,0,1): Below 100 \n - * VL53L1X_SetDistanceThreshold(dev,100,300,1,1): Above 300 \n - * VL53L1X_SetDistanceThreshold(dev,100,300,2,1): Out of window \n - * VL53L1X_SetDistanceThreshold(dev,100,300,3,1): In window \n - * @param dev : device address - * @param ThreshLow(in mm) : the threshold under which one the device raises an interrupt if Window = 0 - * @param ThreshHigh(in mm) : the threshold above which one the device raises an interrupt if Window = 1 - * @param Window detection mode : 0=below, 1=above, 2=out, 3=in - * @param IntOnNoTarget = 1 (No longer used - just use 1) - */ - VL53L1X_ERROR VL53L1X_SetDistanceThreshold(uint16_t ThreshLow, - uint16_t ThreshHigh, uint8_t Window, - uint8_t IntOnNoTarget); - - /** - * @brief This function returns the window detection mode (0=below; 1=above; 2=out; 3=in) - */ - VL53L1X_ERROR VL53L1X_GetDistanceThresholdWindow(uint16_t *window); - - /** - * @brief This function returns the low threshold in mm - */ - VL53L1X_ERROR VL53L1X_GetDistanceThresholdLow(uint16_t *low); - - /** - * @brief This function returns the high threshold in mm - */ - VL53L1X_ERROR VL53L1X_GetDistanceThresholdHigh(uint16_t *high); - - /** - * @brief This function programs the ROI (Region of Interest)\n - * The ROI position is centered, only the ROI size can be reprogrammed.\n - * The smallest acceptable ROI size = 4\n - * @param X:ROI Width; Y=ROI Height - */ - VL53L1X_ERROR VL53L1X_SetROI(uint16_t X, uint16_t Y); - - /** - *@brief This function returns width X and height Y - */ - VL53L1X_ERROR VL53L1X_GetROI_XY(uint16_t *ROI_X, uint16_t *ROI_Y); - - /** - * @brief This function programs a new signal threshold in kcps (default=1024 kcps\n - */ - VL53L1X_ERROR VL53L1X_SetSignalThreshold(uint16_t signal); - - /** - * @brief This function returns the current signal threshold in kcps - */ - VL53L1X_ERROR VL53L1X_GetSignalThreshold(uint16_t *signal); - - /** - * @brief This function programs a new sigma threshold in mm (default=15 mm) - */ - VL53L1X_ERROR VL53L1X_SetSigmaThreshold(uint16_t sigma); - - /** - * @brief This function returns the current sigma threshold in mm - */ - VL53L1X_ERROR VL53L1X_GetSigmaThreshold(uint16_t *signal); - - /** - * @brief This function performs the temperature calibration. - * It is recommended to call this function any time the temperature might have changed by more than 8 deg C - * without sensor ranging activity for an extended period. - */ - VL53L1X_ERROR VL53L1X_StartTemperatureUpdate(); - - - /* VL53L1X_calibration.h functions */ - - /** - * @brief This function performs the offset calibration.\n - * The function returns the offset value found and programs the offset compensation into the device. - * @param TargetDistInMm target distance in mm, ST recommended 100 mm - * Target reflectance = grey17% - * @return 0:success, !=0: failed - * @return offset pointer contains the offset found in mm - */ - int8_t VL53L1X_CalibrateOffset(uint16_t TargetDistInMm, int16_t *offset); - - /** - * @brief This function performs the xtalk calibration.\n - * The function returns the xtalk value found and programs the xtalk compensation to the device - * @param TargetDistInMm target distance in mm\n - * The target distance : the distance where the sensor start to "under range"\n - * due to the influence of the photons reflected back from the cover glass becoming strong\n - * It's also called inflection point\n - * Target reflectance = grey 17% - * @return 0: success, !=0: failed - * @return xtalk pointer contains the xtalk value found in cps (number of photons in count per second) - */ - int8_t VL53L1X_CalibrateXtalk(uint16_t TargetDistInMm, uint16_t *xtalk); - - - /* Write and read functions from I2C */ - - VL53L1X_ERROR VL53L1_WrByte(VL53L1_DEV dev, uint16_t index, uint8_t data); - VL53L1X_ERROR VL53L1_WrWord(VL53L1_DEV dev, uint16_t index, uint16_t data); - VL53L1X_ERROR VL53L1_WrDWord(VL53L1_DEV dev, uint16_t index, uint32_t data); - VL53L1X_ERROR VL53L1_RdByte(VL53L1_DEV dev, uint16_t index, uint8_t *data); - VL53L1X_ERROR VL53L1_RdWord(VL53L1_DEV dev, uint16_t index, uint16_t *data); - VL53L1X_ERROR VL53L1_RdDWord(VL53L1_DEV dev, uint16_t index, uint32_t *data); - VL53L1X_ERROR VL53L1_UpdateByte(VL53L1_DEV dev, uint16_t index, uint8_t AndData, uint8_t OrData); - - VL53L1X_ERROR VL53L1_WriteMulti(VL53L1_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count); - VL53L1X_ERROR VL53L1_ReadMulti(VL53L1_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count); - - VL53L1X_ERROR VL53L1_I2CWrite(uint8_t dev, uint16_t index, uint8_t *data, uint16_t number_of_bytes); - VL53L1X_ERROR VL53L1_I2CRead(uint8_t dev, uint16_t index, uint8_t *data, uint16_t number_of_bytes); - VL53L1X_ERROR VL53L1_GetTickCount(uint32_t *ptick_count_ms); - VL53L1X_ERROR VL53L1_WaitUs(VL53L1_Dev_t *pdev, int32_t wait_us); - VL53L1X_ERROR VL53L1_WaitMs(VL53L1_Dev_t *pdev, int32_t wait_ms); - - VL53L1X_ERROR VL53L1_WaitValueMaskEx(VL53L1_Dev_t *pdev, uint32_t timeout_ms, uint16_t index, uint8_t value, uint8_t mask, uint32_t poll_delay_ms); - - protected: - - /* IO Device */ - vl53L1X_DevI2C *dev_i2c; - - /* Digital out pin */ - DigitalOut *_gpio0; - /* GPIO expander */ - Stmpe1600DigiOut *_expgpio0; - /* Measure detection IRQ */ - InterruptIn *_gpio1Int; - - ///* Digital out pin */ - //int gpio0; - //int gpio1Int; - /* Device data */ - VL53L1_Dev_t MyDevice; - VL53L1_DEV Device; -}; - - -#endif /* _VL53L1X_CLASS_H_ */ \ No newline at end of file
diff -r f16727052990 -r 8ac15bf6d635 vl53l1x_configuration.h --- a/vl53l1x_configuration.h Mon Jan 28 10:14:03 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -#ifndef __VL53L1X_CONFIGURATION_H -#define __VL53L1X_CONFIGURATION_H - - -const uint8_t VL51L1X_DEFAULT_CONFIGURATION[] = { -0x00, /* 0x2d : set bit 2 and 5 to 1 for fast plus mode (1MHz I2C), else don't touch */ -0x00, /* 0x2e : bit 0 if I2C pulled up at 1.8V, else set bit 0 to 1 (pull up at AVDD) */ -0x00, /* 0x2f : bit 0 if GPIO pulled up at 1.8V, else set bit 0 to 1 (pull up at AVDD) */ -0x01, /* 0x30 : set bit 4 to 0 for active high interrupt and 1 for active low (bits 3:0 must be 0x1), use SetInterruptPolarity() */ -0x02, /* 0x31 : bit 1 = interrupt depending on the polarity, use CheckForDataReady() */ -0x00, /* 0x32 : not user-modifiable */ -0x02, /* 0x33 : not user-modifiable */ -0x08, /* 0x34 : not user-modifiable */ -0x00, /* 0x35 : not user-modifiable */ -0x08, /* 0x36 : not user-modifiable */ -0x10, /* 0x37 : not user-modifiable */ -0x01, /* 0x38 : not user-modifiable */ -0x01, /* 0x39 : not user-modifiable */ -0x00, /* 0x3a : not user-modifiable */ -0x00, /* 0x3b : not user-modifiable */ -0x00, /* 0x3c : not user-modifiable */ -0x00, /* 0x3d : not user-modifiable */ -0xff, /* 0x3e : not user-modifiable */ -0x00, /* 0x3f : not user-modifiable */ -0x0F, /* 0x40 : not user-modifiable */ -0x00, /* 0x41 : not user-modifiable */ -0x00, /* 0x42 : not user-modifiable */ -0x00, /* 0x43 : not user-modifiable */ -0x00, /* 0x44 : not user-modifiable */ -0x00, /* 0x45 : not user-modifiable */ -0x20, /* 0x46 : interrupt configuration 0->level low detection, 1-> level high, 2-> Out of window, 3->In window, 0x20-> New sample ready , TBC */ -0x0b, /* 0x47 : not user-modifiable */ -0x00, /* 0x48 : not user-modifiable */ -0x00, /* 0x49 : not user-modifiable */ -0x02, /* 0x4a : not user-modifiable */ -0x0a, /* 0x4b : not user-modifiable */ -0x21, /* 0x4c : not user-modifiable */ -0x00, /* 0x4d : not user-modifiable */ -0x00, /* 0x4e : not user-modifiable */ -0x05, /* 0x4f : not user-modifiable */ -0x00, /* 0x50 : not user-modifiable */ -0x00, /* 0x51 : not user-modifiable */ -0x00, /* 0x52 : not user-modifiable */ -0x00, /* 0x53 : not user-modifiable */ -0xc8, /* 0x54 : not user-modifiable */ -0x00, /* 0x55 : not user-modifiable */ -0x00, /* 0x56 : not user-modifiable */ -0x38, /* 0x57 : not user-modifiable */ -0xff, /* 0x58 : not user-modifiable */ -0x01, /* 0x59 : not user-modifiable */ -0x00, /* 0x5a : not user-modifiable */ -0x08, /* 0x5b : not user-modifiable */ -0x00, /* 0x5c : not user-modifiable */ -0x00, /* 0x5d : not user-modifiable */ -0x01, /* 0x5e : not user-modifiable */ -0xcc, /* 0x5f : not user-modifiable */ -0x0f, /* 0x60 : not user-modifiable */ -0x01, /* 0x61 : not user-modifiable */ -0xf1, /* 0x62 : not user-modifiable */ -0x0d, /* 0x63 : not user-modifiable */ -0x01, /* 0x64 : Sigma threshold MSB (mm in 14.2 format for MSB+LSB), use SetSigmaThreshold(), default value 90 mm */ -0x68, /* 0x65 : Sigma threshold LSB */ -0x00, /* 0x66 : Min count Rate MSB (MCPS in 9.7 format for MSB+LSB), use SetSignalThreshold() */ -0x80, /* 0x67 : Min count Rate LSB */ -0x08, /* 0x68 : not user-modifiable */ -0xb8, /* 0x69 : not user-modifiable */ -0x00, /* 0x6a : not user-modifiable */ -0x00, /* 0x6b : not user-modifiable */ -0x00, /* 0x6c : Intermeasurement period MSB, 32 bits register, use SetIntermeasurementInMs() */ -0x00, /* 0x6d : Intermeasurement period */ -0x0f, /* 0x6e : Intermeasurement period */ -0x89, /* 0x6f : Intermeasurement period LSB */ -0x00, /* 0x70 : not user-modifiable */ -0x00, /* 0x71 : not user-modifiable */ -0x00, /* 0x72 : distance threshold high MSB (in mm, MSB+LSB), use SetD:tanceThreshold() */ -0x00, /* 0x73 : distance threshold high LSB */ -0x00, /* 0x74 : distance threshold low MSB ( in mm, MSB+LSB), use SetD:tanceThreshold() */ -0x00, /* 0x75 : distance threshold low LSB */ -0x00, /* 0x76 : not user-modifiable */ -0x01, /* 0x77 : not user-modifiable */ -0x0f, /* 0x78 : not user-modifiable */ -0x0d, /* 0x79 : not user-modifiable */ -0x0e, /* 0x7a : not user-modifiable */ -0x0e, /* 0x7b : not user-modifiable */ -0x00, /* 0x7c : not user-modifiable */ -0x00, /* 0x7d : not user-modifiable */ -0x02, /* 0x7e : not user-modifiable */ -0xc7, /* 0x7f : ROI center, use SetROI() */ -0xff, /* 0x80 : XY ROI (X=Width, Y=Height), use SetROI() */ -0x9B, /* 0x81 : not user-modifiable */ -0x00, /* 0x82 : not user-modifiable */ -0x00, /* 0x83 : not user-modifiable */ -0x00, /* 0x84 : not user-modifiable */ -0x01, /* 0x85 : not user-modifiable */ -0x00, /* 0x86 : clear interrupt, use ClearInterrupt() */ -0x00 /* 0x87 : start ranging, use StartRanging() or StopRanging(), If you want an automatic start after VL53L1X_init() call, put 0x40 in location 0x87 */ -}; - -#endif //__VL53L1X_CONFIGURATION_H \ No newline at end of file
diff -r f16727052990 -r 8ac15bf6d635 vl53l1x_error_codes.h --- a/vl53l1x_error_codes.h Mon Jan 28 10:14:03 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,251 +0,0 @@ -/* -* Copyright (c) 2017, STMicroelectronics - All Rights Reserved -* -* This file is part of VL53L1 Core and is dual licensed, -* either 'STMicroelectronics -* Proprietary license' -* or 'BSD 3-clause "New" or "Revised" License' , at your option. -* -******************************************************************************** -* -* 'STMicroelectronics Proprietary license' -* -******************************************************************************** -* -* License terms: STMicroelectronics Proprietary in accordance with licensing -* terms at www.st.com/sla0081 -* -* STMicroelectronics confidential -* Reproduction and Communication of this document is strictly prohibited unless -* specifically authorized in writing by STMicroelectronics. -* -* -******************************************************************************** -* -* Alternatively, VL53L1 Core may be distributed under the terms of -* 'BSD 3-clause "New" or "Revised" License', in which case the following -* provisions apply instead of the ones mentioned above : -* -******************************************************************************** -* -* License terms: BSD 3-clause "New" or "Revised" License. -* -* 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 the copyright holder 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. -* -* -******************************************************************************** -* -*/ - -/** - * @file vl53l1_error_codes.h - * - * @brief Error Code definitions for VL53L1 API. - * - */ - -#ifndef _VL53L1X_ERROR_CODES_H_ -#define _VL53L1X_ERROR_CODES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - -/**************************************** - * PRIVATE define do not edit - ****************************************/ - -/** @defgroup VL53L1_define_Error_group Error and Warning code returned by API - * The following DEFINE are used to identify the PAL ERROR - * @{ - */ - -typedef int8_t VL53L1_Error; - -#define VL53L1_ERROR_NONE ((VL53L1_Error) 0) -#define VL53L1_ERROR_CALIBRATION_WARNING ((VL53L1_Error) - 1) - /*!< Warning invalid calibration data may be in used - \a VL53L1_InitData() - \a VL53L1_GetOffsetCalibrationData - \a VL53L1_SetOffsetCalibrationData */ -#define VL53L1_ERROR_MIN_CLIPPED ((VL53L1_Error) - 2) - /*!< Warning parameter passed was clipped to min before to be applied */ - -#define VL53L1_ERROR_UNDEFINED ((VL53L1_Error) - 3) - /*!< Unqualified error */ -#define VL53L1_ERROR_INVALID_PARAMS ((VL53L1_Error) - 4) - /*!< Parameter passed is invalid or out of range */ -#define VL53L1_ERROR_NOT_SUPPORTED ((VL53L1_Error) - 5) - /*!< Function is not supported in current mode or configuration */ -#define VL53L1_ERROR_RANGE_ERROR ((VL53L1_Error) - 6) - /*!< Device report a ranging error interrupt status */ -#define VL53L1_ERROR_TIME_OUT ((VL53L1_Error) - 7) - /*!< Aborted due to time out */ -#define VL53L1_ERROR_MODE_NOT_SUPPORTED ((VL53L1_Error) - 8) - /*!< Asked mode is not supported by the device */ -#define VL53L1_ERROR_BUFFER_TOO_SMALL ((VL53L1_Error) - 9) - /*!< ... */ -#define VL53L1_ERROR_COMMS_BUFFER_TOO_SMALL ((VL53L1_Error) - 10) - /*!< Supplied buffer is larger than I2C supports */ -#define VL53L1_ERROR_GPIO_NOT_EXISTING ((VL53L1_Error) - 11) - /*!< User tried to setup a non-existing GPIO pin */ -#define VL53L1_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED ((VL53L1_Error) - 12) - /*!< unsupported GPIO functionality */ -#define VL53L1_ERROR_CONTROL_INTERFACE ((VL53L1_Error) - 13) - /*!< error reported from IO functions */ -#define VL53L1_ERROR_INVALID_COMMAND ((VL53L1_Error) - 14) - /*!< The command is not allowed in the current device state - * (power down) */ -#define VL53L1_ERROR_DIVISION_BY_ZERO ((VL53L1_Error) - 15) - /*!< In the function a division by zero occurs */ -#define VL53L1_ERROR_REF_SPAD_INIT ((VL53L1_Error) - 16) - /*!< Error during reference SPAD initialization */ -#define VL53L1_ERROR_GPH_SYNC_CHECK_FAIL ((VL53L1_Error) - 17) - /*!< GPH sync interrupt check fail - API out of sync with device*/ -#define VL53L1_ERROR_STREAM_COUNT_CHECK_FAIL ((VL53L1_Error) - 18) - /*!< Stream count check fail - API out of sync with device */ -#define VL53L1_ERROR_GPH_ID_CHECK_FAIL ((VL53L1_Error) - 19) - /*!< GPH ID check fail - API out of sync with device */ -#define VL53L1_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL ((VL53L1_Error) - 20) - /*!< Zone dynamic config stream count check failed - API out of sync */ -#define VL53L1_ERROR_ZONE_GPH_ID_CHECK_FAIL ((VL53L1_Error) - 21) - /*!< Zone dynamic config GPH ID check failed - API out of sync */ - -#define VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL ((VL53L1_Error) - 22) - /*!< Thrown when run_xtalk_extraction fn has 0 succesful samples - * when using the full array to sample the xtalk. In this case there is - * not enough information to generate new Xtalk parm info. The function - * will exit and leave the current xtalk parameters unaltered */ -#define VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL ((VL53L1_Error) - 23) - /*!< Thrown when run_xtalk_extraction fn has found that the - * avg sigma estimate of the full array xtalk sample is > than the - * maximal limit allowed. In this case the xtalk sample is too noisy for - * measurement. The function will exit and leave the current xtalk parameters - * unaltered. */ - - -#define VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL ((VL53L1_Error) - 24) - /*!< Thrown if there one of stages has no valid offset calibration - * samples. A fatal error calibration not valid */ -#define VL53L1_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL ((VL53L1_Error) - 25) - /*!< Thrown if there one of stages has zero effective SPADS - * Traps the case when MM1 SPADs is zero. - * A fatal error calibration not valid */ -#define VL53L1_ERROR_ZONE_CAL_NO_SAMPLE_FAIL ((VL53L1_Error) - 26) - /*!< Thrown if then some of the zones have no valid samples - * A fatal error calibration not valid */ - -#define VL53L1_ERROR_TUNING_PARM_KEY_MISMATCH ((VL53L1_Error) - 27) - /*!< Thrown if the tuning file key table version does not match with - * expected value. The driver expects the key table version to match - * the compiled default version number in the define - * #VL53L1_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT - * */ - -#define VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS ((VL53L1_Error) - 28) - /*!< Thrown if there are less than 5 good SPADs are available. */ -#define VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH ((VL53L1_Error) - 29) - /*!< Thrown if the final reference rate is greater than - the upper reference rate limit - default is 40 Mcps. - Implies a minimum Q3 (x10) SPAD (5) selected */ -#define VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW ((VL53L1_Error) - 30) - /*!< Thrown if the final reference rate is less than - the lower reference rate limit - default is 10 Mcps. - Implies maximum Q1 (x1) SPADs selected */ - - -#define VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES ((VL53L1_Error) - 31) - /*!< Thrown if there is less than the requested number of - * valid samples. */ -#define VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH ((VL53L1_Error) - 32) - /*!< Thrown if the offset calibration range sigma estimate is greater - * than 8.0 mm. This is the recommended min value to yield a stable - * offset measurement */ -#define VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH ((VL53L1_Error) - 33) - /*!< Thrown when VL53L1_run_offset_calibration() peak rate is greater - than that 50.0Mcps. This is the recommended max rate to avoid - pile-up influencing the offset measurement */ -#define VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW ((VL53L1_Error) - 34) - /*!< Thrown when VL53L1_run_offset_calibration() when one of stages - range has less that 5.0 effective SPADS. This is the recommended - min value to yield a stable offset */ - - -#define VL53L1_WARNING_ZONE_CAL_MISSING_SAMPLES ((VL53L1_Error) - 35) - /*!< Thrown if one of more of the zones have less than - the requested number of valid samples */ -#define VL53L1_WARNING_ZONE_CAL_SIGMA_TOO_HIGH ((VL53L1_Error) - 36) - /*!< Thrown if one or more zones have sigma estimate value greater - * than 8.0 mm. This is the recommended min value to yield a stable - * offset measurement */ -#define VL53L1_WARNING_ZONE_CAL_RATE_TOO_HIGH ((VL53L1_Error) - 37) - /*!< Thrown if one of more zones have peak rate higher than - that 50.0Mcps. This is the recommended max rate to avoid - pile-up influencing the offset measurement */ - - -#define VL53L1_WARNING_XTALK_MISSING_SAMPLES ((VL53L1_Error) - 38) - /*!< Thrown to notify that some of the xtalk samples did not yield - * valid ranging pulse data while attempting to measure - * the xtalk signal in vl53l1_run_xtalk_extract(). This can signify any of - * the zones are missing samples, for further debug information the - * xtalk_results struct should be referred to. This warning is for - * notification only, the xtalk pulse and shape have still been generated - */ -#define VL53L1_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT ((VL53L1_Error) - 39) - /*!< Thrown to notify that some of teh xtalk samples used for gradient - * generation did not yield valid ranging pulse data while attempting to - * measure the xtalk signal in vl53l1_run_xtalk_extract(). This can signify - * that any one of the zones 0-3 yielded no successful samples. The - * xtalk_results struct should be referred to for further debug info. - * This warning is for notification only, the xtalk pulse and shape - * have still been generated. - */ -#define VL53L1_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT ((VL53L1_Error) - 40) -/*!< Thrown to notify that some of the xtalk samples used for gradient - * generation did not pass the sigma limit check while attempting to - * measure the xtalk signal in vl53l1_run_xtalk_extract(). This can signify - * that any one of the zones 0-3 yielded an avg sigma_mm value > the limit. - * The xtalk_results struct should be referred to for further debug info. - * This warning is for notification only, the xtalk pulse and shape - * have still been generated. - */ - -#define VL53L1_ERROR_NOT_IMPLEMENTED ((VL53L1_Error) - 41) - /*!< Tells requested functionality has not been implemented yet or - * not compatible with the device */ -#define VL53L1_ERROR_PLATFORM_SPECIFIC_START ((VL53L1_Error) - 60) - /*!< Tells the starting code for platform */ -/** @} VL53L1_define_Error_group */ - - -#ifdef __cplusplus -} -#endif - - -#endif /* _VL53L1X_ERROR_CODES_H_ */ \ No newline at end of file