Working version without LEDs

Dependencies:   mbed WS2812

Voici le dernier schéma de cablage (version du 08/02/2020)

https://os.mbed.com/media/uploads/max_ence/schemarobot_fev2020.pdf

Committer:
elab
Date:
Sat May 30 09:31:57 2020 +0000
Revision:
1:69b5d8f0ba9c
Parent:
0:0e577ce96b2f
pour eLab;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elab 0:0e577ce96b2f 1 /**
elab 0:0e577ce96b2f 2 ******************************************************************************
elab 0:0e577ce96b2f 3 * @file VL53L0X_class.cpp
elab 0:0e577ce96b2f 4 * @author IMG
elab 0:0e577ce96b2f 5 * @version V0.0.1
elab 0:0e577ce96b2f 6 * @date 28-June-2016
elab 0:0e577ce96b2f 7 * @brief Implementation file for the VL53L0X driver class
elab 0:0e577ce96b2f 8 ******************************************************************************
elab 0:0e577ce96b2f 9 * @attention
elab 0:0e577ce96b2f 10 *
elab 0:0e577ce96b2f 11 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
elab 0:0e577ce96b2f 12 *
elab 0:0e577ce96b2f 13 * Redistribution and use in source and binary forms, with or without modification,
elab 0:0e577ce96b2f 14 * are permitted provided that the following conditions are met:
elab 0:0e577ce96b2f 15 * 1. Redistributions of source code must retain the above copyright notice,
elab 0:0e577ce96b2f 16 * this list of conditions and the following disclaimer.
elab 0:0e577ce96b2f 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
elab 0:0e577ce96b2f 18 * this list of conditions and the following disclaimer in the documentation
elab 0:0e577ce96b2f 19 * and/or other materials provided with the distribution.
elab 0:0e577ce96b2f 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
elab 0:0e577ce96b2f 21 * may be used to endorse or promote products derived from this software
elab 0:0e577ce96b2f 22 * without specific prior written permission.
elab 0:0e577ce96b2f 23 *
elab 0:0e577ce96b2f 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
elab 0:0e577ce96b2f 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
elab 0:0e577ce96b2f 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
elab 0:0e577ce96b2f 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
elab 0:0e577ce96b2f 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
elab 0:0e577ce96b2f 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
elab 0:0e577ce96b2f 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
elab 0:0e577ce96b2f 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
elab 0:0e577ce96b2f 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
elab 0:0e577ce96b2f 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
elab 0:0e577ce96b2f 34 *
elab 0:0e577ce96b2f 35 ******************************************************************************
elab 0:0e577ce96b2f 36 */
elab 0:0e577ce96b2f 37
elab 0:0e577ce96b2f 38 /*
elab 0:0e577ce96b2f 39 Simplifications versus the original library:
elab 0:0e577ce96b2f 40
elab 0:0e577ce96b2f 41 Replace:
elab 0:0e577ce96b2f 42 * "MicroSeconds" or "micro_seconds" by "us" or "_us"
elab 0:0e577ce96b2f 43 * "MilliSeconds" or "milli_seconds" by "ms" or "_ms"
elab 0:0e577ce96b2f 44 * "MegaCps" or "MCps" or "_mega_cps" by "MHz" or "_MHz"
elab 0:0e577ce96b2f 45 * "MicroMeter" by "um" or "_um"
elab 0:0e577ce96b2f 46 * "FIXEDPNT" by "FP"
elab 0:0e577ce96b2f 47
elab 0:0e577ce96b2f 48 Everything related to histogram_mode seems completely not implemented, so all definitions removed.
elab 0:0e577ce96b2f 49
elab 0:0e577ce96b2f 50 Everything related to x_talk_compensation seems also not implemented, all removed
elab 0:0e577ce96b2f 51
elab 0:0e577ce96b2f 52 Some example regular expressinos used to simplify the code:
elab 0:0e577ce96b2f 53 b) Search for: \QRead_Byte(\E([A-Za-z_\d]+)[[:punct:]](\s*)\Q&\E([A-Za-z\d_]+)\Q);\E
elab 0:0e577ce96b2f 54 Replace by: \3 = Read_Byte\(\1\);
elab 0:0e577ce96b2f 55 to replace: Read_Byte(0x90,&module_id);
elab 0:0e577ce96b2f 56 by this: module_id = Read_Byte(0x90);
elab 0:0e577ce96b2f 57
elab 0:0e577ce96b2f 58 c) Search for: ([A-Za-z_\d]+)\Q(\E\r\n(\s*)
elab 0:0e577ce96b2f 59 Replace by: \1\(
elab 0:0e577ce96b2f 60 To join lines where the first line has an open bracket, and the next line starts listing the parameters.
elab 0:0e577ce96b2f 61 for example: Status = VL53L0X_UpdateByte(V
elab 0:0e577ce96b2f 62 L53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV, ....
elab 0:0e577ce96b2f 63 becomes: Status = VL53L0X_UpdateByte(VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV, ....
elab 0:0e577ce96b2f 64
elab 0:0e577ce96b2f 65 */
elab 0:0e577ce96b2f 66
elab 0:0e577ce96b2f 67 /* Includes */
elab 0:0e577ce96b2f 68 #include <stdlib.h>
elab 0:0e577ce96b2f 69 #include "VL53L0X.h"
elab 0:0e577ce96b2f 70
elab 0:0e577ce96b2f 71 void Report_Range_Infos(VL53L0X_RangingMeasurementData_t RangeResults, Serial *aSerial )
elab 0:0e577ce96b2f 72 {
elab 0:0e577ce96b2f 73 aSerial->printf("\n\r Reporting All Fields of VL53L0X_RangingMeasurementData_t structure \n\r" );
elab 0:0e577ce96b2f 74 aSerial->printf(" .Range_mm = %dmm; Ranged distance. \n\r", RangeResults.Range_mm );
elab 0:0e577ce96b2f 75 aSerial->printf(" .RangeDMax_mm = %dmm; maximum detection distance in current setup and environment conditions \n\r", RangeResults.RangeDMax_mm );
elab 0:0e577ce96b2f 76 aSerial->printf(" .SignalRateRtn_MHz = %3.3fMHz; effectively a measure of target reflectance \n\r", RangeResults.SignalRateRtn_MHz / 65535.01);
elab 0:0e577ce96b2f 77 aSerial->printf(" .AmbientRateRtn_MHz = %3.3fMHz; effectively a measure of the ambient light \n\r", RangeResults.AmbientRateRtn_MHz / 65535.01 );
elab 0:0e577ce96b2f 78 aSerial->printf(" .EffectiveSpadRtnCount = %3.3f; effective SPAD count for the return signal \n\r", RangeResults.EffectiveSpadRtnCount / 256.001 );
elab 0:0e577ce96b2f 79 aSerial->printf(" .RangeFractionalPart = %d; Fractional part of range distance. \n\r", RangeResults.RangeFractionalPart >> 6 );
elab 0:0e577ce96b2f 80 aSerial->printf(" .RangeStatus = %d[u8]; Status for the current measurement, 0 = value is valid \n\r", RangeResults.RangeStatus );
elab 0:0e577ce96b2f 81 aSerial->printf(" .SigmaEstimate = %3.2f; Estimated Sigma - based on ambient & VCSEL rates and signal_total_events \n\r", RangeResults.SigmaEstimate/ 65535.01 );
elab 0:0e577ce96b2f 82 };
elab 0:0e577ce96b2f 83
elab 0:0e577ce96b2f 84 void Report_Deep_Infos(VL53L0X TOF1, Serial *aSerial)
elab 0:0e577ce96b2f 85 {
elab 0:0e577ce96b2f 86 aSerial->printf("\n\r Reporting All Top Level Infos of the class \n\r" );
elab 0:0e577ce96b2f 87 aSerial->printf("I2cDevAddr = %d. \n\r", TOF1.I2cDevAddr );
elab 0:0e577ce96b2f 88 aSerial->printf("comms_type = %d. Type of comms: 1=VL53L0X_COMMS_I2C or VL53L0X_COMMS_SPI \n\r", TOF1.comms_type );
elab 0:0e577ce96b2f 89 aSerial->printf("comms_speed = %d. Communication speed [kHz] : typically 400kHz for I2C \n\r", TOF1.comms_speed_khz );
elab 0:0e577ce96b2f 90
elab 0:0e577ce96b2f 91 aSerial->printf("\n\r Reporting All Infos of the Device_Info structure: \n\r" );
elab 0:0e577ce96b2f 92 aSerial->printf("Device_Info.ProductType = 0x%2X. VL53L0X = 1, VL53L1 = 2 \n\r", TOF1.Device_Info.ProductType );
elab 0:0e577ce96b2f 93 aSerial->printf("Device_Info.ProductRevision = %d.%d. Revision NR, major.minor \n\r",
elab 0:0e577ce96b2f 94 TOF1.Device_Info.ProductRevisionMajor, TOF1.Device_Info.ProductRevisionMinor );
elab 0:0e577ce96b2f 95 aSerial->printf("Device_Info.Name = %s. Name of Device e.g. Left_Distance\n\r", TOF1.Device_Info.Name );
elab 0:0e577ce96b2f 96 aSerial->printf("Device_Info.Type = %s. Type of Device e.g VL53L0X \n\r", TOF1.Device_Info.Type );
elab 0:0e577ce96b2f 97 aSerial->printf("Device_Info.ProductId = %s. Product Identifier String \n\r", TOF1.Device_Info.ProductId );
elab 0:0e577ce96b2f 98
elab 0:0e577ce96b2f 99 aSerial->printf("\n\r Reporting All Fields of CurrentParameters \n\r" );
elab 0:0e577ce96b2f 100 aSerial->printf(" .DeviceMode = %d. Defines type of measurement to be done for the next measurement \n\r",
elab 0:0e577ce96b2f 101 TOF1.CurrentParameters.DeviceMode );
elab 0:0e577ce96b2f 102 aSerial->printf(" .Measure_Time_Budget_us= %dus. Allowed total time for a single measurement \n\r",
elab 0:0e577ce96b2f 103 TOF1.CurrentParameters.MeasurementTimingBudget_us );
elab 0:0e577ce96b2f 104 aSerial->printf(" .Measure_Period_ms = %dms. Time between two consecutive measurements \n\r",
elab 0:0e577ce96b2f 105 TOF1.CurrentParameters.InterMeasurementPeriod_ms );
elab 0:0e577ce96b2f 106 aSerial->printf(" .XTalk_Compens_En = %d. Crosstalk compensation enable or not (0, default) \n\r",
elab 0:0e577ce96b2f 107 TOF1.CurrentParameters.XTalkCompensationEnable );
elab 0:0e577ce96b2f 108 aSerial->printf(" .XTalk_CompRange_mm = %dmm. CrossTalk compensation range, seems never used \n\r",
elab 0:0e577ce96b2f 109 TOF1.CurrentParameters.XTalkCompensationRange_mm );
elab 0:0e577ce96b2f 110 aSerial->printf(" .XTalk_CompRate_MHz = %3.2fMHz. CrossTalk compensation rate . \n\r",
elab 0:0e577ce96b2f 111 (float) TOF1.CurrentParameters.XTalkCompensationRate_MHz / 65536);
elab 0:0e577ce96b2f 112 aSerial->printf(" .RangeOffset_um = %d. Range offset adjustment (um) last programmed.\n\r",
elab 0:0e577ce96b2f 113 TOF1.CurrentParameters.RangeOffset_um );
elab 0:0e577ce96b2f 114 aSerial->printf(" .LimitChecks ... = SIGMA_FINAL, SIGNAL_RATE_FINAL, SIGNAL_REF_CLIP, IGNORE_THRESHOLD, SIGNAL_RATE_MSRC, SIGNAL_RATE_PRE.\n\r");
elab 0:0e577ce96b2f 115 aSerial->printf(" .LimitChecksEnable[x] = %d %d %d %d %d %d. The Limit Checks enabled or not.\n\r",
elab 0:0e577ce96b2f 116 TOF1.CurrentParameters.LimitChecksEnable[0],TOF1.CurrentParameters.LimitChecksEnable[1] ,TOF1.CurrentParameters.LimitChecksEnable[2],
elab 0:0e577ce96b2f 117 TOF1.CurrentParameters.LimitChecksEnable[3],TOF1.CurrentParameters.LimitChecksEnable[4] ,TOF1.CurrentParameters.LimitChecksEnable[5] );
elab 0:0e577ce96b2f 118 aSerial->printf(" .LimitChecksStatus[x] = %d %d %d %d %d %d. Status of checks of last measurement.\n\r",
elab 0:0e577ce96b2f 119 TOF1.CurrentParameters.LimitChecksStatus[0],TOF1.CurrentParameters.LimitChecksStatus[1] ,TOF1.CurrentParameters.LimitChecksStatus[2],
elab 0:0e577ce96b2f 120 TOF1.CurrentParameters.LimitChecksStatus[3],TOF1.CurrentParameters.LimitChecksStatus[4] ,TOF1.CurrentParameters.LimitChecksStatus[5] );
elab 0:0e577ce96b2f 121 aSerial->printf(" .LimitChecksValue[x] = %d %d %d %d %d %d [FP1616]. The Limit Check values \n\r",
elab 0:0e577ce96b2f 122 TOF1.CurrentParameters.LimitChecksValue[0],TOF1.CurrentParameters.LimitChecksValue[1] ,TOF1.CurrentParameters.LimitChecksValue[2],
elab 0:0e577ce96b2f 123 TOF1.CurrentParameters.LimitChecksValue[3],TOF1.CurrentParameters.LimitChecksValue[4] ,TOF1.CurrentParameters.LimitChecksValue[5] );
elab 0:0e577ce96b2f 124 aSerial->printf(" .WrapAroundCheckEnable = %d. Wrap Around Check enabled or not \n\r",
elab 0:0e577ce96b2f 125 TOF1.CurrentParameters.WrapAroundCheckEnable );
elab 0:0e577ce96b2f 126
elab 0:0e577ce96b2f 127 aSerial->printf("\n\r Reporting All Fields of VL53L0X_DevData_t Data structure \n\r" );
elab 0:0e577ce96b2f 128 aSerial->printf(" .OscFrequency_MHz = %3.2fMHz; Frequency used \n\r", (float) TOF1.Data.OscFrequency_MHz/65536 );
elab 0:0e577ce96b2f 129 aSerial->printf(" .LastEncodedTimeout = %d[u16]; Last encoded Time out used for timing budget \n\r", TOF1.Data.LastEncodedTimeout );
elab 0:0e577ce96b2f 130 aSerial->printf(" .Pin0GpioFunctionality = %d[u8]; functionality of the GPIO: pin0 \n\r", TOF1.Data.Pin0GpioFunctionality );
elab 0:0e577ce96b2f 131 aSerial->printf(" .FinalRangeTimeout_us = %d[u32]; Execution time of the final ranging \n\r", TOF1.Data.FinalRangeTimeout_us );
elab 0:0e577ce96b2f 132 aSerial->printf(" .FinalRangeVcselPulsePeriod= %d[u8]; Vcsel pulse period (pll clocks) for the final range measurement \n\r", TOF1.Data.FinalRangeVcselPulsePeriod );
elab 0:0e577ce96b2f 133 aSerial->printf(" .PreRangeTimeout_us = %d[u32]; Execution time of the final range \n\r", TOF1.Data.PreRangeTimeout_us );
elab 0:0e577ce96b2f 134 aSerial->printf(" .PreRangeVcselPulsePeriod = %d[u8]; Vcsel pulse period (pll clocks) for the pre-range measurement \n\r", TOF1.Data.PreRangeVcselPulsePeriod );
elab 0:0e577ce96b2f 135 aSerial->printf(" .ReadDataFromDeviceDone = %2d; reads from device has been done (>0) or not. \n\r", TOF1.Data.ReadDataFromDeviceDone );
elab 0:0e577ce96b2f 136 aSerial->printf(" .ModuleId = %X; Module ID \n\r", TOF1.Data.ModuleId );
elab 0:0e577ce96b2f 137 aSerial->printf(" .Revision = %d[u8]; test Revision \n\r", TOF1.Data.Revision );
elab 0:0e577ce96b2f 138 aSerial->printf(" .ProductId = %s[char*]; Product Identifier String \n\r", TOF1.Data.ProductId );
elab 0:0e577ce96b2f 139 aSerial->printf(" .ReferenceSpadCount = %d[u8]; used for ref spad management \n\r", TOF1.Data.ReferenceSpadCount );
elab 0:0e577ce96b2f 140 aSerial->printf(" .ReferenceSpadType = %d[u8]; used for ref spad management \n\r", TOF1.Data.ReferenceSpadType );
elab 0:0e577ce96b2f 141 aSerial->printf(" .RefSpadsInitialised = %d[u8]; reports if ref spads are initialised. \n\r", TOF1.Data.RefSpadsInitialised );
elab 0:0e577ce96b2f 142 aSerial->printf(" .PartUIDUpper = %d[u32]; Unique Part ID Upper \n\r", TOF1.Data.PartUIDUpper );
elab 0:0e577ce96b2f 143 aSerial->printf(" .PartUIDLower = %d[u32]; Unique Part ID Lower \n\r", TOF1.Data.PartUIDLower );
elab 0:0e577ce96b2f 144 aSerial->printf(" .SignalRateMeasFixed400mm = %3.3f; Peak Signal rate at 400 mm \n\r", 1.0 / 65535.0 * TOF1.Data.SignalRateMeasFixed400mm );
elab 0:0e577ce96b2f 145 aSerial->printf(" .RefSpadEnables[x] = %X %X %X %X %X %X[hex8]; Reference Spad Enables \n\r",
elab 0:0e577ce96b2f 146 TOF1.Data.RefSpadEnables[0], TOF1.Data.RefSpadEnables[1], TOF1.Data.RefSpadEnables[2],
elab 0:0e577ce96b2f 147 TOF1.Data.RefSpadEnables[3], TOF1.Data.RefSpadEnables[4], TOF1.Data.RefSpadEnables[5] );
elab 0:0e577ce96b2f 148 aSerial->printf(" .RefGoodSpadMap[x] = %X %X %X %X %X %X[hex8]; Reference Spad Good Spad Map\n\r",
elab 0:0e577ce96b2f 149 TOF1.Data.RefGoodSpadMap[0], TOF1.Data.RefGoodSpadMap[1], TOF1.Data.RefGoodSpadMap[2],
elab 0:0e577ce96b2f 150 TOF1.Data.RefGoodSpadMap[3], TOF1.Data.RefGoodSpadMap[4], TOF1.Data.RefGoodSpadMap[5] );
elab 0:0e577ce96b2f 151 aSerial->printf(" .Part2PartOffsetNVM_um = %d[i32]; backed up NVM value \n\r", TOF1.Data.Part2PartOffsetNVM_um );
elab 0:0e577ce96b2f 152 aSerial->printf(" .Part2PartOffsetAdjustNVM_um= %d[i32]; backed up NVM value of additional offset adjustment \n\r", TOF1.Data.Part2PartOffsetAdjustNVM_um );
elab 0:0e577ce96b2f 153 aSerial->printf(" .SequenceConfig = %d[u8]; Internal value for the sequence config \n\r", TOF1.Data.SequenceConfig );
elab 0:0e577ce96b2f 154 aSerial->printf(" .RangeFractionalEnable = %d[u8]; Enable/Disable fractional part of range data \n\r", TOF1.Data.RangeFractionalEnable);
elab 0:0e577ce96b2f 155 aSerial->printf(" .PalState = %d[u8]; Current state of the PAL \n\r", TOF1.Data.PalState );
elab 0:0e577ce96b2f 156 aSerial->printf(" .PowerMode = %d[u8]; Current Power Mode; Stdby1/2, Idle1/2 \n\r", TOF1.Data.PowerMode );
elab 0:0e577ce96b2f 157 aSerial->printf(" .SigmaEstRefArray = %d[u16]; Reference array sigma value in 1/100th of [mm] \n\r", TOF1.Data.SigmaEstRefArray );
elab 0:0e577ce96b2f 158 aSerial->printf(" .SigmaEstEffPulseWidth = %d[u16]; Effective Pulse width for sigma estimate in 1/100th of ns \n\r", TOF1.Data.SigmaEstEffPulseWidth );
elab 0:0e577ce96b2f 159 aSerial->printf(" .SigmaEstEffAmbWidth = %d. Effective Ambient width for sigma estimate in 1/100th of ns \n\r", TOF1.Data.SigmaEstEffAmbWidth );
elab 0:0e577ce96b2f 160 aSerial->printf(" .StopVariable = %d[u8]; StopVariable used during the stop sequence \n\r", TOF1.Data.StopVariable );
elab 0:0e577ce96b2f 161 aSerial->printf(" .targetRefRate = %d. Target Ambient Rate for Ref spad management \n\r", TOF1.Data.targetRefRate );
elab 0:0e577ce96b2f 162 aSerial->printf(" .LastSignalRef_MHz = %3.3fMHz; Latest Signal ref \n\r", TOF1.Data.LastSignalRef_MHz / 65535.01 );
elab 0:0e577ce96b2f 163 aSerial->printf(" .UseInternalTuningSetting = %d[u8]; Indicate if we use Tuning Settings table \n\r", TOF1.Data.UseInternalTuningSettings );
elab 0:0e577ce96b2f 164 aSerial->printf(" .LinearityCorrectiveGain = %d[u8]; Linearity Corrective Gain value in x1000 \n\r", TOF1.Data.LinearityCorrectiveGain );
elab 0:0e577ce96b2f 165 aSerial->printf(" .DmaxCalRange_mm = %dmm; Dmax Calibration Range \n\r", TOF1.Data.DmaxCalRange_mm );
elab 0:0e577ce96b2f 166 aSerial->printf(" .DmaxCalSignalRateRtn_MHz = %3.3fMHz; Dmax Calibration Signal Rate Return \n\r", TOF1.Data.DmaxCalSignalRateRtn_MHz / 65535.01 );
elab 0:0e577ce96b2f 167 }
elab 0:0e577ce96b2f 168
elab 0:0e577ce96b2f 169 int VL53L0X::read_id(uint8_t *id)
elab 0:0e577ce96b2f 170 { int status = 0;
elab 0:0e577ce96b2f 171 uint16_t rl_id = 0;
elab 0:0e577ce96b2f 172
elab 0:0e577ce96b2f 173 status = VL53L0X_read_word(VL53L0X_REG_IDENTIFICATION_MODEL_ID, &rl_id);
elab 0:0e577ce96b2f 174 if (rl_id == 0xEEAA) {
elab 0:0e577ce96b2f 175 return status;
elab 0:0e577ce96b2f 176 }
elab 0:0e577ce96b2f 177 return -1;
elab 0:0e577ce96b2f 178 }
elab 0:0e577ce96b2f 179
elab 0:0e577ce96b2f 180 int VL53L0X::init_sensor(uint8_t new_addr)
elab 0:0e577ce96b2f 181 { int status;
elab 0:0e577ce96b2f 182
elab 0:0e577ce96b2f 183 VL53L0X_off();
elab 0:0e577ce96b2f 184 VL53L0X_on();
elab 0:0e577ce96b2f 185
elab 0:0e577ce96b2f 186 // Verify if the device is actually present
elab 0:0e577ce96b2f 187 uint8_t id = 0;
elab 0:0e577ce96b2f 188 status = read_id(&id);
elab 0:0e577ce96b2f 189 if (status != 0) {
elab 0:0e577ce96b2f 190 //aSerial->printf("VL53L0X sensor is not present!\n\r");
elab 0:0e577ce96b2f 191 return 99; } // device is not present
elab 0:0e577ce96b2f 192
elab 0:0e577ce96b2f 193 status = VL53L0X_data_init();
elab 0:0e577ce96b2f 194 if (status != VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 195 //aSerial->printf("Failed to init VL53L0X sensor!\n\r");
elab 0:0e577ce96b2f 196 return status;
elab 0:0e577ce96b2f 197 }
elab 0:0e577ce96b2f 198
elab 0:0e577ce96b2f 199 // deduce silicon version
elab 0:0e577ce96b2f 200 status = VL53L0X_get_device_info();
elab 0:0e577ce96b2f 201
elab 0:0e577ce96b2f 202 status = prepare();
elab 0:0e577ce96b2f 203 if (status != VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 204 //aSerial->printf("Failed to prepare VL53L0X!\n\r");
elab 0:0e577ce96b2f 205 return status;
elab 0:0e577ce96b2f 206 }
elab 0:0e577ce96b2f 207
elab 0:0e577ce96b2f 208 if (new_addr != VL53L0X_DEFAULT_ADDRESS) {
elab 0:0e577ce96b2f 209 status = set_device_address(new_addr);
elab 0:0e577ce96b2f 210 if (status) {
elab 0:0e577ce96b2f 211 //aSerial->printf("Failed to change I2C address!\n\r");
elab 0:0e577ce96b2f 212 return status;
elab 0:0e577ce96b2f 213 }
elab 0:0e577ce96b2f 214 }
elab 0:0e577ce96b2f 215 return status;
elab 0:0e577ce96b2f 216 }
elab 0:0e577ce96b2f 217
elab 0:0e577ce96b2f 218 VL53L0X_Error VL53L0X::VL53L0X_data_init(void)
elab 0:0e577ce96b2f 219 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 220 VL53L0X_DeviceParameters_t CurrentParameters;
elab 0:0e577ce96b2f 221 int i;
elab 0:0e577ce96b2f 222 uint8_t StopVariable;
elab 0:0e577ce96b2f 223
elab 0:0e577ce96b2f 224 /* by default the I2C is running at 1V8 if you want to change it you
elab 0:0e577ce96b2f 225 * need to include this define at compilation level. */
elab 0:0e577ce96b2f 226 #ifdef USE_I2C_2V8
elab 0:0e577ce96b2f 227 Status = VL53L0X_UpdateByte(VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV,0xFE,0x01);
elab 0:0e577ce96b2f 228 #endif
elab 0:0e577ce96b2f 229
elab 0:0e577ce96b2f 230 /* Set I2C standard mode */
elab 0:0e577ce96b2f 231 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 232 status = VL53L0X_write_byte( 0x88, 0x00); }
elab 0:0e577ce96b2f 233
elab 0:0e577ce96b2f 234 Data.ReadDataFromDeviceDone = 0;
elab 0:0e577ce96b2f 235 Data.ReadDataFromDeviceDone = 0;
elab 0:0e577ce96b2f 236
elab 0:0e577ce96b2f 237 #ifdef USE_IQC_STATION
elab 0:0e577ce96b2f 238 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 239 Status = VL53L0X_apply_offset_adjustment();
elab 0:0e577ce96b2f 240 }
elab 0:0e577ce96b2f 241 #endif
elab 0:0e577ce96b2f 242
elab 0:0e577ce96b2f 243 /* Default value is 1000 for Linearity Corrective Gain */
elab 0:0e577ce96b2f 244 Data.LinearityCorrectiveGain = 1000;
elab 0:0e577ce96b2f 245
elab 0:0e577ce96b2f 246 /* Dmax default Parameter */
elab 0:0e577ce96b2f 247 Data.DmaxCalRange_mm = 400;
elab 0:0e577ce96b2f 248 Data.DmaxCalSignalRateRtn_MHz = (FixPoint1616_t)((0x00016B85)); /* 1.42 No Cover Glass*/
elab 0:0e577ce96b2f 249
elab 0:0e577ce96b2f 250 /* Set Default static parameters
elab 0:0e577ce96b2f 251 *set first temporary values 9.44_MHz * 65536 = 618660 */
elab 0:0e577ce96b2f 252 Data.OscFrequency_MHz = 618660;
elab 0:0e577ce96b2f 253
elab 0:0e577ce96b2f 254 /* Set Default XTalkCompensationRate_MHz to 0 */
elab 0:0e577ce96b2f 255 CurrentParameters.XTalkCompensationRate_MHz = 0;
elab 0:0e577ce96b2f 256
elab 0:0e577ce96b2f 257 /* Get default parameters */
elab 0:0e577ce96b2f 258 status = VL53L0X_get_device_parameters( &CurrentParameters);
elab 0:0e577ce96b2f 259 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 260 /* initialize PAL values */
elab 0:0e577ce96b2f 261 CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_SINGLE_RANGING;
elab 0:0e577ce96b2f 262 CurrentParameters = CurrentParameters;
elab 0:0e577ce96b2f 263 }
elab 0:0e577ce96b2f 264
elab 0:0e577ce96b2f 265 /* Sigma estimator variable */
elab 0:0e577ce96b2f 266 Data.SigmaEstRefArray = 100;
elab 0:0e577ce96b2f 267 Data.SigmaEstEffPulseWidth = 900;
elab 0:0e577ce96b2f 268 Data.SigmaEstEffAmbWidth = 500;
elab 0:0e577ce96b2f 269 Data.targetRefRate = 0x0A00; /* 20 MHz in 9:7 format */
elab 0:0e577ce96b2f 270
elab 0:0e577ce96b2f 271 /* Use internal default settings */
elab 0:0e577ce96b2f 272 Data.UseInternalTuningSettings = 1;
elab 0:0e577ce96b2f 273
elab 0:0e577ce96b2f 274 status |= VL53L0X_write_byte( 0x80, 0x01);
elab 0:0e577ce96b2f 275 status |= VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 276 status |= VL53L0X_write_byte( 0x00, 0x00);
elab 0:0e577ce96b2f 277 status |= VL53L0X_read_byte( 0x91, &StopVariable);
elab 0:0e577ce96b2f 278 Data.StopVariable = StopVariable;
elab 0:0e577ce96b2f 279 status |= VL53L0X_write_byte( 0x00, 0x01);
elab 0:0e577ce96b2f 280 status |= VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 281 status |= VL53L0X_write_byte( 0x80, 0x00);
elab 0:0e577ce96b2f 282
elab 0:0e577ce96b2f 283 /* Enable all check */
elab 0:0e577ce96b2f 284 for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
elab 0:0e577ce96b2f 285 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 286 status |= VL53L0X_set_limit_check_enable( i, 1);
elab 0:0e577ce96b2f 287 } else { break; }
elab 0:0e577ce96b2f 288 }
elab 0:0e577ce96b2f 289
elab 0:0e577ce96b2f 290 /* Disable the following checks */
elab 0:0e577ce96b2f 291 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 292 status = VL53L0X_set_limit_check_enable(VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, 0);
elab 0:0e577ce96b2f 293
elab 0:0e577ce96b2f 294 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 295 status = VL53L0X_set_limit_check_enable(VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 0);
elab 0:0e577ce96b2f 296
elab 0:0e577ce96b2f 297 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 298 status = VL53L0X_set_limit_check_enable(VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC, 0);
elab 0:0e577ce96b2f 299
elab 0:0e577ce96b2f 300 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 301 status = VL53L0X_set_limit_check_enable(VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE, 0);
elab 0:0e577ce96b2f 302
elab 0:0e577ce96b2f 303 /* Limit default values */
elab 0:0e577ce96b2f 304 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 305 status = VL53L0X_set_limit_check_value(VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
elab 0:0e577ce96b2f 306 (FixPoint1616_t)(18 * 65536));
elab 0:0e577ce96b2f 307 }
elab 0:0e577ce96b2f 308 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 309 status = VL53L0X_set_limit_check_value(VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
elab 0:0e577ce96b2f 310 (FixPoint1616_t)(25 * 65536 / 100)); /* 0.25 * 65536 */
elab 0:0e577ce96b2f 311 }
elab 0:0e577ce96b2f 312
elab 0:0e577ce96b2f 313 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 314 status = VL53L0X_set_limit_check_value(VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
elab 0:0e577ce96b2f 315 (FixPoint1616_t)(35 * 65536));
elab 0:0e577ce96b2f 316 }
elab 0:0e577ce96b2f 317
elab 0:0e577ce96b2f 318 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 319 status = VL53L0X_set_limit_check_value(VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
elab 0:0e577ce96b2f 320 (FixPoint1616_t)(0 * 65536));
elab 0:0e577ce96b2f 321 }
elab 0:0e577ce96b2f 322
elab 0:0e577ce96b2f 323 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 324 Data.SequenceConfig = 0xFF;
elab 0:0e577ce96b2f 325 status = VL53L0X_write_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,0xFF);
elab 0:0e577ce96b2f 326
elab 0:0e577ce96b2f 327 /* Set PAL state to tell that we are waiting for call to VL53L0X_StaticInit */
elab 0:0e577ce96b2f 328 Data.PalState = VL53L0X_STATE_WAIT_STATICINIT;
elab 0:0e577ce96b2f 329 }
elab 0:0e577ce96b2f 330
elab 0:0e577ce96b2f 331 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 332 Data.RefSpadsInitialised = 0;
elab 0:0e577ce96b2f 333 }
elab 0:0e577ce96b2f 334
elab 0:0e577ce96b2f 335 return status;
elab 0:0e577ce96b2f 336 }
elab 0:0e577ce96b2f 337
elab 0:0e577ce96b2f 338 int VL53L0X::prepare()
elab 0:0e577ce96b2f 339 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 340 uint32_t ref_spad_count;
elab 0:0e577ce96b2f 341 uint8_t is_aperture_spads;
elab 0:0e577ce96b2f 342 uint8_t vhv_settings;
elab 0:0e577ce96b2f 343 uint8_t phase_cal;
elab 0:0e577ce96b2f 344
elab 0:0e577ce96b2f 345 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 346 status = VL53L0X_static_init(); // Device Initialization
elab 0:0e577ce96b2f 347 }
elab 0:0e577ce96b2f 348
elab 0:0e577ce96b2f 349 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 350 status = VL53L0X_perform_ref_calibration(&vhv_settings, &phase_cal); // Device Initialization
elab 0:0e577ce96b2f 351 }
elab 0:0e577ce96b2f 352
elab 0:0e577ce96b2f 353 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 354 status = VL53L0X_perform_ref_spad_management(&ref_spad_count, &is_aperture_spads); // Device Initialization
elab 0:0e577ce96b2f 355 }
elab 0:0e577ce96b2f 356
elab 0:0e577ce96b2f 357 return status;
elab 0:0e577ce96b2f 358 }
elab 0:0e577ce96b2f 359
elab 0:0e577ce96b2f 360 int VL53L0X::start_measurement(OperatingMode operating_mode, void (*fptr)(void),
elab 0:0e577ce96b2f 361 VL53L0X_RangingConfig rangingConfig)
elab 0:0e577ce96b2f 362 { int Status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 363 int ClrStatus;
elab 0:0e577ce96b2f 364
elab 0:0e577ce96b2f 365 uint8_t VhvSettings;
elab 0:0e577ce96b2f 366 uint8_t PhaseCal;
elab 0:0e577ce96b2f 367 // default settings, for normal range.
elab 0:0e577ce96b2f 368 FixPoint1616_t signalLimit = (FixPoint1616_t)(0.25 * 65536);
elab 0:0e577ce96b2f 369 FixPoint1616_t sigmaLimit = (FixPoint1616_t)(25 * 65536);
elab 0:0e577ce96b2f 370 uint32_t timingBudget = 33000;
elab 0:0e577ce96b2f 371 uint8_t preRangeVcselPeriod = 14;
elab 0:0e577ce96b2f 372 uint8_t finalRangeVcselPeriod = 10;
elab 0:0e577ce96b2f 373
elab 0:0e577ce96b2f 374 if (operating_mode == range_continuous_interrupt) {
elab 0:0e577ce96b2f 375 if (_gpio1Int == NULL) {
elab 0:0e577ce96b2f 376 //aSerial->printf("GPIO1 Error\r\n");
elab 0:0e577ce96b2f 377 return 1;
elab 0:0e577ce96b2f 378 }
elab 0:0e577ce96b2f 379
elab 0:0e577ce96b2f 380 Status = VL53L0X_stop_measurement(); // it is safer to do this while sensor is stopped
elab 0:0e577ce96b2f 381
elab 0:0e577ce96b2f 382 // Status = VL53L0X_SetInterruptThresholds(Device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, 0, 300);
elab 0:0e577ce96b2f 383
elab 0:0e577ce96b2f 384 Status = VL53L0X_set_gpio_config(0, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,
elab 0:0e577ce96b2f 385 VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY,
elab 0:0e577ce96b2f 386 VL53L0X_INTERRUPTPOLARITY_HIGH);
elab 0:0e577ce96b2f 387
elab 0:0e577ce96b2f 388 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 389 attach_interrupt_measure_detection_irq(fptr);
elab 0:0e577ce96b2f 390 enable_interrupt_measure_detection_irq();
elab 0:0e577ce96b2f 391 }
elab 0:0e577ce96b2f 392
elab 0:0e577ce96b2f 393 ClrStatus = clear_interrupt(VL53L0X_REG_RESULT_INTERRUPT_STATUS | VL53L0X_REG_RESULT_RANGE_STATUS);
elab 0:0e577ce96b2f 394 if (ClrStatus) { Status = 97; } // VL53L0X_ClearErrorInterrupt fail
elab 0:0e577ce96b2f 395
elab 0:0e577ce96b2f 396 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 397 CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_CONTINUOUS_RANGING; // Setup in continuous ranging mode
elab 0:0e577ce96b2f 398 Status = VL53L0X_start_measurement();
elab 0:0e577ce96b2f 399 }
elab 0:0e577ce96b2f 400 }
elab 0:0e577ce96b2f 401
elab 0:0e577ce96b2f 402 if (operating_mode == range_single_shot_polling) {
elab 0:0e577ce96b2f 403 // singelshot, polled ranging
elab 0:0e577ce96b2f 404 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 405 // no need to do this when we use VL53L0X_PerformSingleRangingMeasurement
elab 0:0e577ce96b2f 406 CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_SINGLE_RANGING; // Setup in single ranging mode
elab 0:0e577ce96b2f 407 // Enable/Disable Sigma and Signal check
elab 0:0e577ce96b2f 408 Status = VL53L0X_set_limit_check_enable(VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, 1);
elab 0:0e577ce96b2f 409 }
elab 0:0e577ce96b2f 410 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 411 Status = VL53L0X_set_limit_check_enable(VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1);
elab 0:0e577ce96b2f 412 }
elab 0:0e577ce96b2f 413
elab 0:0e577ce96b2f 414 /* Preselected Ranging configurations */
elab 0:0e577ce96b2f 415 switch(rangingConfig) {
elab 0:0e577ce96b2f 416 case Range_Config_DEFAULT:
elab 0:0e577ce96b2f 417 // default settings, for normal range.
elab 0:0e577ce96b2f 418 signalLimit = (FixPoint1616_t)(0.25 * 65536);
elab 0:0e577ce96b2f 419 sigmaLimit = (FixPoint1616_t)(16 * 65536);
elab 0:0e577ce96b2f 420 timingBudget = 33000;
elab 0:0e577ce96b2f 421 preRangeVcselPeriod = 14;
elab 0:0e577ce96b2f 422 finalRangeVcselPeriod = 10;
elab 0:0e577ce96b2f 423 break;
elab 0:0e577ce96b2f 424 case Range_Config_LONG_RANGE: // *** from mass market cube expansion v1.1, ranging with satellites.
elab 0:0e577ce96b2f 425 signalLimit = (FixPoint1616_t)(0.1 * 65536);
elab 0:0e577ce96b2f 426 sigmaLimit = (FixPoint1616_t)(60 * 65536);
elab 0:0e577ce96b2f 427 timingBudget = 33000;
elab 0:0e577ce96b2f 428 preRangeVcselPeriod = 18;
elab 0:0e577ce96b2f 429 finalRangeVcselPeriod = 14;
elab 0:0e577ce96b2f 430 break;
elab 0:0e577ce96b2f 431 case Range_Config_HIGH_ACCURACY:
elab 0:0e577ce96b2f 432 signalLimit = (FixPoint1616_t)(0.25*65536);
elab 0:0e577ce96b2f 433 sigmaLimit = (FixPoint1616_t)(18*65536);
elab 0:0e577ce96b2f 434 timingBudget = 200000;
elab 0:0e577ce96b2f 435 preRangeVcselPeriod = 14;
elab 0:0e577ce96b2f 436 finalRangeVcselPeriod = 10;
elab 0:0e577ce96b2f 437 break;
elab 0:0e577ce96b2f 438 case Range_Config_HIGH_SPEED:
elab 0:0e577ce96b2f 439 signalLimit = (FixPoint1616_t)(0.25*65536);
elab 0:0e577ce96b2f 440 sigmaLimit = (FixPoint1616_t)(60*65536);
elab 0:0e577ce96b2f 441 timingBudget = 20000;
elab 0:0e577ce96b2f 442 preRangeVcselPeriod = 14;
elab 0:0e577ce96b2f 443 finalRangeVcselPeriod = 10;
elab 0:0e577ce96b2f 444 break;
elab 0:0e577ce96b2f 445 default:
elab 0:0e577ce96b2f 446 Status = 96; // Config Not Supported
elab 0:0e577ce96b2f 447 }
elab 0:0e577ce96b2f 448
elab 0:0e577ce96b2f 449 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 450 Status = VL53L0X_set_limit_check_value(VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, signalLimit);}
elab 0:0e577ce96b2f 451
elab 0:0e577ce96b2f 452 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 453 Status = VL53L0X_set_limit_check_value(VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, sigmaLimit);}
elab 0:0e577ce96b2f 454
elab 0:0e577ce96b2f 455 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 456 Status = VL53L0X_set_measurement_timing_budget_us( timingBudget);}
elab 0:0e577ce96b2f 457
elab 0:0e577ce96b2f 458 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 459 Status = VL53L0X_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE, preRangeVcselPeriod);}
elab 0:0e577ce96b2f 460
elab 0:0e577ce96b2f 461 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 462 Status = VL53L0X_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_FINAL_RANGE, finalRangeVcselPeriod);}
elab 0:0e577ce96b2f 463
elab 0:0e577ce96b2f 464 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 465 Status = VL53L0X_perform_ref_calibration( &VhvSettings, &PhaseCal);}
elab 0:0e577ce96b2f 466
elab 0:0e577ce96b2f 467 }
elab 0:0e577ce96b2f 468
elab 0:0e577ce96b2f 469 if (operating_mode == range_continuous_polling) {
elab 0:0e577ce96b2f 470 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 471 CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_CONTINUOUS_RANGING; // Setup in continuous ranging mode
elab 0:0e577ce96b2f 472 Status = VL53L0X_start_measurement();
elab 0:0e577ce96b2f 473 }
elab 0:0e577ce96b2f 474 }
elab 0:0e577ce96b2f 475 return Status;
elab 0:0e577ce96b2f 476 }
elab 0:0e577ce96b2f 477
elab 0:0e577ce96b2f 478 int VL53L0X::range_meas_int_continuous_mode(void (*fptr)(void))
elab 0:0e577ce96b2f 479 { int status, clr_status;
elab 0:0e577ce96b2f 480
elab 0:0e577ce96b2f 481 status = VL53L0X_stop_measurement(); // it is safer to do this while sensor is stopped
elab 0:0e577ce96b2f 482
elab 0:0e577ce96b2f 483 // status = VL53L0X_SetInterruptThresholds(Device, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, 0, 300);
elab 0:0e577ce96b2f 484
elab 0:0e577ce96b2f 485 status = VL53L0X_set_gpio_config( 0, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,
elab 0:0e577ce96b2f 486 VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY, VL53L0X_INTERRUPTPOLARITY_HIGH);
elab 0:0e577ce96b2f 487
elab 0:0e577ce96b2f 488 if (!status) {
elab 0:0e577ce96b2f 489 attach_interrupt_measure_detection_irq(fptr);
elab 0:0e577ce96b2f 490 enable_interrupt_measure_detection_irq();
elab 0:0e577ce96b2f 491 }
elab 0:0e577ce96b2f 492
elab 0:0e577ce96b2f 493 clr_status = clear_interrupt(VL53L0X_REG_RESULT_INTERRUPT_STATUS | VL53L0X_REG_RESULT_RANGE_STATUS);
elab 0:0e577ce96b2f 494 if (clr_status!=0) { status = 98; } // VL53L0X_ClearErrorInterrupt_fail;
elab 0:0e577ce96b2f 495
elab 0:0e577ce96b2f 496 if (!status) {
elab 0:0e577ce96b2f 497 status = range_start_continuous_mode();
elab 0:0e577ce96b2f 498 }
elab 0:0e577ce96b2f 499 return status;
elab 0:0e577ce96b2f 500 }
elab 0:0e577ce96b2f 501
elab 0:0e577ce96b2f 502 VL53L0X_Error VL53L0X::wait_measurement_data_ready(void)
elab 0:0e577ce96b2f 503 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 504 uint8_t new_dat_ready = 0;
elab 0:0e577ce96b2f 505 uint32_t loop_nb;
elab 0:0e577ce96b2f 506
elab 0:0e577ce96b2f 507 // Wait until it finished
elab 0:0e577ce96b2f 508 // use timeout to avoid deadlock
elab 0:0e577ce96b2f 509 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 510 loop_nb = 0;
elab 0:0e577ce96b2f 511 do {
elab 0:0e577ce96b2f 512 status = VL53L0X_get_measurement_data_ready( &new_dat_ready);
elab 0:0e577ce96b2f 513 if ((new_dat_ready == 0x01) || status != VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 514 break;
elab 0:0e577ce96b2f 515 }
elab 0:0e577ce96b2f 516 loop_nb = loop_nb + 1;
elab 0:0e577ce96b2f 517 VL53L0X_polling_delay();
elab 0:0e577ce96b2f 518 } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP);
elab 0:0e577ce96b2f 519
elab 0:0e577ce96b2f 520 if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
elab 0:0e577ce96b2f 521 status = VL53L0X_ERROR_TIME_OUT;
elab 0:0e577ce96b2f 522 }
elab 0:0e577ce96b2f 523 }
elab 0:0e577ce96b2f 524
elab 0:0e577ce96b2f 525 return status;
elab 0:0e577ce96b2f 526 }
elab 0:0e577ce96b2f 527
elab 0:0e577ce96b2f 528 int VL53L0X::get_distance(uint32_t *p_data)
elab 0:0e577ce96b2f 529 {
elab 0:0e577ce96b2f 530 int status = 0;
elab 0:0e577ce96b2f 531 VL53L0X_RangingMeasurementData_t p_ranging_measurement_data;
elab 0:0e577ce96b2f 532
elab 0:0e577ce96b2f 533 status = start_measurement(range_single_shot_polling, NULL, Range_Config_DEFAULT);
elab 0:0e577ce96b2f 534 if (!status) {
elab 0:0e577ce96b2f 535 status = get_measurement(range_single_shot_polling, &p_ranging_measurement_data);
elab 0:0e577ce96b2f 536 }
elab 0:0e577ce96b2f 537 if (p_ranging_measurement_data.RangeStatus == 0) { // we have a valid range.
elab 0:0e577ce96b2f 538 *p_data = p_ranging_measurement_data.Range_mm;
elab 0:0e577ce96b2f 539 } else {
elab 0:0e577ce96b2f 540 *p_data = 0;
elab 0:0e577ce96b2f 541 status = VL53L0X_ERROR_RANGE_ERROR;
elab 0:0e577ce96b2f 542 }
elab 0:0e577ce96b2f 543 stop_measurement(range_single_shot_polling);
elab 0:0e577ce96b2f 544 return status;
elab 0:0e577ce96b2f 545 }
elab 0:0e577ce96b2f 546
elab 0:0e577ce96b2f 547 VL53L0X_Error VL53L0X::wait_stop_completed(void)
elab 0:0e577ce96b2f 548 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 549 uint32_t stop_completed = 0;
elab 0:0e577ce96b2f 550 uint32_t loop_nb;
elab 0:0e577ce96b2f 551
elab 0:0e577ce96b2f 552 // Wait until it finished
elab 0:0e577ce96b2f 553 // use timeout to avoid deadlock
elab 0:0e577ce96b2f 554 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 555 loop_nb = 0;
elab 0:0e577ce96b2f 556 do {
elab 0:0e577ce96b2f 557 status = VL53L0X_get_stop_completed_status( &stop_completed);
elab 0:0e577ce96b2f 558 if ((stop_completed == 0x00) || status != VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 559 break;
elab 0:0e577ce96b2f 560 }
elab 0:0e577ce96b2f 561 loop_nb = loop_nb + 1;
elab 0:0e577ce96b2f 562 VL53L0X_polling_delay();
elab 0:0e577ce96b2f 563 } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP);
elab 0:0e577ce96b2f 564
elab 0:0e577ce96b2f 565 if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
elab 0:0e577ce96b2f 566 status = VL53L0X_ERROR_TIME_OUT;
elab 0:0e577ce96b2f 567 }
elab 0:0e577ce96b2f 568 }
elab 0:0e577ce96b2f 569
elab 0:0e577ce96b2f 570 return status;
elab 0:0e577ce96b2f 571 }
elab 0:0e577ce96b2f 572
elab 0:0e577ce96b2f 573 int VL53L0X::get_measurement(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *p_data)
elab 0:0e577ce96b2f 574 { int Status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 575
elab 0:0e577ce96b2f 576 if (operating_mode == range_single_shot_polling) {
elab 0:0e577ce96b2f 577 Status = VL53L0X_perform_single_ranging_measurement( p_data);
elab 0:0e577ce96b2f 578 }
elab 0:0e577ce96b2f 579
elab 0:0e577ce96b2f 580 if (operating_mode == range_continuous_polling) {
elab 0:0e577ce96b2f 581 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 582 Status = VL53L0X_measurement_poll_for_completion();
elab 0:0e577ce96b2f 583 }
elab 0:0e577ce96b2f 584
elab 0:0e577ce96b2f 585 if (Status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 586 Status = VL53L0X_get_ranging_measurement_data( p_data);
elab 0:0e577ce96b2f 587
elab 0:0e577ce96b2f 588 // Clear the interrupt
elab 0:0e577ce96b2f 589 VL53L0X_clear_interrupt_mask( VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY);
elab 0:0e577ce96b2f 590 VL53L0X_polling_delay();
elab 0:0e577ce96b2f 591 }
elab 0:0e577ce96b2f 592 }
elab 0:0e577ce96b2f 593
elab 0:0e577ce96b2f 594 if (operating_mode == range_continuous_interrupt) {
elab 0:0e577ce96b2f 595 Status = VL53L0X_get_ranging_measurement_data( p_data);
elab 0:0e577ce96b2f 596 VL53L0X_clear_interrupt_mask( VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR | VL53L0X_REG_RESULT_INTERRUPT_STATUS);
elab 0:0e577ce96b2f 597 }
elab 0:0e577ce96b2f 598
elab 0:0e577ce96b2f 599 return Status;
elab 0:0e577ce96b2f 600 }
elab 0:0e577ce96b2f 601
elab 0:0e577ce96b2f 602 int VL53L0X::stop_measurement(OperatingMode operating_mode)
elab 0:0e577ce96b2f 603 { int status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 604
elab 0:0e577ce96b2f 605 // don't need to stop for a singleshot range!
elab 0:0e577ce96b2f 606 if (operating_mode == range_single_shot_polling) {
elab 0:0e577ce96b2f 607 }
elab 0:0e577ce96b2f 608
elab 0:0e577ce96b2f 609 if (operating_mode == range_continuous_interrupt || operating_mode == range_continuous_polling) {
elab 0:0e577ce96b2f 610 // continuous mode
elab 0:0e577ce96b2f 611 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 612 //aSerial->printf("Call of VL53L0X_StopMeasurement\n");
elab 0:0e577ce96b2f 613 status = VL53L0X_stop_measurement();
elab 0:0e577ce96b2f 614 }
elab 0:0e577ce96b2f 615
elab 0:0e577ce96b2f 616 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 617 //aSerial->printf("Wait Stop to be competed\n");
elab 0:0e577ce96b2f 618 status = wait_stop_completed();
elab 0:0e577ce96b2f 619 }
elab 0:0e577ce96b2f 620
elab 0:0e577ce96b2f 621 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 622 status = VL53L0X_clear_interrupt_mask(VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY);
elab 0:0e577ce96b2f 623 }
elab 0:0e577ce96b2f 624
elab 0:0e577ce96b2f 625 return status;
elab 0:0e577ce96b2f 626 }
elab 0:0e577ce96b2f 627
elab 0:0e577ce96b2f 628 int VL53L0X::handle_irq(OperatingMode operating_mode, VL53L0X_RangingMeasurementData_t *data)
elab 0:0e577ce96b2f 629 { int status;
elab 0:0e577ce96b2f 630 status = get_measurement(operating_mode, data);
elab 0:0e577ce96b2f 631 enable_interrupt_measure_detection_irq();
elab 0:0e577ce96b2f 632 return status;
elab 0:0e577ce96b2f 633 }
elab 0:0e577ce96b2f 634
elab 0:0e577ce96b2f 635 int VL53L0X::range_start_continuous_mode()
elab 0:0e577ce96b2f 636 { CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_CONTINUOUS_RANGING;
elab 0:0e577ce96b2f 637
elab 0:0e577ce96b2f 638 return VL53L0X_start_measurement();
elab 0:0e577ce96b2f 639
elab 0:0e577ce96b2f 640 }
elab 0:0e577ce96b2f 641
elab 0:0e577ce96b2f 642 VL53L0X_Error VL53L0X::VL53L0X_device_read_strobe(void)
elab 0:0e577ce96b2f 643 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 644 uint8_t strobe;
elab 0:0e577ce96b2f 645 uint32_t loop_nb;
elab 0:0e577ce96b2f 646
elab 0:0e577ce96b2f 647 status |= VL53L0X_write_byte( 0x83, 0x00);
elab 0:0e577ce96b2f 648
elab 0:0e577ce96b2f 649 /* polling
elab 0:0e577ce96b2f 650 * use timeout to avoid deadlock*/
elab 0:0e577ce96b2f 651 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 652 loop_nb = 0;
elab 0:0e577ce96b2f 653 do {
elab 0:0e577ce96b2f 654 status = VL53L0X_read_byte( 0x83, &strobe);
elab 0:0e577ce96b2f 655 if ((strobe != 0x00) || status != VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 656 break;
elab 0:0e577ce96b2f 657 }
elab 0:0e577ce96b2f 658
elab 0:0e577ce96b2f 659 loop_nb = loop_nb + 1;
elab 0:0e577ce96b2f 660 } while (loop_nb < VL53L0X_DEFAULT_MAX_LOOP);
elab 0:0e577ce96b2f 661
elab 0:0e577ce96b2f 662 if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
elab 0:0e577ce96b2f 663 status = VL53L0X_ERROR_TIME_OUT;
elab 0:0e577ce96b2f 664 }
elab 0:0e577ce96b2f 665 }
elab 0:0e577ce96b2f 666
elab 0:0e577ce96b2f 667 status |= VL53L0X_write_byte( 0x83, 0x01);
elab 0:0e577ce96b2f 668
elab 0:0e577ce96b2f 669 return status;
elab 0:0e577ce96b2f 670 }
elab 0:0e577ce96b2f 671
elab 0:0e577ce96b2f 672 VL53L0X_Error VL53L0X::VL53L0X_get_info_from_device( uint8_t option)
elab 0:0e577ce96b2f 673 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 674 uint8_t byte;
elab 0:0e577ce96b2f 675 uint32_t tmp_dword;
elab 0:0e577ce96b2f 676 uint8_t module_id;
elab 0:0e577ce96b2f 677 uint8_t revision;
elab 0:0e577ce96b2f 678 uint8_t reference_spad_count = 0;
elab 0:0e577ce96b2f 679 uint8_t reference_spad_type = 0;
elab 0:0e577ce96b2f 680 uint32_t part_uid_upper = 0;
elab 0:0e577ce96b2f 681 uint32_t part_uid_lower = 0;
elab 0:0e577ce96b2f 682 uint32_t offset_fixed1104_mm = 0;
elab 0:0e577ce96b2f 683 int16_t offset_micro_meters = 0;
elab 0:0e577ce96b2f 684 uint32_t dist_meas_tgt_fixed1104_mm = 400 << 4;
elab 0:0e577ce96b2f 685 uint32_t dist_meas_fixed1104_400_mm = 0;
elab 0:0e577ce96b2f 686 uint32_t signal_rate_meas_fixed1104_400_mm = 0;
elab 0:0e577ce96b2f 687 char product_id[19];
elab 0:0e577ce96b2f 688 char *product_id_tmp;
elab 0:0e577ce96b2f 689 uint8_t read_data_from_device_done;
elab 0:0e577ce96b2f 690 FixPoint1616_t signal_rate_meas_fixed400_mm_fix = 0;
elab 0:0e577ce96b2f 691 uint8_t nvm_ref_good_spad_map[VL53L0X_REF_SPAD_BUFFER_SIZE];
elab 0:0e577ce96b2f 692 int i;
elab 0:0e577ce96b2f 693
elab 0:0e577ce96b2f 694 read_data_from_device_done = Data.ReadDataFromDeviceDone;
elab 0:0e577ce96b2f 695 read_data_from_device_done = Data.ReadDataFromDeviceDone;
elab 0:0e577ce96b2f 696 read_data_from_device_done = Data.ReadDataFromDeviceDone;
elab 0:0e577ce96b2f 697
elab 0:0e577ce96b2f 698 /* This access is done only once after that a GetDeviceInfo or
elab 0:0e577ce96b2f 699 * datainit is done*/
elab 0:0e577ce96b2f 700 if (read_data_from_device_done != 7) {
elab 0:0e577ce96b2f 701
elab 0:0e577ce96b2f 702 status |= VL53L0X_write_byte( 0x80, 0x01);
elab 0:0e577ce96b2f 703 status |= VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 704 status |= VL53L0X_write_byte( 0x00, 0x00);
elab 0:0e577ce96b2f 705 status |= VL53L0X_write_byte( 0xFF, 0x06);
elab 0:0e577ce96b2f 706 status |= VL53L0X_read_byte ( 0x83, &byte);
elab 0:0e577ce96b2f 707 status |= VL53L0X_write_byte( 0x83, byte | 4);
elab 0:0e577ce96b2f 708 status |= VL53L0X_write_byte( 0xFF, 0x07);
elab 0:0e577ce96b2f 709 status |= VL53L0X_write_byte( 0x81, 0x01);
elab 0:0e577ce96b2f 710
elab 0:0e577ce96b2f 711 status |= VL53L0X_polling_delay();
elab 0:0e577ce96b2f 712
elab 0:0e577ce96b2f 713 status |= VL53L0X_write_byte( 0x80, 0x01);
elab 0:0e577ce96b2f 714
elab 0:0e577ce96b2f 715 if (((option & 1) == 1) &&
elab 0:0e577ce96b2f 716 ((read_data_from_device_done & 1) == 0)) {
elab 0:0e577ce96b2f 717 status |= VL53L0X_write_byte( 0x94, 0x6b);
elab 0:0e577ce96b2f 718 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 719 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 720
elab 0:0e577ce96b2f 721 reference_spad_count = (uint8_t)((tmp_dword >> 8) & 0x07f);
elab 0:0e577ce96b2f 722 reference_spad_type = (uint8_t)((tmp_dword >> 15) & 0x01);
elab 0:0e577ce96b2f 723
elab 0:0e577ce96b2f 724 status |= VL53L0X_write_byte( 0x94, 0x24);
elab 0:0e577ce96b2f 725 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 726 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 727
elab 0:0e577ce96b2f 728 nvm_ref_good_spad_map[0] = (uint8_t)((tmp_dword >> 24) & 0xff);
elab 0:0e577ce96b2f 729 nvm_ref_good_spad_map[1] = (uint8_t)((tmp_dword >> 16) & 0xff);
elab 0:0e577ce96b2f 730 nvm_ref_good_spad_map[2] = (uint8_t)((tmp_dword >> 8) & 0xff);
elab 0:0e577ce96b2f 731 nvm_ref_good_spad_map[3] = (uint8_t)(tmp_dword & 0xff);
elab 0:0e577ce96b2f 732
elab 0:0e577ce96b2f 733 status |= VL53L0X_write_byte( 0x94, 0x25);
elab 0:0e577ce96b2f 734 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 735 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 736
elab 0:0e577ce96b2f 737 nvm_ref_good_spad_map[4] = (uint8_t)((tmp_dword >> 24) & 0xff);
elab 0:0e577ce96b2f 738 nvm_ref_good_spad_map[5] = (uint8_t)((tmp_dword >> 16) & 0xff);
elab 0:0e577ce96b2f 739 }
elab 0:0e577ce96b2f 740
elab 0:0e577ce96b2f 741 if (((option & 2) == 2) &&
elab 0:0e577ce96b2f 742 ((read_data_from_device_done & 2) == 0)) {
elab 0:0e577ce96b2f 743
elab 0:0e577ce96b2f 744 status |= VL53L0X_write_byte( 0x94, 0x02);
elab 0:0e577ce96b2f 745 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 746 status |= VL53L0X_read_byte( 0x90, &module_id);
elab 0:0e577ce96b2f 747
elab 0:0e577ce96b2f 748 status |= VL53L0X_write_byte( 0x94, 0x7B);
elab 0:0e577ce96b2f 749 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 750 status |= VL53L0X_read_byte( 0x90, &revision);
elab 0:0e577ce96b2f 751
elab 0:0e577ce96b2f 752 status |= VL53L0X_write_byte( 0x94, 0x77);
elab 0:0e577ce96b2f 753 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 754 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 755
elab 0:0e577ce96b2f 756 product_id[0] = (char)((tmp_dword >> 25) & 0x07f);
elab 0:0e577ce96b2f 757 product_id[1] = (char)((tmp_dword >> 18) & 0x07f);
elab 0:0e577ce96b2f 758 product_id[2] = (char)((tmp_dword >> 11) & 0x07f);
elab 0:0e577ce96b2f 759 product_id[3] = (char)((tmp_dword >> 4) & 0x07f);
elab 0:0e577ce96b2f 760
elab 0:0e577ce96b2f 761 byte = (uint8_t)((tmp_dword & 0x00f) << 3);
elab 0:0e577ce96b2f 762
elab 0:0e577ce96b2f 763 status |= VL53L0X_write_byte( 0x94, 0x78);
elab 0:0e577ce96b2f 764 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 765 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 766
elab 0:0e577ce96b2f 767 product_id[4] = (char)(byte +
elab 0:0e577ce96b2f 768 ((tmp_dword >> 29) & 0x07f));
elab 0:0e577ce96b2f 769 product_id[5] = (char)((tmp_dword >> 22) & 0x07f);
elab 0:0e577ce96b2f 770 product_id[6] = (char)((tmp_dword >> 15) & 0x07f);
elab 0:0e577ce96b2f 771 product_id[7] = (char)((tmp_dword >> 8) & 0x07f);
elab 0:0e577ce96b2f 772 product_id[8] = (char)((tmp_dword >> 1) & 0x07f);
elab 0:0e577ce96b2f 773
elab 0:0e577ce96b2f 774 byte = (uint8_t)((tmp_dword & 0x001) << 6);
elab 0:0e577ce96b2f 775
elab 0:0e577ce96b2f 776 status |= VL53L0X_write_byte( 0x94, 0x79);
elab 0:0e577ce96b2f 777
elab 0:0e577ce96b2f 778 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 779
elab 0:0e577ce96b2f 780 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 781
elab 0:0e577ce96b2f 782 product_id[9] = (char)(byte +
elab 0:0e577ce96b2f 783 ((tmp_dword >> 26) & 0x07f));
elab 0:0e577ce96b2f 784 product_id[10] = (char)((tmp_dword >> 19) & 0x07f);
elab 0:0e577ce96b2f 785 product_id[11] = (char)((tmp_dword >> 12) & 0x07f);
elab 0:0e577ce96b2f 786 product_id[12] = (char)((tmp_dword >> 5) & 0x07f);
elab 0:0e577ce96b2f 787
elab 0:0e577ce96b2f 788 byte = (uint8_t)((tmp_dword & 0x01f) << 2);
elab 0:0e577ce96b2f 789
elab 0:0e577ce96b2f 790 status |= VL53L0X_write_byte( 0x94, 0x7A);
elab 0:0e577ce96b2f 791
elab 0:0e577ce96b2f 792 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 793
elab 0:0e577ce96b2f 794 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 795
elab 0:0e577ce96b2f 796 product_id[13] = (char)(byte +
elab 0:0e577ce96b2f 797 ((tmp_dword >> 30) & 0x07f));
elab 0:0e577ce96b2f 798 product_id[14] = (char)((tmp_dword >> 23) & 0x07f);
elab 0:0e577ce96b2f 799 product_id[15] = (char)((tmp_dword >> 16) & 0x07f);
elab 0:0e577ce96b2f 800 product_id[16] = (char)((tmp_dword >> 9) & 0x07f);
elab 0:0e577ce96b2f 801 product_id[17] = (char)((tmp_dword >> 2) & 0x07f);
elab 0:0e577ce96b2f 802 product_id[18] = '\0';
elab 0:0e577ce96b2f 803
elab 0:0e577ce96b2f 804 }
elab 0:0e577ce96b2f 805
elab 0:0e577ce96b2f 806 if (((option & 4) == 4) &&
elab 0:0e577ce96b2f 807 ((read_data_from_device_done & 4) == 0)) {
elab 0:0e577ce96b2f 808
elab 0:0e577ce96b2f 809 status |= VL53L0X_write_byte( 0x94, 0x7B);
elab 0:0e577ce96b2f 810 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 811 status |= VL53L0X_read_dword( 0x90, &part_uid_upper);
elab 0:0e577ce96b2f 812 status |= VL53L0X_write_byte( 0x94, 0x7C);
elab 0:0e577ce96b2f 813 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 814 status |= VL53L0X_read_dword( 0x90, &part_uid_lower);
elab 0:0e577ce96b2f 815
elab 0:0e577ce96b2f 816 status |= VL53L0X_write_byte( 0x94, 0x73);
elab 0:0e577ce96b2f 817 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 818 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 819 signal_rate_meas_fixed1104_400_mm = (tmp_dword & 0x0000000ff) << 8;
elab 0:0e577ce96b2f 820
elab 0:0e577ce96b2f 821 status |= VL53L0X_write_byte( 0x94, 0x74);
elab 0:0e577ce96b2f 822 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 823 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 824 signal_rate_meas_fixed1104_400_mm |= ((tmp_dword & 0xff000000) >> 24);
elab 0:0e577ce96b2f 825
elab 0:0e577ce96b2f 826 status |= VL53L0X_write_byte( 0x94, 0x75);
elab 0:0e577ce96b2f 827 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 828 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 829 dist_meas_fixed1104_400_mm = (tmp_dword & 0x0000000ff) << 8;
elab 0:0e577ce96b2f 830
elab 0:0e577ce96b2f 831 status |= VL53L0X_write_byte( 0x94, 0x76);
elab 0:0e577ce96b2f 832 status |= VL53L0X_device_read_strobe();
elab 0:0e577ce96b2f 833 status |= VL53L0X_read_dword( 0x90, &tmp_dword);
elab 0:0e577ce96b2f 834 dist_meas_fixed1104_400_mm |= ((tmp_dword & 0xff000000) >> 24);
elab 0:0e577ce96b2f 835 }
elab 0:0e577ce96b2f 836
elab 0:0e577ce96b2f 837 status |= VL53L0X_write_byte( 0x81, 0x00);
elab 0:0e577ce96b2f 838 status |= VL53L0X_write_byte( 0xFF, 0x06);
elab 0:0e577ce96b2f 839 status |= VL53L0X_read_byte( 0x83, &byte);
elab 0:0e577ce96b2f 840 status |= VL53L0X_write_byte( 0x83, byte & 0xfb);
elab 0:0e577ce96b2f 841 status |= VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 842 status |= VL53L0X_write_byte( 0x00, 0x01);
elab 0:0e577ce96b2f 843 status |= VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 844 status |= VL53L0X_write_byte( 0x80, 0x00);
elab 0:0e577ce96b2f 845 }
elab 0:0e577ce96b2f 846
elab 0:0e577ce96b2f 847 if ((status == VL53L0X_ERROR_NONE) &&
elab 0:0e577ce96b2f 848 (read_data_from_device_done != 7)) {
elab 0:0e577ce96b2f 849 /* Assign to variable if status is ok */
elab 0:0e577ce96b2f 850 if (((option & 1) == 1) &&
elab 0:0e577ce96b2f 851 ((read_data_from_device_done & 1) == 0)) {
elab 0:0e577ce96b2f 852 Data.ReferenceSpadCount = reference_spad_count;
elab 0:0e577ce96b2f 853 Data.ReferenceSpadType = reference_spad_type;
elab 0:0e577ce96b2f 854
elab 0:0e577ce96b2f 855 for (i = 0; i < VL53L0X_REF_SPAD_BUFFER_SIZE; i++) {
elab 0:0e577ce96b2f 856 Data.RefGoodSpadMap[i] =
elab 0:0e577ce96b2f 857 nvm_ref_good_spad_map[i];
elab 0:0e577ce96b2f 858 }
elab 0:0e577ce96b2f 859 }
elab 0:0e577ce96b2f 860
elab 0:0e577ce96b2f 861 if (((option & 2) == 2) &&
elab 0:0e577ce96b2f 862 ((read_data_from_device_done & 2) == 0)) {
elab 0:0e577ce96b2f 863 Data.ModuleId = module_id;
elab 0:0e577ce96b2f 864 Data.Revision = revision;
elab 0:0e577ce96b2f 865 product_id_tmp = Data.ProductId;
elab 0:0e577ce96b2f 866 VL53L0X_COPYSTRING(product_id_tmp, product_id);
elab 0:0e577ce96b2f 867 }
elab 0:0e577ce96b2f 868
elab 0:0e577ce96b2f 869 if (((option & 4) == 4) &&
elab 0:0e577ce96b2f 870 ((read_data_from_device_done & 4) == 0)) {
elab 0:0e577ce96b2f 871 Data.PartUIDUpper = part_uid_upper;
elab 0:0e577ce96b2f 872 Data.PartUIDLower = part_uid_lower;
elab 0:0e577ce96b2f 873 signal_rate_meas_fixed400_mm_fix =
elab 0:0e577ce96b2f 874 VL53L0X_FP97TOFP1616(signal_rate_meas_fixed1104_400_mm);
elab 0:0e577ce96b2f 875 Data.SignalRateMeasFixed400mm = signal_rate_meas_fixed400_mm_fix;
elab 0:0e577ce96b2f 876
elab 0:0e577ce96b2f 877 offset_micro_meters = 0;
elab 0:0e577ce96b2f 878 if (dist_meas_fixed1104_400_mm != 0) {
elab 0:0e577ce96b2f 879 offset_fixed1104_mm =
elab 0:0e577ce96b2f 880 dist_meas_fixed1104_400_mm -
elab 0:0e577ce96b2f 881 dist_meas_tgt_fixed1104_mm;
elab 0:0e577ce96b2f 882 offset_micro_meters = (offset_fixed1104_mm
elab 0:0e577ce96b2f 883 * 1000) >> 4;
elab 0:0e577ce96b2f 884 offset_micro_meters *= -1;
elab 0:0e577ce96b2f 885 }
elab 0:0e577ce96b2f 886
elab 0:0e577ce96b2f 887 Data.Part2PartOffsetAdjustNVM_um = offset_micro_meters;
elab 0:0e577ce96b2f 888 }
elab 0:0e577ce96b2f 889 byte = (uint8_t)(read_data_from_device_done | option);
elab 0:0e577ce96b2f 890 Data.ReadDataFromDeviceDone = byte;
elab 0:0e577ce96b2f 891 }
elab 0:0e577ce96b2f 892 return status;
elab 0:0e577ce96b2f 893 }
elab 0:0e577ce96b2f 894
elab 0:0e577ce96b2f 895 VL53L0X_Error VL53L0X::VL53L0X_get_offset_calibration_data_micro_meter(int32_t *p_offset_calibration_data_micro_meter)
elab 0:0e577ce96b2f 896 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 897 uint16_t range_offset_register;
elab 0:0e577ce96b2f 898 int16_t c_max_offset = 2047;
elab 0:0e577ce96b2f 899 int16_t c_offset_range = 4096;
elab 0:0e577ce96b2f 900
elab 0:0e577ce96b2f 901 /* Note, that offset has 10.2 format */
elab 0:0e577ce96b2f 902 status = VL53L0X_read_word(VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM,
elab 0:0e577ce96b2f 903 &range_offset_register);
elab 0:0e577ce96b2f 904
elab 0:0e577ce96b2f 905 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 906 range_offset_register = (range_offset_register & 0x0fff);
elab 0:0e577ce96b2f 907
elab 0:0e577ce96b2f 908 /* Apply 12 bit 2's compliment conversion */
elab 0:0e577ce96b2f 909 if (range_offset_register > c_max_offset) {
elab 0:0e577ce96b2f 910 *p_offset_calibration_data_micro_meter =
elab 0:0e577ce96b2f 911 (int16_t)(range_offset_register - c_offset_range) * 250;
elab 0:0e577ce96b2f 912 } else {
elab 0:0e577ce96b2f 913 *p_offset_calibration_data_micro_meter =
elab 0:0e577ce96b2f 914 (int16_t)range_offset_register * 250; }
elab 0:0e577ce96b2f 915 }
elab 0:0e577ce96b2f 916
elab 0:0e577ce96b2f 917 return status;
elab 0:0e577ce96b2f 918 }
elab 0:0e577ce96b2f 919
elab 0:0e577ce96b2f 920 VL53L0X_Error VL53L0X::VL53L0X_set_offset_calibration_data_micro_meter(int32_t offset_calibration_data_micro_meter)
elab 0:0e577ce96b2f 921 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 922 int32_t c_max_offset_micro_meter = 511000;
elab 0:0e577ce96b2f 923 int32_t c_min_offset_micro_meter = -512000;
elab 0:0e577ce96b2f 924 int16_t c_offset_range = 4096;
elab 0:0e577ce96b2f 925 uint32_t encoded_offset_val;
elab 0:0e577ce96b2f 926
elab 0:0e577ce96b2f 927 if (offset_calibration_data_micro_meter > c_max_offset_micro_meter) {
elab 0:0e577ce96b2f 928 offset_calibration_data_micro_meter = c_max_offset_micro_meter;
elab 0:0e577ce96b2f 929 } else {
elab 0:0e577ce96b2f 930 if (offset_calibration_data_micro_meter < c_min_offset_micro_meter) {
elab 0:0e577ce96b2f 931 offset_calibration_data_micro_meter = c_min_offset_micro_meter;
elab 0:0e577ce96b2f 932 }
elab 0:0e577ce96b2f 933 }
elab 0:0e577ce96b2f 934
elab 0:0e577ce96b2f 935 /* The offset register is 10.2 format and units are mm
elab 0:0e577ce96b2f 936 * therefore conversion is applied by a division of 250. */
elab 0:0e577ce96b2f 937 if (offset_calibration_data_micro_meter >= 0) {
elab 0:0e577ce96b2f 938 encoded_offset_val = offset_calibration_data_micro_meter / 250;
elab 0:0e577ce96b2f 939 } else {
elab 0:0e577ce96b2f 940 encoded_offset_val =
elab 0:0e577ce96b2f 941 c_offset_range + offset_calibration_data_micro_meter / 250;
elab 0:0e577ce96b2f 942 }
elab 0:0e577ce96b2f 943
elab 0:0e577ce96b2f 944 status = VL53L0X_write_word(VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM,
elab 0:0e577ce96b2f 945 encoded_offset_val);
elab 0:0e577ce96b2f 946 return status;
elab 0:0e577ce96b2f 947 }
elab 0:0e577ce96b2f 948
elab 0:0e577ce96b2f 949 VL53L0X_Error VL53L0X::VL53L0X_apply_offset_adjustment(void)
elab 0:0e577ce96b2f 950 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 951 int32_t corrected_offset_micro_meters;
elab 0:0e577ce96b2f 952 int32_t current_offset_micro_meters;
elab 0:0e577ce96b2f 953
elab 0:0e577ce96b2f 954 /* if we run on this function we can read all the NVM info used by the API */
elab 0:0e577ce96b2f 955 status = VL53L0X_get_info_from_device( 7);
elab 0:0e577ce96b2f 956
elab 0:0e577ce96b2f 957 /* Read back current device offset */
elab 0:0e577ce96b2f 958 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 959 status = VL53L0X_get_offset_calibration_data_micro_meter(&current_offset_micro_meters);
elab 0:0e577ce96b2f 960 }
elab 0:0e577ce96b2f 961
elab 0:0e577ce96b2f 962 /* Apply Offset Adjustment derived from 400mm measurements */
elab 0:0e577ce96b2f 963 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 964
elab 0:0e577ce96b2f 965 /* Store initial device offset */
elab 0:0e577ce96b2f 966 Data.Part2PartOffsetNVM_um = current_offset_micro_meters;
elab 0:0e577ce96b2f 967
elab 0:0e577ce96b2f 968 corrected_offset_micro_meters = current_offset_micro_meters +
elab 0:0e577ce96b2f 969 (int32_t)Data.Part2PartOffsetAdjustNVM_um;
elab 0:0e577ce96b2f 970
elab 0:0e577ce96b2f 971 status = VL53L0X_set_offset_calibration_data_micro_meter(corrected_offset_micro_meters);
elab 0:0e577ce96b2f 972
elab 0:0e577ce96b2f 973 /* store current, adjusted offset */
elab 0:0e577ce96b2f 974 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 975 CurrentParameters.RangeOffset_um = corrected_offset_micro_meters;
elab 0:0e577ce96b2f 976 }
elab 0:0e577ce96b2f 977 }
elab 0:0e577ce96b2f 978 return status;
elab 0:0e577ce96b2f 979 }
elab 0:0e577ce96b2f 980
elab 0:0e577ce96b2f 981 VL53L0X_Error VL53L0X::VL53L0X_get_inter_measurement_period_ms(uint32_t *p_inter_measurement_period_ms)
elab 0:0e577ce96b2f 982 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 983 uint16_t osc_calibrate_val;
elab 0:0e577ce96b2f 984 uint32_t im_period_ms;
elab 0:0e577ce96b2f 985
elab 0:0e577ce96b2f 986
elab 0:0e577ce96b2f 987
elab 0:0e577ce96b2f 988 status = VL53L0X_read_word( VL53L0X_REG_OSC_CALIBRATE_VAL,
elab 0:0e577ce96b2f 989 &osc_calibrate_val);
elab 0:0e577ce96b2f 990
elab 0:0e577ce96b2f 991 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 992 status = VL53L0X_read_dword(VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD,
elab 0:0e577ce96b2f 993 &im_period_ms);
elab 0:0e577ce96b2f 994 }
elab 0:0e577ce96b2f 995
elab 0:0e577ce96b2f 996 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 997 if (osc_calibrate_val != 0) {
elab 0:0e577ce96b2f 998 *p_inter_measurement_period_ms =
elab 0:0e577ce96b2f 999 im_period_ms / osc_calibrate_val;
elab 0:0e577ce96b2f 1000 }
elab 0:0e577ce96b2f 1001 CurrentParameters.InterMeasurementPeriod_ms = *p_inter_measurement_period_ms;
elab 0:0e577ce96b2f 1002 }
elab 0:0e577ce96b2f 1003
elab 0:0e577ce96b2f 1004 return status;
elab 0:0e577ce96b2f 1005 }
elab 0:0e577ce96b2f 1006
elab 0:0e577ce96b2f 1007 VL53L0X_Error VL53L0X::VL53L0X_get_x_talk_compensation_rate_MHz(FixPoint1616_t *p_xtalk_compensation_rate_MHz)
elab 0:0e577ce96b2f 1008 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1009 uint16_t value;
elab 0:0e577ce96b2f 1010 FixPoint1616_t temp_fix1616;
elab 0:0e577ce96b2f 1011
elab 0:0e577ce96b2f 1012 status = VL53L0X_read_word(VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MHz, (uint16_t *)&value);
elab 0:0e577ce96b2f 1013 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1014 if (value == 0) {
elab 0:0e577ce96b2f 1015 /* the Xtalk is disabled return value from memory */
elab 0:0e577ce96b2f 1016 temp_fix1616 = CurrentParameters.XTalkCompensationRate_MHz ;
elab 0:0e577ce96b2f 1017 *p_xtalk_compensation_rate_MHz = temp_fix1616;
elab 0:0e577ce96b2f 1018 CurrentParameters.XTalkCompensationEnable = 0;
elab 0:0e577ce96b2f 1019 } else {
elab 0:0e577ce96b2f 1020 temp_fix1616 = VL53L0X_FP313TOFP1616(value);
elab 0:0e577ce96b2f 1021 *p_xtalk_compensation_rate_MHz = temp_fix1616;
elab 0:0e577ce96b2f 1022 CurrentParameters.XTalkCompensationRate_MHz = temp_fix1616;
elab 0:0e577ce96b2f 1023 CurrentParameters.XTalkCompensationEnable = 1;
elab 0:0e577ce96b2f 1024 }
elab 0:0e577ce96b2f 1025 }
elab 0:0e577ce96b2f 1026
elab 0:0e577ce96b2f 1027 return status;
elab 0:0e577ce96b2f 1028 }
elab 0:0e577ce96b2f 1029
elab 0:0e577ce96b2f 1030 VL53L0X_Error VL53L0X::VL53L0X_get_limit_check_value( uint16_t limit_check_id,
elab 0:0e577ce96b2f 1031 FixPoint1616_t *p_limit_check_value)
elab 0:0e577ce96b2f 1032 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1033 uint8_t enable_zero_value = 0;
elab 0:0e577ce96b2f 1034 uint16_t temp16;
elab 0:0e577ce96b2f 1035 FixPoint1616_t temp_fix1616;
elab 0:0e577ce96b2f 1036
elab 0:0e577ce96b2f 1037 switch (limit_check_id) {
elab 0:0e577ce96b2f 1038
elab 0:0e577ce96b2f 1039 case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
elab 0:0e577ce96b2f 1040 /* internal computation: */
elab 0:0e577ce96b2f 1041 temp_fix1616 = CurrentParameters.LimitChecksValue[VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE];
elab 0:0e577ce96b2f 1042 enable_zero_value = 0;
elab 0:0e577ce96b2f 1043 break;
elab 0:0e577ce96b2f 1044
elab 0:0e577ce96b2f 1045 case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
elab 0:0e577ce96b2f 1046 status = VL53L0X_read_word(VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, &temp16);
elab 0:0e577ce96b2f 1047 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1048 temp_fix1616 = VL53L0X_FP97TOFP1616(temp16);
elab 0:0e577ce96b2f 1049 }
elab 0:0e577ce96b2f 1050 enable_zero_value = 1;
elab 0:0e577ce96b2f 1051 break;
elab 0:0e577ce96b2f 1052
elab 0:0e577ce96b2f 1053 case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:
elab 0:0e577ce96b2f 1054 /* internal computation: */
elab 0:0e577ce96b2f 1055 temp_fix1616 = CurrentParameters.LimitChecksValue[VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP];
elab 0:0e577ce96b2f 1056 enable_zero_value = 0;
elab 0:0e577ce96b2f 1057 break;
elab 0:0e577ce96b2f 1058
elab 0:0e577ce96b2f 1059 case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:
elab 0:0e577ce96b2f 1060 /* internal computation: */
elab 0:0e577ce96b2f 1061 temp_fix1616 = CurrentParameters.LimitChecksValue[VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD];
elab 0:0e577ce96b2f 1062 enable_zero_value = 0;
elab 0:0e577ce96b2f 1063 break;
elab 0:0e577ce96b2f 1064
elab 0:0e577ce96b2f 1065 case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
elab 0:0e577ce96b2f 1066 case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
elab 0:0e577ce96b2f 1067 status = VL53L0X_read_word(VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT,
elab 0:0e577ce96b2f 1068 &temp16);
elab 0:0e577ce96b2f 1069 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1070 temp_fix1616 = VL53L0X_FP97TOFP1616(temp16);
elab 0:0e577ce96b2f 1071 }
elab 0:0e577ce96b2f 1072
elab 0:0e577ce96b2f 1073 enable_zero_value = 0;
elab 0:0e577ce96b2f 1074 break;
elab 0:0e577ce96b2f 1075
elab 0:0e577ce96b2f 1076 default:
elab 0:0e577ce96b2f 1077 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1078
elab 0:0e577ce96b2f 1079 }
elab 0:0e577ce96b2f 1080
elab 0:0e577ce96b2f 1081 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1082 if (enable_zero_value == 1) {
elab 0:0e577ce96b2f 1083
elab 0:0e577ce96b2f 1084 if (temp_fix1616 == 0) {
elab 0:0e577ce96b2f 1085 /* disabled: return value from memory */
elab 0:0e577ce96b2f 1086 temp_fix1616 = CurrentParameters.LimitChecksValue[limit_check_id];
elab 0:0e577ce96b2f 1087 *p_limit_check_value = temp_fix1616;
elab 0:0e577ce96b2f 1088 CurrentParameters.LimitChecksEnable[limit_check_id] = 0;
elab 0:0e577ce96b2f 1089 } else {
elab 0:0e577ce96b2f 1090 *p_limit_check_value = temp_fix1616;
elab 0:0e577ce96b2f 1091 CurrentParameters.LimitChecksValue[limit_check_id] = temp_fix1616;
elab 0:0e577ce96b2f 1092 CurrentParameters.LimitChecksEnable[limit_check_id] = 1;
elab 0:0e577ce96b2f 1093 }
elab 0:0e577ce96b2f 1094 } else { *p_limit_check_value = temp_fix1616; }
elab 0:0e577ce96b2f 1095 }
elab 0:0e577ce96b2f 1096
elab 0:0e577ce96b2f 1097 return status;
elab 0:0e577ce96b2f 1098 }
elab 0:0e577ce96b2f 1099
elab 0:0e577ce96b2f 1100 VL53L0X_Error VL53L0X::VL53L0X_get_limit_check_enable( uint16_t limit_check_id,
elab 0:0e577ce96b2f 1101 uint8_t *p_limit_check_enable)
elab 0:0e577ce96b2f 1102 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1103 uint8_t temp8;
elab 0:0e577ce96b2f 1104
elab 0:0e577ce96b2f 1105 if (limit_check_id >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) {
elab 0:0e577ce96b2f 1106 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1107 *p_limit_check_enable = 0;
elab 0:0e577ce96b2f 1108 } else {
elab 0:0e577ce96b2f 1109 temp8 = CurrentParameters.LimitChecksEnable[limit_check_id];
elab 0:0e577ce96b2f 1110 *p_limit_check_enable = temp8;
elab 0:0e577ce96b2f 1111 }
elab 0:0e577ce96b2f 1112
elab 0:0e577ce96b2f 1113 return status;
elab 0:0e577ce96b2f 1114 }
elab 0:0e577ce96b2f 1115
elab 0:0e577ce96b2f 1116 VL53L0X_Error VL53L0X::VL53L0X_get_wrap_around_check_enable(uint8_t *p_wrap_around_check_enable)
elab 0:0e577ce96b2f 1117 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1118 uint8_t data;
elab 0:0e577ce96b2f 1119
elab 0:0e577ce96b2f 1120 status = VL53L0X_read_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &data);
elab 0:0e577ce96b2f 1121 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1122 Data.SequenceConfig = data;
elab 0:0e577ce96b2f 1123 if (data & (0x01 << 7)) {
elab 0:0e577ce96b2f 1124 *p_wrap_around_check_enable = 0x01;
elab 0:0e577ce96b2f 1125 } else {
elab 0:0e577ce96b2f 1126 *p_wrap_around_check_enable = 0x00;
elab 0:0e577ce96b2f 1127 }
elab 0:0e577ce96b2f 1128 }
elab 0:0e577ce96b2f 1129 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1130 CurrentParameters.WrapAroundCheckEnable = *p_wrap_around_check_enable;
elab 0:0e577ce96b2f 1131 }
elab 0:0e577ce96b2f 1132
elab 0:0e577ce96b2f 1133 return status;
elab 0:0e577ce96b2f 1134 }
elab 0:0e577ce96b2f 1135
elab 0:0e577ce96b2f 1136 VL53L0X_Error VL53L0X::sequence_step_enabled(VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_config,
elab 0:0e577ce96b2f 1137 uint8_t *p_sequence_step_enabled)
elab 0:0e577ce96b2f 1138 { VL53L0X_Error Status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1139 *p_sequence_step_enabled = 0;
elab 0:0e577ce96b2f 1140
elab 0:0e577ce96b2f 1141 switch (sequence_step_id) {
elab 0:0e577ce96b2f 1142 case VL53L0X_SEQUENCESTEP_TCC:
elab 0:0e577ce96b2f 1143 *p_sequence_step_enabled = (sequence_config & 0x10) >> 4;
elab 0:0e577ce96b2f 1144 break;
elab 0:0e577ce96b2f 1145 case VL53L0X_SEQUENCESTEP_DSS:
elab 0:0e577ce96b2f 1146 *p_sequence_step_enabled = (sequence_config & 0x08) >> 3;
elab 0:0e577ce96b2f 1147 break;
elab 0:0e577ce96b2f 1148 case VL53L0X_SEQUENCESTEP_MSRC:
elab 0:0e577ce96b2f 1149 *p_sequence_step_enabled = (sequence_config & 0x04) >> 2;
elab 0:0e577ce96b2f 1150 break;
elab 0:0e577ce96b2f 1151 case VL53L0X_SEQUENCESTEP_PRE_RANGE:
elab 0:0e577ce96b2f 1152 *p_sequence_step_enabled = (sequence_config & 0x40) >> 6;
elab 0:0e577ce96b2f 1153 break;
elab 0:0e577ce96b2f 1154 case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
elab 0:0e577ce96b2f 1155 *p_sequence_step_enabled = (sequence_config & 0x80) >> 7;
elab 0:0e577ce96b2f 1156 break;
elab 0:0e577ce96b2f 1157 default:
elab 0:0e577ce96b2f 1158 Status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1159 }
elab 0:0e577ce96b2f 1160 return Status;
elab 0:0e577ce96b2f 1161 }
elab 0:0e577ce96b2f 1162
elab 0:0e577ce96b2f 1163 VL53L0X_Error VL53L0X::VL53L0X_get_sequence_step_enables(VL53L0X_SchedulerSequenceSteps_t *p_scheduler_sequence_steps)
elab 0:0e577ce96b2f 1164 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1165 uint8_t sequence_config = 0;
elab 0:0e577ce96b2f 1166
elab 0:0e577ce96b2f 1167 status = VL53L0X_read_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
elab 0:0e577ce96b2f 1168 &sequence_config);
elab 0:0e577ce96b2f 1169
elab 0:0e577ce96b2f 1170 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1171 status = sequence_step_enabled(VL53L0X_SEQUENCESTEP_TCC, sequence_config,
elab 0:0e577ce96b2f 1172 &p_scheduler_sequence_steps->TccOn);
elab 0:0e577ce96b2f 1173 }
elab 0:0e577ce96b2f 1174 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1175 status = sequence_step_enabled(VL53L0X_SEQUENCESTEP_DSS, sequence_config,
elab 0:0e577ce96b2f 1176 &p_scheduler_sequence_steps->DssOn);
elab 0:0e577ce96b2f 1177 }
elab 0:0e577ce96b2f 1178 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1179 status = sequence_step_enabled(VL53L0X_SEQUENCESTEP_MSRC, sequence_config,
elab 0:0e577ce96b2f 1180 &p_scheduler_sequence_steps->MsrcOn);
elab 0:0e577ce96b2f 1181 }
elab 0:0e577ce96b2f 1182 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1183 status = sequence_step_enabled(VL53L0X_SEQUENCESTEP_PRE_RANGE, sequence_config,
elab 0:0e577ce96b2f 1184 &p_scheduler_sequence_steps->PreRangeOn);
elab 0:0e577ce96b2f 1185 }
elab 0:0e577ce96b2f 1186 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1187 status = sequence_step_enabled(VL53L0X_SEQUENCESTEP_FINAL_RANGE, sequence_config,
elab 0:0e577ce96b2f 1188 &p_scheduler_sequence_steps->FinalRangeOn);
elab 0:0e577ce96b2f 1189 }
elab 0:0e577ce96b2f 1190 return status;
elab 0:0e577ce96b2f 1191 }
elab 0:0e577ce96b2f 1192
elab 0:0e577ce96b2f 1193 uint8_t VL53L0X::VL53L0X_decode_vcsel_period(uint8_t vcsel_period_reg)
elab 0:0e577ce96b2f 1194 { /*! Converts the encoded VCSEL period register value into the real period in PLL clocks */
elab 0:0e577ce96b2f 1195 uint8_t vcsel_period_pclks = 0;
elab 0:0e577ce96b2f 1196
elab 0:0e577ce96b2f 1197 vcsel_period_pclks = (vcsel_period_reg + 1) << 1;
elab 0:0e577ce96b2f 1198
elab 0:0e577ce96b2f 1199 return vcsel_period_pclks;
elab 0:0e577ce96b2f 1200 }
elab 0:0e577ce96b2f 1201
elab 0:0e577ce96b2f 1202 uint8_t VL53L0X::lv53l0x_encode_vcsel_period(uint8_t vcsel_period_pclks)
elab 0:0e577ce96b2f 1203 { /*! Converts the encoded VCSEL period register value into the real period in PLL clocks */
elab 0:0e577ce96b2f 1204
elab 0:0e577ce96b2f 1205 uint8_t vcsel_period_reg = 0;
elab 0:0e577ce96b2f 1206
elab 0:0e577ce96b2f 1207 vcsel_period_reg = (vcsel_period_pclks >> 1) - 1;
elab 0:0e577ce96b2f 1208
elab 0:0e577ce96b2f 1209 return vcsel_period_reg;
elab 0:0e577ce96b2f 1210 }
elab 0:0e577ce96b2f 1211
elab 0:0e577ce96b2f 1212 VL53L0X_Error VL53L0X::wrapped_VL53L0X_set_vcsel_pulse_period(VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period_pclk)
elab 0:0e577ce96b2f 1213 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1214 uint8_t vcsel_period_reg;
elab 0:0e577ce96b2f 1215 uint8_t min_pre_vcsel_period_pclk = 12;
elab 0:0e577ce96b2f 1216 uint8_t max_pre_vcsel_period_pclk = 18;
elab 0:0e577ce96b2f 1217 uint8_t min_final_vcsel_period_pclk = 8;
elab 0:0e577ce96b2f 1218 uint8_t max_final_vcsel_period_pclk = 14;
elab 0:0e577ce96b2f 1219 uint32_t measurement_timing_budget_us;
elab 0:0e577ce96b2f 1220 uint32_t final_range_timeout_us;
elab 0:0e577ce96b2f 1221 uint32_t pre_range_timeout_us;
elab 0:0e577ce96b2f 1222 uint32_t msrc_timeout_us;
elab 0:0e577ce96b2f 1223 uint8_t phase_cal_int = 0;
elab 0:0e577ce96b2f 1224
elab 0:0e577ce96b2f 1225 /* Check if valid clock period requested */
elab 0:0e577ce96b2f 1226
elab 0:0e577ce96b2f 1227 if ((vcsel_pulse_period_pclk % 2) != 0) {
elab 0:0e577ce96b2f 1228 /* Value must be an even number */
elab 0:0e577ce96b2f 1229 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1230 } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_PRE_RANGE &&
elab 0:0e577ce96b2f 1231 (vcsel_pulse_period_pclk < min_pre_vcsel_period_pclk ||
elab 0:0e577ce96b2f 1232 vcsel_pulse_period_pclk > max_pre_vcsel_period_pclk)) {
elab 0:0e577ce96b2f 1233 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1234 } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_FINAL_RANGE &&
elab 0:0e577ce96b2f 1235 (vcsel_pulse_period_pclk < min_final_vcsel_period_pclk ||
elab 0:0e577ce96b2f 1236 vcsel_pulse_period_pclk > max_final_vcsel_period_pclk)) {
elab 0:0e577ce96b2f 1237
elab 0:0e577ce96b2f 1238 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1239 }
elab 0:0e577ce96b2f 1240
elab 0:0e577ce96b2f 1241 /* Apply specific settings for the requested clock period */
elab 0:0e577ce96b2f 1242
elab 0:0e577ce96b2f 1243 if (status != VL53L0X_ERROR_NONE) { return status; }
elab 0:0e577ce96b2f 1244
elab 0:0e577ce96b2f 1245 if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_PRE_RANGE) {
elab 0:0e577ce96b2f 1246
elab 0:0e577ce96b2f 1247 /* Set phase check limits */
elab 0:0e577ce96b2f 1248 if (vcsel_pulse_period_pclk == 12) {
elab 0:0e577ce96b2f 1249
elab 0:0e577ce96b2f 1250 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,
elab 0:0e577ce96b2f 1251 0x18);
elab 0:0e577ce96b2f 1252 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW,
elab 0:0e577ce96b2f 1253 0x08);
elab 0:0e577ce96b2f 1254 } else if (vcsel_pulse_period_pclk == 14) {
elab 0:0e577ce96b2f 1255
elab 0:0e577ce96b2f 1256 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,
elab 0:0e577ce96b2f 1257 0x30);
elab 0:0e577ce96b2f 1258 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW,
elab 0:0e577ce96b2f 1259 0x08);
elab 0:0e577ce96b2f 1260 } else if (vcsel_pulse_period_pclk == 16) {
elab 0:0e577ce96b2f 1261
elab 0:0e577ce96b2f 1262 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,
elab 0:0e577ce96b2f 1263 0x40);
elab 0:0e577ce96b2f 1264 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW,
elab 0:0e577ce96b2f 1265 0x08);
elab 0:0e577ce96b2f 1266 } else if (vcsel_pulse_period_pclk == 18) {
elab 0:0e577ce96b2f 1267
elab 0:0e577ce96b2f 1268 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,
elab 0:0e577ce96b2f 1269 0x50);
elab 0:0e577ce96b2f 1270 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW,
elab 0:0e577ce96b2f 1271 0x08);
elab 0:0e577ce96b2f 1272 }
elab 0:0e577ce96b2f 1273 } else if (vcsel_period_type == VL53L0X_VCSEL_PERIOD_FINAL_RANGE) {
elab 0:0e577ce96b2f 1274 if (vcsel_pulse_period_pclk == 8) {
elab 0:0e577ce96b2f 1275 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,0x10);
elab 0:0e577ce96b2f 1276 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,0x08);
elab 0:0e577ce96b2f 1277 status |= VL53L0X_write_byte(VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x02);
elab 0:0e577ce96b2f 1278 status |= VL53L0X_write_byte(VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x0C);
elab 0:0e577ce96b2f 1279 status |= VL53L0X_write_byte( 0xff, 0x01);
elab 0:0e577ce96b2f 1280 status |= VL53L0X_write_byte(VL53L0X_REG_ALGO_PHASECAL_LIM,0x30);
elab 0:0e577ce96b2f 1281 status |= VL53L0X_write_byte( 0xff, 0x00);
elab 0:0e577ce96b2f 1282 } else if (vcsel_pulse_period_pclk == 10) {
elab 0:0e577ce96b2f 1283 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,0x28);
elab 0:0e577ce96b2f 1284 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,0x08);
elab 0:0e577ce96b2f 1285 status |= VL53L0X_write_byte(VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
elab 0:0e577ce96b2f 1286 status |= VL53L0X_write_byte(VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x09);
elab 0:0e577ce96b2f 1287 status |= VL53L0X_write_byte( 0xff, 0x01);
elab 0:0e577ce96b2f 1288 status |= VL53L0X_write_byte(VL53L0X_REG_ALGO_PHASECAL_LIM,0x20);
elab 0:0e577ce96b2f 1289 status |= VL53L0X_write_byte( 0xff, 0x00);
elab 0:0e577ce96b2f 1290 } else if (vcsel_pulse_period_pclk == 12) {
elab 0:0e577ce96b2f 1291 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x38);
elab 0:0e577ce96b2f 1292 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08);
elab 0:0e577ce96b2f 1293 status |= VL53L0X_write_byte(VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
elab 0:0e577ce96b2f 1294 status |= VL53L0X_write_byte(VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x08);
elab 0:0e577ce96b2f 1295 status |= VL53L0X_write_byte( 0xff, 0x01);
elab 0:0e577ce96b2f 1296 status |= VL53L0X_write_byte(VL53L0X_REG_ALGO_PHASECAL_LIM,0x20);
elab 0:0e577ce96b2f 1297 status |= VL53L0X_write_byte( 0xff, 0x00);
elab 0:0e577ce96b2f 1298 } else if (vcsel_pulse_period_pclk == 14) {
elab 0:0e577ce96b2f 1299 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,0x048);
elab 0:0e577ce96b2f 1300 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,0x08);
elab 0:0e577ce96b2f 1301 status |= VL53L0X_write_byte(VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
elab 0:0e577ce96b2f 1302 status |= VL53L0X_write_byte(VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x07);
elab 0:0e577ce96b2f 1303 status |= VL53L0X_write_byte( 0xff, 0x01);
elab 0:0e577ce96b2f 1304 status |= VL53L0X_write_byte(VL53L0X_REG_ALGO_PHASECAL_LIM,0x20);
elab 0:0e577ce96b2f 1305 status |= VL53L0X_write_byte( 0xff, 0x00);
elab 0:0e577ce96b2f 1306 }
elab 0:0e577ce96b2f 1307 }
elab 0:0e577ce96b2f 1308
elab 0:0e577ce96b2f 1309 /* Re-calculate and apply timeouts, in macro periods */
elab 0:0e577ce96b2f 1310
elab 0:0e577ce96b2f 1311 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1312 vcsel_period_reg = lv53l0x_encode_vcsel_period((uint8_t) vcsel_pulse_period_pclk);
elab 0:0e577ce96b2f 1313
elab 0:0e577ce96b2f 1314 /* When the VCSEL period for the pre or final range is changed,
elab 0:0e577ce96b2f 1315 * the corresponding timeout must be read from the device using
elab 0:0e577ce96b2f 1316 * the current VCSEL period, then the new VCSEL period can be
elab 0:0e577ce96b2f 1317 * applied. The timeout then must be written back to the device
elab 0:0e577ce96b2f 1318 * using the new VCSEL period.
elab 0:0e577ce96b2f 1319 *
elab 0:0e577ce96b2f 1320 * For the MSRC timeout, the same applies - this timeout being
elab 0:0e577ce96b2f 1321 * dependant on the pre-range vcsel period.
elab 0:0e577ce96b2f 1322 */
elab 0:0e577ce96b2f 1323 switch (vcsel_period_type) {
elab 0:0e577ce96b2f 1324 case VL53L0X_VCSEL_PERIOD_PRE_RANGE:
elab 0:0e577ce96b2f 1325 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE,
elab 0:0e577ce96b2f 1326 &pre_range_timeout_us);
elab 0:0e577ce96b2f 1327
elab 0:0e577ce96b2f 1328 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1329 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_MSRC,
elab 0:0e577ce96b2f 1330 &msrc_timeout_us);
elab 0:0e577ce96b2f 1331
elab 0:0e577ce96b2f 1332 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1333 status = VL53L0X_write_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD,
elab 0:0e577ce96b2f 1334 vcsel_period_reg);
elab 0:0e577ce96b2f 1335
elab 0:0e577ce96b2f 1336 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1337 status = set_sequence_step_timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE,
elab 0:0e577ce96b2f 1338 pre_range_timeout_us);
elab 0:0e577ce96b2f 1339
elab 0:0e577ce96b2f 1340 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1341 status = set_sequence_step_timeout(VL53L0X_SEQUENCESTEP_MSRC,
elab 0:0e577ce96b2f 1342 msrc_timeout_us);
elab 0:0e577ce96b2f 1343
elab 0:0e577ce96b2f 1344 Data.PreRangeVcselPulsePeriod = vcsel_pulse_period_pclk;
elab 0:0e577ce96b2f 1345 break;
elab 0:0e577ce96b2f 1346 case VL53L0X_VCSEL_PERIOD_FINAL_RANGE:
elab 0:0e577ce96b2f 1347 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE,
elab 0:0e577ce96b2f 1348 &final_range_timeout_us);
elab 0:0e577ce96b2f 1349
elab 0:0e577ce96b2f 1350 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1351 status = VL53L0X_write_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD,
elab 0:0e577ce96b2f 1352 vcsel_period_reg);
elab 0:0e577ce96b2f 1353
elab 0:0e577ce96b2f 1354 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1355 status = set_sequence_step_timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE,
elab 0:0e577ce96b2f 1356 final_range_timeout_us);
elab 0:0e577ce96b2f 1357
elab 0:0e577ce96b2f 1358 Data.FinalRangeVcselPulsePeriod = vcsel_pulse_period_pclk;
elab 0:0e577ce96b2f 1359 break;
elab 0:0e577ce96b2f 1360 default:
elab 0:0e577ce96b2f 1361 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1362 }
elab 0:0e577ce96b2f 1363 }
elab 0:0e577ce96b2f 1364
elab 0:0e577ce96b2f 1365 /* Finally, the timing budget must be re-applied */
elab 0:0e577ce96b2f 1366 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1367 measurement_timing_budget_us = CurrentParameters.MeasurementTimingBudget_us ;
elab 0:0e577ce96b2f 1368 status = VL53L0X_set_measurement_timing_budget_us(measurement_timing_budget_us);
elab 0:0e577ce96b2f 1369 }
elab 0:0e577ce96b2f 1370
elab 0:0e577ce96b2f 1371 /* Perform the phase calibration. This is needed after changing on
elab 0:0e577ce96b2f 1372 * vcsel period. get_data_enable = 0, restore_config = 1 */
elab 0:0e577ce96b2f 1373 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1374 status = VL53L0X_perform_phase_calibration(&phase_cal_int, 0, 1);
elab 0:0e577ce96b2f 1375
elab 0:0e577ce96b2f 1376 return status;
elab 0:0e577ce96b2f 1377 }
elab 0:0e577ce96b2f 1378
elab 0:0e577ce96b2f 1379 VL53L0X_Error VL53L0X::VL53L0X_set_vcsel_pulse_period(VL53L0X_VcselPeriod vcsel_period_type, uint8_t vcsel_pulse_period)
elab 0:0e577ce96b2f 1380 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1381
elab 0:0e577ce96b2f 1382 status = wrapped_VL53L0X_set_vcsel_pulse_period( vcsel_period_type, vcsel_pulse_period);
elab 0:0e577ce96b2f 1383
elab 0:0e577ce96b2f 1384 return status;
elab 0:0e577ce96b2f 1385 }
elab 0:0e577ce96b2f 1386
elab 0:0e577ce96b2f 1387 VL53L0X_Error VL53L0X::VL53L0X_get_vcsel_pulse_period(VL53L0X_VcselPeriod vcsel_period_type, uint8_t *p_vcsel_pulse_period_pclk)
elab 0:0e577ce96b2f 1388 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1389 uint8_t vcsel_period_reg;
elab 0:0e577ce96b2f 1390
elab 0:0e577ce96b2f 1391 switch (vcsel_period_type) {
elab 0:0e577ce96b2f 1392 case VL53L0X_VCSEL_PERIOD_PRE_RANGE:
elab 0:0e577ce96b2f 1393 status = VL53L0X_read_byte(VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD,
elab 0:0e577ce96b2f 1394 &vcsel_period_reg);
elab 0:0e577ce96b2f 1395 break;
elab 0:0e577ce96b2f 1396 case VL53L0X_VCSEL_PERIOD_FINAL_RANGE:
elab 0:0e577ce96b2f 1397 status = VL53L0X_read_byte(VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD,
elab 0:0e577ce96b2f 1398 &vcsel_period_reg);
elab 0:0e577ce96b2f 1399 break;
elab 0:0e577ce96b2f 1400 default:
elab 0:0e577ce96b2f 1401 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1402 }
elab 0:0e577ce96b2f 1403
elab 0:0e577ce96b2f 1404 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1405 *p_vcsel_pulse_period_pclk = VL53L0X_decode_vcsel_period(vcsel_period_reg);
elab 0:0e577ce96b2f 1406
elab 0:0e577ce96b2f 1407 return status;
elab 0:0e577ce96b2f 1408 }
elab 0:0e577ce96b2f 1409
elab 0:0e577ce96b2f 1410 uint32_t VL53L0X::VL53L0X_decode_timeout(uint16_t encoded_timeout)
elab 0:0e577ce96b2f 1411 { /*! Decode 16-bit timeout register value - format (LSByte * 2^MSByte) + 1 */
elab 0:0e577ce96b2f 1412 uint32_t timeout_macro_clks = 0;
elab 0:0e577ce96b2f 1413
elab 0:0e577ce96b2f 1414 timeout_macro_clks = ((uint32_t)(encoded_timeout & 0x00FF)
elab 0:0e577ce96b2f 1415 << (uint32_t)((encoded_timeout & 0xFF00) >> 8)) + 1;
elab 0:0e577ce96b2f 1416
elab 0:0e577ce96b2f 1417 return timeout_macro_clks;
elab 0:0e577ce96b2f 1418 }
elab 0:0e577ce96b2f 1419
elab 0:0e577ce96b2f 1420 uint32_t VL53L0X::VL53L0X_calc_macro_period_ps( uint8_t vcsel_period_pclks)
elab 0:0e577ce96b2f 1421 { uint64_t pll_period_ps;
elab 0:0e577ce96b2f 1422 uint32_t macro_period_vclks;
elab 0:0e577ce96b2f 1423 uint32_t macro_period_ps;
elab 0:0e577ce96b2f 1424
elab 0:0e577ce96b2f 1425 /* The above calculation will produce rounding errors, therefore set fixed value*/
elab 0:0e577ce96b2f 1426 pll_period_ps = 1655;
elab 0:0e577ce96b2f 1427 macro_period_vclks = 2304;
elab 0:0e577ce96b2f 1428 macro_period_ps = (uint32_t)(macro_period_vclks
elab 0:0e577ce96b2f 1429 * vcsel_period_pclks * pll_period_ps);
elab 0:0e577ce96b2f 1430 return macro_period_ps;
elab 0:0e577ce96b2f 1431 }
elab 0:0e577ce96b2f 1432
elab 0:0e577ce96b2f 1433 /* To convert register value into us */
elab 0:0e577ce96b2f 1434 uint32_t VL53L0X::VL53L0X_calc_timeout_us(uint16_t timeout_period_mclks,
elab 0:0e577ce96b2f 1435 uint8_t vcsel_period_pclks)
elab 0:0e577ce96b2f 1436 { uint32_t macro_period_ps;
elab 0:0e577ce96b2f 1437 uint32_t macro_period_ns;
elab 0:0e577ce96b2f 1438 uint32_t actual_timeout_period_us = 0;
elab 0:0e577ce96b2f 1439
elab 0:0e577ce96b2f 1440 macro_period_ps = VL53L0X_calc_macro_period_ps( vcsel_period_pclks);
elab 0:0e577ce96b2f 1441 macro_period_ns = (macro_period_ps + 500) / 1000;
elab 0:0e577ce96b2f 1442
elab 0:0e577ce96b2f 1443 actual_timeout_period_us =
elab 0:0e577ce96b2f 1444 ((timeout_period_mclks * macro_period_ns) + 500) / 1000;
elab 0:0e577ce96b2f 1445
elab 0:0e577ce96b2f 1446 return actual_timeout_period_us;
elab 0:0e577ce96b2f 1447 }
elab 0:0e577ce96b2f 1448
elab 0:0e577ce96b2f 1449 VL53L0X_Error VL53L0X::get_sequence_step_timeout(VL53L0X_SequenceStepId sequence_step_id,
elab 0:0e577ce96b2f 1450 uint32_t *p_time_out_micro_secs)
elab 0:0e577ce96b2f 1451 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1452 uint8_t current_vcsel_pulse_period_p_clk;
elab 0:0e577ce96b2f 1453 uint8_t encoded_time_out_byte = 0;
elab 0:0e577ce96b2f 1454 uint32_t timeout_us = 0;
elab 0:0e577ce96b2f 1455 uint16_t pre_range_encoded_time_out = 0;
elab 0:0e577ce96b2f 1456 uint16_t msrc_time_out_m_clks;
elab 0:0e577ce96b2f 1457 uint16_t pre_range_time_out_m_clks;
elab 0:0e577ce96b2f 1458 uint16_t final_range_time_out_m_clks = 0;
elab 0:0e577ce96b2f 1459 uint16_t final_range_encoded_time_out;
elab 0:0e577ce96b2f 1460 VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps;
elab 0:0e577ce96b2f 1461
elab 0:0e577ce96b2f 1462 if ((sequence_step_id == VL53L0X_SEQUENCESTEP_TCC) ||
elab 0:0e577ce96b2f 1463 (sequence_step_id == VL53L0X_SEQUENCESTEP_DSS) ||
elab 0:0e577ce96b2f 1464 (sequence_step_id == VL53L0X_SEQUENCESTEP_MSRC)) {
elab 0:0e577ce96b2f 1465
elab 0:0e577ce96b2f 1466 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE,
elab 0:0e577ce96b2f 1467 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 1468 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1469 status = VL53L0X_read_byte(VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP,
elab 0:0e577ce96b2f 1470 &encoded_time_out_byte);
elab 0:0e577ce96b2f 1471 }
elab 0:0e577ce96b2f 1472 msrc_time_out_m_clks = VL53L0X_decode_timeout(encoded_time_out_byte);
elab 0:0e577ce96b2f 1473
elab 0:0e577ce96b2f 1474 timeout_us = VL53L0X_calc_timeout_us(msrc_time_out_m_clks,
elab 0:0e577ce96b2f 1475 current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 1476 } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_PRE_RANGE) {
elab 0:0e577ce96b2f 1477 /* Retrieve PRE-RANGE VCSEL Period */
elab 0:0e577ce96b2f 1478 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE,
elab 0:0e577ce96b2f 1479 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 1480
elab 0:0e577ce96b2f 1481 /* Retrieve PRE-RANGE Timeout in Macro periods (MCLKS) */
elab 0:0e577ce96b2f 1482 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1483
elab 0:0e577ce96b2f 1484 /* Retrieve PRE-RANGE VCSEL Period */
elab 0:0e577ce96b2f 1485 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE,
elab 0:0e577ce96b2f 1486 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 1487
elab 0:0e577ce96b2f 1488 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1489 status = VL53L0X_read_word(VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI,
elab 0:0e577ce96b2f 1490 &pre_range_encoded_time_out);
elab 0:0e577ce96b2f 1491 }
elab 0:0e577ce96b2f 1492
elab 0:0e577ce96b2f 1493 pre_range_time_out_m_clks = VL53L0X_decode_timeout(pre_range_encoded_time_out);
elab 0:0e577ce96b2f 1494
elab 0:0e577ce96b2f 1495 timeout_us = VL53L0X_calc_timeout_us(pre_range_time_out_m_clks,
elab 0:0e577ce96b2f 1496 current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 1497 }
elab 0:0e577ce96b2f 1498 } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_FINAL_RANGE) {
elab 0:0e577ce96b2f 1499
elab 0:0e577ce96b2f 1500 VL53L0X_get_sequence_step_enables( &scheduler_sequence_steps);
elab 0:0e577ce96b2f 1501 pre_range_time_out_m_clks = 0;
elab 0:0e577ce96b2f 1502
elab 0:0e577ce96b2f 1503 if (scheduler_sequence_steps.PreRangeOn) {
elab 0:0e577ce96b2f 1504 /* Retrieve PRE-RANGE VCSEL Period */
elab 0:0e577ce96b2f 1505 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE,
elab 0:0e577ce96b2f 1506 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 1507
elab 0:0e577ce96b2f 1508 /* Retrieve PRE-RANGE Timeout in Macro periods
elab 0:0e577ce96b2f 1509 * (MCLKS) */
elab 0:0e577ce96b2f 1510 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1511 status = VL53L0X_read_word(VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI,
elab 0:0e577ce96b2f 1512 &pre_range_encoded_time_out);
elab 0:0e577ce96b2f 1513 pre_range_time_out_m_clks = VL53L0X_decode_timeout(pre_range_encoded_time_out);
elab 0:0e577ce96b2f 1514 }
elab 0:0e577ce96b2f 1515 }
elab 0:0e577ce96b2f 1516
elab 0:0e577ce96b2f 1517 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1518 /* Retrieve FINAL-RANGE VCSEL Period */
elab 0:0e577ce96b2f 1519 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_FINAL_RANGE,
elab 0:0e577ce96b2f 1520 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 1521 }
elab 0:0e577ce96b2f 1522
elab 0:0e577ce96b2f 1523 /* Retrieve FINAL-RANGE Timeout in Macro periods (MCLKS) */
elab 0:0e577ce96b2f 1524 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1525 status = VL53L0X_read_word(VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI,
elab 0:0e577ce96b2f 1526 &final_range_encoded_time_out);
elab 0:0e577ce96b2f 1527 final_range_time_out_m_clks = VL53L0X_decode_timeout(final_range_encoded_time_out);
elab 0:0e577ce96b2f 1528 }
elab 0:0e577ce96b2f 1529
elab 0:0e577ce96b2f 1530 final_range_time_out_m_clks -= pre_range_time_out_m_clks;
elab 0:0e577ce96b2f 1531 timeout_us = VL53L0X_calc_timeout_us(final_range_time_out_m_clks,
elab 0:0e577ce96b2f 1532 current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 1533 }
elab 0:0e577ce96b2f 1534
elab 0:0e577ce96b2f 1535 *p_time_out_micro_secs = timeout_us;
elab 0:0e577ce96b2f 1536
elab 0:0e577ce96b2f 1537 return status;
elab 0:0e577ce96b2f 1538 }
elab 0:0e577ce96b2f 1539
elab 0:0e577ce96b2f 1540 VL53L0X_Error VL53L0X::VL53L0X_get_measurement_timing_budget_us(uint32_t *p_measurement_timing_budget_us)
elab 0:0e577ce96b2f 1541 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1542 VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps;
elab 0:0e577ce96b2f 1543 uint32_t final_range_timeout_us;
elab 0:0e577ce96b2f 1544 uint32_t msrc_dcc_tcc_timeout_us = 2000;
elab 0:0e577ce96b2f 1545 uint32_t start_overhead_us = 1910;
elab 0:0e577ce96b2f 1546 uint32_t end_overhead_us = 960;
elab 0:0e577ce96b2f 1547 uint32_t msrc_overhead_us = 660;
elab 0:0e577ce96b2f 1548 uint32_t tcc_overhead_us = 590;
elab 0:0e577ce96b2f 1549 uint32_t dss_overhead_us = 690;
elab 0:0e577ce96b2f 1550 uint32_t pre_range_overhead_us = 660;
elab 0:0e577ce96b2f 1551 uint32_t final_range_overhead_us = 550;
elab 0:0e577ce96b2f 1552 uint32_t pre_range_timeout_us = 0;
elab 0:0e577ce96b2f 1553
elab 0:0e577ce96b2f 1554 /* Start and end overhead times always present */
elab 0:0e577ce96b2f 1555 *p_measurement_timing_budget_us
elab 0:0e577ce96b2f 1556 = start_overhead_us + end_overhead_us;
elab 0:0e577ce96b2f 1557
elab 0:0e577ce96b2f 1558 status = VL53L0X_get_sequence_step_enables( &scheduler_sequence_steps);
elab 0:0e577ce96b2f 1559
elab 0:0e577ce96b2f 1560 if (status != VL53L0X_ERROR_NONE) { return status; }
elab 0:0e577ce96b2f 1561
elab 0:0e577ce96b2f 1562 if (scheduler_sequence_steps.TccOn ||
elab 0:0e577ce96b2f 1563 scheduler_sequence_steps.MsrcOn ||
elab 0:0e577ce96b2f 1564 scheduler_sequence_steps.DssOn) {
elab 0:0e577ce96b2f 1565
elab 0:0e577ce96b2f 1566 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_MSRC,
elab 0:0e577ce96b2f 1567 &msrc_dcc_tcc_timeout_us);
elab 0:0e577ce96b2f 1568
elab 0:0e577ce96b2f 1569 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1570 if (scheduler_sequence_steps.TccOn) {
elab 0:0e577ce96b2f 1571 *p_measurement_timing_budget_us +=
elab 0:0e577ce96b2f 1572 msrc_dcc_tcc_timeout_us + tcc_overhead_us;
elab 0:0e577ce96b2f 1573 }
elab 0:0e577ce96b2f 1574
elab 0:0e577ce96b2f 1575 if (scheduler_sequence_steps.DssOn) {
elab 0:0e577ce96b2f 1576 *p_measurement_timing_budget_us +=
elab 0:0e577ce96b2f 1577 2 * (msrc_dcc_tcc_timeout_us + dss_overhead_us);
elab 0:0e577ce96b2f 1578 } else if (scheduler_sequence_steps.MsrcOn) {
elab 0:0e577ce96b2f 1579 *p_measurement_timing_budget_us +=
elab 0:0e577ce96b2f 1580 msrc_dcc_tcc_timeout_us + msrc_overhead_us;
elab 0:0e577ce96b2f 1581 }
elab 0:0e577ce96b2f 1582 }
elab 0:0e577ce96b2f 1583 }
elab 0:0e577ce96b2f 1584
elab 0:0e577ce96b2f 1585 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1586 if (scheduler_sequence_steps.PreRangeOn) {
elab 0:0e577ce96b2f 1587 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE,
elab 0:0e577ce96b2f 1588 &pre_range_timeout_us);
elab 0:0e577ce96b2f 1589 *p_measurement_timing_budget_us +=
elab 0:0e577ce96b2f 1590 pre_range_timeout_us + pre_range_overhead_us;
elab 0:0e577ce96b2f 1591 }
elab 0:0e577ce96b2f 1592 }
elab 0:0e577ce96b2f 1593
elab 0:0e577ce96b2f 1594 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1595 if (scheduler_sequence_steps.FinalRangeOn) {
elab 0:0e577ce96b2f 1596 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE,
elab 0:0e577ce96b2f 1597 &final_range_timeout_us);
elab 0:0e577ce96b2f 1598 *p_measurement_timing_budget_us +=
elab 0:0e577ce96b2f 1599 (final_range_timeout_us + final_range_overhead_us);
elab 0:0e577ce96b2f 1600 }
elab 0:0e577ce96b2f 1601 }
elab 0:0e577ce96b2f 1602
elab 0:0e577ce96b2f 1603 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1604 CurrentParameters.MeasurementTimingBudget_us = *p_measurement_timing_budget_us;}
elab 0:0e577ce96b2f 1605
elab 0:0e577ce96b2f 1606 return status;
elab 0:0e577ce96b2f 1607 }
elab 0:0e577ce96b2f 1608
elab 0:0e577ce96b2f 1609 VL53L0X_Error VL53L0X::VL53L0X_get_device_parameters(VL53L0X_DeviceParameters_t *p_device_parameters)
elab 0:0e577ce96b2f 1610 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1611 int i;
elab 0:0e577ce96b2f 1612
elab 0:0e577ce96b2f 1613 p_device_parameters->DeviceMode = CurrentParameters.DeviceMode;
elab 0:0e577ce96b2f 1614
elab 0:0e577ce96b2f 1615 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1616 status = VL53L0X_get_inter_measurement_period_ms(&(p_device_parameters->InterMeasurementPeriod_ms));
elab 0:0e577ce96b2f 1617
elab 0:0e577ce96b2f 1618 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1619 p_device_parameters->XTalkCompensationEnable = 0;
elab 0:0e577ce96b2f 1620 }
elab 0:0e577ce96b2f 1621
elab 0:0e577ce96b2f 1622 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1623 status = VL53L0X_get_x_talk_compensation_rate_MHz(&(p_device_parameters->XTalkCompensationRate_MHz));
elab 0:0e577ce96b2f 1624
elab 0:0e577ce96b2f 1625 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 1626 status = VL53L0X_get_offset_calibration_data_micro_meter(&(p_device_parameters->RangeOffset_um));
elab 0:0e577ce96b2f 1627
elab 0:0e577ce96b2f 1628 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1629 for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) {
elab 0:0e577ce96b2f 1630 /* get first the values, then the enables.
elab 0:0e577ce96b2f 1631 * VL53L0X_GetLimitCheckValue will modify the enable
elab 0:0e577ce96b2f 1632 * flags
elab 0:0e577ce96b2f 1633 */
elab 0:0e577ce96b2f 1634 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1635 status |= VL53L0X_get_limit_check_value( i,
elab 0:0e577ce96b2f 1636 &(p_device_parameters->LimitChecksValue[i]));
elab 0:0e577ce96b2f 1637 } else {
elab 0:0e577ce96b2f 1638 break;
elab 0:0e577ce96b2f 1639 }
elab 0:0e577ce96b2f 1640 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1641 status |= VL53L0X_get_limit_check_enable( i,
elab 0:0e577ce96b2f 1642 &(p_device_parameters->LimitChecksEnable[i]));
elab 0:0e577ce96b2f 1643 } else {
elab 0:0e577ce96b2f 1644 break;
elab 0:0e577ce96b2f 1645 }
elab 0:0e577ce96b2f 1646 }
elab 0:0e577ce96b2f 1647 }
elab 0:0e577ce96b2f 1648
elab 0:0e577ce96b2f 1649 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1650 status = VL53L0X_get_wrap_around_check_enable(&(p_device_parameters->WrapAroundCheckEnable));
elab 0:0e577ce96b2f 1651 }
elab 0:0e577ce96b2f 1652
elab 0:0e577ce96b2f 1653 /* Need to be done at the end as it uses VCSELPulsePeriod */
elab 0:0e577ce96b2f 1654 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1655 status = VL53L0X_get_measurement_timing_budget_us(&(p_device_parameters->MeasurementTimingBudget_us));
elab 0:0e577ce96b2f 1656 }
elab 0:0e577ce96b2f 1657
elab 0:0e577ce96b2f 1658
elab 0:0e577ce96b2f 1659 return status;
elab 0:0e577ce96b2f 1660 }
elab 0:0e577ce96b2f 1661
elab 0:0e577ce96b2f 1662 VL53L0X_Error VL53L0X::VL53L0X_set_limit_check_value( uint16_t limit_check_id,
elab 0:0e577ce96b2f 1663 FixPoint1616_t limit_check_value)
elab 0:0e577ce96b2f 1664 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1665 uint8_t temp8;
elab 0:0e577ce96b2f 1666
elab 0:0e577ce96b2f 1667 temp8 = CurrentParameters.LimitChecksEnable[limit_check_id];
elab 0:0e577ce96b2f 1668
elab 0:0e577ce96b2f 1669 if (temp8 == 0) { /* disabled write only internal value */
elab 0:0e577ce96b2f 1670 CurrentParameters.LimitChecksValue[limit_check_id] = limit_check_value;
elab 0:0e577ce96b2f 1671 } else {
elab 0:0e577ce96b2f 1672
elab 0:0e577ce96b2f 1673 switch (limit_check_id) {
elab 0:0e577ce96b2f 1674
elab 0:0e577ce96b2f 1675 case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:/* internal computation: */
elab 0:0e577ce96b2f 1676 CurrentParameters.LimitChecksValue[VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE] = limit_check_value;
elab 0:0e577ce96b2f 1677 break;
elab 0:0e577ce96b2f 1678
elab 0:0e577ce96b2f 1679 case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
elab 0:0e577ce96b2f 1680 status = VL53L0X_write_word(VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT,
elab 0:0e577ce96b2f 1681 VL53L0X_FP1616TOFP97(limit_check_value));
elab 0:0e577ce96b2f 1682 break;
elab 0:0e577ce96b2f 1683
elab 0:0e577ce96b2f 1684 case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:/* internal computation: */
elab 0:0e577ce96b2f 1685 CurrentParameters.LimitChecksValue[VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP] = limit_check_value;
elab 0:0e577ce96b2f 1686 break;
elab 0:0e577ce96b2f 1687
elab 0:0e577ce96b2f 1688 case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:/* internal computation: */
elab 0:0e577ce96b2f 1689 CurrentParameters.LimitChecksValue[VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD] = limit_check_value;
elab 0:0e577ce96b2f 1690 break;
elab 0:0e577ce96b2f 1691
elab 0:0e577ce96b2f 1692 case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
elab 0:0e577ce96b2f 1693 case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
elab 0:0e577ce96b2f 1694 status = VL53L0X_write_word(VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT,
elab 0:0e577ce96b2f 1695 VL53L0X_FP1616TOFP97(limit_check_value));
elab 0:0e577ce96b2f 1696 break;
elab 0:0e577ce96b2f 1697
elab 0:0e577ce96b2f 1698 default:
elab 0:0e577ce96b2f 1699 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 1700 }
elab 0:0e577ce96b2f 1701
elab 0:0e577ce96b2f 1702 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1703 CurrentParameters.LimitChecksValue[limit_check_id] = limit_check_value;
elab 0:0e577ce96b2f 1704 }
elab 0:0e577ce96b2f 1705 }
elab 0:0e577ce96b2f 1706 return status;
elab 0:0e577ce96b2f 1707 }
elab 0:0e577ce96b2f 1708
elab 0:0e577ce96b2f 1709 // instead of passing VL53L0X_DeviceInfo_t *p_VL53L0X_device_info, directly fill Device_Info
elab 0:0e577ce96b2f 1710 VL53L0X_Error VL53L0X::VL53L0X_get_device_info()
elab 0:0e577ce96b2f 1711 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1712 uint8_t revision_id;
elab 0:0e577ce96b2f 1713 uint8_t revision;
elab 0:0e577ce96b2f 1714 char *product_id_tmp;
elab 0:0e577ce96b2f 1715
elab 0:0e577ce96b2f 1716 status = VL53L0X_get_info_from_device( 2);
elab 0:0e577ce96b2f 1717
elab 0:0e577ce96b2f 1718 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1719 if (Data.ModuleId == 0) {
elab 0:0e577ce96b2f 1720 revision = 0;
elab 0:0e577ce96b2f 1721 VL53L0X_COPYSTRING(Device_Info.ProductId, "");
elab 0:0e577ce96b2f 1722 } else {
elab 0:0e577ce96b2f 1723 revision = Data.Revision;
elab 0:0e577ce96b2f 1724 product_id_tmp = Data.ProductId;
elab 0:0e577ce96b2f 1725 VL53L0X_COPYSTRING(Device_Info.ProductId, product_id_tmp);
elab 0:0e577ce96b2f 1726 }
elab 0:0e577ce96b2f 1727 }
elab 0:0e577ce96b2f 1728
elab 0:0e577ce96b2f 1729 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1730 if (revision == 0) {
elab 0:0e577ce96b2f 1731 VL53L0X_COPYSTRING(Device_Info.Name,
elab 0:0e577ce96b2f 1732 VL53L0X_STRING_DEVICE_INFO_NAME_TS0);
elab 0:0e577ce96b2f 1733 } else if ((revision <= 34) && (revision != 32)) {
elab 0:0e577ce96b2f 1734 VL53L0X_COPYSTRING(Device_Info.Name,
elab 0:0e577ce96b2f 1735 VL53L0X_STRING_DEVICE_INFO_NAME_TS1);
elab 0:0e577ce96b2f 1736 } else if (revision < 39) {
elab 0:0e577ce96b2f 1737 VL53L0X_COPYSTRING(Device_Info.Name,
elab 0:0e577ce96b2f 1738 VL53L0X_STRING_DEVICE_INFO_NAME_TS2);
elab 0:0e577ce96b2f 1739 } else {VL53L0X_COPYSTRING(Device_Info.Name,
elab 0:0e577ce96b2f 1740 VL53L0X_STRING_DEVICE_INFO_NAME_ES1);
elab 0:0e577ce96b2f 1741 }
elab 0:0e577ce96b2f 1742
elab 0:0e577ce96b2f 1743 VL53L0X_COPYSTRING(Device_Info.Type, VL53L0X_STRING_DEVICE_INFO_TYPE);
elab 0:0e577ce96b2f 1744 }
elab 0:0e577ce96b2f 1745
elab 0:0e577ce96b2f 1746 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1747 status = VL53L0X_read_byte( VL53L0X_REG_IDENTIFICATION_MODEL_ID,
elab 0:0e577ce96b2f 1748 &Device_Info.ProductType);}
elab 0:0e577ce96b2f 1749
elab 0:0e577ce96b2f 1750 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1751 status = VL53L0X_read_byte(VL53L0X_REG_IDENTIFICATION_REVISION_ID,
elab 0:0e577ce96b2f 1752 &revision_id);
elab 0:0e577ce96b2f 1753 Device_Info.ProductRevisionMajor = 1;
elab 0:0e577ce96b2f 1754 Device_Info.ProductRevisionMinor =
elab 0:0e577ce96b2f 1755 (revision_id & 0xF0) >> 4;
elab 0:0e577ce96b2f 1756 }
elab 0:0e577ce96b2f 1757 return status;
elab 0:0e577ce96b2f 1758 }
elab 0:0e577ce96b2f 1759
elab 0:0e577ce96b2f 1760 VL53L0X_Error VL53L0X::VL53L0X_get_interrupt_mask_status(uint32_t *p_interrupt_mask_status)
elab 0:0e577ce96b2f 1761 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1762 uint8_t byte;
elab 0:0e577ce96b2f 1763
elab 0:0e577ce96b2f 1764 status = VL53L0X_read_byte( VL53L0X_REG_RESULT_INTERRUPT_STATUS, &byte);
elab 0:0e577ce96b2f 1765 *p_interrupt_mask_status = byte & 0x07;
elab 0:0e577ce96b2f 1766
elab 0:0e577ce96b2f 1767 if (byte & 0x18) { status = VL53L0X_ERROR_RANGE_ERROR;}
elab 0:0e577ce96b2f 1768
elab 0:0e577ce96b2f 1769 return status;
elab 0:0e577ce96b2f 1770 }
elab 0:0e577ce96b2f 1771
elab 0:0e577ce96b2f 1772 VL53L0X_Error VL53L0X::VL53L0X_get_measurement_data_ready(uint8_t *p_measurement_data_ready)
elab 0:0e577ce96b2f 1773 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1774 uint8_t sys_range_status_register;
elab 0:0e577ce96b2f 1775 uint8_t interrupt_config;
elab 0:0e577ce96b2f 1776 uint32_t interrupt_mask;
elab 0:0e577ce96b2f 1777
elab 0:0e577ce96b2f 1778 interrupt_config = Data.Pin0GpioFunctionality;
elab 0:0e577ce96b2f 1779
elab 0:0e577ce96b2f 1780 if (interrupt_config ==
elab 0:0e577ce96b2f 1781 VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) {
elab 0:0e577ce96b2f 1782 status = VL53L0X_get_interrupt_mask_status( &interrupt_mask);
elab 0:0e577ce96b2f 1783 if (interrupt_mask ==
elab 0:0e577ce96b2f 1784 VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) {
elab 0:0e577ce96b2f 1785 *p_measurement_data_ready = 1;
elab 0:0e577ce96b2f 1786 } else {
elab 0:0e577ce96b2f 1787 *p_measurement_data_ready = 0;
elab 0:0e577ce96b2f 1788 }
elab 0:0e577ce96b2f 1789 } else {
elab 0:0e577ce96b2f 1790 status = VL53L0X_read_byte( VL53L0X_REG_RESULT_RANGE_STATUS,
elab 0:0e577ce96b2f 1791 &sys_range_status_register);
elab 0:0e577ce96b2f 1792 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1793 if (sys_range_status_register & 0x01) {
elab 0:0e577ce96b2f 1794 *p_measurement_data_ready = 1;
elab 0:0e577ce96b2f 1795 } else { *p_measurement_data_ready = 0; }
elab 0:0e577ce96b2f 1796 }
elab 0:0e577ce96b2f 1797 }
elab 0:0e577ce96b2f 1798
elab 0:0e577ce96b2f 1799 return status;
elab 0:0e577ce96b2f 1800 }
elab 0:0e577ce96b2f 1801
elab 0:0e577ce96b2f 1802 VL53L0X_Error VL53L0X::VL53L0X_polling_delay(void)
elab 0:0e577ce96b2f 1803 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1804
elab 0:0e577ce96b2f 1805 // do nothing
elab 0:0e577ce96b2f 1806 VL53L0X_OsDelay();
elab 0:0e577ce96b2f 1807 return status;
elab 0:0e577ce96b2f 1808 }
elab 0:0e577ce96b2f 1809
elab 0:0e577ce96b2f 1810 VL53L0X_Error VL53L0X::VL53L0X_measurement_poll_for_completion(void)
elab 0:0e577ce96b2f 1811 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1812 uint8_t new_data_ready = 0;
elab 0:0e577ce96b2f 1813 uint32_t loop_nb;
elab 0:0e577ce96b2f 1814
elab 0:0e577ce96b2f 1815 loop_nb = 0;
elab 0:0e577ce96b2f 1816
elab 0:0e577ce96b2f 1817 do {
elab 0:0e577ce96b2f 1818 status = VL53L0X_get_measurement_data_ready( &new_data_ready);
elab 0:0e577ce96b2f 1819 if (status != 0) {
elab 0:0e577ce96b2f 1820 break; /* the error is set */
elab 0:0e577ce96b2f 1821 }
elab 0:0e577ce96b2f 1822
elab 0:0e577ce96b2f 1823 if (new_data_ready == 1) {
elab 0:0e577ce96b2f 1824 break; /* done note that status == 0 */
elab 0:0e577ce96b2f 1825 }
elab 0:0e577ce96b2f 1826
elab 0:0e577ce96b2f 1827 loop_nb++;
elab 0:0e577ce96b2f 1828 if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
elab 0:0e577ce96b2f 1829 status = VL53L0X_ERROR_TIME_OUT;
elab 0:0e577ce96b2f 1830 break;
elab 0:0e577ce96b2f 1831 }
elab 0:0e577ce96b2f 1832
elab 0:0e577ce96b2f 1833 VL53L0X_polling_delay();
elab 0:0e577ce96b2f 1834 } while (1);
elab 0:0e577ce96b2f 1835
elab 0:0e577ce96b2f 1836 return status;
elab 0:0e577ce96b2f 1837 }
elab 0:0e577ce96b2f 1838
elab 0:0e577ce96b2f 1839 /* Group PAL Interrupt Functions */
elab 0:0e577ce96b2f 1840 VL53L0X_Error VL53L0X::VL53L0X_clear_interrupt_mask( uint32_t interrupt_mask)
elab 0:0e577ce96b2f 1841 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1842 uint8_t loop_count;
elab 0:0e577ce96b2f 1843 uint8_t byte;
elab 0:0e577ce96b2f 1844
elab 0:0e577ce96b2f 1845 /* clear bit 0 range interrupt, bit 1 error interrupt */
elab 0:0e577ce96b2f 1846 loop_count = 0;
elab 0:0e577ce96b2f 1847 do {
elab 0:0e577ce96b2f 1848 status = VL53L0X_write_byte(VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x01);
elab 0:0e577ce96b2f 1849 status |= VL53L0X_write_byte(VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x00);
elab 0:0e577ce96b2f 1850 status |= VL53L0X_read_byte(VL53L0X_REG_RESULT_INTERRUPT_STATUS, &byte);
elab 0:0e577ce96b2f 1851 loop_count++;
elab 0:0e577ce96b2f 1852 } while (((byte & 0x07) != 0x00)
elab 0:0e577ce96b2f 1853 && (loop_count < 3)
elab 0:0e577ce96b2f 1854 && (status == VL53L0X_ERROR_NONE));
elab 0:0e577ce96b2f 1855
elab 0:0e577ce96b2f 1856 if (loop_count >= 3) {
elab 0:0e577ce96b2f 1857 status = VL53L0X_ERROR_INTERRUPT_NOT_CLEARED;
elab 0:0e577ce96b2f 1858 }
elab 0:0e577ce96b2f 1859
elab 0:0e577ce96b2f 1860
elab 0:0e577ce96b2f 1861 return status;
elab 0:0e577ce96b2f 1862 }
elab 0:0e577ce96b2f 1863
elab 0:0e577ce96b2f 1864 VL53L0X_Error VL53L0X::VL53L0X_perform_single_ref_calibration(uint8_t vhv_init_byte)
elab 0:0e577ce96b2f 1865 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1866
elab 0:0e577ce96b2f 1867 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1868 status = VL53L0X_write_byte( VL53L0X_REG_SYSRANGE_START,
elab 0:0e577ce96b2f 1869 VL53L0X_REG_SYSRANGE_MODE_START_STOP |
elab 0:0e577ce96b2f 1870 vhv_init_byte);
elab 0:0e577ce96b2f 1871 }
elab 0:0e577ce96b2f 1872
elab 0:0e577ce96b2f 1873 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1874 status = VL53L0X_measurement_poll_for_completion();}
elab 0:0e577ce96b2f 1875
elab 0:0e577ce96b2f 1876 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1877 status = VL53L0X_clear_interrupt_mask( 0);}
elab 0:0e577ce96b2f 1878
elab 0:0e577ce96b2f 1879 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1880 status = VL53L0X_write_byte( VL53L0X_REG_SYSRANGE_START, 0x00);
elab 0:0e577ce96b2f 1881 }
elab 0:0e577ce96b2f 1882
elab 0:0e577ce96b2f 1883 return status;
elab 0:0e577ce96b2f 1884 }
elab 0:0e577ce96b2f 1885
elab 0:0e577ce96b2f 1886 VL53L0X_Error VL53L0X::VL53L0X_ref_calibration_io( uint8_t read_not_write,
elab 0:0e577ce96b2f 1887 uint8_t vhv_settings, uint8_t phase_cal,
elab 0:0e577ce96b2f 1888 uint8_t *p_vhv_settings, uint8_t *p_phase_cal,
elab 0:0e577ce96b2f 1889 const uint8_t vhv_enable, const uint8_t phase_enable)
elab 0:0e577ce96b2f 1890 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1891 uint8_t phase_calint = 0;
elab 0:0e577ce96b2f 1892
elab 0:0e577ce96b2f 1893 /* Read VHV from device */
elab 0:0e577ce96b2f 1894 status |= VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 1895 status |= VL53L0X_write_byte( 0x00, 0x00);
elab 0:0e577ce96b2f 1896 status |= VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 1897
elab 0:0e577ce96b2f 1898 if (read_not_write) {
elab 0:0e577ce96b2f 1899 if (vhv_enable) {
elab 0:0e577ce96b2f 1900 status |= VL53L0X_read_byte( 0xCB, p_vhv_settings);}
elab 0:0e577ce96b2f 1901 if (phase_enable) {
elab 0:0e577ce96b2f 1902 status |= VL53L0X_read_byte( 0xEE, &phase_calint);}
elab 0:0e577ce96b2f 1903 } else {
elab 0:0e577ce96b2f 1904 if (vhv_enable) {
elab 0:0e577ce96b2f 1905 status |= VL53L0X_write_byte( 0xCB, vhv_settings);}
elab 0:0e577ce96b2f 1906 if (phase_enable) {
elab 0:0e577ce96b2f 1907 status |= VL53L0X_update_byte( 0xEE, 0x80, phase_cal);}
elab 0:0e577ce96b2f 1908 }
elab 0:0e577ce96b2f 1909
elab 0:0e577ce96b2f 1910 status |= VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 1911 status |= VL53L0X_write_byte( 0x00, 0x01);
elab 0:0e577ce96b2f 1912 status |= VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 1913
elab 0:0e577ce96b2f 1914 *p_phase_cal = (uint8_t)(phase_calint & 0xEF);
elab 0:0e577ce96b2f 1915
elab 0:0e577ce96b2f 1916 return status;
elab 0:0e577ce96b2f 1917 }
elab 0:0e577ce96b2f 1918
elab 0:0e577ce96b2f 1919 VL53L0X_Error VL53L0X::VL53L0X_perform_vhv_calibration(uint8_t *p_vhv_settings, const uint8_t get_data_enable,
elab 0:0e577ce96b2f 1920 const uint8_t restore_config)
elab 0:0e577ce96b2f 1921 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1922 uint8_t sequence_config = 0;
elab 0:0e577ce96b2f 1923 uint8_t vhv_settings = 0;
elab 0:0e577ce96b2f 1924 uint8_t phase_cal = 0;
elab 0:0e577ce96b2f 1925 uint8_t phase_cal_int = 0;
elab 0:0e577ce96b2f 1926
elab 0:0e577ce96b2f 1927 /* store the value of the sequence config,
elab 0:0e577ce96b2f 1928 * this will be reset before the end of the function
elab 0:0e577ce96b2f 1929 */
elab 0:0e577ce96b2f 1930
elab 0:0e577ce96b2f 1931 if (restore_config) {
elab 0:0e577ce96b2f 1932 sequence_config = Data.SequenceConfig;
elab 0:0e577ce96b2f 1933 }
elab 0:0e577ce96b2f 1934
elab 0:0e577ce96b2f 1935 /* Run VHV */
elab 0:0e577ce96b2f 1936 status = VL53L0X_write_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0x01);
elab 0:0e577ce96b2f 1937
elab 0:0e577ce96b2f 1938 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1939 status = VL53L0X_perform_single_ref_calibration( 0x40);}
elab 0:0e577ce96b2f 1940
elab 0:0e577ce96b2f 1941 /* Read VHV from device */
elab 0:0e577ce96b2f 1942 if ((status == VL53L0X_ERROR_NONE) && (get_data_enable == 1)) {
elab 0:0e577ce96b2f 1943 status = VL53L0X_ref_calibration_io( 1, vhv_settings, phase_cal, /* Not used here */
elab 0:0e577ce96b2f 1944 p_vhv_settings, &phase_cal_int, 1, 0);
elab 0:0e577ce96b2f 1945 } else {*p_vhv_settings = 0; }
elab 0:0e577ce96b2f 1946
elab 0:0e577ce96b2f 1947 if ((status == VL53L0X_ERROR_NONE) && restore_config) {
elab 0:0e577ce96b2f 1948 /* restore the previous Sequence Config */
elab 0:0e577ce96b2f 1949 status = VL53L0X_write_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
elab 0:0e577ce96b2f 1950 sequence_config);
elab 0:0e577ce96b2f 1951 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1952 Data.SequenceConfig = sequence_config; }
elab 0:0e577ce96b2f 1953 }
elab 0:0e577ce96b2f 1954
elab 0:0e577ce96b2f 1955 return status;
elab 0:0e577ce96b2f 1956 }
elab 0:0e577ce96b2f 1957
elab 0:0e577ce96b2f 1958 VL53L0X_Error VL53L0X::VL53L0X_perform_phase_calibration(uint8_t *p_phase_cal, const uint8_t get_data_enable,
elab 0:0e577ce96b2f 1959 const uint8_t restore_config)
elab 0:0e577ce96b2f 1960 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 1961 uint8_t sequence_config = 0;
elab 0:0e577ce96b2f 1962 uint8_t vhv_settings = 0;
elab 0:0e577ce96b2f 1963 uint8_t phase_cal = 0;
elab 0:0e577ce96b2f 1964 uint8_t vhv_settingsint;
elab 0:0e577ce96b2f 1965
elab 0:0e577ce96b2f 1966 /* store the value of the sequence config,
elab 0:0e577ce96b2f 1967 * this will be reset before the end of the function */
elab 0:0e577ce96b2f 1968
elab 0:0e577ce96b2f 1969 if (restore_config) {
elab 0:0e577ce96b2f 1970 sequence_config = Data.SequenceConfig;
elab 0:0e577ce96b2f 1971 }
elab 0:0e577ce96b2f 1972
elab 0:0e577ce96b2f 1973 /* Run PhaseCal */
elab 0:0e577ce96b2f 1974 status = VL53L0X_write_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0x02);
elab 0:0e577ce96b2f 1975
elab 0:0e577ce96b2f 1976 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1977 status = VL53L0X_perform_single_ref_calibration( 0x0);
elab 0:0e577ce96b2f 1978 }
elab 0:0e577ce96b2f 1979
elab 0:0e577ce96b2f 1980 /* Read PhaseCal from device */
elab 0:0e577ce96b2f 1981 if ((status == VL53L0X_ERROR_NONE) && (get_data_enable == 1)) {
elab 0:0e577ce96b2f 1982 status = VL53L0X_ref_calibration_io( 1,
elab 0:0e577ce96b2f 1983 vhv_settings, phase_cal, /* Not used here */
elab 0:0e577ce96b2f 1984 &vhv_settingsint, p_phase_cal,
elab 0:0e577ce96b2f 1985 0, 1);
elab 0:0e577ce96b2f 1986 } else {
elab 0:0e577ce96b2f 1987 *p_phase_cal = 0;
elab 0:0e577ce96b2f 1988 }
elab 0:0e577ce96b2f 1989
elab 0:0e577ce96b2f 1990 if ((status == VL53L0X_ERROR_NONE) && restore_config) {
elab 0:0e577ce96b2f 1991 /* restore the previous Sequence Config */
elab 0:0e577ce96b2f 1992 status = VL53L0X_write_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
elab 0:0e577ce96b2f 1993 sequence_config);
elab 0:0e577ce96b2f 1994 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 1995 Data.SequenceConfig = sequence_config;
elab 0:0e577ce96b2f 1996 }
elab 0:0e577ce96b2f 1997
elab 0:0e577ce96b2f 1998 }
elab 0:0e577ce96b2f 1999
elab 0:0e577ce96b2f 2000 return status;
elab 0:0e577ce96b2f 2001 }
elab 0:0e577ce96b2f 2002
elab 0:0e577ce96b2f 2003 VL53L0X_Error VL53L0X::VL53L0X_perform_ref_calibration(uint8_t *p_vhv_settings, uint8_t *p_phase_cal, uint8_t get_data_enable)
elab 0:0e577ce96b2f 2004 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2005 uint8_t sequence_config = 0;
elab 0:0e577ce96b2f 2006
elab 0:0e577ce96b2f 2007 /* store the value of the sequence config,
elab 0:0e577ce96b2f 2008 * this will be reset before the end of the function */
elab 0:0e577ce96b2f 2009
elab 0:0e577ce96b2f 2010 sequence_config = Data.SequenceConfig;
elab 0:0e577ce96b2f 2011
elab 0:0e577ce96b2f 2012 /* In the following function we don't save the config to optimize
elab 0:0e577ce96b2f 2013 * writes on device. Config is saved and restored only once. */
elab 0:0e577ce96b2f 2014 status = VL53L0X_perform_vhv_calibration(p_vhv_settings, get_data_enable, 0);
elab 0:0e577ce96b2f 2015
elab 0:0e577ce96b2f 2016 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2017 status = VL53L0X_perform_phase_calibration(p_phase_cal, get_data_enable, 0); }
elab 0:0e577ce96b2f 2018
elab 0:0e577ce96b2f 2019 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2020 /* restore the previous Sequence Config */
elab 0:0e577ce96b2f 2021 status = VL53L0X_write_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
elab 0:0e577ce96b2f 2022 sequence_config);
elab 0:0e577ce96b2f 2023 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2024 Data.SequenceConfig = sequence_config; }
elab 0:0e577ce96b2f 2025 }
elab 0:0e577ce96b2f 2026
elab 0:0e577ce96b2f 2027 return status;
elab 0:0e577ce96b2f 2028 }
elab 0:0e577ce96b2f 2029
elab 0:0e577ce96b2f 2030 void VL53L0X::get_next_good_spad(uint8_t good_spad_array[], uint32_t size,
elab 0:0e577ce96b2f 2031 uint32_t curr, int32_t *p_next)
elab 0:0e577ce96b2f 2032 { uint32_t start_index;
elab 0:0e577ce96b2f 2033 uint32_t fine_offset;
elab 0:0e577ce96b2f 2034 uint32_t c_spads_per_byte = 8;
elab 0:0e577ce96b2f 2035 uint32_t coarse_index;
elab 0:0e577ce96b2f 2036 uint32_t fine_index;
elab 0:0e577ce96b2f 2037 uint8_t data_byte;
elab 0:0e577ce96b2f 2038 uint8_t success = 0;
elab 0:0e577ce96b2f 2039
elab 0:0e577ce96b2f 2040 /* Starting with the current good spad, loop through the array to find
elab 0:0e577ce96b2f 2041 * the next. i.e. the next bit set in the sequence.
elab 0:0e577ce96b2f 2042 *
elab 0:0e577ce96b2f 2043 * The coarse index is the byte index of the array and the fine index is
elab 0:0e577ce96b2f 2044 * the index of the bit within each byte. */
elab 0:0e577ce96b2f 2045
elab 0:0e577ce96b2f 2046 *p_next = -1;
elab 0:0e577ce96b2f 2047
elab 0:0e577ce96b2f 2048 start_index = curr / c_spads_per_byte;
elab 0:0e577ce96b2f 2049 fine_offset = curr % c_spads_per_byte;
elab 0:0e577ce96b2f 2050
elab 0:0e577ce96b2f 2051 for (coarse_index = start_index; ((coarse_index < size) && !success);
elab 0:0e577ce96b2f 2052 coarse_index++) {
elab 0:0e577ce96b2f 2053 fine_index = 0;
elab 0:0e577ce96b2f 2054 data_byte = good_spad_array[coarse_index];
elab 0:0e577ce96b2f 2055
elab 0:0e577ce96b2f 2056 if (coarse_index == start_index) {
elab 0:0e577ce96b2f 2057 /* locate the bit position of the provided current
elab 0:0e577ce96b2f 2058 * spad bit before iterating */
elab 0:0e577ce96b2f 2059 data_byte >>= fine_offset;
elab 0:0e577ce96b2f 2060 fine_index = fine_offset;
elab 0:0e577ce96b2f 2061 }
elab 0:0e577ce96b2f 2062
elab 0:0e577ce96b2f 2063 while (fine_index < c_spads_per_byte) {
elab 0:0e577ce96b2f 2064 if ((data_byte & 0x1) == 1) {
elab 0:0e577ce96b2f 2065 success = 1;
elab 0:0e577ce96b2f 2066 *p_next = coarse_index * c_spads_per_byte + fine_index;
elab 0:0e577ce96b2f 2067 break;
elab 0:0e577ce96b2f 2068 }
elab 0:0e577ce96b2f 2069 data_byte >>= 1;
elab 0:0e577ce96b2f 2070 fine_index++;
elab 0:0e577ce96b2f 2071 }
elab 0:0e577ce96b2f 2072 }
elab 0:0e577ce96b2f 2073 }
elab 0:0e577ce96b2f 2074
elab 0:0e577ce96b2f 2075 uint8_t VL53L0X::is_aperture(uint32_t spad_index)
elab 0:0e577ce96b2f 2076 { /* This function reports if a given spad index is an aperture SPAD by
elab 0:0e577ce96b2f 2077 * deriving the quadrant.*/
elab 0:0e577ce96b2f 2078 uint32_t quadrant;
elab 0:0e577ce96b2f 2079 uint8_t is_aperture = 1;
elab 0:0e577ce96b2f 2080 quadrant = spad_index >> 6;
elab 0:0e577ce96b2f 2081 if (refArrayQuadrants[quadrant] == REF_ARRAY_SPAD_0) {
elab 0:0e577ce96b2f 2082 is_aperture = 0;
elab 0:0e577ce96b2f 2083 }
elab 0:0e577ce96b2f 2084
elab 0:0e577ce96b2f 2085 return is_aperture;
elab 0:0e577ce96b2f 2086 }
elab 0:0e577ce96b2f 2087
elab 0:0e577ce96b2f 2088 VL53L0X_Error VL53L0X::enable_spad_bit(uint8_t spad_array[], uint32_t size,
elab 0:0e577ce96b2f 2089 uint32_t spad_index)
elab 0:0e577ce96b2f 2090 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2091 uint32_t c_spads_per_byte = 8;
elab 0:0e577ce96b2f 2092 uint32_t coarse_index;
elab 0:0e577ce96b2f 2093 uint32_t fine_index;
elab 0:0e577ce96b2f 2094
elab 0:0e577ce96b2f 2095 coarse_index = spad_index / c_spads_per_byte;
elab 0:0e577ce96b2f 2096 fine_index = spad_index % c_spads_per_byte;
elab 0:0e577ce96b2f 2097 if (coarse_index >= size) {
elab 0:0e577ce96b2f 2098 status = VL53L0X_ERROR_REF_SPAD_INIT;
elab 0:0e577ce96b2f 2099 } else {
elab 0:0e577ce96b2f 2100 spad_array[coarse_index] |= (1 << fine_index);
elab 0:0e577ce96b2f 2101 }
elab 0:0e577ce96b2f 2102
elab 0:0e577ce96b2f 2103 return status;
elab 0:0e577ce96b2f 2104 }
elab 0:0e577ce96b2f 2105
elab 0:0e577ce96b2f 2106 VL53L0X_Error VL53L0X::set_ref_spad_map( uint8_t *p_ref_spad_array)
elab 0:0e577ce96b2f 2107 { VL53L0X_Error status = VL53L0X_i2c_write(VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0,
elab 0:0e577ce96b2f 2108 p_ref_spad_array, 6);
elab 0:0e577ce96b2f 2109
elab 0:0e577ce96b2f 2110 return status;
elab 0:0e577ce96b2f 2111 }
elab 0:0e577ce96b2f 2112
elab 0:0e577ce96b2f 2113 VL53L0X_Error VL53L0X::get_ref_spad_map( uint8_t *p_ref_spad_array)
elab 0:0e577ce96b2f 2114 { VL53L0X_Error status = VL53L0X_read_multi(VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0,
elab 0:0e577ce96b2f 2115 p_ref_spad_array,
elab 0:0e577ce96b2f 2116 6);
elab 0:0e577ce96b2f 2117 // VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2118 // uint8_t count=0;
elab 0:0e577ce96b2f 2119
elab 0:0e577ce96b2f 2120 // for (count = 0; count < 6; count++)
elab 0:0e577ce96b2f 2121 // status = VL53L0X_RdByte( (VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0 + count), &refSpadArray[count]);
elab 0:0e577ce96b2f 2122 return status;
elab 0:0e577ce96b2f 2123 }
elab 0:0e577ce96b2f 2124
elab 0:0e577ce96b2f 2125 VL53L0X_Error VL53L0X::enable_ref_spads(uint8_t aperture_spads,
elab 0:0e577ce96b2f 2126 uint8_t good_spad_array[],
elab 0:0e577ce96b2f 2127 uint8_t spad_array[],
elab 0:0e577ce96b2f 2128 uint32_t size,
elab 0:0e577ce96b2f 2129 uint32_t start,
elab 0:0e577ce96b2f 2130 uint32_t offset,
elab 0:0e577ce96b2f 2131 uint32_t spad_count,
elab 0:0e577ce96b2f 2132 uint32_t *p_last_spad)
elab 0:0e577ce96b2f 2133 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2134 uint32_t index;
elab 0:0e577ce96b2f 2135 uint32_t i;
elab 0:0e577ce96b2f 2136 int32_t next_good_spad = offset;
elab 0:0e577ce96b2f 2137 uint32_t current_spad;
elab 0:0e577ce96b2f 2138 uint8_t check_spad_array[6];
elab 0:0e577ce96b2f 2139
elab 0:0e577ce96b2f 2140 /*
elab 0:0e577ce96b2f 2141 * This function takes in a spad array which may or may not have SPADS
elab 0:0e577ce96b2f 2142 * already enabled and appends from a given offset a requested number
elab 0:0e577ce96b2f 2143 * of new SPAD enables. The 'good spad map' is applied to
elab 0:0e577ce96b2f 2144 * determine the next SPADs to enable.
elab 0:0e577ce96b2f 2145 *
elab 0:0e577ce96b2f 2146 * This function applies to only aperture or only non-aperture spads.
elab 0:0e577ce96b2f 2147 * Checks are performed to ensure this.
elab 0:0e577ce96b2f 2148 */
elab 0:0e577ce96b2f 2149
elab 0:0e577ce96b2f 2150 current_spad = offset;
elab 0:0e577ce96b2f 2151 for (index = 0; index < spad_count; index++) {
elab 0:0e577ce96b2f 2152 get_next_good_spad(good_spad_array, size, current_spad,
elab 0:0e577ce96b2f 2153 &next_good_spad);
elab 0:0e577ce96b2f 2154
elab 0:0e577ce96b2f 2155 if (next_good_spad == -1) {
elab 0:0e577ce96b2f 2156 status = VL53L0X_ERROR_REF_SPAD_INIT;
elab 0:0e577ce96b2f 2157 break;
elab 0:0e577ce96b2f 2158 }
elab 0:0e577ce96b2f 2159
elab 0:0e577ce96b2f 2160 /* Confirm that the next good SPAD is non-aperture */
elab 0:0e577ce96b2f 2161 if (is_aperture(start + next_good_spad) != aperture_spads) {
elab 0:0e577ce96b2f 2162 /* if we can't get the required number of good aperture
elab 0:0e577ce96b2f 2163 * spads from the current quadrant then this is an error
elab 0:0e577ce96b2f 2164 */
elab 0:0e577ce96b2f 2165 status = VL53L0X_ERROR_REF_SPAD_INIT;
elab 0:0e577ce96b2f 2166 break;
elab 0:0e577ce96b2f 2167 }
elab 0:0e577ce96b2f 2168 current_spad = (uint32_t)next_good_spad;
elab 0:0e577ce96b2f 2169 enable_spad_bit(spad_array, size, current_spad);
elab 0:0e577ce96b2f 2170 current_spad++;
elab 0:0e577ce96b2f 2171 }
elab 0:0e577ce96b2f 2172 *p_last_spad = current_spad;
elab 0:0e577ce96b2f 2173
elab 0:0e577ce96b2f 2174 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2175 status = set_ref_spad_map( spad_array);
elab 0:0e577ce96b2f 2176 }
elab 0:0e577ce96b2f 2177
elab 0:0e577ce96b2f 2178 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2179 status = get_ref_spad_map( check_spad_array);
elab 0:0e577ce96b2f 2180
elab 0:0e577ce96b2f 2181 i = 0;
elab 0:0e577ce96b2f 2182
elab 0:0e577ce96b2f 2183 /* Compare spad maps. If not equal report error. */
elab 0:0e577ce96b2f 2184 while (i < size) {
elab 0:0e577ce96b2f 2185 if (spad_array[i] != check_spad_array[i]) {
elab 0:0e577ce96b2f 2186 status = VL53L0X_ERROR_REF_SPAD_INIT;
elab 0:0e577ce96b2f 2187 break;
elab 0:0e577ce96b2f 2188 }
elab 0:0e577ce96b2f 2189 i++;
elab 0:0e577ce96b2f 2190 }
elab 0:0e577ce96b2f 2191 }
elab 0:0e577ce96b2f 2192 return status;
elab 0:0e577ce96b2f 2193 }
elab 0:0e577ce96b2f 2194
elab 0:0e577ce96b2f 2195 VL53L0X_Error VL53L0X::VL53L0X_set_device_mode( VL53L0X_DeviceModes device_mode)
elab 0:0e577ce96b2f 2196 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2197
elab 0:0e577ce96b2f 2198 switch (device_mode) {
elab 0:0e577ce96b2f 2199 case VL53L0X_DEVICEMODE_SINGLE_RANGING:
elab 0:0e577ce96b2f 2200 case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING:
elab 0:0e577ce96b2f 2201 case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING:
elab 0:0e577ce96b2f 2202 case VL53L0X_DEVICEMODE_GPIO_DRIVE:
elab 0:0e577ce96b2f 2203 case VL53L0X_DEVICEMODE_GPIO_OSC:
elab 0:0e577ce96b2f 2204 /* Supported modes */
elab 0:0e577ce96b2f 2205 CurrentParameters.DeviceMode = device_mode;
elab 0:0e577ce96b2f 2206 break;
elab 0:0e577ce96b2f 2207 default:
elab 0:0e577ce96b2f 2208 /* Unsupported mode */
elab 0:0e577ce96b2f 2209 status = VL53L0X_ERROR_MODE_NOT_SUPPORTED;
elab 0:0e577ce96b2f 2210 }
elab 0:0e577ce96b2f 2211
elab 0:0e577ce96b2f 2212
elab 0:0e577ce96b2f 2213 return status;
elab 0:0e577ce96b2f 2214 }
elab 0:0e577ce96b2f 2215
elab 0:0e577ce96b2f 2216 VL53L0X_Error VL53L0X::VL53L0X_set_interrupt_thresholds(VL53L0X_DeviceModes device_mode, FixPoint1616_t threshold_low,
elab 0:0e577ce96b2f 2217 FixPoint1616_t threshold_high)
elab 0:0e577ce96b2f 2218 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2219 uint16_t threshold16;
elab 0:0e577ce96b2f 2220
elab 0:0e577ce96b2f 2221
elab 0:0e577ce96b2f 2222 /* no dependency on DeviceMode for Ewok */
elab 0:0e577ce96b2f 2223 /* Need to divide by 2 because the FW will apply a x2 */
elab 0:0e577ce96b2f 2224 threshold16 = (uint16_t)((threshold_low >> 17) & 0x00fff);
elab 0:0e577ce96b2f 2225 status = VL53L0X_write_word( VL53L0X_REG_SYSTEM_THRESH_LOW, threshold16);
elab 0:0e577ce96b2f 2226
elab 0:0e577ce96b2f 2227 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2228 /* Need to divide by 2 because the FW will apply a x2 */
elab 0:0e577ce96b2f 2229 threshold16 = (uint16_t)((threshold_high >> 17) & 0x00fff);
elab 0:0e577ce96b2f 2230 status = VL53L0X_write_word( VL53L0X_REG_SYSTEM_THRESH_HIGH,
elab 0:0e577ce96b2f 2231 threshold16);
elab 0:0e577ce96b2f 2232 }
elab 0:0e577ce96b2f 2233
elab 0:0e577ce96b2f 2234
elab 0:0e577ce96b2f 2235 return status;
elab 0:0e577ce96b2f 2236 }
elab 0:0e577ce96b2f 2237
elab 0:0e577ce96b2f 2238 VL53L0X_Error VL53L0X::VL53L0X_get_interrupt_thresholds(VL53L0X_DeviceModes device_mode, FixPoint1616_t *p_threshold_low,
elab 0:0e577ce96b2f 2239 FixPoint1616_t *p_threshold_high)
elab 0:0e577ce96b2f 2240 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2241 uint16_t threshold16;
elab 0:0e577ce96b2f 2242
elab 0:0e577ce96b2f 2243
elab 0:0e577ce96b2f 2244 /* no dependency on DeviceMode for Ewok */
elab 0:0e577ce96b2f 2245
elab 0:0e577ce96b2f 2246 status = VL53L0X_read_word( VL53L0X_REG_SYSTEM_THRESH_LOW, &threshold16);
elab 0:0e577ce96b2f 2247 /* Need to multiply by 2 because the FW will apply a x2 */
elab 0:0e577ce96b2f 2248 *p_threshold_low = (FixPoint1616_t)((0x00fff & threshold16) << 17);
elab 0:0e577ce96b2f 2249
elab 0:0e577ce96b2f 2250 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2251 status = VL53L0X_read_word( VL53L0X_REG_SYSTEM_THRESH_HIGH,
elab 0:0e577ce96b2f 2252 &threshold16);
elab 0:0e577ce96b2f 2253 /* Need to multiply by 2 because the FW will apply a x2 */
elab 0:0e577ce96b2f 2254 *p_threshold_high =
elab 0:0e577ce96b2f 2255 (FixPoint1616_t)((0x00fff & threshold16) << 17);
elab 0:0e577ce96b2f 2256 }
elab 0:0e577ce96b2f 2257
elab 0:0e577ce96b2f 2258
elab 0:0e577ce96b2f 2259 return status;
elab 0:0e577ce96b2f 2260 }
elab 0:0e577ce96b2f 2261
elab 0:0e577ce96b2f 2262 VL53L0X_Error VL53L0X::VL53L0X_load_tuning_settings(uint8_t *p_tuning_setting_buffer)
elab 0:0e577ce96b2f 2263 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2264 int i;
elab 0:0e577ce96b2f 2265 int index;
elab 0:0e577ce96b2f 2266 uint8_t msb;
elab 0:0e577ce96b2f 2267 uint8_t lsb;
elab 0:0e577ce96b2f 2268 uint8_t select_param;
elab 0:0e577ce96b2f 2269 uint16_t number_of_writes;
elab 0:0e577ce96b2f 2270 uint8_t address;
elab 0:0e577ce96b2f 2271 uint8_t local_buffer[4]; /* max */
elab 0:0e577ce96b2f 2272 uint16_t temp16;
elab 0:0e577ce96b2f 2273
elab 0:0e577ce96b2f 2274 index = 0;
elab 0:0e577ce96b2f 2275
elab 0:0e577ce96b2f 2276 while ((*(p_tuning_setting_buffer + index) != 0) &&
elab 0:0e577ce96b2f 2277 (status == VL53L0X_ERROR_NONE)) {
elab 0:0e577ce96b2f 2278 number_of_writes = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2279 index++;
elab 0:0e577ce96b2f 2280 if (number_of_writes == 0xFF) {
elab 0:0e577ce96b2f 2281 /* internal parameters */
elab 0:0e577ce96b2f 2282 select_param = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2283 index++;
elab 0:0e577ce96b2f 2284 switch (select_param) {
elab 0:0e577ce96b2f 2285 case 0: /* uint16_t SigmaEstRefArray -> 2 bytes */
elab 0:0e577ce96b2f 2286 msb = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2287 index++;
elab 0:0e577ce96b2f 2288 lsb = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2289 index++;
elab 0:0e577ce96b2f 2290 temp16 = VL53L0X_MAKEUINT16(lsb, msb);
elab 0:0e577ce96b2f 2291 Data.SigmaEstRefArray = temp16;
elab 0:0e577ce96b2f 2292 break;
elab 0:0e577ce96b2f 2293 case 1: /* uint16_t SigmaEstEffPulseWidth -> 2 bytes */
elab 0:0e577ce96b2f 2294 msb = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2295 index++;
elab 0:0e577ce96b2f 2296 lsb = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2297 index++;
elab 0:0e577ce96b2f 2298 temp16 = VL53L0X_MAKEUINT16(lsb, msb);
elab 0:0e577ce96b2f 2299 Data.SigmaEstEffPulseWidth = temp16;
elab 0:0e577ce96b2f 2300 break;
elab 0:0e577ce96b2f 2301 case 2: /* uint16_t SigmaEstEffAmbWidth -> 2 bytes */
elab 0:0e577ce96b2f 2302 msb = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2303 index++;
elab 0:0e577ce96b2f 2304 lsb = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2305 index++;
elab 0:0e577ce96b2f 2306 temp16 = VL53L0X_MAKEUINT16(lsb, msb);
elab 0:0e577ce96b2f 2307 Data.SigmaEstEffAmbWidth = temp16;
elab 0:0e577ce96b2f 2308 break;
elab 0:0e577ce96b2f 2309 case 3: /* uint16_t targetRefRate -> 2 bytes */
elab 0:0e577ce96b2f 2310 msb = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2311 index++;
elab 0:0e577ce96b2f 2312 lsb = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2313 index++;
elab 0:0e577ce96b2f 2314 temp16 = VL53L0X_MAKEUINT16(lsb, msb);
elab 0:0e577ce96b2f 2315 Data.targetRefRate = temp16;
elab 0:0e577ce96b2f 2316 break;
elab 0:0e577ce96b2f 2317 default: /* invalid parameter */
elab 0:0e577ce96b2f 2318 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 2319 }
elab 0:0e577ce96b2f 2320
elab 0:0e577ce96b2f 2321 } else if (number_of_writes <= 4) {
elab 0:0e577ce96b2f 2322 address = *(p_tuning_setting_buffer + index);
elab 0:0e577ce96b2f 2323 index++;
elab 0:0e577ce96b2f 2324
elab 0:0e577ce96b2f 2325 for (i = 0; i < number_of_writes; i++) {
elab 0:0e577ce96b2f 2326 local_buffer[i] = *(p_tuning_setting_buffer +
elab 0:0e577ce96b2f 2327 index);
elab 0:0e577ce96b2f 2328 index++;
elab 0:0e577ce96b2f 2329 }
elab 0:0e577ce96b2f 2330
elab 0:0e577ce96b2f 2331 status = VL53L0X_i2c_write( address, local_buffer, number_of_writes);
elab 0:0e577ce96b2f 2332
elab 0:0e577ce96b2f 2333 } else { status = VL53L0X_ERROR_INVALID_PARAMS; }
elab 0:0e577ce96b2f 2334 }
elab 0:0e577ce96b2f 2335 return status;
elab 0:0e577ce96b2f 2336 }
elab 0:0e577ce96b2f 2337
elab 0:0e577ce96b2f 2338 VL53L0X_Error VL53L0X::VL53L0X_check_and_load_interrupt_settings(uint8_t start_not_stopflag)
elab 0:0e577ce96b2f 2339 { uint8_t interrupt_config;
elab 0:0e577ce96b2f 2340 FixPoint1616_t threshold_low;
elab 0:0e577ce96b2f 2341 FixPoint1616_t threshold_high;
elab 0:0e577ce96b2f 2342 VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2343
elab 0:0e577ce96b2f 2344 interrupt_config = Data.Pin0GpioFunctionality;
elab 0:0e577ce96b2f 2345
elab 0:0e577ce96b2f 2346 if ((interrupt_config ==
elab 0:0e577ce96b2f 2347 VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW) ||
elab 0:0e577ce96b2f 2348 (interrupt_config ==
elab 0:0e577ce96b2f 2349 VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH) ||
elab 0:0e577ce96b2f 2350 (interrupt_config ==
elab 0:0e577ce96b2f 2351 VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT)) {
elab 0:0e577ce96b2f 2352
elab 0:0e577ce96b2f 2353 status = VL53L0X_get_interrupt_thresholds(VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,
elab 0:0e577ce96b2f 2354 &threshold_low, &threshold_high);
elab 0:0e577ce96b2f 2355
elab 0:0e577ce96b2f 2356 if (((threshold_low > 255 * 65536) ||
elab 0:0e577ce96b2f 2357 (threshold_high > 255 * 65536)) &&
elab 0:0e577ce96b2f 2358 (status == VL53L0X_ERROR_NONE)) {
elab 0:0e577ce96b2f 2359
elab 0:0e577ce96b2f 2360 if (start_not_stopflag != 0) {
elab 0:0e577ce96b2f 2361 status = VL53L0X_load_tuning_settings(InterruptThresholdSettings);
elab 0:0e577ce96b2f 2362 } else {
elab 0:0e577ce96b2f 2363 status |= VL53L0X_write_byte( 0xFF, 0x04);
elab 0:0e577ce96b2f 2364 status |= VL53L0X_write_byte( 0x70, 0x00);
elab 0:0e577ce96b2f 2365 status |= VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 2366 status |= VL53L0X_write_byte( 0x80, 0x00);
elab 0:0e577ce96b2f 2367 }
elab 0:0e577ce96b2f 2368 }
elab 0:0e577ce96b2f 2369 }
elab 0:0e577ce96b2f 2370 return status;
elab 0:0e577ce96b2f 2371 }
elab 0:0e577ce96b2f 2372
elab 0:0e577ce96b2f 2373 VL53L0X_Error VL53L0X::VL53L0X_start_measurement(void)
elab 0:0e577ce96b2f 2374 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2375 VL53L0X_DeviceModes device_mode;
elab 0:0e577ce96b2f 2376 uint8_t byte;
elab 0:0e577ce96b2f 2377 uint8_t start_stop_byte = VL53L0X_REG_SYSRANGE_MODE_START_STOP;
elab 0:0e577ce96b2f 2378 uint32_t loop_nb;
elab 0:0e577ce96b2f 2379
elab 0:0e577ce96b2f 2380
elab 0:0e577ce96b2f 2381 /* Get Current DeviceMode */
elab 0:0e577ce96b2f 2382 device_mode = CurrentParameters.DeviceMode;
elab 0:0e577ce96b2f 2383
elab 0:0e577ce96b2f 2384 status = VL53L0X_write_byte( 0x80, 0x01);
elab 0:0e577ce96b2f 2385 status = VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 2386 status = VL53L0X_write_byte( 0x00, 0x00);
elab 0:0e577ce96b2f 2387 status = VL53L0X_write_byte( 0x91, Data.StopVariable);
elab 0:0e577ce96b2f 2388 status = VL53L0X_write_byte( 0x00, 0x01);
elab 0:0e577ce96b2f 2389 status = VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 2390 status = VL53L0X_write_byte( 0x80, 0x00);
elab 0:0e577ce96b2f 2391
elab 0:0e577ce96b2f 2392 switch (device_mode) {
elab 0:0e577ce96b2f 2393 case VL53L0X_DEVICEMODE_SINGLE_RANGING:
elab 0:0e577ce96b2f 2394 status = VL53L0X_write_byte( VL53L0X_REG_SYSRANGE_START, 0x01);
elab 0:0e577ce96b2f 2395
elab 0:0e577ce96b2f 2396 byte = start_stop_byte;
elab 0:0e577ce96b2f 2397 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2398 /* Wait until start bit has been cleared */
elab 0:0e577ce96b2f 2399 loop_nb = 0;
elab 0:0e577ce96b2f 2400 do {
elab 0:0e577ce96b2f 2401 if (loop_nb > 0)
elab 0:0e577ce96b2f 2402 status = VL53L0X_read_byte(VL53L0X_REG_SYSRANGE_START, &byte);
elab 0:0e577ce96b2f 2403 loop_nb = loop_nb + 1;
elab 0:0e577ce96b2f 2404 } while (((byte & start_stop_byte) == start_stop_byte)
elab 0:0e577ce96b2f 2405 && (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 2406 && (loop_nb < VL53L0X_DEFAULT_MAX_LOOP));
elab 0:0e577ce96b2f 2407
elab 0:0e577ce96b2f 2408 if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) {
elab 0:0e577ce96b2f 2409 status = VL53L0X_ERROR_TIME_OUT;
elab 0:0e577ce96b2f 2410 }
elab 0:0e577ce96b2f 2411 }
elab 0:0e577ce96b2f 2412
elab 0:0e577ce96b2f 2413 break;
elab 0:0e577ce96b2f 2414 case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING: /* Back-to-back mode */
elab 0:0e577ce96b2f 2415
elab 0:0e577ce96b2f 2416 /* Check if need to apply interrupt settings */
elab 0:0e577ce96b2f 2417 if (status == VL53L0X_ERROR_NONE)
elab 0:0e577ce96b2f 2418 { status = VL53L0X_check_and_load_interrupt_settings( 1); }
elab 0:0e577ce96b2f 2419
elab 0:0e577ce96b2f 2420 status = VL53L0X_write_byte(VL53L0X_REG_SYSRANGE_START,
elab 0:0e577ce96b2f 2421 VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK);
elab 0:0e577ce96b2f 2422 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2423 /* Set PAL State to Running */
elab 0:0e577ce96b2f 2424 Data.PalState = VL53L0X_STATE_RUNNING;
elab 0:0e577ce96b2f 2425 }
elab 0:0e577ce96b2f 2426 break;
elab 0:0e577ce96b2f 2427 case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING:
elab 0:0e577ce96b2f 2428 /* Continuous mode */
elab 0:0e577ce96b2f 2429 /* Check if need to apply interrupt settings */
elab 0:0e577ce96b2f 2430 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2431 status = VL53L0X_check_and_load_interrupt_settings( 1);
elab 0:0e577ce96b2f 2432 }
elab 0:0e577ce96b2f 2433
elab 0:0e577ce96b2f 2434 status = VL53L0X_write_byte(VL53L0X_REG_SYSRANGE_START,
elab 0:0e577ce96b2f 2435 VL53L0X_REG_SYSRANGE_MODE_TIMED);
elab 0:0e577ce96b2f 2436
elab 0:0e577ce96b2f 2437 if (status == VL53L0X_ERROR_NONE)/* Set PAL State to Running */
elab 0:0e577ce96b2f 2438 { Data.PalState = VL53L0X_STATE_RUNNING; }
elab 0:0e577ce96b2f 2439 break;
elab 0:0e577ce96b2f 2440 default:
elab 0:0e577ce96b2f 2441 /* Selected mode not supported */
elab 0:0e577ce96b2f 2442 status = VL53L0X_ERROR_MODE_NOT_SUPPORTED;
elab 0:0e577ce96b2f 2443 }
elab 0:0e577ce96b2f 2444
elab 0:0e577ce96b2f 2445 return status;
elab 0:0e577ce96b2f 2446 }
elab 0:0e577ce96b2f 2447
elab 0:0e577ce96b2f 2448 /* Group PAL Measurement Functions */
elab 0:0e577ce96b2f 2449 VL53L0X_Error VL53L0X::VL53L0X_perform_single_measurement(void)
elab 0:0e577ce96b2f 2450 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2451 VL53L0X_DeviceModes device_mode;
elab 0:0e577ce96b2f 2452
elab 0:0e577ce96b2f 2453 /* Get Current DeviceMode */
elab 0:0e577ce96b2f 2454 device_mode = CurrentParameters.DeviceMode;
elab 0:0e577ce96b2f 2455
elab 0:0e577ce96b2f 2456 /* Start immediately to run a single ranging measurement in case of
elab 0:0e577ce96b2f 2457 * single ranging or single histogram */
elab 0:0e577ce96b2f 2458 if (status == VL53L0X_ERROR_NONE && device_mode == VL53L0X_DEVICEMODE_SINGLE_RANGING) {
elab 0:0e577ce96b2f 2459 status = VL53L0X_start_measurement(); }
elab 0:0e577ce96b2f 2460
elab 0:0e577ce96b2f 2461 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2462 status = VL53L0X_measurement_poll_for_completion(); }
elab 0:0e577ce96b2f 2463
elab 0:0e577ce96b2f 2464 /* Change PAL State in case of single ranging or single histogram */
elab 0:0e577ce96b2f 2465 if (status == VL53L0X_ERROR_NONE && device_mode == VL53L0X_DEVICEMODE_SINGLE_RANGING) {
elab 0:0e577ce96b2f 2466 Data.PalState = VL53L0X_STATE_IDLE; }
elab 0:0e577ce96b2f 2467
elab 0:0e577ce96b2f 2468 return status;
elab 0:0e577ce96b2f 2469 }
elab 0:0e577ce96b2f 2470
elab 0:0e577ce96b2f 2471 VL53L0X_Error VL53L0X::VL53L0X_get_x_talk_compensation_enable(uint8_t *p_x_talk_compensation_enable)
elab 0:0e577ce96b2f 2472 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2473 uint8_t temp8;
elab 0:0e577ce96b2f 2474
elab 0:0e577ce96b2f 2475 temp8 = CurrentParameters.XTalkCompensationEnable ;
elab 0:0e577ce96b2f 2476 *p_x_talk_compensation_enable = temp8;
elab 0:0e577ce96b2f 2477
elab 0:0e577ce96b2f 2478 return status;
elab 0:0e577ce96b2f 2479 }
elab 0:0e577ce96b2f 2480
elab 0:0e577ce96b2f 2481 VL53L0X_Error VL53L0X::VL53L0X_get_total_xtalk_rate(VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
elab 0:0e577ce96b2f 2482 FixPoint1616_t *p_total_xtalk_rate_MHz)
elab 0:0e577ce96b2f 2483 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2484
elab 0:0e577ce96b2f 2485 uint8_t xtalk_comp_enable;
elab 0:0e577ce96b2f 2486 FixPoint1616_t total_xtalk_MHz;
elab 0:0e577ce96b2f 2487 FixPoint1616_t xtalk_per_spad_MHz;
elab 0:0e577ce96b2f 2488
elab 0:0e577ce96b2f 2489 *p_total_xtalk_rate_MHz = 0;
elab 0:0e577ce96b2f 2490
elab 0:0e577ce96b2f 2491 status = VL53L0X_get_x_talk_compensation_enable( &xtalk_comp_enable);
elab 0:0e577ce96b2f 2492 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2493
elab 0:0e577ce96b2f 2494 if (xtalk_comp_enable) {
elab 0:0e577ce96b2f 2495
elab 0:0e577ce96b2f 2496 xtalk_per_spad_MHz = CurrentParameters.XTalkCompensationRate_MHz ;
elab 0:0e577ce96b2f 2497
elab 0:0e577ce96b2f 2498 /* FixPoint1616 * FixPoint 8:8 = FixPoint0824 */
elab 0:0e577ce96b2f 2499 total_xtalk_MHz =
elab 0:0e577ce96b2f 2500 p_ranging_measurement_data->EffectiveSpadRtnCount *
elab 0:0e577ce96b2f 2501 xtalk_per_spad_MHz;
elab 0:0e577ce96b2f 2502
elab 0:0e577ce96b2f 2503 /* FixPoint0824 >> 8 = FixPoint1616 */
elab 0:0e577ce96b2f 2504 *p_total_xtalk_rate_MHz =
elab 0:0e577ce96b2f 2505 (total_xtalk_MHz + 0x80) >> 8;
elab 0:0e577ce96b2f 2506 }
elab 0:0e577ce96b2f 2507 }
elab 0:0e577ce96b2f 2508 return status;
elab 0:0e577ce96b2f 2509 }
elab 0:0e577ce96b2f 2510
elab 0:0e577ce96b2f 2511 VL53L0X_Error VL53L0X::VL53L0X_get_total_signal_rate(VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
elab 0:0e577ce96b2f 2512 FixPoint1616_t *p_total_signal_rate_MHz)
elab 0:0e577ce96b2f 2513 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2514 FixPoint1616_t total_xtalk_MHz;
elab 0:0e577ce96b2f 2515
elab 0:0e577ce96b2f 2516 *p_total_signal_rate_MHz =
elab 0:0e577ce96b2f 2517 p_ranging_measurement_data->SignalRateRtn_MHz;
elab 0:0e577ce96b2f 2518
elab 0:0e577ce96b2f 2519 status = VL53L0X_get_total_xtalk_rate(p_ranging_measurement_data, &total_xtalk_MHz);
elab 0:0e577ce96b2f 2520
elab 0:0e577ce96b2f 2521 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2522 *p_total_signal_rate_MHz += total_xtalk_MHz; }
elab 0:0e577ce96b2f 2523
elab 0:0e577ce96b2f 2524 return status;
elab 0:0e577ce96b2f 2525 }
elab 0:0e577ce96b2f 2526
elab 0:0e577ce96b2f 2527 /* To convert ms into register value */
elab 0:0e577ce96b2f 2528 uint32_t VL53L0X::VL53L0X_calc_timeout_mclks(uint32_t timeout_period_us,
elab 0:0e577ce96b2f 2529 uint8_t vcsel_period_pclks)
elab 0:0e577ce96b2f 2530 { uint32_t macro_period_ps;
elab 0:0e577ce96b2f 2531 uint32_t macro_period_ns;
elab 0:0e577ce96b2f 2532 uint32_t timeout_period_mclks = 0;
elab 0:0e577ce96b2f 2533
elab 0:0e577ce96b2f 2534 macro_period_ps = VL53L0X_calc_macro_period_ps( vcsel_period_pclks);
elab 0:0e577ce96b2f 2535 macro_period_ns = (macro_period_ps + 500) / 1000;
elab 0:0e577ce96b2f 2536
elab 0:0e577ce96b2f 2537 timeout_period_mclks = (uint32_t)(((timeout_period_us * 1000)
elab 0:0e577ce96b2f 2538 + (macro_period_ns / 2)) / macro_period_ns);
elab 0:0e577ce96b2f 2539
elab 0:0e577ce96b2f 2540 return timeout_period_mclks;
elab 0:0e577ce96b2f 2541 }
elab 0:0e577ce96b2f 2542
elab 0:0e577ce96b2f 2543 uint32_t VL53L0X::VL53L0X_isqrt(uint32_t num)
elab 0:0e577ce96b2f 2544 { /* Implements an integer square root
elab 0:0e577ce96b2f 2545 * From: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots */
elab 0:0e577ce96b2f 2546
elab 0:0e577ce96b2f 2547 uint32_t res = 0;
elab 0:0e577ce96b2f 2548 uint32_t bit = 1 << 30;
elab 0:0e577ce96b2f 2549 /* The second-to-top bit is set: 1 << 14 for 16-bits, 1 << 30 for 32 bits */
elab 0:0e577ce96b2f 2550
elab 0:0e577ce96b2f 2551 /* "bit" starts at the highest power of four <= the argument. */
elab 0:0e577ce96b2f 2552 while (bit > num) { bit >>= 2; }
elab 0:0e577ce96b2f 2553
elab 0:0e577ce96b2f 2554 while (bit != 0) {
elab 0:0e577ce96b2f 2555 if (num >= res + bit) {
elab 0:0e577ce96b2f 2556 num -= res + bit;
elab 0:0e577ce96b2f 2557 res = (res >> 1) + bit;
elab 0:0e577ce96b2f 2558 }
elab 0:0e577ce96b2f 2559 else { res >>= 1; }
elab 0:0e577ce96b2f 2560 bit >>= 2;
elab 0:0e577ce96b2f 2561 }
elab 0:0e577ce96b2f 2562 return res;
elab 0:0e577ce96b2f 2563 }
elab 0:0e577ce96b2f 2564
elab 0:0e577ce96b2f 2565 VL53L0X_Error VL53L0X::VL53L0X_calc_dmax(FixPoint1616_t total_signal_rate_MHz,
elab 0:0e577ce96b2f 2566 FixPoint1616_t total_corr_signal_rate_MHz,
elab 0:0e577ce96b2f 2567 FixPoint1616_t pw_mult,
elab 0:0e577ce96b2f 2568 uint32_t sigma_estimate_p1,
elab 0:0e577ce96b2f 2569 FixPoint1616_t sigma_estimate_p2,
elab 0:0e577ce96b2f 2570 uint32_t peak_vcsel_duration_us,
elab 0:0e577ce96b2f 2571 uint32_t *pd_max_mm)
elab 0:0e577ce96b2f 2572 { const uint32_t c_sigma_limit = 18;
elab 0:0e577ce96b2f 2573 const FixPoint1616_t c_signal_limit = 0x4000; /* 0.25 */
elab 0:0e577ce96b2f 2574 const FixPoint1616_t c_sigma_est_ref = 0x00000042; /* 0.001 */
elab 0:0e577ce96b2f 2575 const uint32_t c_amb_eff_width_sigma_est_ns = 6;
elab 0:0e577ce96b2f 2576 const uint32_t c_amb_eff_width_d_max_ns = 7;
elab 0:0e577ce96b2f 2577 uint32_t dmax_cal_range_mm;
elab 0:0e577ce96b2f 2578 FixPoint1616_t dmax_cal_signal_rate_rtn_MHz;
elab 0:0e577ce96b2f 2579 FixPoint1616_t min_signal_needed;
elab 0:0e577ce96b2f 2580 FixPoint1616_t min_signal_needed_p1;
elab 0:0e577ce96b2f 2581 FixPoint1616_t min_signal_needed_p2;
elab 0:0e577ce96b2f 2582 FixPoint1616_t min_signal_needed_p3;
elab 0:0e577ce96b2f 2583 FixPoint1616_t min_signal_needed_p4;
elab 0:0e577ce96b2f 2584 FixPoint1616_t sigma_limit_tmp;
elab 0:0e577ce96b2f 2585 FixPoint1616_t sigma_est_sq_tmp;
elab 0:0e577ce96b2f 2586 FixPoint1616_t signal_limit_tmp;
elab 0:0e577ce96b2f 2587 FixPoint1616_t signal_at0_mm;
elab 0:0e577ce96b2f 2588 FixPoint1616_t dmax_dark;
elab 0:0e577ce96b2f 2589 FixPoint1616_t dmax_ambient;
elab 0:0e577ce96b2f 2590 FixPoint1616_t dmax_dark_tmp;
elab 0:0e577ce96b2f 2591 FixPoint1616_t sigma_est_p2_tmp;
elab 0:0e577ce96b2f 2592 uint32_t signal_rate_temp_MHz;
elab 0:0e577ce96b2f 2593
elab 0:0e577ce96b2f 2594 VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2595
elab 0:0e577ce96b2f 2596 dmax_cal_range_mm = Data.DmaxCalRange_mm;
elab 0:0e577ce96b2f 2597
elab 0:0e577ce96b2f 2598 dmax_cal_signal_rate_rtn_MHz = Data.DmaxCalSignalRateRtn_MHz;
elab 0:0e577ce96b2f 2599
elab 0:0e577ce96b2f 2600 /* uint32 * FixPoint1616 = FixPoint1616 */
elab 0:0e577ce96b2f 2601 signal_at0_mm = dmax_cal_range_mm * dmax_cal_signal_rate_rtn_MHz;
elab 0:0e577ce96b2f 2602
elab 0:0e577ce96b2f 2603 /* FixPoint1616 >> 8 = FixPoint2408 */
elab 0:0e577ce96b2f 2604 signal_at0_mm = (signal_at0_mm + 0x80) >> 8;
elab 0:0e577ce96b2f 2605 signal_at0_mm *= dmax_cal_range_mm;
elab 0:0e577ce96b2f 2606
elab 0:0e577ce96b2f 2607 min_signal_needed_p1 = 0;
elab 0:0e577ce96b2f 2608 if (total_corr_signal_rate_MHz > 0) {
elab 0:0e577ce96b2f 2609
elab 0:0e577ce96b2f 2610 /* Shift by 10 bits to increase resolution prior to the division */
elab 0:0e577ce96b2f 2611 signal_rate_temp_MHz = total_signal_rate_MHz << 10;
elab 0:0e577ce96b2f 2612
elab 0:0e577ce96b2f 2613 /* Add rounding value prior to division */
elab 0:0e577ce96b2f 2614 min_signal_needed_p1 = signal_rate_temp_MHz +
elab 0:0e577ce96b2f 2615 (total_corr_signal_rate_MHz / 2);
elab 0:0e577ce96b2f 2616
elab 0:0e577ce96b2f 2617 /* FixPoint0626/FixPoint1616 = FixPoint2210 */
elab 0:0e577ce96b2f 2618 min_signal_needed_p1 /= total_corr_signal_rate_MHz;
elab 0:0e577ce96b2f 2619
elab 0:0e577ce96b2f 2620 /* Apply a factored version of the speed of light.
elab 0:0e577ce96b2f 2621 Correction to be applied at the end */
elab 0:0e577ce96b2f 2622 min_signal_needed_p1 *= 3;
elab 0:0e577ce96b2f 2623
elab 0:0e577ce96b2f 2624 /* FixPoint2210 * FixPoint2210 = FixPoint1220 */
elab 0:0e577ce96b2f 2625 min_signal_needed_p1 *= min_signal_needed_p1;
elab 0:0e577ce96b2f 2626
elab 0:0e577ce96b2f 2627 /* FixPoint1220 >> 16 = FixPoint2804 */
elab 0:0e577ce96b2f 2628 min_signal_needed_p1 = (min_signal_needed_p1 + 0x8000) >> 16;
elab 0:0e577ce96b2f 2629 }
elab 0:0e577ce96b2f 2630 min_signal_needed_p2 = pw_mult * sigma_estimate_p1;
elab 0:0e577ce96b2f 2631
elab 0:0e577ce96b2f 2632 /* FixPoint1616 >> 16 = uint32 */
elab 0:0e577ce96b2f 2633 min_signal_needed_p2 = (min_signal_needed_p2 + 0x8000) >> 16;
elab 0:0e577ce96b2f 2634
elab 0:0e577ce96b2f 2635 /* uint32 * uint32 = uint32 */
elab 0:0e577ce96b2f 2636 min_signal_needed_p2 *= min_signal_needed_p2;
elab 0:0e577ce96b2f 2637
elab 0:0e577ce96b2f 2638 /* Check sigmaEstimateP2
elab 0:0e577ce96b2f 2639 * If this value is too high there is not enough signal rate
elab 0:0e577ce96b2f 2640 * to calculate dmax value so set a suitable value to ensure
elab 0:0e577ce96b2f 2641 * a very small dmax. */
elab 0:0e577ce96b2f 2642 sigma_est_p2_tmp = (sigma_estimate_p2 + 0x8000) >> 16;
elab 0:0e577ce96b2f 2643 sigma_est_p2_tmp = (sigma_est_p2_tmp + c_amb_eff_width_sigma_est_ns / 2) /
elab 0:0e577ce96b2f 2644 c_amb_eff_width_sigma_est_ns;
elab 0:0e577ce96b2f 2645 sigma_est_p2_tmp *= c_amb_eff_width_d_max_ns;
elab 0:0e577ce96b2f 2646
elab 0:0e577ce96b2f 2647 if (sigma_est_p2_tmp > 0xffff) {
elab 0:0e577ce96b2f 2648 min_signal_needed_p3 = 0xfff00000;
elab 0:0e577ce96b2f 2649 } else {
elab 0:0e577ce96b2f 2650 /* DMAX uses a different ambient width from sigma, so apply correction.
elab 0:0e577ce96b2f 2651 * Perform division before multiplication to prevent overflow. */
elab 0:0e577ce96b2f 2652 sigma_estimate_p2 = (sigma_estimate_p2 + c_amb_eff_width_sigma_est_ns / 2) /
elab 0:0e577ce96b2f 2653 c_amb_eff_width_sigma_est_ns;
elab 0:0e577ce96b2f 2654 sigma_estimate_p2 *= c_amb_eff_width_d_max_ns;
elab 0:0e577ce96b2f 2655
elab 0:0e577ce96b2f 2656 /* FixPoint1616 >> 16 = uint32 */
elab 0:0e577ce96b2f 2657 min_signal_needed_p3 = (sigma_estimate_p2 + 0x8000) >> 16;
elab 0:0e577ce96b2f 2658 min_signal_needed_p3 *= min_signal_needed_p3;
elab 0:0e577ce96b2f 2659 }
elab 0:0e577ce96b2f 2660
elab 0:0e577ce96b2f 2661 /* FixPoint1814 / uint32 = FixPoint1814 */
elab 0:0e577ce96b2f 2662 sigma_limit_tmp = ((c_sigma_limit << 14) + 500) / 1000;
elab 0:0e577ce96b2f 2663
elab 0:0e577ce96b2f 2664 /* FixPoint1814 * FixPoint1814 = FixPoint3628 := FixPoint0428 */
elab 0:0e577ce96b2f 2665 sigma_limit_tmp *= sigma_limit_tmp;
elab 0:0e577ce96b2f 2666
elab 0:0e577ce96b2f 2667 /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
elab 0:0e577ce96b2f 2668 sigma_est_sq_tmp = c_sigma_est_ref * c_sigma_est_ref;
elab 0:0e577ce96b2f 2669
elab 0:0e577ce96b2f 2670 /* FixPoint3232 >> 4 = FixPoint0428 */
elab 0:0e577ce96b2f 2671 sigma_est_sq_tmp = (sigma_est_sq_tmp + 0x08) >> 4;
elab 0:0e577ce96b2f 2672
elab 0:0e577ce96b2f 2673 /* FixPoint0428 - FixPoint0428 = FixPoint0428 */
elab 0:0e577ce96b2f 2674 sigma_limit_tmp -= sigma_est_sq_tmp;
elab 0:0e577ce96b2f 2675
elab 0:0e577ce96b2f 2676 /* uint32_t * FixPoint0428 = FixPoint0428 */
elab 0:0e577ce96b2f 2677 min_signal_needed_p4 = 4 * 12 * sigma_limit_tmp;
elab 0:0e577ce96b2f 2678
elab 0:0e577ce96b2f 2679 /* FixPoint0428 >> 14 = FixPoint1814 */
elab 0:0e577ce96b2f 2680 min_signal_needed_p4 = (min_signal_needed_p4 + 0x2000) >> 14;
elab 0:0e577ce96b2f 2681
elab 0:0e577ce96b2f 2682 /* uint32 + uint32 = uint32 */
elab 0:0e577ce96b2f 2683 min_signal_needed = (min_signal_needed_p2 + min_signal_needed_p3);
elab 0:0e577ce96b2f 2684
elab 0:0e577ce96b2f 2685 /* uint32 / uint32 = uint32 */
elab 0:0e577ce96b2f 2686 min_signal_needed += (peak_vcsel_duration_us / 2);
elab 0:0e577ce96b2f 2687 min_signal_needed /= peak_vcsel_duration_us;
elab 0:0e577ce96b2f 2688
elab 0:0e577ce96b2f 2689 /* uint32 << 14 = FixPoint1814 */
elab 0:0e577ce96b2f 2690 min_signal_needed <<= 14;
elab 0:0e577ce96b2f 2691
elab 0:0e577ce96b2f 2692 /* FixPoint1814 / FixPoint1814 = uint32 */
elab 0:0e577ce96b2f 2693 min_signal_needed += (min_signal_needed_p4 / 2);
elab 0:0e577ce96b2f 2694 min_signal_needed /= min_signal_needed_p4;
elab 0:0e577ce96b2f 2695
elab 0:0e577ce96b2f 2696 /* FixPoint3200 * FixPoint2804 := FixPoint2804*/
elab 0:0e577ce96b2f 2697 min_signal_needed *= min_signal_needed_p1;
elab 0:0e577ce96b2f 2698
elab 0:0e577ce96b2f 2699 /* Apply correction by dividing by 1000000.
elab 0:0e577ce96b2f 2700 * This assumes 10E16 on the numerator of the equation
elab 0:0e577ce96b2f 2701 * and 10E-22 on the denominator.
elab 0:0e577ce96b2f 2702 * We do this because 32bit fix point calculation can't
elab 0:0e577ce96b2f 2703 * handle the larger and smaller elements of this equation,
elab 0:0e577ce96b2f 2704 * i.e. speed of light and pulse widths.
elab 0:0e577ce96b2f 2705 */
elab 0:0e577ce96b2f 2706 min_signal_needed = (min_signal_needed + 500) / 1000;
elab 0:0e577ce96b2f 2707 min_signal_needed <<= 4;
elab 0:0e577ce96b2f 2708
elab 0:0e577ce96b2f 2709 min_signal_needed = (min_signal_needed + 500) / 1000;
elab 0:0e577ce96b2f 2710
elab 0:0e577ce96b2f 2711 /* FixPoint1616 >> 8 = FixPoint2408 */
elab 0:0e577ce96b2f 2712 signal_limit_tmp = (c_signal_limit + 0x80) >> 8;
elab 0:0e577ce96b2f 2713
elab 0:0e577ce96b2f 2714 /* FixPoint2408/FixPoint2408 = uint32 */
elab 0:0e577ce96b2f 2715 if (signal_limit_tmp != 0) {
elab 0:0e577ce96b2f 2716 dmax_dark_tmp = (signal_at0_mm + (signal_limit_tmp / 2))
elab 0:0e577ce96b2f 2717 / signal_limit_tmp;
elab 0:0e577ce96b2f 2718 } else { dmax_dark_tmp = 0; }
elab 0:0e577ce96b2f 2719
elab 0:0e577ce96b2f 2720 dmax_dark = VL53L0X_isqrt(dmax_dark_tmp);
elab 0:0e577ce96b2f 2721
elab 0:0e577ce96b2f 2722 /* FixPoint2408/FixPoint2408 = uint32 */
elab 0:0e577ce96b2f 2723 if (min_signal_needed != 0) {
elab 0:0e577ce96b2f 2724 dmax_ambient = (signal_at0_mm + min_signal_needed / 2)
elab 0:0e577ce96b2f 2725 / min_signal_needed;
elab 0:0e577ce96b2f 2726 } else { dmax_ambient = 0; }
elab 0:0e577ce96b2f 2727
elab 0:0e577ce96b2f 2728 dmax_ambient = VL53L0X_isqrt(dmax_ambient);
elab 0:0e577ce96b2f 2729
elab 0:0e577ce96b2f 2730 *pd_max_mm = dmax_dark;
elab 0:0e577ce96b2f 2731 if (dmax_dark > dmax_ambient) { *pd_max_mm = dmax_ambient; }
elab 0:0e577ce96b2f 2732
elab 0:0e577ce96b2f 2733 return status;
elab 0:0e577ce96b2f 2734 }
elab 0:0e577ce96b2f 2735
elab 0:0e577ce96b2f 2736 VL53L0X_Error VL53L0X::VL53L0X_calc_sigma_estimate(VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
elab 0:0e577ce96b2f 2737 FixPoint1616_t *p_sigma_estimate, uint32_t *p_dmax_mm)
elab 0:0e577ce96b2f 2738 { /* Expressed in 100ths of a ns, i.e. centi-ns */
elab 0:0e577ce96b2f 2739 const uint32_t c_pulse_effective_width_centi_ns = 800;
elab 0:0e577ce96b2f 2740 /* Expressed in 100ths of a ns, i.e. centi-ns */
elab 0:0e577ce96b2f 2741 const uint32_t c_ambient_effective_width_centi_ns = 600;
elab 0:0e577ce96b2f 2742 const FixPoint1616_t c_dflt_final_range_integration_time_milli_secs = 0x00190000; /* 25ms */
elab 0:0e577ce96b2f 2743 const uint32_t c_vcsel_pulse_width_ps = 4700; /* pico secs */
elab 0:0e577ce96b2f 2744 const FixPoint1616_t c_sigma_est_max = 0x028F87AE;
elab 0:0e577ce96b2f 2745 const FixPoint1616_t c_sigma_est_rtn_max = 0xF000;
elab 0:0e577ce96b2f 2746 const FixPoint1616_t c_amb_to_signal_ratio_max = 0xF0000000 /
elab 0:0e577ce96b2f 2747 c_ambient_effective_width_centi_ns;
elab 0:0e577ce96b2f 2748 /* Time Of Flight per mm (6.6 pico secs) */
elab 0:0e577ce96b2f 2749 const FixPoint1616_t c_tof_per_mm_ps = 0x0006999A;
elab 0:0e577ce96b2f 2750 const uint32_t c_16bit_rounding_param = 0x00008000;
elab 0:0e577ce96b2f 2751 const FixPoint1616_t c_max_x_talk_kcps = 0x00320000;
elab 0:0e577ce96b2f 2752 const uint32_t c_pll_period_ps = 1655;
elab 0:0e577ce96b2f 2753
elab 0:0e577ce96b2f 2754 uint32_t vcsel_total_events_rtn;
elab 0:0e577ce96b2f 2755 uint32_t final_range_timeout_micro_secs;
elab 0:0e577ce96b2f 2756 uint32_t pre_range_timeout_micro_secs;
elab 0:0e577ce96b2f 2757 uint32_t final_range_integration_time_milli_secs;
elab 0:0e577ce96b2f 2758 FixPoint1616_t sigma_estimate_p1;
elab 0:0e577ce96b2f 2759 FixPoint1616_t sigma_estimate_p2;
elab 0:0e577ce96b2f 2760 FixPoint1616_t sigma_estimate_p3;
elab 0:0e577ce96b2f 2761 FixPoint1616_t delta_t_ps;
elab 0:0e577ce96b2f 2762 FixPoint1616_t pw_mult;
elab 0:0e577ce96b2f 2763 FixPoint1616_t sigma_est_rtn;
elab 0:0e577ce96b2f 2764 FixPoint1616_t sigma_estimate;
elab 0:0e577ce96b2f 2765 FixPoint1616_t x_talk_correction;
elab 0:0e577ce96b2f 2766 FixPoint1616_t ambient_rate_kcps;
elab 0:0e577ce96b2f 2767 FixPoint1616_t peak_signal_rate_kcps;
elab 0:0e577ce96b2f 2768 FixPoint1616_t x_talk_comp_rate_MHz;
elab 0:0e577ce96b2f 2769 uint32_t x_talk_comp_rate_kcps;
elab 0:0e577ce96b2f 2770 VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 2771 FixPoint1616_t diff1_MHz;
elab 0:0e577ce96b2f 2772 FixPoint1616_t diff2_MHz;
elab 0:0e577ce96b2f 2773 FixPoint1616_t sqr1;
elab 0:0e577ce96b2f 2774 FixPoint1616_t sqr2;
elab 0:0e577ce96b2f 2775 FixPoint1616_t sqr_sum;
elab 0:0e577ce96b2f 2776 FixPoint1616_t sqrt_result_centi_ns;
elab 0:0e577ce96b2f 2777 FixPoint1616_t sqrt_result;
elab 0:0e577ce96b2f 2778 FixPoint1616_t total_signal_rate_MHz;
elab 0:0e577ce96b2f 2779 FixPoint1616_t corrected_signal_rate_MHz;
elab 0:0e577ce96b2f 2780 FixPoint1616_t sigma_est_ref;
elab 0:0e577ce96b2f 2781 uint32_t vcsel_width;
elab 0:0e577ce96b2f 2782 uint32_t final_range_macro_pclks;
elab 0:0e577ce96b2f 2783 uint32_t pre_range_macro_pclks;
elab 0:0e577ce96b2f 2784 uint32_t peak_vcsel_duration_us;
elab 0:0e577ce96b2f 2785 uint8_t final_range_vcsel_pclks;
elab 0:0e577ce96b2f 2786 uint8_t pre_range_vcsel_pclks;
elab 0:0e577ce96b2f 2787 /*! \addtogroup calc_sigma_estimate
elab 0:0e577ce96b2f 2788 * @{
elab 0:0e577ce96b2f 2789 *
elab 0:0e577ce96b2f 2790 * Estimates the range sigma
elab 0:0e577ce96b2f 2791 */
elab 0:0e577ce96b2f 2792
elab 0:0e577ce96b2f 2793 x_talk_comp_rate_MHz = CurrentParameters.XTalkCompensationRate_MHz ;
elab 0:0e577ce96b2f 2794
elab 0:0e577ce96b2f 2795 /*
elab 0:0e577ce96b2f 2796 * We work in kcps rather than MHz as this helps keep within the
elab 0:0e577ce96b2f 2797 * confines of the 32 Fix1616 type.
elab 0:0e577ce96b2f 2798 */
elab 0:0e577ce96b2f 2799
elab 0:0e577ce96b2f 2800 ambient_rate_kcps = (p_ranging_measurement_data->AmbientRateRtn_MHz * 1000) >> 16;
elab 0:0e577ce96b2f 2801
elab 0:0e577ce96b2f 2802 corrected_signal_rate_MHz = p_ranging_measurement_data->SignalRateRtn_MHz;
elab 0:0e577ce96b2f 2803
elab 0:0e577ce96b2f 2804 status = VL53L0X_get_total_signal_rate(p_ranging_measurement_data, &total_signal_rate_MHz);
elab 0:0e577ce96b2f 2805 status = VL53L0X_get_total_xtalk_rate(p_ranging_measurement_data, &x_talk_comp_rate_MHz);
elab 0:0e577ce96b2f 2806
elab 0:0e577ce96b2f 2807 /* Signal rate measurement provided by device is the
elab 0:0e577ce96b2f 2808 * peak signal rate, not average.
elab 0:0e577ce96b2f 2809 */
elab 0:0e577ce96b2f 2810 peak_signal_rate_kcps = (total_signal_rate_MHz * 1000);
elab 0:0e577ce96b2f 2811 peak_signal_rate_kcps = (peak_signal_rate_kcps + 0x8000) >> 16;
elab 0:0e577ce96b2f 2812
elab 0:0e577ce96b2f 2813 x_talk_comp_rate_kcps = x_talk_comp_rate_MHz * 1000;
elab 0:0e577ce96b2f 2814
elab 0:0e577ce96b2f 2815 if (x_talk_comp_rate_kcps > c_max_x_talk_kcps) {
elab 0:0e577ce96b2f 2816 x_talk_comp_rate_kcps = c_max_x_talk_kcps;
elab 0:0e577ce96b2f 2817 }
elab 0:0e577ce96b2f 2818
elab 0:0e577ce96b2f 2819 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 2820
elab 0:0e577ce96b2f 2821 /* Calculate final range macro periods */
elab 0:0e577ce96b2f 2822 final_range_timeout_micro_secs = Data.FinalRangeTimeout_us;
elab 0:0e577ce96b2f 2823 final_range_vcsel_pclks = Data.FinalRangeVcselPulsePeriod;
elab 0:0e577ce96b2f 2824 final_range_macro_pclks = VL53L0X_calc_timeout_mclks( final_range_timeout_micro_secs, final_range_vcsel_pclks);
elab 0:0e577ce96b2f 2825
elab 0:0e577ce96b2f 2826 /* Calculate pre-range macro periods */
elab 0:0e577ce96b2f 2827 pre_range_timeout_micro_secs = Data.PreRangeTimeout_us;
elab 0:0e577ce96b2f 2828 pre_range_vcsel_pclks = Data.PreRangeVcselPulsePeriod;
elab 0:0e577ce96b2f 2829
elab 0:0e577ce96b2f 2830 pre_range_macro_pclks = VL53L0X_calc_timeout_mclks(pre_range_timeout_micro_secs, pre_range_vcsel_pclks);
elab 0:0e577ce96b2f 2831
elab 0:0e577ce96b2f 2832 vcsel_width = 3;
elab 0:0e577ce96b2f 2833 if (final_range_vcsel_pclks == 8) {
elab 0:0e577ce96b2f 2834 vcsel_width = 2;
elab 0:0e577ce96b2f 2835 }
elab 0:0e577ce96b2f 2836
elab 0:0e577ce96b2f 2837 peak_vcsel_duration_us = vcsel_width * 2048 *
elab 0:0e577ce96b2f 2838 (pre_range_macro_pclks + final_range_macro_pclks);
elab 0:0e577ce96b2f 2839 peak_vcsel_duration_us = (peak_vcsel_duration_us + 500) / 1000;
elab 0:0e577ce96b2f 2840 peak_vcsel_duration_us *= c_pll_period_ps;
elab 0:0e577ce96b2f 2841 peak_vcsel_duration_us = (peak_vcsel_duration_us + 500) / 1000;
elab 0:0e577ce96b2f 2842
elab 0:0e577ce96b2f 2843 /* Fix1616 >> 8 = Fix2408 */
elab 0:0e577ce96b2f 2844 total_signal_rate_MHz = (total_signal_rate_MHz + 0x80) >> 8;
elab 0:0e577ce96b2f 2845
elab 0:0e577ce96b2f 2846 /* Fix2408 * uint32 = Fix2408 */
elab 0:0e577ce96b2f 2847 vcsel_total_events_rtn = total_signal_rate_MHz *
elab 0:0e577ce96b2f 2848 peak_vcsel_duration_us;
elab 0:0e577ce96b2f 2849
elab 0:0e577ce96b2f 2850 /* Fix2408 >> 8 = uint32 */
elab 0:0e577ce96b2f 2851 vcsel_total_events_rtn = (vcsel_total_events_rtn + 0x80) >> 8;
elab 0:0e577ce96b2f 2852
elab 0:0e577ce96b2f 2853 /* Fix2408 << 8 = Fix1616 = */
elab 0:0e577ce96b2f 2854 total_signal_rate_MHz <<= 8;
elab 0:0e577ce96b2f 2855 }
elab 0:0e577ce96b2f 2856
elab 0:0e577ce96b2f 2857 if (status != VL53L0X_ERROR_NONE) { return status; }
elab 0:0e577ce96b2f 2858
elab 0:0e577ce96b2f 2859 if (peak_signal_rate_kcps == 0) {
elab 0:0e577ce96b2f 2860 *p_sigma_estimate = c_sigma_est_max;
elab 0:0e577ce96b2f 2861 p_ranging_measurement_data->SigmaEstimate = c_sigma_est_max;
elab 0:0e577ce96b2f 2862 *p_dmax_mm = 0;
elab 0:0e577ce96b2f 2863 } else {
elab 0:0e577ce96b2f 2864 if (vcsel_total_events_rtn < 1) { vcsel_total_events_rtn = 1; }
elab 0:0e577ce96b2f 2865
elab 0:0e577ce96b2f 2866 sigma_estimate_p1 = c_pulse_effective_width_centi_ns;
elab 0:0e577ce96b2f 2867
elab 0:0e577ce96b2f 2868 /* ((FixPoint1616 << 16)* uint32)/uint32 = FixPoint1616 */
elab 0:0e577ce96b2f 2869 sigma_estimate_p2 = (ambient_rate_kcps << 16) / peak_signal_rate_kcps;
elab 0:0e577ce96b2f 2870 if (sigma_estimate_p2 > c_amb_to_signal_ratio_max) {
elab 0:0e577ce96b2f 2871 /* Clip to prevent overflow. Will ensure safe
elab 0:0e577ce96b2f 2872 * max result. */
elab 0:0e577ce96b2f 2873 sigma_estimate_p2 = c_amb_to_signal_ratio_max;
elab 0:0e577ce96b2f 2874 }
elab 0:0e577ce96b2f 2875 sigma_estimate_p2 *= c_ambient_effective_width_centi_ns;
elab 0:0e577ce96b2f 2876
elab 0:0e577ce96b2f 2877 sigma_estimate_p3 = 2 * VL53L0X_isqrt(vcsel_total_events_rtn * 12);
elab 0:0e577ce96b2f 2878
elab 0:0e577ce96b2f 2879 /* uint32 * FixPoint1616 = FixPoint1616 */
elab 0:0e577ce96b2f 2880 delta_t_ps = p_ranging_measurement_data->Range_mm * c_tof_per_mm_ps;
elab 0:0e577ce96b2f 2881
elab 0:0e577ce96b2f 2882 /* vcselRate - xtalkCompRate
elab 0:0e577ce96b2f 2883 * (uint32 << 16) - FixPoint1616 = FixPoint1616.
elab 0:0e577ce96b2f 2884 * Divide result by 1000 to convert to MHz.
elab 0:0e577ce96b2f 2885 * 500 is added to ensure rounding when integer division truncates. */
elab 0:0e577ce96b2f 2886 diff1_MHz = (((peak_signal_rate_kcps << 16) -
elab 0:0e577ce96b2f 2887 2 * x_talk_comp_rate_kcps) + 500) / 1000;
elab 0:0e577ce96b2f 2888
elab 0:0e577ce96b2f 2889 /* vcselRate + xtalkCompRate */
elab 0:0e577ce96b2f 2890 diff2_MHz = ((peak_signal_rate_kcps << 16) + 500) / 1000;
elab 0:0e577ce96b2f 2891
elab 0:0e577ce96b2f 2892 /* Shift by 8 bits to increase resolution prior to the division */
elab 0:0e577ce96b2f 2893 diff1_MHz <<= 8;
elab 0:0e577ce96b2f 2894
elab 0:0e577ce96b2f 2895 /* FixPoint0824/FixPoint1616 = FixPoint2408 */
elab 0:0e577ce96b2f 2896 x_talk_correction = diff1_MHz / diff2_MHz;
elab 0:0e577ce96b2f 2897
elab 0:0e577ce96b2f 2898 /* FixPoint2408 << 8 = FixPoint1616 */
elab 0:0e577ce96b2f 2899 x_talk_correction <<= 8;
elab 0:0e577ce96b2f 2900
elab 0:0e577ce96b2f 2901 if (p_ranging_measurement_data->RangeStatus != 0) {
elab 0:0e577ce96b2f 2902 pw_mult = 1 << 16;
elab 0:0e577ce96b2f 2903 } else {
elab 0:0e577ce96b2f 2904 /* FixPoint1616/uint32 = FixPoint1616 */
elab 0:0e577ce96b2f 2905 pw_mult = delta_t_ps / c_vcsel_pulse_width_ps; /* smaller than 1.0f */
elab 0:0e577ce96b2f 2906
elab 0:0e577ce96b2f 2907 /* FixPoint1616 * FixPoint1616 = FixPoint3232, however both
elab 0:0e577ce96b2f 2908 * values are small enough such that32 bits will not be exceeded. */
elab 0:0e577ce96b2f 2909 pw_mult *= ((1 << 16) - x_talk_correction);
elab 0:0e577ce96b2f 2910
elab 0:0e577ce96b2f 2911 /* (FixPoint3232 >> 16) = FixPoint1616 */
elab 0:0e577ce96b2f 2912 pw_mult = (pw_mult + c_16bit_rounding_param) >> 16;
elab 0:0e577ce96b2f 2913
elab 0:0e577ce96b2f 2914 /* FixPoint1616 + FixPoint1616 = FixPoint1616 */
elab 0:0e577ce96b2f 2915 pw_mult += (1 << 16);
elab 0:0e577ce96b2f 2916
elab 0:0e577ce96b2f 2917 /* At this point the value will be 1.xx, therefore if we square
elab 0:0e577ce96b2f 2918 * the value this will exceed 32 bits. To address this perform
elab 0:0e577ce96b2f 2919 * a single shift to the right before the multiplication. */
elab 0:0e577ce96b2f 2920 pw_mult >>= 1;
elab 0:0e577ce96b2f 2921 /* FixPoint1715 * FixPoint1715 = FixPoint3430 */
elab 0:0e577ce96b2f 2922 pw_mult = pw_mult * pw_mult;
elab 0:0e577ce96b2f 2923
elab 0:0e577ce96b2f 2924 /* (FixPoint3430 >> 14) = Fix1616 */
elab 0:0e577ce96b2f 2925 pw_mult >>= 14;
elab 0:0e577ce96b2f 2926 }
elab 0:0e577ce96b2f 2927
elab 0:0e577ce96b2f 2928 /* FixPoint1616 * uint32 = FixPoint1616 */
elab 0:0e577ce96b2f 2929 sqr1 = pw_mult * sigma_estimate_p1;
elab 0:0e577ce96b2f 2930
elab 0:0e577ce96b2f 2931 /* (FixPoint1616 >> 16) = FixPoint3200 */
elab 0:0e577ce96b2f 2932 sqr1 = (sqr1 + 0x8000) >> 16;
elab 0:0e577ce96b2f 2933
elab 0:0e577ce96b2f 2934 /* FixPoint3200 * FixPoint3200 = FixPoint6400 */
elab 0:0e577ce96b2f 2935 sqr1 *= sqr1;
elab 0:0e577ce96b2f 2936
elab 0:0e577ce96b2f 2937 sqr2 = sigma_estimate_p2;
elab 0:0e577ce96b2f 2938
elab 0:0e577ce96b2f 2939 /* (FixPoint1616 >> 16) = FixPoint3200 */
elab 0:0e577ce96b2f 2940 sqr2 = (sqr2 + 0x8000) >> 16;
elab 0:0e577ce96b2f 2941
elab 0:0e577ce96b2f 2942 /* FixPoint3200 * FixPoint3200 = FixPoint6400 */
elab 0:0e577ce96b2f 2943 sqr2 *= sqr2;
elab 0:0e577ce96b2f 2944
elab 0:0e577ce96b2f 2945 /* FixPoint64000 + FixPoint6400 = FixPoint6400 */
elab 0:0e577ce96b2f 2946 sqr_sum = sqr1 + sqr2;
elab 0:0e577ce96b2f 2947
elab 0:0e577ce96b2f 2948 /* SQRT(FixPoin6400) = FixPoint3200 */
elab 0:0e577ce96b2f 2949 sqrt_result_centi_ns = VL53L0X_isqrt(sqr_sum);
elab 0:0e577ce96b2f 2950
elab 0:0e577ce96b2f 2951 /* (FixPoint3200 << 16) = FixPoint1616 */
elab 0:0e577ce96b2f 2952 sqrt_result_centi_ns <<= 16;
elab 0:0e577ce96b2f 2953
elab 0:0e577ce96b2f 2954 /* Note that the Speed Of Light is expressed in um per 1E-10
elab 0:0e577ce96b2f 2955 * seconds (2997) Therefore to get mm/ns we have to divide by
elab 0:0e577ce96b2f 2956 * 10000
elab 0:0e577ce96b2f 2957 */
elab 0:0e577ce96b2f 2958 sigma_est_rtn = (((sqrt_result_centi_ns + 50) / 100) /
elab 0:0e577ce96b2f 2959 sigma_estimate_p3);
elab 0:0e577ce96b2f 2960 sigma_est_rtn *= VL53L0X_SPEED_OF_LIGHT_IN_AIR;
elab 0:0e577ce96b2f 2961
elab 0:0e577ce96b2f 2962 /* Add 5000 before dividing by 10000 to ensure rounding. */
elab 0:0e577ce96b2f 2963 sigma_est_rtn += 5000;
elab 0:0e577ce96b2f 2964 sigma_est_rtn /= 10000;
elab 0:0e577ce96b2f 2965
elab 0:0e577ce96b2f 2966 if (sigma_est_rtn > c_sigma_est_rtn_max) {
elab 0:0e577ce96b2f 2967 /* Clip to prevent overflow. Will ensure safe
elab 0:0e577ce96b2f 2968 * max result. */
elab 0:0e577ce96b2f 2969 sigma_est_rtn = c_sigma_est_rtn_max;
elab 0:0e577ce96b2f 2970 }
elab 0:0e577ce96b2f 2971 final_range_integration_time_milli_secs =
elab 0:0e577ce96b2f 2972 (final_range_timeout_micro_secs + pre_range_timeout_micro_secs + 500) / 1000;
elab 0:0e577ce96b2f 2973
elab 0:0e577ce96b2f 2974 /* sigmaEstRef = 1mm * 25ms/final range integration time (inc pre-range)
elab 0:0e577ce96b2f 2975 * sqrt(FixPoint1616/int) = FixPoint2408)
elab 0:0e577ce96b2f 2976 */
elab 0:0e577ce96b2f 2977 sigma_est_ref =
elab 0:0e577ce96b2f 2978 VL53L0X_isqrt((c_dflt_final_range_integration_time_milli_secs +
elab 0:0e577ce96b2f 2979 final_range_integration_time_milli_secs / 2) /
elab 0:0e577ce96b2f 2980 final_range_integration_time_milli_secs);
elab 0:0e577ce96b2f 2981
elab 0:0e577ce96b2f 2982 /* FixPoint2408 << 8 = FixPoint1616 */
elab 0:0e577ce96b2f 2983 sigma_est_ref <<= 8;
elab 0:0e577ce96b2f 2984 sigma_est_ref = (sigma_est_ref + 500) / 1000;
elab 0:0e577ce96b2f 2985
elab 0:0e577ce96b2f 2986 /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
elab 0:0e577ce96b2f 2987 sqr1 = sigma_est_rtn * sigma_est_rtn;
elab 0:0e577ce96b2f 2988 /* FixPoint1616 * FixPoint1616 = FixPoint3232 */
elab 0:0e577ce96b2f 2989 sqr2 = sigma_est_ref * sigma_est_ref;
elab 0:0e577ce96b2f 2990
elab 0:0e577ce96b2f 2991 /* sqrt(FixPoint3232) = FixPoint1616 */
elab 0:0e577ce96b2f 2992 sqrt_result = VL53L0X_isqrt((sqr1 + sqr2));
elab 0:0e577ce96b2f 2993 /*
elab 0:0e577ce96b2f 2994 * Note that the Shift by 4 bits increases resolution prior to
elab 0:0e577ce96b2f 2995 * the sqrt, therefore the result must be shifted by 2 bits to
elab 0:0e577ce96b2f 2996 * the right to revert back to the FixPoint1616 format.
elab 0:0e577ce96b2f 2997 */
elab 0:0e577ce96b2f 2998
elab 0:0e577ce96b2f 2999 sigma_estimate = 1000 * sqrt_result;
elab 0:0e577ce96b2f 3000
elab 0:0e577ce96b2f 3001 if ((peak_signal_rate_kcps < 1) || (vcsel_total_events_rtn < 1) ||
elab 0:0e577ce96b2f 3002 (sigma_estimate > c_sigma_est_max)) {
elab 0:0e577ce96b2f 3003 sigma_estimate = c_sigma_est_max;
elab 0:0e577ce96b2f 3004 }
elab 0:0e577ce96b2f 3005
elab 0:0e577ce96b2f 3006 *p_sigma_estimate = (uint32_t)(sigma_estimate);
elab 0:0e577ce96b2f 3007 p_ranging_measurement_data->SigmaEstimate = *p_sigma_estimate;
elab 0:0e577ce96b2f 3008 status = VL53L0X_calc_dmax(total_signal_rate_MHz,
elab 0:0e577ce96b2f 3009 corrected_signal_rate_MHz,
elab 0:0e577ce96b2f 3010 pw_mult,
elab 0:0e577ce96b2f 3011 sigma_estimate_p1,
elab 0:0e577ce96b2f 3012 sigma_estimate_p2,
elab 0:0e577ce96b2f 3013 peak_vcsel_duration_us,
elab 0:0e577ce96b2f 3014 p_dmax_mm);
elab 0:0e577ce96b2f 3015 }
elab 0:0e577ce96b2f 3016
elab 0:0e577ce96b2f 3017 return status;
elab 0:0e577ce96b2f 3018 }
elab 0:0e577ce96b2f 3019
elab 0:0e577ce96b2f 3020 VL53L0X_Error VL53L0X::VL53L0X_get_pal_range_status(uint8_t device_range_status,
elab 0:0e577ce96b2f 3021 FixPoint1616_t signal_rate,
elab 0:0e577ce96b2f 3022 uint16_t effective_spad_rtn_count,
elab 0:0e577ce96b2f 3023 VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data,
elab 0:0e577ce96b2f 3024 uint8_t *p_pal_range_status)
elab 0:0e577ce96b2f 3025 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3026 uint8_t none_flag;
elab 0:0e577ce96b2f 3027 uint8_t sigma_limitflag = 0;
elab 0:0e577ce96b2f 3028 uint8_t signal_ref_clipflag = 0;
elab 0:0e577ce96b2f 3029 uint8_t range_ignore_thresholdflag = 0;
elab 0:0e577ce96b2f 3030 uint8_t sigma_limit_check_enable = 0;
elab 0:0e577ce96b2f 3031 uint8_t signal_rate_final_range_limit_check_enable = 0;
elab 0:0e577ce96b2f 3032 uint8_t signal_ref_clip_limit_check_enable = 0;
elab 0:0e577ce96b2f 3033 uint8_t range_ignore_threshold_limit_check_enable = 0;
elab 0:0e577ce96b2f 3034 FixPoint1616_t sigma_estimate;
elab 0:0e577ce96b2f 3035 FixPoint1616_t sigma_limit_value;
elab 0:0e577ce96b2f 3036 FixPoint1616_t signal_ref_clip_value;
elab 0:0e577ce96b2f 3037 FixPoint1616_t range_ignore_threshold_value;
elab 0:0e577ce96b2f 3038 FixPoint1616_t signal_rate_per_spad;
elab 0:0e577ce96b2f 3039 uint8_t device_range_status_internal = 0;
elab 0:0e577ce96b2f 3040 uint16_t tmp_word = 0;
elab 0:0e577ce96b2f 3041 uint8_t temp8;
elab 0:0e577ce96b2f 3042 uint32_t dmax_mm = 0;
elab 0:0e577ce96b2f 3043 FixPoint1616_t last_signal_ref_MHz;
elab 0:0e577ce96b2f 3044
elab 0:0e577ce96b2f 3045 /* VL53L0X has a good ranging when the value of the
elab 0:0e577ce96b2f 3046 * DeviceRangeStatus = 11. This function will replace the value 0 with
elab 0:0e577ce96b2f 3047 * the value 11 in the DeviceRangeStatus.
elab 0:0e577ce96b2f 3048 * In addition, the SigmaEstimator is not included in the VL53L0X
elab 0:0e577ce96b2f 3049 * DeviceRangeStatus, this will be added in the PalRangeStatus. */
elab 0:0e577ce96b2f 3050
elab 0:0e577ce96b2f 3051 device_range_status_internal = ((device_range_status & 0x78) >> 3);
elab 0:0e577ce96b2f 3052
elab 0:0e577ce96b2f 3053 if (device_range_status_internal == 0 ||
elab 0:0e577ce96b2f 3054 device_range_status_internal == 5 ||
elab 0:0e577ce96b2f 3055 device_range_status_internal == 7 ||
elab 0:0e577ce96b2f 3056 device_range_status_internal == 12 ||
elab 0:0e577ce96b2f 3057 device_range_status_internal == 13 ||
elab 0:0e577ce96b2f 3058 device_range_status_internal == 14 ||
elab 0:0e577ce96b2f 3059 device_range_status_internal == 15
elab 0:0e577ce96b2f 3060 ) {
elab 0:0e577ce96b2f 3061 none_flag = 1;
elab 0:0e577ce96b2f 3062 } else {
elab 0:0e577ce96b2f 3063 none_flag = 0;
elab 0:0e577ce96b2f 3064 }
elab 0:0e577ce96b2f 3065
elab 0:0e577ce96b2f 3066 /* Check if Sigma limit is enabled, if yes then do comparison with limit
elab 0:0e577ce96b2f 3067 * value and put the result back into pPalRangeStatus. */
elab 0:0e577ce96b2f 3068 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3069 status = VL53L0X_get_limit_check_enable(VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
elab 0:0e577ce96b2f 3070 &sigma_limit_check_enable);
elab 0:0e577ce96b2f 3071 }
elab 0:0e577ce96b2f 3072
elab 0:0e577ce96b2f 3073 if ((sigma_limit_check_enable != 0) && (status == VL53L0X_ERROR_NONE)) {
elab 0:0e577ce96b2f 3074 /* compute the Sigma and check with limit */
elab 0:0e577ce96b2f 3075 status = VL53L0X_calc_sigma_estimate(p_ranging_measurement_data, &sigma_estimate, &dmax_mm);
elab 0:0e577ce96b2f 3076 if (status == VL53L0X_ERROR_NONE) { p_ranging_measurement_data->RangeDMax_mm = dmax_mm; }
elab 0:0e577ce96b2f 3077
elab 0:0e577ce96b2f 3078 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3079 status = VL53L0X_get_limit_check_value(VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,
elab 0:0e577ce96b2f 3080 &sigma_limit_value);
elab 0:0e577ce96b2f 3081
elab 0:0e577ce96b2f 3082 if ((sigma_limit_value > 0) && (sigma_estimate > sigma_limit_value))
elab 0:0e577ce96b2f 3083 { sigma_limitflag = 1; } /* Limit Fail */
elab 0:0e577ce96b2f 3084 }
elab 0:0e577ce96b2f 3085 }
elab 0:0e577ce96b2f 3086
elab 0:0e577ce96b2f 3087 /* Check if Signal ref clip limit is enabled, if yes then do comparison
elab 0:0e577ce96b2f 3088 * with limit value and put the result back into pPalRangeStatus. */
elab 0:0e577ce96b2f 3089 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3090 status = VL53L0X_get_limit_check_enable(VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
elab 0:0e577ce96b2f 3091 &signal_ref_clip_limit_check_enable);
elab 0:0e577ce96b2f 3092 }
elab 0:0e577ce96b2f 3093
elab 0:0e577ce96b2f 3094 if ((signal_ref_clip_limit_check_enable != 0) &&
elab 0:0e577ce96b2f 3095 (status == VL53L0X_ERROR_NONE)) {
elab 0:0e577ce96b2f 3096
elab 0:0e577ce96b2f 3097 status = VL53L0X_get_limit_check_value(VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP,
elab 0:0e577ce96b2f 3098 &signal_ref_clip_value);
elab 0:0e577ce96b2f 3099
elab 0:0e577ce96b2f 3100 /* Read LastSignalRef_MHz from device */
elab 0:0e577ce96b2f 3101 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3102 status = VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 3103 }
elab 0:0e577ce96b2f 3104
elab 0:0e577ce96b2f 3105 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3106 status = VL53L0X_read_word(VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF,
elab 0:0e577ce96b2f 3107 &tmp_word);
elab 0:0e577ce96b2f 3108 }
elab 0:0e577ce96b2f 3109
elab 0:0e577ce96b2f 3110 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3111 status = VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 3112 }
elab 0:0e577ce96b2f 3113
elab 0:0e577ce96b2f 3114 last_signal_ref_MHz = VL53L0X_FP97TOFP1616(tmp_word);
elab 0:0e577ce96b2f 3115 Data.LastSignalRef_MHz = last_signal_ref_MHz;
elab 0:0e577ce96b2f 3116
elab 0:0e577ce96b2f 3117 if ((signal_ref_clip_value > 0) &&
elab 0:0e577ce96b2f 3118 (last_signal_ref_MHz > signal_ref_clip_value)) {
elab 0:0e577ce96b2f 3119 /* Limit Fail */
elab 0:0e577ce96b2f 3120 signal_ref_clipflag = 1;
elab 0:0e577ce96b2f 3121 }
elab 0:0e577ce96b2f 3122 }
elab 0:0e577ce96b2f 3123
elab 0:0e577ce96b2f 3124 /*
elab 0:0e577ce96b2f 3125 * Check if Signal ref clip limit is enabled, if yes then do comparison
elab 0:0e577ce96b2f 3126 * with limit value and put the result back into pPalRangeStatus.
elab 0:0e577ce96b2f 3127 * EffectiveSpadRtnCount has a format 8.8
elab 0:0e577ce96b2f 3128 * If (Return signal rate < (1.5 x Xtalk x number of Spads)) : FAIL
elab 0:0e577ce96b2f 3129 */
elab 0:0e577ce96b2f 3130 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3131 status = VL53L0X_get_limit_check_enable(VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
elab 0:0e577ce96b2f 3132 &range_ignore_threshold_limit_check_enable);
elab 0:0e577ce96b2f 3133 }
elab 0:0e577ce96b2f 3134
elab 0:0e577ce96b2f 3135 if ((range_ignore_threshold_limit_check_enable != 0) &&
elab 0:0e577ce96b2f 3136 (status == VL53L0X_ERROR_NONE)) {
elab 0:0e577ce96b2f 3137
elab 0:0e577ce96b2f 3138 /* Compute the signal rate per spad */
elab 0:0e577ce96b2f 3139 if (effective_spad_rtn_count == 0) {
elab 0:0e577ce96b2f 3140 signal_rate_per_spad = 0;
elab 0:0e577ce96b2f 3141 } else {
elab 0:0e577ce96b2f 3142 signal_rate_per_spad = (FixPoint1616_t)((256 * signal_rate)
elab 0:0e577ce96b2f 3143 / effective_spad_rtn_count);
elab 0:0e577ce96b2f 3144 }
elab 0:0e577ce96b2f 3145
elab 0:0e577ce96b2f 3146 status = VL53L0X_get_limit_check_value(VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD,
elab 0:0e577ce96b2f 3147 &range_ignore_threshold_value);
elab 0:0e577ce96b2f 3148
elab 0:0e577ce96b2f 3149 if ((range_ignore_threshold_value > 0) &&
elab 0:0e577ce96b2f 3150 (signal_rate_per_spad < range_ignore_threshold_value)) {
elab 0:0e577ce96b2f 3151 /* Limit Fail add 2^6 to range status */
elab 0:0e577ce96b2f 3152 range_ignore_thresholdflag = 1;
elab 0:0e577ce96b2f 3153 }
elab 0:0e577ce96b2f 3154 }
elab 0:0e577ce96b2f 3155
elab 0:0e577ce96b2f 3156 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3157 if (none_flag == 1) {
elab 0:0e577ce96b2f 3158 *p_pal_range_status = 255; /* NONE */
elab 0:0e577ce96b2f 3159 } else if (device_range_status_internal == 1 ||
elab 0:0e577ce96b2f 3160 device_range_status_internal == 2 ||
elab 0:0e577ce96b2f 3161 device_range_status_internal == 3) {
elab 0:0e577ce96b2f 3162 *p_pal_range_status = 5; /* HW fail */
elab 0:0e577ce96b2f 3163 } else if (device_range_status_internal == 6 ||
elab 0:0e577ce96b2f 3164 device_range_status_internal == 9) {
elab 0:0e577ce96b2f 3165 *p_pal_range_status = 4; /* Phase fail */
elab 0:0e577ce96b2f 3166 } else if (device_range_status_internal == 8 ||
elab 0:0e577ce96b2f 3167 device_range_status_internal == 10 ||
elab 0:0e577ce96b2f 3168 signal_ref_clipflag == 1) {
elab 0:0e577ce96b2f 3169 *p_pal_range_status = 3; /* Min range */
elab 0:0e577ce96b2f 3170 } else if (device_range_status_internal == 4 ||
elab 0:0e577ce96b2f 3171 range_ignore_thresholdflag == 1) {
elab 0:0e577ce96b2f 3172 *p_pal_range_status = 2; /* Signal Fail */
elab 0:0e577ce96b2f 3173 } else if (sigma_limitflag == 1) {
elab 0:0e577ce96b2f 3174 *p_pal_range_status = 1; /* Sigma Fail */
elab 0:0e577ce96b2f 3175 } else {
elab 0:0e577ce96b2f 3176 *p_pal_range_status = 0; /* Range Valid */
elab 0:0e577ce96b2f 3177 }
elab 0:0e577ce96b2f 3178 }
elab 0:0e577ce96b2f 3179
elab 0:0e577ce96b2f 3180 /* DMAX only relevant during range error */
elab 0:0e577ce96b2f 3181 if (*p_pal_range_status == 0) {
elab 0:0e577ce96b2f 3182 p_ranging_measurement_data->RangeDMax_mm = 0;
elab 0:0e577ce96b2f 3183 }
elab 0:0e577ce96b2f 3184
elab 0:0e577ce96b2f 3185 /* fill the Limit Check Status */
elab 0:0e577ce96b2f 3186
elab 0:0e577ce96b2f 3187 status = VL53L0X_get_limit_check_enable(VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,
elab 0:0e577ce96b2f 3188 &signal_rate_final_range_limit_check_enable);
elab 0:0e577ce96b2f 3189
elab 0:0e577ce96b2f 3190 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3191 if ((sigma_limit_check_enable == 0) || (sigma_limitflag == 1)) {
elab 0:0e577ce96b2f 3192 temp8 = 1;
elab 0:0e577ce96b2f 3193 } else {
elab 0:0e577ce96b2f 3194 temp8 = 0;
elab 0:0e577ce96b2f 3195 }
elab 0:0e577ce96b2f 3196 CurrentParameters.LimitChecksStatus[VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE] = temp8;
elab 0:0e577ce96b2f 3197
elab 0:0e577ce96b2f 3198 if ((device_range_status_internal == 4) ||
elab 0:0e577ce96b2f 3199 (signal_rate_final_range_limit_check_enable == 0)) {
elab 0:0e577ce96b2f 3200 temp8 = 1;
elab 0:0e577ce96b2f 3201 } else {
elab 0:0e577ce96b2f 3202 temp8 = 0;
elab 0:0e577ce96b2f 3203 }
elab 0:0e577ce96b2f 3204 CurrentParameters.LimitChecksStatus[VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE] = temp8;
elab 0:0e577ce96b2f 3205
elab 0:0e577ce96b2f 3206 if ((signal_ref_clip_limit_check_enable == 0) ||
elab 0:0e577ce96b2f 3207 (signal_ref_clipflag == 1)) {
elab 0:0e577ce96b2f 3208 temp8 = 1;
elab 0:0e577ce96b2f 3209 } else {
elab 0:0e577ce96b2f 3210 temp8 = 0;
elab 0:0e577ce96b2f 3211 }
elab 0:0e577ce96b2f 3212
elab 0:0e577ce96b2f 3213 CurrentParameters.LimitChecksStatus[VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP] = temp8;
elab 0:0e577ce96b2f 3214
elab 0:0e577ce96b2f 3215 if ((range_ignore_threshold_limit_check_enable == 0) ||
elab 0:0e577ce96b2f 3216 (range_ignore_thresholdflag == 1)) {
elab 0:0e577ce96b2f 3217 temp8 = 1;
elab 0:0e577ce96b2f 3218 } else {
elab 0:0e577ce96b2f 3219 temp8 = 0;
elab 0:0e577ce96b2f 3220 }
elab 0:0e577ce96b2f 3221
elab 0:0e577ce96b2f 3222 CurrentParameters.LimitChecksStatus[VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD] = temp8;
elab 0:0e577ce96b2f 3223 }
elab 0:0e577ce96b2f 3224
elab 0:0e577ce96b2f 3225 return status;
elab 0:0e577ce96b2f 3226 }
elab 0:0e577ce96b2f 3227
elab 0:0e577ce96b2f 3228 VL53L0X_Error VL53L0X::VL53L0X_get_ranging_measurement_data(VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data)
elab 0:0e577ce96b2f 3229 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3230 uint8_t device_range_status;
elab 0:0e577ce96b2f 3231 uint8_t range_fractional_enable;
elab 0:0e577ce96b2f 3232 uint8_t pal_range_status;
elab 0:0e577ce96b2f 3233 uint8_t x_talk_compensation_enable;
elab 0:0e577ce96b2f 3234 uint16_t ambient_rate;
elab 0:0e577ce96b2f 3235 FixPoint1616_t signal_rate;
elab 0:0e577ce96b2f 3236 uint16_t x_talk_compensation_rate_MHz;
elab 0:0e577ce96b2f 3237 uint16_t effective_spad_rtn_count;
elab 0:0e577ce96b2f 3238 uint16_t tmpuint16;
elab 0:0e577ce96b2f 3239 uint16_t xtalk_range_milli_meter;
elab 0:0e577ce96b2f 3240 uint16_t linearity_corrective_gain;
elab 0:0e577ce96b2f 3241 uint8_t localBuffer[12];
elab 0:0e577ce96b2f 3242
elab 0:0e577ce96b2f 3243 /* use multi read even if some registers are not useful, result will
elab 0:0e577ce96b2f 3244 * be more efficient start reading at 0x14 dec20
elab 0:0e577ce96b2f 3245 * end reading at 0x21 dec33 total 14 bytes to read */
elab 0:0e577ce96b2f 3246 status = VL53L0X_read_multi( 0x14, localBuffer, 12);
elab 0:0e577ce96b2f 3247
elab 0:0e577ce96b2f 3248 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3249
elab 0:0e577ce96b2f 3250 tmpuint16 = VL53L0X_MAKEUINT16(localBuffer[11], localBuffer[10]);
elab 0:0e577ce96b2f 3251 /* cut1.1 if SYSTEM__RANGE_CONFIG if 1 range is 2bits fractional
elab 0:0e577ce96b2f 3252 *(format 11.2) else no fractional */
elab 0:0e577ce96b2f 3253
elab 0:0e577ce96b2f 3254 signal_rate = VL53L0X_FP97TOFP1616(VL53L0X_MAKEUINT16(localBuffer[7], localBuffer[6]));
elab 0:0e577ce96b2f 3255 /* peak_signal_count_rate_rtn_MHz */
elab 0:0e577ce96b2f 3256 p_ranging_measurement_data->SignalRateRtn_MHz = signal_rate;
elab 0:0e577ce96b2f 3257
elab 0:0e577ce96b2f 3258 ambient_rate = VL53L0X_MAKEUINT16(localBuffer[9], localBuffer[8]);
elab 0:0e577ce96b2f 3259 p_ranging_measurement_data->AmbientRateRtn_MHz =
elab 0:0e577ce96b2f 3260 VL53L0X_FP97TOFP1616(ambient_rate);
elab 0:0e577ce96b2f 3261
elab 0:0e577ce96b2f 3262 effective_spad_rtn_count = VL53L0X_MAKEUINT16(localBuffer[3],
elab 0:0e577ce96b2f 3263 localBuffer[2]);
elab 0:0e577ce96b2f 3264 /* EffectiveSpadRtnCount is 8.8 format */
elab 0:0e577ce96b2f 3265 p_ranging_measurement_data->EffectiveSpadRtnCount =
elab 0:0e577ce96b2f 3266 effective_spad_rtn_count;
elab 0:0e577ce96b2f 3267
elab 0:0e577ce96b2f 3268 device_range_status = localBuffer[0];
elab 0:0e577ce96b2f 3269
elab 0:0e577ce96b2f 3270 /* Get Linearity Corrective Gain */
elab 0:0e577ce96b2f 3271 linearity_corrective_gain = Data.LinearityCorrectiveGain;
elab 0:0e577ce96b2f 3272
elab 0:0e577ce96b2f 3273 /* Get ranging configuration */
elab 0:0e577ce96b2f 3274 range_fractional_enable = Data.RangeFractionalEnable;
elab 0:0e577ce96b2f 3275
elab 0:0e577ce96b2f 3276 if (linearity_corrective_gain != 1000) {
elab 0:0e577ce96b2f 3277
elab 0:0e577ce96b2f 3278 tmpuint16 = (uint16_t)((linearity_corrective_gain * tmpuint16 + 500) / 1000);
elab 0:0e577ce96b2f 3279
elab 0:0e577ce96b2f 3280 /* Implement Xtalk */
elab 0:0e577ce96b2f 3281 x_talk_compensation_rate_MHz = CurrentParameters.XTalkCompensationRate_MHz ;
elab 0:0e577ce96b2f 3282 x_talk_compensation_enable = CurrentParameters.XTalkCompensationEnable ;
elab 0:0e577ce96b2f 3283
elab 0:0e577ce96b2f 3284 if (x_talk_compensation_enable) {
elab 0:0e577ce96b2f 3285
elab 0:0e577ce96b2f 3286 if ((signal_rate
elab 0:0e577ce96b2f 3287 - ((x_talk_compensation_rate_MHz
elab 0:0e577ce96b2f 3288 * effective_spad_rtn_count) >> 8))
elab 0:0e577ce96b2f 3289 <= 0) {
elab 0:0e577ce96b2f 3290 if (range_fractional_enable) {
elab 0:0e577ce96b2f 3291 xtalk_range_milli_meter = 8888;
elab 0:0e577ce96b2f 3292 } else {
elab 0:0e577ce96b2f 3293 xtalk_range_milli_meter = 8888 << 2;
elab 0:0e577ce96b2f 3294 }
elab 0:0e577ce96b2f 3295 } else {
elab 0:0e577ce96b2f 3296 xtalk_range_milli_meter =
elab 0:0e577ce96b2f 3297 (tmpuint16 * signal_rate)
elab 0:0e577ce96b2f 3298 / (signal_rate
elab 0:0e577ce96b2f 3299 - ((x_talk_compensation_rate_MHz
elab 0:0e577ce96b2f 3300 * effective_spad_rtn_count)
elab 0:0e577ce96b2f 3301 >> 8));
elab 0:0e577ce96b2f 3302 }
elab 0:0e577ce96b2f 3303 tmpuint16 = xtalk_range_milli_meter;
elab 0:0e577ce96b2f 3304 }
elab 0:0e577ce96b2f 3305 }
elab 0:0e577ce96b2f 3306
elab 0:0e577ce96b2f 3307 if (range_fractional_enable) {
elab 0:0e577ce96b2f 3308 p_ranging_measurement_data->Range_mm =
elab 0:0e577ce96b2f 3309 (uint16_t)((tmpuint16) >> 2);
elab 0:0e577ce96b2f 3310 p_ranging_measurement_data->RangeFractionalPart =
elab 0:0e577ce96b2f 3311 (uint8_t)((tmpuint16 & 0x03) << 6);
elab 0:0e577ce96b2f 3312 } else {
elab 0:0e577ce96b2f 3313 p_ranging_measurement_data->Range_mm = tmpuint16;
elab 0:0e577ce96b2f 3314 p_ranging_measurement_data->RangeFractionalPart = 0;
elab 0:0e577ce96b2f 3315 }
elab 0:0e577ce96b2f 3316
elab 0:0e577ce96b2f 3317 /* For a standard definition of RangeStatus, this should
elab 0:0e577ce96b2f 3318 * return 0 in case of good result after a ranging
elab 0:0e577ce96b2f 3319 * The range status depends on the device so call a device
elab 0:0e577ce96b2f 3320 * specific function to obtain the right Status.
elab 0:0e577ce96b2f 3321 */
elab 0:0e577ce96b2f 3322 status |= VL53L0X_get_pal_range_status( device_range_status,
elab 0:0e577ce96b2f 3323 signal_rate, effective_spad_rtn_count,
elab 0:0e577ce96b2f 3324 p_ranging_measurement_data, &pal_range_status);
elab 0:0e577ce96b2f 3325
elab 0:0e577ce96b2f 3326 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3327 p_ranging_measurement_data->RangeStatus = pal_range_status;}
elab 0:0e577ce96b2f 3328
elab 0:0e577ce96b2f 3329 }
elab 0:0e577ce96b2f 3330
elab 0:0e577ce96b2f 3331 if (status == VL53L0X_ERROR_NONE) { /* Copy last read data into Device buffer */
elab 0:0e577ce96b2f 3332 LastRangeMeasure.Range_mm = p_ranging_measurement_data->Range_mm;
elab 0:0e577ce96b2f 3333 LastRangeMeasure.RangeFractionalPart = p_ranging_measurement_data->RangeFractionalPart;
elab 0:0e577ce96b2f 3334 LastRangeMeasure.RangeDMax_mm = p_ranging_measurement_data->RangeDMax_mm;
elab 0:0e577ce96b2f 3335 LastRangeMeasure.SignalRateRtn_MHz = p_ranging_measurement_data->SignalRateRtn_MHz;
elab 0:0e577ce96b2f 3336 LastRangeMeasure.AmbientRateRtn_MHz = p_ranging_measurement_data->AmbientRateRtn_MHz;
elab 0:0e577ce96b2f 3337 LastRangeMeasure.EffectiveSpadRtnCount = p_ranging_measurement_data->EffectiveSpadRtnCount;
elab 0:0e577ce96b2f 3338 LastRangeMeasure.RangeStatus = p_ranging_measurement_data->RangeStatus;
elab 0:0e577ce96b2f 3339 }
elab 0:0e577ce96b2f 3340
elab 0:0e577ce96b2f 3341 return status;
elab 0:0e577ce96b2f 3342 }
elab 0:0e577ce96b2f 3343
elab 0:0e577ce96b2f 3344 VL53L0X_Error VL53L0X::VL53L0X_perform_single_ranging_measurement(VL53L0X_RangingMeasurementData_t *p_ranging_measurement_data)
elab 0:0e577ce96b2f 3345 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3346
elab 0:0e577ce96b2f 3347 /* This function will do a complete single ranging
elab 0:0e577ce96b2f 3348 * Here we fix the mode! */
elab 0:0e577ce96b2f 3349 CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_SINGLE_RANGING;
elab 0:0e577ce96b2f 3350
elab 0:0e577ce96b2f 3351 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3352 status = VL53L0X_perform_single_measurement(); }
elab 0:0e577ce96b2f 3353
elab 0:0e577ce96b2f 3354 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3355 status = VL53L0X_get_ranging_measurement_data(p_ranging_measurement_data); }
elab 0:0e577ce96b2f 3356
elab 0:0e577ce96b2f 3357 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3358 status = VL53L0X_clear_interrupt_mask( 0);}
elab 0:0e577ce96b2f 3359
elab 0:0e577ce96b2f 3360 return status;
elab 0:0e577ce96b2f 3361 }
elab 0:0e577ce96b2f 3362
elab 0:0e577ce96b2f 3363 VL53L0X_Error VL53L0X::perform_ref_signal_measurement(uint16_t *p_ref_signal_rate)
elab 0:0e577ce96b2f 3364 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3365 VL53L0X_RangingMeasurementData_t ranging_measurement_data;
elab 0:0e577ce96b2f 3366
elab 0:0e577ce96b2f 3367 uint8_t sequence_config = 0;
elab 0:0e577ce96b2f 3368
elab 0:0e577ce96b2f 3369 /* store the value of the sequence config,
elab 0:0e577ce96b2f 3370 * this will be reset before the end of the function*/
elab 0:0e577ce96b2f 3371 sequence_config = Data.SequenceConfig;
elab 0:0e577ce96b2f 3372
elab 0:0e577ce96b2f 3373 /*
elab 0:0e577ce96b2f 3374 * This function performs a reference signal rate measurement.
elab 0:0e577ce96b2f 3375 */
elab 0:0e577ce96b2f 3376 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3377 status = VL53L0X_write_byte(VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0xC0);}
elab 0:0e577ce96b2f 3378
elab 0:0e577ce96b2f 3379 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3380 status = VL53L0X_perform_single_ranging_measurement(&ranging_measurement_data); }
elab 0:0e577ce96b2f 3381
elab 0:0e577ce96b2f 3382 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3383 status = VL53L0X_write_byte( 0xFF, 0x01); }
elab 0:0e577ce96b2f 3384
elab 0:0e577ce96b2f 3385 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3386 status = VL53L0X_read_word(VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF,
elab 0:0e577ce96b2f 3387 p_ref_signal_rate);}
elab 0:0e577ce96b2f 3388
elab 0:0e577ce96b2f 3389 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3390 status = VL53L0X_write_byte( 0xFF, 0x00);}
elab 0:0e577ce96b2f 3391
elab 0:0e577ce96b2f 3392 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3393 /* restore the previous Sequence Config */
elab 0:0e577ce96b2f 3394 status = VL53L0X_write_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG,
elab 0:0e577ce96b2f 3395 sequence_config);
elab 0:0e577ce96b2f 3396 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3397 Data.SequenceConfig = sequence_config;
elab 0:0e577ce96b2f 3398 }
elab 0:0e577ce96b2f 3399 }
elab 0:0e577ce96b2f 3400 return status;
elab 0:0e577ce96b2f 3401 }
elab 0:0e577ce96b2f 3402
elab 0:0e577ce96b2f 3403 VL53L0X_Error VL53L0X::wrapped_VL53L0X_perform_ref_spad_management(uint32_t *ref_spad_count,
elab 0:0e577ce96b2f 3404 uint8_t *is_aperture_spads)
elab 0:0e577ce96b2f 3405 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3406 uint8_t last_spad_array[6];
elab 0:0e577ce96b2f 3407 uint8_t start_select = 0xB4;
elab 0:0e577ce96b2f 3408 uint32_t minimum_spad_count = 3;
elab 0:0e577ce96b2f 3409 uint32_t max_spad_count = 44;
elab 0:0e577ce96b2f 3410 uint32_t current_spad_index = 0;
elab 0:0e577ce96b2f 3411 uint32_t last_spad_index = 0;
elab 0:0e577ce96b2f 3412 int32_t next_good_spad = 0;
elab 0:0e577ce96b2f 3413 uint16_t target_ref_rate = 0x0A00; /* 20 MHz in 9:7 format */
elab 0:0e577ce96b2f 3414 uint16_t peak_signal_rate_ref;
elab 0:0e577ce96b2f 3415 uint32_t need_apt_spads = 0;
elab 0:0e577ce96b2f 3416 uint32_t index = 0;
elab 0:0e577ce96b2f 3417 uint32_t spad_array_size = 6;
elab 0:0e577ce96b2f 3418 uint32_t signal_rate_diff = 0;
elab 0:0e577ce96b2f 3419 uint32_t last_signal_rate_diff = 0;
elab 0:0e577ce96b2f 3420 uint8_t complete = 0;
elab 0:0e577ce96b2f 3421 uint8_t vhv_settings = 0;
elab 0:0e577ce96b2f 3422 uint8_t phase_cal = 0;
elab 0:0e577ce96b2f 3423 uint32_t ref_spad_count_int = 0;
elab 0:0e577ce96b2f 3424 uint8_t is_aperture_spads_int = 0;
elab 0:0e577ce96b2f 3425
elab 0:0e577ce96b2f 3426 /*
elab 0:0e577ce96b2f 3427 * The reference SPAD initialization procedure determines the minimum
elab 0:0e577ce96b2f 3428 * amount of reference spads to be enables to achieve a target reference
elab 0:0e577ce96b2f 3429 * signal rate and should be performed once during initialization.
elab 0:0e577ce96b2f 3430 *
elab 0:0e577ce96b2f 3431 * Either aperture or non-aperture spads are applied but never both.
elab 0:0e577ce96b2f 3432 * Firstly non-aperture spads are set, begining with 5 spads, and
elab 0:0e577ce96b2f 3433 * increased one spad at a time until the closest measurement to the
elab 0:0e577ce96b2f 3434 * target rate is achieved.
elab 0:0e577ce96b2f 3435 *
elab 0:0e577ce96b2f 3436 * If the target rate is exceeded when 5 non-aperture spads are enabled,
elab 0:0e577ce96b2f 3437 * initialization is performed instead with aperture spads.
elab 0:0e577ce96b2f 3438 *
elab 0:0e577ce96b2f 3439 * When setting spads, a 'Good Spad Map' is applied.
elab 0:0e577ce96b2f 3440 *
elab 0:0e577ce96b2f 3441 * This procedure operates within a SPAD window of interest of a maximum
elab 0:0e577ce96b2f 3442 * 44 spads.
elab 0:0e577ce96b2f 3443 * The start point is currently fixed to 180, which lies towards the end
elab 0:0e577ce96b2f 3444 * of the non-aperture quadrant and runs in to the adjacent aperture
elab 0:0e577ce96b2f 3445 * quadrant.
elab 0:0e577ce96b2f 3446 */
elab 0:0e577ce96b2f 3447 target_ref_rate = Data.targetRefRate;
elab 0:0e577ce96b2f 3448
elab 0:0e577ce96b2f 3449 /*
elab 0:0e577ce96b2f 3450 * Initialize Spad arrays.
elab 0:0e577ce96b2f 3451 * Currently the good spad map is initialised to 'All good'.
elab 0:0e577ce96b2f 3452 * This is a short term implementation. The good spad map will be
elab 0:0e577ce96b2f 3453 * provided as an input.
elab 0:0e577ce96b2f 3454 * Note that there are 6 bytes. Only the first 44 bits will be used to
elab 0:0e577ce96b2f 3455 * represent spads.
elab 0:0e577ce96b2f 3456 */
elab 0:0e577ce96b2f 3457 for (index = 0; index < spad_array_size; index++) {
elab 0:0e577ce96b2f 3458 Data.RefSpadEnables[index] = 0;
elab 0:0e577ce96b2f 3459 }
elab 0:0e577ce96b2f 3460
elab 0:0e577ce96b2f 3461 status = VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 3462
elab 0:0e577ce96b2f 3463 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3464 status = VL53L0X_write_byte(VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00);
elab 0:0e577ce96b2f 3465 }
elab 0:0e577ce96b2f 3466
elab 0:0e577ce96b2f 3467 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3468 status = VL53L0X_write_byte(VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C);
elab 0:0e577ce96b2f 3469 }
elab 0:0e577ce96b2f 3470
elab 0:0e577ce96b2f 3471 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3472 status = VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 3473 }
elab 0:0e577ce96b2f 3474
elab 0:0e577ce96b2f 3475 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3476 status = VL53L0X_write_byte(VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT,
elab 0:0e577ce96b2f 3477 start_select);
elab 0:0e577ce96b2f 3478 }
elab 0:0e577ce96b2f 3479
elab 0:0e577ce96b2f 3480 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3481 status = VL53L0X_write_byte(VL53L0X_REG_POWER_MANAGEMENT_GO1_POWER_FORCE, 0);
elab 0:0e577ce96b2f 3482 }
elab 0:0e577ce96b2f 3483
elab 0:0e577ce96b2f 3484 /* Perform ref calibration */
elab 0:0e577ce96b2f 3485 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3486 status = VL53L0X_perform_ref_calibration( &vhv_settings,
elab 0:0e577ce96b2f 3487 &phase_cal, 0);
elab 0:0e577ce96b2f 3488 }
elab 0:0e577ce96b2f 3489
elab 0:0e577ce96b2f 3490 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3491 /* Enable Minimum NON-APERTURE Spads */
elab 0:0e577ce96b2f 3492 current_spad_index = 0;
elab 0:0e577ce96b2f 3493 last_spad_index = current_spad_index;
elab 0:0e577ce96b2f 3494 need_apt_spads = 0;
elab 0:0e577ce96b2f 3495 status = enable_ref_spads(need_apt_spads,
elab 0:0e577ce96b2f 3496 Data.RefGoodSpadMap,
elab 0:0e577ce96b2f 3497 Data.RefSpadEnables,
elab 0:0e577ce96b2f 3498 spad_array_size,
elab 0:0e577ce96b2f 3499 start_select,
elab 0:0e577ce96b2f 3500 current_spad_index,
elab 0:0e577ce96b2f 3501 minimum_spad_count,
elab 0:0e577ce96b2f 3502 &last_spad_index);
elab 0:0e577ce96b2f 3503 }
elab 0:0e577ce96b2f 3504
elab 0:0e577ce96b2f 3505 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3506 current_spad_index = last_spad_index;
elab 0:0e577ce96b2f 3507
elab 0:0e577ce96b2f 3508 status = perform_ref_signal_measurement(&peak_signal_rate_ref);
elab 0:0e577ce96b2f 3509 if ((status == VL53L0X_ERROR_NONE) &&
elab 0:0e577ce96b2f 3510 (peak_signal_rate_ref > target_ref_rate)) {
elab 0:0e577ce96b2f 3511 /* Signal rate measurement too high,
elab 0:0e577ce96b2f 3512 * switch to APERTURE SPADs */
elab 0:0e577ce96b2f 3513
elab 0:0e577ce96b2f 3514 for (index = 0; index < spad_array_size; index++) {
elab 0:0e577ce96b2f 3515 Data.RefSpadEnables[index] = 0;
elab 0:0e577ce96b2f 3516 }
elab 0:0e577ce96b2f 3517
elab 0:0e577ce96b2f 3518 /* Increment to the first APERTURE spad */
elab 0:0e577ce96b2f 3519 while ((is_aperture(start_select + current_spad_index)
elab 0:0e577ce96b2f 3520 == 0) && (current_spad_index < max_spad_count)) {
elab 0:0e577ce96b2f 3521 current_spad_index++;
elab 0:0e577ce96b2f 3522 }
elab 0:0e577ce96b2f 3523
elab 0:0e577ce96b2f 3524 need_apt_spads = 1;
elab 0:0e577ce96b2f 3525
elab 0:0e577ce96b2f 3526 status = enable_ref_spads(need_apt_spads,
elab 0:0e577ce96b2f 3527 Data.RefGoodSpadMap,
elab 0:0e577ce96b2f 3528 Data.RefSpadEnables,
elab 0:0e577ce96b2f 3529 spad_array_size,
elab 0:0e577ce96b2f 3530 start_select,
elab 0:0e577ce96b2f 3531 current_spad_index,
elab 0:0e577ce96b2f 3532 minimum_spad_count,
elab 0:0e577ce96b2f 3533 &last_spad_index);
elab 0:0e577ce96b2f 3534
elab 0:0e577ce96b2f 3535 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3536 current_spad_index = last_spad_index;
elab 0:0e577ce96b2f 3537 status = perform_ref_signal_measurement(&peak_signal_rate_ref);
elab 0:0e577ce96b2f 3538
elab 0:0e577ce96b2f 3539 if ((status == VL53L0X_ERROR_NONE) &&
elab 0:0e577ce96b2f 3540 (peak_signal_rate_ref > target_ref_rate)) {
elab 0:0e577ce96b2f 3541 /* Signal rate still too high after
elab 0:0e577ce96b2f 3542 * setting the minimum number of
elab 0:0e577ce96b2f 3543 * APERTURE spads. Can do no more
elab 0:0e577ce96b2f 3544 * therefore set the min number of
elab 0:0e577ce96b2f 3545 * aperture spads as the result.
elab 0:0e577ce96b2f 3546 */
elab 0:0e577ce96b2f 3547 is_aperture_spads_int = 1;
elab 0:0e577ce96b2f 3548 ref_spad_count_int = minimum_spad_count;
elab 0:0e577ce96b2f 3549 }
elab 0:0e577ce96b2f 3550 }
elab 0:0e577ce96b2f 3551 } else {
elab 0:0e577ce96b2f 3552 need_apt_spads = 0;
elab 0:0e577ce96b2f 3553 }
elab 0:0e577ce96b2f 3554 }
elab 0:0e577ce96b2f 3555
elab 0:0e577ce96b2f 3556 if ((status == VL53L0X_ERROR_NONE) &&
elab 0:0e577ce96b2f 3557 (peak_signal_rate_ref < target_ref_rate)) {
elab 0:0e577ce96b2f 3558 /* At this point, the minimum number of either aperture
elab 0:0e577ce96b2f 3559 * or non-aperture spads have been set. Proceed to add
elab 0:0e577ce96b2f 3560 * spads and perform measurements until the target
elab 0:0e577ce96b2f 3561 * reference is reached.
elab 0:0e577ce96b2f 3562 */
elab 0:0e577ce96b2f 3563 is_aperture_spads_int = need_apt_spads;
elab 0:0e577ce96b2f 3564 ref_spad_count_int = minimum_spad_count;
elab 0:0e577ce96b2f 3565
elab 0:0e577ce96b2f 3566 memcpy(last_spad_array, Data.RefSpadEnables,
elab 0:0e577ce96b2f 3567 spad_array_size);
elab 0:0e577ce96b2f 3568 last_signal_rate_diff = abs(peak_signal_rate_ref -
elab 0:0e577ce96b2f 3569 target_ref_rate);
elab 0:0e577ce96b2f 3570 complete = 0;
elab 0:0e577ce96b2f 3571
elab 0:0e577ce96b2f 3572 while (!complete) {
elab 0:0e577ce96b2f 3573 get_next_good_spad(Data.RefGoodSpadMap,
elab 0:0e577ce96b2f 3574 spad_array_size, current_spad_index,
elab 0:0e577ce96b2f 3575 &next_good_spad);
elab 0:0e577ce96b2f 3576
elab 0:0e577ce96b2f 3577 if (next_good_spad == -1) {
elab 0:0e577ce96b2f 3578 status = VL53L0X_ERROR_REF_SPAD_INIT;
elab 0:0e577ce96b2f 3579 break;
elab 0:0e577ce96b2f 3580 }
elab 0:0e577ce96b2f 3581
elab 0:0e577ce96b2f 3582 /* Cannot combine Aperture and Non-Aperture spads, so
elab 0:0e577ce96b2f 3583 * ensure the current spad is of the correct type.
elab 0:0e577ce96b2f 3584 */
elab 0:0e577ce96b2f 3585 if (is_aperture((uint32_t)start_select + next_good_spad) !=
elab 0:0e577ce96b2f 3586 need_apt_spads) {
elab 0:0e577ce96b2f 3587 /* At this point we have enabled the maximum
elab 0:0e577ce96b2f 3588 * number of Aperture spads.
elab 0:0e577ce96b2f 3589 */
elab 0:0e577ce96b2f 3590 complete = 1;
elab 0:0e577ce96b2f 3591 break;
elab 0:0e577ce96b2f 3592 }
elab 0:0e577ce96b2f 3593
elab 0:0e577ce96b2f 3594 (ref_spad_count_int)++;
elab 0:0e577ce96b2f 3595
elab 0:0e577ce96b2f 3596 current_spad_index = next_good_spad;
elab 0:0e577ce96b2f 3597 status = enable_spad_bit(Data.RefSpadEnables,
elab 0:0e577ce96b2f 3598 spad_array_size, current_spad_index);
elab 0:0e577ce96b2f 3599
elab 0:0e577ce96b2f 3600 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3601 current_spad_index++;
elab 0:0e577ce96b2f 3602 /* Proceed to apply the additional spad and
elab 0:0e577ce96b2f 3603 * perform measurement. */
elab 0:0e577ce96b2f 3604 status = set_ref_spad_map(Data.RefSpadEnables);
elab 0:0e577ce96b2f 3605 }
elab 0:0e577ce96b2f 3606
elab 0:0e577ce96b2f 3607 if (status != VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3608 break;
elab 0:0e577ce96b2f 3609 }
elab 0:0e577ce96b2f 3610
elab 0:0e577ce96b2f 3611 status = perform_ref_signal_measurement(&peak_signal_rate_ref);
elab 0:0e577ce96b2f 3612
elab 0:0e577ce96b2f 3613 if (status != VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3614 break;
elab 0:0e577ce96b2f 3615 }
elab 0:0e577ce96b2f 3616
elab 0:0e577ce96b2f 3617 signal_rate_diff = abs(peak_signal_rate_ref - target_ref_rate);
elab 0:0e577ce96b2f 3618
elab 0:0e577ce96b2f 3619 if (peak_signal_rate_ref > target_ref_rate) {
elab 0:0e577ce96b2f 3620 /* Select the spad map that provides the
elab 0:0e577ce96b2f 3621 * measurement closest to the target rate,
elab 0:0e577ce96b2f 3622 * either above or below it.
elab 0:0e577ce96b2f 3623 */
elab 0:0e577ce96b2f 3624 if (signal_rate_diff > last_signal_rate_diff) {
elab 0:0e577ce96b2f 3625 /* Previous spad map produced a closer
elab 0:0e577ce96b2f 3626 * measurement, so choose this. */
elab 0:0e577ce96b2f 3627 status = set_ref_spad_map(last_spad_array);
elab 0:0e577ce96b2f 3628 memcpy(Data.RefSpadEnables,
elab 0:0e577ce96b2f 3629 last_spad_array, spad_array_size);
elab 0:0e577ce96b2f 3630 (ref_spad_count_int)--;
elab 0:0e577ce96b2f 3631 }
elab 0:0e577ce96b2f 3632 complete = 1;
elab 0:0e577ce96b2f 3633 } else {
elab 0:0e577ce96b2f 3634 /* Continue to add spads */
elab 0:0e577ce96b2f 3635 last_signal_rate_diff = signal_rate_diff;
elab 0:0e577ce96b2f 3636 memcpy(last_spad_array,
elab 0:0e577ce96b2f 3637 Data.RefSpadEnables,
elab 0:0e577ce96b2f 3638 spad_array_size);
elab 0:0e577ce96b2f 3639 }
elab 0:0e577ce96b2f 3640
elab 0:0e577ce96b2f 3641 } /* while */
elab 0:0e577ce96b2f 3642 }
elab 0:0e577ce96b2f 3643
elab 0:0e577ce96b2f 3644 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3645 *ref_spad_count = ref_spad_count_int;
elab 0:0e577ce96b2f 3646 *is_aperture_spads = is_aperture_spads_int;
elab 0:0e577ce96b2f 3647 Data.RefSpadsInitialised = 1;
elab 0:0e577ce96b2f 3648 Data.ReferenceSpadCount = (uint8_t)(*ref_spad_count);
elab 0:0e577ce96b2f 3649 Data.ReferenceSpadType = *is_aperture_spads;
elab 0:0e577ce96b2f 3650 }
elab 0:0e577ce96b2f 3651
elab 0:0e577ce96b2f 3652 return status;
elab 0:0e577ce96b2f 3653 }
elab 0:0e577ce96b2f 3654
elab 0:0e577ce96b2f 3655 VL53L0X_Error VL53L0X::VL53L0X_set_reference_spads(uint32_t count, uint8_t is_aperture_spads)
elab 0:0e577ce96b2f 3656 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3657 uint32_t current_spad_index = 0;
elab 0:0e577ce96b2f 3658 uint8_t start_select = 0xB4;
elab 0:0e577ce96b2f 3659 uint32_t spad_array_size = 6;
elab 0:0e577ce96b2f 3660 uint32_t max_spad_count = 44;
elab 0:0e577ce96b2f 3661 uint32_t last_spad_index;
elab 0:0e577ce96b2f 3662 uint32_t index;
elab 0:0e577ce96b2f 3663
elab 0:0e577ce96b2f 3664 /*
elab 0:0e577ce96b2f 3665 * This function applies a requested number of reference spads, either
elab 0:0e577ce96b2f 3666 * aperture or
elab 0:0e577ce96b2f 3667 * non-aperture, as requested.
elab 0:0e577ce96b2f 3668 * The good spad map will be applied.
elab 0:0e577ce96b2f 3669 */
elab 0:0e577ce96b2f 3670
elab 0:0e577ce96b2f 3671 status = VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 3672
elab 0:0e577ce96b2f 3673 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3674 status = VL53L0X_write_byte(VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00);
elab 0:0e577ce96b2f 3675 }
elab 0:0e577ce96b2f 3676
elab 0:0e577ce96b2f 3677 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3678 status = VL53L0X_write_byte( VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C);
elab 0:0e577ce96b2f 3679 }
elab 0:0e577ce96b2f 3680
elab 0:0e577ce96b2f 3681 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3682 status = VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 3683 }
elab 0:0e577ce96b2f 3684
elab 0:0e577ce96b2f 3685 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3686 status = VL53L0X_write_byte(VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT,
elab 0:0e577ce96b2f 3687 start_select);
elab 0:0e577ce96b2f 3688 }
elab 0:0e577ce96b2f 3689
elab 0:0e577ce96b2f 3690 for (index = 0; index < spad_array_size; index++) {
elab 0:0e577ce96b2f 3691 Data.RefSpadEnables[index] = 0;
elab 0:0e577ce96b2f 3692 }
elab 0:0e577ce96b2f 3693
elab 0:0e577ce96b2f 3694 if (is_aperture_spads) {
elab 0:0e577ce96b2f 3695 /* Increment to the first APERTURE spad */
elab 0:0e577ce96b2f 3696 while ((is_aperture(start_select + current_spad_index) == 0) &&
elab 0:0e577ce96b2f 3697 (current_spad_index < max_spad_count)) {
elab 0:0e577ce96b2f 3698 current_spad_index++;
elab 0:0e577ce96b2f 3699 }
elab 0:0e577ce96b2f 3700 }
elab 0:0e577ce96b2f 3701 status = enable_ref_spads(is_aperture_spads,
elab 0:0e577ce96b2f 3702 Data.RefGoodSpadMap,
elab 0:0e577ce96b2f 3703 Data.RefSpadEnables,
elab 0:0e577ce96b2f 3704 spad_array_size,
elab 0:0e577ce96b2f 3705 start_select,
elab 0:0e577ce96b2f 3706 current_spad_index,
elab 0:0e577ce96b2f 3707 count,
elab 0:0e577ce96b2f 3708 &last_spad_index);
elab 0:0e577ce96b2f 3709
elab 0:0e577ce96b2f 3710 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3711 Data.RefSpadsInitialised = 1;
elab 0:0e577ce96b2f 3712 Data.ReferenceSpadCount = (uint8_t)(count);
elab 0:0e577ce96b2f 3713 Data.ReferenceSpadType = is_aperture_spads;
elab 0:0e577ce96b2f 3714 }
elab 0:0e577ce96b2f 3715
elab 0:0e577ce96b2f 3716 return status;
elab 0:0e577ce96b2f 3717 }
elab 0:0e577ce96b2f 3718
elab 0:0e577ce96b2f 3719 VL53L0X_Error VL53L0X::VL53L0X_perform_ref_calibration( uint8_t *p_vhv_settings,
elab 0:0e577ce96b2f 3720 uint8_t *p_phase_cal)
elab 0:0e577ce96b2f 3721 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3722
elab 0:0e577ce96b2f 3723 status = VL53L0X_perform_ref_calibration( p_vhv_settings, p_phase_cal, 1);
elab 0:0e577ce96b2f 3724
elab 0:0e577ce96b2f 3725 return status;
elab 0:0e577ce96b2f 3726 }
elab 0:0e577ce96b2f 3727
elab 0:0e577ce96b2f 3728 VL53L0X_Error VL53L0X::VL53L0X_perform_ref_spad_management(uint32_t *ref_spad_count, uint8_t *is_aperture_spads)
elab 0:0e577ce96b2f 3729 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3730
elab 0:0e577ce96b2f 3731 status = wrapped_VL53L0X_perform_ref_spad_management( ref_spad_count,
elab 0:0e577ce96b2f 3732 is_aperture_spads);
elab 0:0e577ce96b2f 3733
elab 0:0e577ce96b2f 3734 return status;
elab 0:0e577ce96b2f 3735 }
elab 0:0e577ce96b2f 3736
elab 0:0e577ce96b2f 3737 /* Group PAL Init Functions */
elab 0:0e577ce96b2f 3738 VL53L0X_Error VL53L0X::VL53L0X_set_device_address( uint8_t device_address)
elab 0:0e577ce96b2f 3739 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3740
elab 0:0e577ce96b2f 3741 status = VL53L0X_write_byte( VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS,
elab 0:0e577ce96b2f 3742 device_address / 2);
elab 0:0e577ce96b2f 3743 return status;
elab 0:0e577ce96b2f 3744 }
elab 0:0e577ce96b2f 3745
elab 0:0e577ce96b2f 3746 VL53L0X_Error VL53L0X::VL53L0X_set_gpio_config( uint8_t pin,
elab 0:0e577ce96b2f 3747 VL53L0X_DeviceModes device_mode, VL53L0X_GpioFunctionality functionality,
elab 0:0e577ce96b2f 3748 VL53L0X_InterruptPolarity polarity)
elab 0:0e577ce96b2f 3749 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3750 uint8_t data;
elab 0:0e577ce96b2f 3751
elab 0:0e577ce96b2f 3752 if (pin != 0) {
elab 0:0e577ce96b2f 3753 status = VL53L0X_ERROR_GPIO_NOT_EXISTING;
elab 0:0e577ce96b2f 3754 } else if (device_mode == VL53L0X_DEVICEMODE_GPIO_DRIVE) {
elab 0:0e577ce96b2f 3755 if (polarity == VL53L0X_INTERRUPTPOLARITY_LOW) {
elab 0:0e577ce96b2f 3756 data = 0x10;
elab 0:0e577ce96b2f 3757 } else {data = 1;}
elab 0:0e577ce96b2f 3758
elab 0:0e577ce96b2f 3759 status = VL53L0X_write_byte(VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, data);
elab 0:0e577ce96b2f 3760
elab 0:0e577ce96b2f 3761 } else {
elab 0:0e577ce96b2f 3762 if (device_mode == VL53L0X_DEVICEMODE_GPIO_OSC) {
elab 0:0e577ce96b2f 3763
elab 0:0e577ce96b2f 3764 status |= VL53L0X_write_byte( 0xff, 0x01);
elab 0:0e577ce96b2f 3765 status |= VL53L0X_write_byte( 0x00, 0x00);
elab 0:0e577ce96b2f 3766 status |= VL53L0X_write_byte( 0xff, 0x00);
elab 0:0e577ce96b2f 3767 status |= VL53L0X_write_byte( 0x80, 0x01);
elab 0:0e577ce96b2f 3768 status |= VL53L0X_write_byte( 0x85, 0x02);
elab 0:0e577ce96b2f 3769 status |= VL53L0X_write_byte( 0xff, 0x04);
elab 0:0e577ce96b2f 3770 status |= VL53L0X_write_byte( 0xcd, 0x00);
elab 0:0e577ce96b2f 3771 status |= VL53L0X_write_byte( 0xcc, 0x11);
elab 0:0e577ce96b2f 3772 status |= VL53L0X_write_byte( 0xff, 0x07);
elab 0:0e577ce96b2f 3773 status |= VL53L0X_write_byte( 0xbe, 0x00);
elab 0:0e577ce96b2f 3774 status |= VL53L0X_write_byte( 0xff, 0x06);
elab 0:0e577ce96b2f 3775 status |= VL53L0X_write_byte( 0xcc, 0x09);
elab 0:0e577ce96b2f 3776 status |= VL53L0X_write_byte( 0xff, 0x00);
elab 0:0e577ce96b2f 3777 status |= VL53L0X_write_byte( 0xff, 0x01);
elab 0:0e577ce96b2f 3778 status |= VL53L0X_write_byte( 0x00, 0x00);
elab 0:0e577ce96b2f 3779
elab 0:0e577ce96b2f 3780 } else {
elab 0:0e577ce96b2f 3781
elab 0:0e577ce96b2f 3782 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3783 switch (functionality) {
elab 0:0e577ce96b2f 3784 case VL53L0X_GPIOFUNCTIONALITY_OFF:
elab 0:0e577ce96b2f 3785 data = 0x00;
elab 0:0e577ce96b2f 3786 break;
elab 0:0e577ce96b2f 3787 case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW:
elab 0:0e577ce96b2f 3788 data = 0x01;
elab 0:0e577ce96b2f 3789 break;
elab 0:0e577ce96b2f 3790 case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH:
elab 0:0e577ce96b2f 3791 data = 0x02;
elab 0:0e577ce96b2f 3792 break;
elab 0:0e577ce96b2f 3793 case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT:
elab 0:0e577ce96b2f 3794 data = 0x03;
elab 0:0e577ce96b2f 3795 break;
elab 0:0e577ce96b2f 3796 case VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY:
elab 0:0e577ce96b2f 3797 data = 0x04;
elab 0:0e577ce96b2f 3798 break;
elab 0:0e577ce96b2f 3799 default:
elab 0:0e577ce96b2f 3800 status = VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED;
elab 0:0e577ce96b2f 3801 }
elab 0:0e577ce96b2f 3802 }
elab 0:0e577ce96b2f 3803
elab 0:0e577ce96b2f 3804 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3805 status = VL53L0X_write_byte(VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, data);
elab 0:0e577ce96b2f 3806 }
elab 0:0e577ce96b2f 3807
elab 0:0e577ce96b2f 3808 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3809 if (polarity == VL53L0X_INTERRUPTPOLARITY_LOW) {
elab 0:0e577ce96b2f 3810 data = 0;
elab 0:0e577ce96b2f 3811 } else { data = (uint8_t)(1 << 4); }
elab 0:0e577ce96b2f 3812 status = VL53L0X_update_byte(VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, 0xEF, data);
elab 0:0e577ce96b2f 3813 }
elab 0:0e577ce96b2f 3814
elab 0:0e577ce96b2f 3815 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3816 Data.Pin0GpioFunctionality = functionality; }
elab 0:0e577ce96b2f 3817
elab 0:0e577ce96b2f 3818 if (status == VL53L0X_ERROR_NONE) { status = VL53L0X_clear_interrupt_mask( 0); }
elab 0:0e577ce96b2f 3819 }
elab 0:0e577ce96b2f 3820 }
elab 0:0e577ce96b2f 3821 return status;
elab 0:0e577ce96b2f 3822 }
elab 0:0e577ce96b2f 3823
elab 0:0e577ce96b2f 3824 VL53L0X_Error VL53L0X::VL53L0X_get_fraction_enable( uint8_t *p_enabled)
elab 0:0e577ce96b2f 3825 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3826 status = VL53L0X_read_byte( VL53L0X_REG_SYSTEM_RANGE_CONFIG, p_enabled);
elab 0:0e577ce96b2f 3827 if (status == VL53L0X_ERROR_NONE) { *p_enabled = (*p_enabled & 1); }
elab 0:0e577ce96b2f 3828 return status;
elab 0:0e577ce96b2f 3829 }
elab 0:0e577ce96b2f 3830
elab 0:0e577ce96b2f 3831 uint16_t VL53L0X::VL53L0X_encode_timeout(uint32_t timeout_macro_clks)
elab 0:0e577ce96b2f 3832 { /*!Encode timeout in macro periods in (LSByte * 2^MSByte) + 1 format*/
elab 0:0e577ce96b2f 3833
elab 0:0e577ce96b2f 3834 uint16_t encoded_timeout = 0;
elab 0:0e577ce96b2f 3835 uint32_t ls_byte = 0;
elab 0:0e577ce96b2f 3836 uint16_t ms_byte = 0;
elab 0:0e577ce96b2f 3837
elab 0:0e577ce96b2f 3838 if (timeout_macro_clks > 0) {
elab 0:0e577ce96b2f 3839 ls_byte = timeout_macro_clks - 1;
elab 0:0e577ce96b2f 3840
elab 0:0e577ce96b2f 3841 while ((ls_byte & 0xFFFFFF00) > 0) {
elab 0:0e577ce96b2f 3842 ls_byte = ls_byte >> 1;
elab 0:0e577ce96b2f 3843 ms_byte++;
elab 0:0e577ce96b2f 3844 }
elab 0:0e577ce96b2f 3845 encoded_timeout = (ms_byte << 8) + (uint16_t)(ls_byte & 0x000000FF);
elab 0:0e577ce96b2f 3846 }
elab 0:0e577ce96b2f 3847 return encoded_timeout;
elab 0:0e577ce96b2f 3848 }
elab 0:0e577ce96b2f 3849
elab 0:0e577ce96b2f 3850 VL53L0X_Error VL53L0X::set_sequence_step_timeout(VL53L0X_SequenceStepId sequence_step_id,
elab 0:0e577ce96b2f 3851 uint32_t timeout_micro_secs)
elab 0:0e577ce96b2f 3852 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3853 uint8_t current_vcsel_pulse_period_p_clk;
elab 0:0e577ce96b2f 3854 uint8_t msrc_encoded_time_out;
elab 0:0e577ce96b2f 3855 uint16_t pre_range_encoded_time_out;
elab 0:0e577ce96b2f 3856 uint16_t pre_range_time_out_m_clks;
elab 0:0e577ce96b2f 3857 uint16_t msrc_range_time_out_m_clks;
elab 0:0e577ce96b2f 3858 uint32_t final_range_time_out_m_clks;
elab 0:0e577ce96b2f 3859 uint16_t final_range_encoded_time_out;
elab 0:0e577ce96b2f 3860 VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps;
elab 0:0e577ce96b2f 3861
elab 0:0e577ce96b2f 3862 if ((sequence_step_id == VL53L0X_SEQUENCESTEP_TCC) ||
elab 0:0e577ce96b2f 3863 (sequence_step_id == VL53L0X_SEQUENCESTEP_DSS) ||
elab 0:0e577ce96b2f 3864 (sequence_step_id == VL53L0X_SEQUENCESTEP_MSRC)) {
elab 0:0e577ce96b2f 3865
elab 0:0e577ce96b2f 3866 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE,
elab 0:0e577ce96b2f 3867 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 3868
elab 0:0e577ce96b2f 3869 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3870 msrc_range_time_out_m_clks = VL53L0X_calc_timeout_mclks(timeout_micro_secs,
elab 0:0e577ce96b2f 3871 (uint8_t)current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 3872
elab 0:0e577ce96b2f 3873 if (msrc_range_time_out_m_clks > 256) {
elab 0:0e577ce96b2f 3874 msrc_encoded_time_out = 255;
elab 0:0e577ce96b2f 3875 } else {
elab 0:0e577ce96b2f 3876 msrc_encoded_time_out =
elab 0:0e577ce96b2f 3877 (uint8_t)msrc_range_time_out_m_clks - 1;
elab 0:0e577ce96b2f 3878 }
elab 0:0e577ce96b2f 3879 Data.LastEncodedTimeout = msrc_encoded_time_out;
elab 0:0e577ce96b2f 3880 }
elab 0:0e577ce96b2f 3881
elab 0:0e577ce96b2f 3882 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3883 status = VL53L0X_write_byte(VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP,
elab 0:0e577ce96b2f 3884 msrc_encoded_time_out);
elab 0:0e577ce96b2f 3885 }
elab 0:0e577ce96b2f 3886 } else {
elab 0:0e577ce96b2f 3887
elab 0:0e577ce96b2f 3888 if (sequence_step_id == VL53L0X_SEQUENCESTEP_PRE_RANGE) {
elab 0:0e577ce96b2f 3889
elab 0:0e577ce96b2f 3890 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3891 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE,
elab 0:0e577ce96b2f 3892 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 3893 pre_range_time_out_m_clks =
elab 0:0e577ce96b2f 3894 VL53L0X_calc_timeout_mclks(timeout_micro_secs,
elab 0:0e577ce96b2f 3895 (uint8_t)current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 3896 pre_range_encoded_time_out = VL53L0X_encode_timeout(pre_range_time_out_m_clks);
elab 0:0e577ce96b2f 3897 Data.LastEncodedTimeout = pre_range_encoded_time_out;
elab 0:0e577ce96b2f 3898 }
elab 0:0e577ce96b2f 3899
elab 0:0e577ce96b2f 3900 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3901 status = VL53L0X_write_word(VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI,
elab 0:0e577ce96b2f 3902 pre_range_encoded_time_out);
elab 0:0e577ce96b2f 3903 }
elab 0:0e577ce96b2f 3904
elab 0:0e577ce96b2f 3905 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3906 Data.PreRangeTimeout_us = timeout_micro_secs;
elab 0:0e577ce96b2f 3907 }
elab 0:0e577ce96b2f 3908 } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_FINAL_RANGE) {
elab 0:0e577ce96b2f 3909
elab 0:0e577ce96b2f 3910 /* For the final range timeout, the pre-range timeout
elab 0:0e577ce96b2f 3911 * must be added. To do this both final and pre-range
elab 0:0e577ce96b2f 3912 * timeouts must be expressed in macro periods MClks
elab 0:0e577ce96b2f 3913 * because they have different vcsel periods. */
elab 0:0e577ce96b2f 3914
elab 0:0e577ce96b2f 3915 VL53L0X_get_sequence_step_enables(&scheduler_sequence_steps);
elab 0:0e577ce96b2f 3916 pre_range_time_out_m_clks = 0;
elab 0:0e577ce96b2f 3917 if (scheduler_sequence_steps.PreRangeOn) {
elab 0:0e577ce96b2f 3918
elab 0:0e577ce96b2f 3919 /* Retrieve PRE-RANGE VCSEL Period */
elab 0:0e577ce96b2f 3920 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE,
elab 0:0e577ce96b2f 3921 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 3922
elab 0:0e577ce96b2f 3923 /* Retrieve PRE-RANGE Timeout in Macro periods
elab 0:0e577ce96b2f 3924 * (MCLKS) */
elab 0:0e577ce96b2f 3925 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3926 status = VL53L0X_read_word( 0x51, &pre_range_encoded_time_out);
elab 0:0e577ce96b2f 3927 pre_range_time_out_m_clks =
elab 0:0e577ce96b2f 3928 VL53L0X_decode_timeout( pre_range_encoded_time_out);
elab 0:0e577ce96b2f 3929 }
elab 0:0e577ce96b2f 3930 }
elab 0:0e577ce96b2f 3931
elab 0:0e577ce96b2f 3932 /* Calculate FINAL RANGE Timeout in Macro Periods
elab 0:0e577ce96b2f 3933 * (MCLKS) and add PRE-RANGE value
elab 0:0e577ce96b2f 3934 */
elab 0:0e577ce96b2f 3935 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3936 status = VL53L0X_get_vcsel_pulse_period( VL53L0X_VCSEL_PERIOD_FINAL_RANGE,
elab 0:0e577ce96b2f 3937 &current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 3938 }
elab 0:0e577ce96b2f 3939 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3940 final_range_time_out_m_clks =
elab 0:0e577ce96b2f 3941 VL53L0X_calc_timeout_mclks( timeout_micro_secs,
elab 0:0e577ce96b2f 3942 (uint8_t) current_vcsel_pulse_period_p_clk);
elab 0:0e577ce96b2f 3943
elab 0:0e577ce96b2f 3944 final_range_time_out_m_clks += pre_range_time_out_m_clks;
elab 0:0e577ce96b2f 3945 final_range_encoded_time_out =
elab 0:0e577ce96b2f 3946 VL53L0X_encode_timeout(final_range_time_out_m_clks);
elab 0:0e577ce96b2f 3947
elab 0:0e577ce96b2f 3948 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3949 status = VL53L0X_write_word( 0x71, final_range_encoded_time_out);
elab 0:0e577ce96b2f 3950 }
elab 0:0e577ce96b2f 3951
elab 0:0e577ce96b2f 3952 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 3953 Data.FinalRangeTimeout_us = timeout_micro_secs;
elab 0:0e577ce96b2f 3954 }
elab 0:0e577ce96b2f 3955 }
elab 0:0e577ce96b2f 3956 } else {
elab 0:0e577ce96b2f 3957 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 3958 }
elab 0:0e577ce96b2f 3959 }
elab 0:0e577ce96b2f 3960 return status;
elab 0:0e577ce96b2f 3961 }
elab 0:0e577ce96b2f 3962
elab 0:0e577ce96b2f 3963 VL53L0X_Error VL53L0X::wrapped_VL53L0X_set_measurement_timing_budget_us(uint32_t measurement_timing_budget_us)
elab 0:0e577ce96b2f 3964 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 3965 uint32_t final_range_timing_budget_us;
elab 0:0e577ce96b2f 3966 VL53L0X_SchedulerSequenceSteps_t scheduler_sequence_steps;
elab 0:0e577ce96b2f 3967 uint32_t msrc_dcc_tcc_timeout_us = 2000;
elab 0:0e577ce96b2f 3968 uint32_t start_overhead_us = 1910;
elab 0:0e577ce96b2f 3969 uint32_t end_overhead_us = 960;
elab 0:0e577ce96b2f 3970 uint32_t msrc_overhead_us = 660;
elab 0:0e577ce96b2f 3971 uint32_t tcc_overhead_us = 590;
elab 0:0e577ce96b2f 3972 uint32_t dss_overhead_us = 690;
elab 0:0e577ce96b2f 3973 uint32_t pre_range_overhead_us = 660;
elab 0:0e577ce96b2f 3974 uint32_t final_range_overhead_us = 550;
elab 0:0e577ce96b2f 3975 uint32_t pre_range_timeout_us = 0;
elab 0:0e577ce96b2f 3976 uint32_t c_min_timing_budget_us = 20000;
elab 0:0e577ce96b2f 3977 uint32_t sub_timeout = 0;
elab 0:0e577ce96b2f 3978
elab 0:0e577ce96b2f 3979 if (measurement_timing_budget_us < c_min_timing_budget_us)
elab 0:0e577ce96b2f 3980 { status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 3981 return status;
elab 0:0e577ce96b2f 3982 }
elab 0:0e577ce96b2f 3983
elab 0:0e577ce96b2f 3984 final_range_timing_budget_us =
elab 0:0e577ce96b2f 3985 measurement_timing_budget_us - (start_overhead_us + end_overhead_us);
elab 0:0e577ce96b2f 3986
elab 0:0e577ce96b2f 3987 status = VL53L0X_get_sequence_step_enables( &scheduler_sequence_steps);
elab 0:0e577ce96b2f 3988
elab 0:0e577ce96b2f 3989 if (status == VL53L0X_ERROR_NONE &&
elab 0:0e577ce96b2f 3990 (scheduler_sequence_steps.TccOn ||
elab 0:0e577ce96b2f 3991 scheduler_sequence_steps.MsrcOn ||
elab 0:0e577ce96b2f 3992 scheduler_sequence_steps.DssOn)) {
elab 0:0e577ce96b2f 3993
elab 0:0e577ce96b2f 3994 /* TCC, MSRC and DSS all share the same timeout */
elab 0:0e577ce96b2f 3995 status = get_sequence_step_timeout( VL53L0X_SEQUENCESTEP_MSRC,
elab 0:0e577ce96b2f 3996 &msrc_dcc_tcc_timeout_us);
elab 0:0e577ce96b2f 3997
elab 0:0e577ce96b2f 3998 /* Subtract the TCC, MSRC and DSS timeouts if they are
elab 0:0e577ce96b2f 3999 * enabled. */
elab 0:0e577ce96b2f 4000
elab 0:0e577ce96b2f 4001 if (status != VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4002 return status;
elab 0:0e577ce96b2f 4003 }
elab 0:0e577ce96b2f 4004
elab 0:0e577ce96b2f 4005 /* TCC */
elab 0:0e577ce96b2f 4006 if (scheduler_sequence_steps.TccOn) {
elab 0:0e577ce96b2f 4007
elab 0:0e577ce96b2f 4008 sub_timeout = msrc_dcc_tcc_timeout_us
elab 0:0e577ce96b2f 4009 + tcc_overhead_us;
elab 0:0e577ce96b2f 4010
elab 0:0e577ce96b2f 4011 if (sub_timeout <
elab 0:0e577ce96b2f 4012 final_range_timing_budget_us) {
elab 0:0e577ce96b2f 4013 final_range_timing_budget_us -=
elab 0:0e577ce96b2f 4014 sub_timeout;
elab 0:0e577ce96b2f 4015 } else {
elab 0:0e577ce96b2f 4016 /* Requested timeout too big. */
elab 0:0e577ce96b2f 4017 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 4018 }
elab 0:0e577ce96b2f 4019 }
elab 0:0e577ce96b2f 4020
elab 0:0e577ce96b2f 4021 if (status != VL53L0X_ERROR_NONE) {return status;}
elab 0:0e577ce96b2f 4022
elab 0:0e577ce96b2f 4023 /* DSS */
elab 0:0e577ce96b2f 4024 if (scheduler_sequence_steps.DssOn) {
elab 0:0e577ce96b2f 4025
elab 0:0e577ce96b2f 4026 sub_timeout = 2 * (msrc_dcc_tcc_timeout_us +
elab 0:0e577ce96b2f 4027 dss_overhead_us);
elab 0:0e577ce96b2f 4028
elab 0:0e577ce96b2f 4029 if (sub_timeout < final_range_timing_budget_us) {
elab 0:0e577ce96b2f 4030 final_range_timing_budget_us
elab 0:0e577ce96b2f 4031 -= sub_timeout;
elab 0:0e577ce96b2f 4032 } else {
elab 0:0e577ce96b2f 4033 /* Requested timeout too big. */
elab 0:0e577ce96b2f 4034 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 4035 }
elab 0:0e577ce96b2f 4036 } else if (scheduler_sequence_steps.MsrcOn) {
elab 0:0e577ce96b2f 4037 /* MSRC */
elab 0:0e577ce96b2f 4038 sub_timeout = msrc_dcc_tcc_timeout_us +
elab 0:0e577ce96b2f 4039 msrc_overhead_us;
elab 0:0e577ce96b2f 4040
elab 0:0e577ce96b2f 4041 if (sub_timeout < final_range_timing_budget_us) {
elab 0:0e577ce96b2f 4042 final_range_timing_budget_us
elab 0:0e577ce96b2f 4043 -= sub_timeout;
elab 0:0e577ce96b2f 4044 } else {
elab 0:0e577ce96b2f 4045 /* Requested timeout too big. */
elab 0:0e577ce96b2f 4046 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 4047 }
elab 0:0e577ce96b2f 4048 }
elab 0:0e577ce96b2f 4049 }
elab 0:0e577ce96b2f 4050
elab 0:0e577ce96b2f 4051 if (status != VL53L0X_ERROR_NONE) { return status; }
elab 0:0e577ce96b2f 4052
elab 0:0e577ce96b2f 4053 if (scheduler_sequence_steps.PreRangeOn) {
elab 0:0e577ce96b2f 4054
elab 0:0e577ce96b2f 4055 /* Subtract the Pre-range timeout if enabled. */
elab 0:0e577ce96b2f 4056
elab 0:0e577ce96b2f 4057 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE,
elab 0:0e577ce96b2f 4058 &pre_range_timeout_us);
elab 0:0e577ce96b2f 4059
elab 0:0e577ce96b2f 4060 sub_timeout = pre_range_timeout_us +
elab 0:0e577ce96b2f 4061 pre_range_overhead_us;
elab 0:0e577ce96b2f 4062
elab 0:0e577ce96b2f 4063 if (sub_timeout < final_range_timing_budget_us) {
elab 0:0e577ce96b2f 4064 final_range_timing_budget_us -= sub_timeout;
elab 0:0e577ce96b2f 4065 } else {
elab 0:0e577ce96b2f 4066 /* Requested timeout too big. */
elab 0:0e577ce96b2f 4067 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 4068 }
elab 0:0e577ce96b2f 4069 }
elab 0:0e577ce96b2f 4070
elab 0:0e577ce96b2f 4071 if (status == VL53L0X_ERROR_NONE &&
elab 0:0e577ce96b2f 4072 scheduler_sequence_steps.FinalRangeOn) {
elab 0:0e577ce96b2f 4073
elab 0:0e577ce96b2f 4074 final_range_timing_budget_us -=
elab 0:0e577ce96b2f 4075 final_range_overhead_us;
elab 0:0e577ce96b2f 4076
elab 0:0e577ce96b2f 4077 /* Final Range Timeout
elab 0:0e577ce96b2f 4078 * Note that the final range timeout is determined by the timing
elab 0:0e577ce96b2f 4079 * budget and the sum of all other timeouts within the sequence.
elab 0:0e577ce96b2f 4080 * If there is no room for the final range timeout, then an error
elab 0:0e577ce96b2f 4081 * will be set. Otherwise the remaining time will be applied to
elab 0:0e577ce96b2f 4082 * the final range.
elab 0:0e577ce96b2f 4083 */
elab 0:0e577ce96b2f 4084 status = set_sequence_step_timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE,
elab 0:0e577ce96b2f 4085 final_range_timing_budget_us);
elab 0:0e577ce96b2f 4086 CurrentParameters.MeasurementTimingBudget_us = measurement_timing_budget_us;
elab 0:0e577ce96b2f 4087 }
elab 0:0e577ce96b2f 4088
elab 0:0e577ce96b2f 4089 return status;
elab 0:0e577ce96b2f 4090 }
elab 0:0e577ce96b2f 4091
elab 0:0e577ce96b2f 4092 VL53L0X_Error VL53L0X::VL53L0X_set_measurement_timing_budget_us(uint32_t measurement_timing_budget_us)
elab 0:0e577ce96b2f 4093 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 4094 status = wrapped_VL53L0X_set_measurement_timing_budget_us(measurement_timing_budget_us);
elab 0:0e577ce96b2f 4095 return status;
elab 0:0e577ce96b2f 4096 }
elab 0:0e577ce96b2f 4097
elab 0:0e577ce96b2f 4098 VL53L0X_Error VL53L0X::VL53L0X_set_sequence_step_enable(VL53L0X_SequenceStepId sequence_step_id, uint8_t sequence_step_enabled)
elab 0:0e577ce96b2f 4099 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 4100 uint8_t sequence_config = 0;
elab 0:0e577ce96b2f 4101 uint8_t sequence_config_new = 0;
elab 0:0e577ce96b2f 4102 uint32_t measurement_timing_budget_us;
elab 0:0e577ce96b2f 4103
elab 0:0e577ce96b2f 4104 status = VL53L0X_read_byte( VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &sequence_config);
elab 0:0e577ce96b2f 4105
elab 0:0e577ce96b2f 4106 sequence_config_new = sequence_config;
elab 0:0e577ce96b2f 4107
elab 0:0e577ce96b2f 4108 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4109 if (sequence_step_enabled == 1) {
elab 0:0e577ce96b2f 4110
elab 0:0e577ce96b2f 4111 /* Enable requested sequence step
elab 0:0e577ce96b2f 4112 */
elab 0:0e577ce96b2f 4113 switch (sequence_step_id) {
elab 0:0e577ce96b2f 4114 case VL53L0X_SEQUENCESTEP_TCC:
elab 0:0e577ce96b2f 4115 sequence_config_new |= 0x10;
elab 0:0e577ce96b2f 4116 break;
elab 0:0e577ce96b2f 4117 case VL53L0X_SEQUENCESTEP_DSS:
elab 0:0e577ce96b2f 4118 sequence_config_new |= 0x28;
elab 0:0e577ce96b2f 4119 break;
elab 0:0e577ce96b2f 4120 case VL53L0X_SEQUENCESTEP_MSRC:
elab 0:0e577ce96b2f 4121 sequence_config_new |= 0x04;
elab 0:0e577ce96b2f 4122 break;
elab 0:0e577ce96b2f 4123 case VL53L0X_SEQUENCESTEP_PRE_RANGE:
elab 0:0e577ce96b2f 4124 sequence_config_new |= 0x40;
elab 0:0e577ce96b2f 4125 break;
elab 0:0e577ce96b2f 4126 case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
elab 0:0e577ce96b2f 4127 sequence_config_new |= 0x80;
elab 0:0e577ce96b2f 4128 break;
elab 0:0e577ce96b2f 4129 default:
elab 0:0e577ce96b2f 4130 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 4131 }
elab 0:0e577ce96b2f 4132 } else {
elab 0:0e577ce96b2f 4133 /* Disable requested sequence step */
elab 0:0e577ce96b2f 4134 switch (sequence_step_id) {
elab 0:0e577ce96b2f 4135 case VL53L0X_SEQUENCESTEP_TCC:
elab 0:0e577ce96b2f 4136 sequence_config_new &= 0xef;
elab 0:0e577ce96b2f 4137 break;
elab 0:0e577ce96b2f 4138 case VL53L0X_SEQUENCESTEP_DSS:
elab 0:0e577ce96b2f 4139 sequence_config_new &= 0xd7;
elab 0:0e577ce96b2f 4140 break;
elab 0:0e577ce96b2f 4141 case VL53L0X_SEQUENCESTEP_MSRC:
elab 0:0e577ce96b2f 4142 sequence_config_new &= 0xfb;
elab 0:0e577ce96b2f 4143 break;
elab 0:0e577ce96b2f 4144 case VL53L0X_SEQUENCESTEP_PRE_RANGE:
elab 0:0e577ce96b2f 4145 sequence_config_new &= 0xbf;
elab 0:0e577ce96b2f 4146 break;
elab 0:0e577ce96b2f 4147 case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
elab 0:0e577ce96b2f 4148 sequence_config_new &= 0x7f;
elab 0:0e577ce96b2f 4149 break;
elab 0:0e577ce96b2f 4150 default:
elab 0:0e577ce96b2f 4151 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 4152 }
elab 0:0e577ce96b2f 4153 }
elab 0:0e577ce96b2f 4154 }
elab 0:0e577ce96b2f 4155
elab 0:0e577ce96b2f 4156 if (sequence_config_new != sequence_config) {
elab 0:0e577ce96b2f 4157 /* Apply New Setting */
elab 0:0e577ce96b2f 4158 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4159 status = VL53L0X_write_byte(VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, sequence_config_new);
elab 0:0e577ce96b2f 4160 }
elab 0:0e577ce96b2f 4161 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4162 Data.SequenceConfig = sequence_config_new;}
elab 0:0e577ce96b2f 4163
elab 0:0e577ce96b2f 4164 /* Recalculate timing budget */
elab 0:0e577ce96b2f 4165 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4166 measurement_timing_budget_us = CurrentParameters.MeasurementTimingBudget_us ;
elab 0:0e577ce96b2f 4167 VL53L0X_set_measurement_timing_budget_us(measurement_timing_budget_us);
elab 0:0e577ce96b2f 4168 }
elab 0:0e577ce96b2f 4169 }
elab 0:0e577ce96b2f 4170
elab 0:0e577ce96b2f 4171 return status;
elab 0:0e577ce96b2f 4172 }
elab 0:0e577ce96b2f 4173
elab 0:0e577ce96b2f 4174 VL53L0X_Error VL53L0X::VL53L0X_set_limit_check_enable( uint16_t limit_check_id,
elab 0:0e577ce96b2f 4175 uint8_t limit_check_enable)
elab 0:0e577ce96b2f 4176 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 4177 FixPoint1616_t temp_fix1616 = 0;
elab 0:0e577ce96b2f 4178 uint8_t limit_check_enable_int = 0;
elab 0:0e577ce96b2f 4179 uint8_t limit_check_disable = 0;
elab 0:0e577ce96b2f 4180 uint8_t temp8;
elab 0:0e577ce96b2f 4181
elab 0:0e577ce96b2f 4182 if (limit_check_id >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) {
elab 0:0e577ce96b2f 4183 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 4184 } else {
elab 0:0e577ce96b2f 4185 if (limit_check_enable == 0) {
elab 0:0e577ce96b2f 4186 temp_fix1616 = 0;
elab 0:0e577ce96b2f 4187 limit_check_enable_int = 0;
elab 0:0e577ce96b2f 4188 limit_check_disable = 1;
elab 0:0e577ce96b2f 4189 } else {
elab 0:0e577ce96b2f 4190 temp_fix1616 = CurrentParameters.LimitChecksValue[limit_check_id];
elab 0:0e577ce96b2f 4191 limit_check_disable = 0;
elab 0:0e577ce96b2f 4192 /* this to be sure to have either 0 or 1 */
elab 0:0e577ce96b2f 4193 limit_check_enable_int = 1;
elab 0:0e577ce96b2f 4194 }
elab 0:0e577ce96b2f 4195
elab 0:0e577ce96b2f 4196 switch (limit_check_id) {
elab 0:0e577ce96b2f 4197
elab 0:0e577ce96b2f 4198 case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE:
elab 0:0e577ce96b2f 4199 /* internal computation: */
elab 0:0e577ce96b2f 4200 CurrentParameters.LimitChecksEnable[VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE] = limit_check_enable_int;
elab 0:0e577ce96b2f 4201 break;
elab 0:0e577ce96b2f 4202
elab 0:0e577ce96b2f 4203 case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
elab 0:0e577ce96b2f 4204 status = VL53L0X_write_word( VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT,
elab 0:0e577ce96b2f 4205 VL53L0X_FP1616TOFP97(temp_fix1616));
elab 0:0e577ce96b2f 4206 break;
elab 0:0e577ce96b2f 4207
elab 0:0e577ce96b2f 4208 case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP:/* internal computation: */
elab 0:0e577ce96b2f 4209 CurrentParameters.LimitChecksEnable[VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP] = limit_check_enable_int;
elab 0:0e577ce96b2f 4210 break;
elab 0:0e577ce96b2f 4211
elab 0:0e577ce96b2f 4212 case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD:/* internal computation: */
elab 0:0e577ce96b2f 4213 CurrentParameters.LimitChecksEnable[VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD] = limit_check_enable_int;
elab 0:0e577ce96b2f 4214 break;
elab 0:0e577ce96b2f 4215
elab 0:0e577ce96b2f 4216 case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC:
elab 0:0e577ce96b2f 4217 temp8 = (uint8_t)(limit_check_disable << 1);
elab 0:0e577ce96b2f 4218 status = VL53L0X_update_byte(VL53L0X_REG_MSRC_CONFIG_CONTROL,
elab 0:0e577ce96b2f 4219 0xFE, temp8);
elab 0:0e577ce96b2f 4220 break;
elab 0:0e577ce96b2f 4221
elab 0:0e577ce96b2f 4222 case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE:
elab 0:0e577ce96b2f 4223
elab 0:0e577ce96b2f 4224 temp8 = (uint8_t)(limit_check_disable << 4);
elab 0:0e577ce96b2f 4225 status = VL53L0X_update_byte(VL53L0X_REG_MSRC_CONFIG_CONTROL,
elab 0:0e577ce96b2f 4226 0xEF, temp8);
elab 0:0e577ce96b2f 4227 break;
elab 0:0e577ce96b2f 4228
elab 0:0e577ce96b2f 4229 default:
elab 0:0e577ce96b2f 4230 status = VL53L0X_ERROR_INVALID_PARAMS;
elab 0:0e577ce96b2f 4231 }
elab 0:0e577ce96b2f 4232 }
elab 0:0e577ce96b2f 4233
elab 0:0e577ce96b2f 4234 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4235 if (limit_check_enable == 0) {
elab 0:0e577ce96b2f 4236 CurrentParameters.LimitChecksEnable[limit_check_id] = 0;
elab 0:0e577ce96b2f 4237 } else {
elab 0:0e577ce96b2f 4238 CurrentParameters.LimitChecksEnable[limit_check_id] = 1;
elab 0:0e577ce96b2f 4239 }
elab 0:0e577ce96b2f 4240 }
elab 0:0e577ce96b2f 4241 return status;
elab 0:0e577ce96b2f 4242 }
elab 0:0e577ce96b2f 4243
elab 0:0e577ce96b2f 4244 VL53L0X_Error VL53L0X::VL53L0X_static_init(void)
elab 0:0e577ce96b2f 4245 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 4246 VL53L0X_DeviceParameters_t current_parameters = {0};
elab 0:0e577ce96b2f 4247 uint8_t *p_tuning_setting_buffer;
elab 0:0e577ce96b2f 4248 uint16_t tempword = 0;
elab 0:0e577ce96b2f 4249 uint8_t tempbyte = 0;
elab 0:0e577ce96b2f 4250 uint8_t use_internal_tuning_settings = 0;
elab 0:0e577ce96b2f 4251 uint32_t count = 0;
elab 0:0e577ce96b2f 4252 uint8_t is_aperture_spads = 0;
elab 0:0e577ce96b2f 4253 uint32_t ref_spad_count = 0;
elab 0:0e577ce96b2f 4254 uint8_t aperture_spads = 0;
elab 0:0e577ce96b2f 4255 uint8_t vcsel_pulse_period_pclk;
elab 0:0e577ce96b2f 4256 uint32_t seq_timeout_micro_secs;
elab 0:0e577ce96b2f 4257
elab 0:0e577ce96b2f 4258 status = VL53L0X_get_info_from_device( 1);
elab 0:0e577ce96b2f 4259
elab 0:0e577ce96b2f 4260 /* set the ref spad from NVM */
elab 0:0e577ce96b2f 4261 count = (uint32_t)Data.ReferenceSpadCount;
elab 0:0e577ce96b2f 4262 aperture_spads = Data.ReferenceSpadType;
elab 0:0e577ce96b2f 4263
elab 0:0e577ce96b2f 4264 /* NVM value invalid */
elab 0:0e577ce96b2f 4265 if ((aperture_spads > 1) ||
elab 0:0e577ce96b2f 4266 ((aperture_spads == 1) && (count > 32)) ||
elab 0:0e577ce96b2f 4267 ((aperture_spads == 0) && (count > 12))) {
elab 0:0e577ce96b2f 4268 status = wrapped_VL53L0X_perform_ref_spad_management( &ref_spad_count,
elab 0:0e577ce96b2f 4269 &is_aperture_spads);
elab 0:0e577ce96b2f 4270 } else {
elab 0:0e577ce96b2f 4271 status = VL53L0X_set_reference_spads( count, aperture_spads);
elab 0:0e577ce96b2f 4272 }
elab 0:0e577ce96b2f 4273
elab 0:0e577ce96b2f 4274 /* Initialize tuning settings buffer to prevent compiler warning. */
elab 0:0e577ce96b2f 4275 p_tuning_setting_buffer = DefaultTuningSettings;
elab 0:0e577ce96b2f 4276
elab 0:0e577ce96b2f 4277 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4278 use_internal_tuning_settings = Data.UseInternalTuningSettings;
elab 0:0e577ce96b2f 4279
elab 0:0e577ce96b2f 4280 if (use_internal_tuning_settings == 0) {
elab 0:0e577ce96b2f 4281 p_tuning_setting_buffer = Data.pTuningSettingsPointer; }
elab 0:0e577ce96b2f 4282 else { p_tuning_setting_buffer = DefaultTuningSettings; }
elab 0:0e577ce96b2f 4283
elab 0:0e577ce96b2f 4284 }
elab 0:0e577ce96b2f 4285
elab 0:0e577ce96b2f 4286 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4287 status = VL53L0X_load_tuning_settings( p_tuning_setting_buffer); }
elab 0:0e577ce96b2f 4288
elab 0:0e577ce96b2f 4289 /* Set interrupt config to new sample ready */
elab 0:0e577ce96b2f 4290 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4291 status = VL53L0X_set_gpio_config( 0, 0,
elab 0:0e577ce96b2f 4292 VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY,
elab 0:0e577ce96b2f 4293 VL53L0X_INTERRUPTPOLARITY_LOW);
elab 0:0e577ce96b2f 4294 }
elab 0:0e577ce96b2f 4295
elab 0:0e577ce96b2f 4296 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4297 status = VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 4298 status |= VL53L0X_read_word ( 0x84, &tempword);
elab 0:0e577ce96b2f 4299 status |= VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 4300 }
elab 0:0e577ce96b2f 4301
elab 0:0e577ce96b2f 4302 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4303 Data.OscFrequency_MHz = VL53L0X_FP412TOFP1616(tempword) ;
elab 0:0e577ce96b2f 4304 }
elab 0:0e577ce96b2f 4305
elab 0:0e577ce96b2f 4306 /* After static init, some device parameters may be changed,
elab 0:0e577ce96b2f 4307 * so update them */
elab 0:0e577ce96b2f 4308 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4309 status = VL53L0X_get_device_parameters( &current_parameters);
elab 0:0e577ce96b2f 4310 }
elab 0:0e577ce96b2f 4311
elab 0:0e577ce96b2f 4312 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4313 status = VL53L0X_get_fraction_enable( &tempbyte);
elab 0:0e577ce96b2f 4314 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4315 Data.RangeFractionalEnable = tempbyte;
elab 0:0e577ce96b2f 4316 }
elab 0:0e577ce96b2f 4317 }
elab 0:0e577ce96b2f 4318
elab 0:0e577ce96b2f 4319 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4320 CurrentParameters = current_parameters;
elab 0:0e577ce96b2f 4321 }
elab 0:0e577ce96b2f 4322
elab 0:0e577ce96b2f 4323 /* read the sequence config and save it */
elab 0:0e577ce96b2f 4324 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4325 status = VL53L0X_read_byte(VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &tempbyte);
elab 0:0e577ce96b2f 4326 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4327 Data.SequenceConfig = tempbyte;
elab 0:0e577ce96b2f 4328 }
elab 0:0e577ce96b2f 4329 }
elab 0:0e577ce96b2f 4330
elab 0:0e577ce96b2f 4331 /* Disable MSRC and TCC by default */
elab 0:0e577ce96b2f 4332 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4333 status = VL53L0X_set_sequence_step_enable(VL53L0X_SEQUENCESTEP_TCC, 0);
elab 0:0e577ce96b2f 4334 }
elab 0:0e577ce96b2f 4335
elab 0:0e577ce96b2f 4336 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4337 status = VL53L0X_set_sequence_step_enable(VL53L0X_SEQUENCESTEP_MSRC, 0);
elab 0:0e577ce96b2f 4338 }
elab 0:0e577ce96b2f 4339
elab 0:0e577ce96b2f 4340 /* Set PAL State to standby */
elab 0:0e577ce96b2f 4341 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4342 Data.PalState = VL53L0X_STATE_IDLE;
elab 0:0e577ce96b2f 4343 }
elab 0:0e577ce96b2f 4344
elab 0:0e577ce96b2f 4345 /* Store pre-range vcsel period */
elab 0:0e577ce96b2f 4346 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4347 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE,&vcsel_pulse_period_pclk);
elab 0:0e577ce96b2f 4348 }
elab 0:0e577ce96b2f 4349
elab 0:0e577ce96b2f 4350 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4351 Data.PreRangeVcselPulsePeriod = vcsel_pulse_period_pclk;
elab 0:0e577ce96b2f 4352 }
elab 0:0e577ce96b2f 4353
elab 0:0e577ce96b2f 4354 /* Store final-range vcsel period */
elab 0:0e577ce96b2f 4355 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4356 status = VL53L0X_get_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_FINAL_RANGE,
elab 0:0e577ce96b2f 4357 &vcsel_pulse_period_pclk);
elab 0:0e577ce96b2f 4358 }
elab 0:0e577ce96b2f 4359
elab 0:0e577ce96b2f 4360 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4361 Data.FinalRangeVcselPulsePeriod = vcsel_pulse_period_pclk;
elab 0:0e577ce96b2f 4362 }
elab 0:0e577ce96b2f 4363
elab 0:0e577ce96b2f 4364 /* Store pre-range timeout */
elab 0:0e577ce96b2f 4365 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4366 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE,&seq_timeout_micro_secs);
elab 0:0e577ce96b2f 4367 }
elab 0:0e577ce96b2f 4368
elab 0:0e577ce96b2f 4369 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4370 Data.PreRangeTimeout_us = seq_timeout_micro_secs;
elab 0:0e577ce96b2f 4371 }
elab 0:0e577ce96b2f 4372
elab 0:0e577ce96b2f 4373 /* Store final-range timeout */
elab 0:0e577ce96b2f 4374 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4375 status = get_sequence_step_timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE,&seq_timeout_micro_secs);
elab 0:0e577ce96b2f 4376 }
elab 0:0e577ce96b2f 4377
elab 0:0e577ce96b2f 4378 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4379 Data.FinalRangeTimeout_us = seq_timeout_micro_secs;
elab 0:0e577ce96b2f 4380 }
elab 0:0e577ce96b2f 4381 return status;
elab 0:0e577ce96b2f 4382 }
elab 0:0e577ce96b2f 4383
elab 0:0e577ce96b2f 4384 VL53L0X_Error VL53L0X::VL53L0X_stop_measurement(void)
elab 0:0e577ce96b2f 4385 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 4386
elab 0:0e577ce96b2f 4387 status = VL53L0X_write_byte( VL53L0X_REG_SYSRANGE_START,
elab 0:0e577ce96b2f 4388 VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT);
elab 0:0e577ce96b2f 4389 status = VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 4390 status = VL53L0X_write_byte( 0x00, 0x00);
elab 0:0e577ce96b2f 4391 status = VL53L0X_write_byte( 0x91, 0x00);
elab 0:0e577ce96b2f 4392 status = VL53L0X_write_byte( 0x00, 0x01);
elab 0:0e577ce96b2f 4393 status = VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 4394
elab 0:0e577ce96b2f 4395 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4396 /* Set PAL State to Idle */
elab 0:0e577ce96b2f 4397 Data.PalState = VL53L0X_STATE_IDLE;
elab 0:0e577ce96b2f 4398 }
elab 0:0e577ce96b2f 4399
elab 0:0e577ce96b2f 4400 /* Check if need to apply interrupt settings */
elab 0:0e577ce96b2f 4401 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4402 status = VL53L0X_check_and_load_interrupt_settings( 0);
elab 0:0e577ce96b2f 4403 }
elab 0:0e577ce96b2f 4404 return status;
elab 0:0e577ce96b2f 4405 }
elab 0:0e577ce96b2f 4406
elab 0:0e577ce96b2f 4407 VL53L0X_Error VL53L0X::VL53L0X_get_stop_completed_status(uint32_t *p_stop_status)
elab 0:0e577ce96b2f 4408 { VL53L0X_Error status = VL53L0X_ERROR_NONE;
elab 0:0e577ce96b2f 4409 uint8_t byte = 0;
elab 0:0e577ce96b2f 4410
elab 0:0e577ce96b2f 4411
elab 0:0e577ce96b2f 4412 status = VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 4413
elab 0:0e577ce96b2f 4414 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4415 status = VL53L0X_read_byte( 0x04, &byte);}
elab 0:0e577ce96b2f 4416
elab 0:0e577ce96b2f 4417 if (status == VL53L0X_ERROR_NONE) {
elab 0:0e577ce96b2f 4418 status = VL53L0X_write_byte( 0xFF, 0x0); }
elab 0:0e577ce96b2f 4419
elab 0:0e577ce96b2f 4420 *p_stop_status = byte;
elab 0:0e577ce96b2f 4421
elab 0:0e577ce96b2f 4422 if (byte == 0) {
elab 0:0e577ce96b2f 4423 status = VL53L0X_write_byte( 0x80, 0x01);
elab 0:0e577ce96b2f 4424 status = VL53L0X_write_byte( 0xFF, 0x01);
elab 0:0e577ce96b2f 4425 status = VL53L0X_write_byte( 0x00, 0x00);
elab 0:0e577ce96b2f 4426 status = VL53L0X_write_byte( 0x91,Data.StopVariable);
elab 0:0e577ce96b2f 4427 status = VL53L0X_write_byte( 0x00, 0x01);
elab 0:0e577ce96b2f 4428 status = VL53L0X_write_byte( 0xFF, 0x00);
elab 0:0e577ce96b2f 4429 status = VL53L0X_write_byte( 0x80, 0x00);
elab 0:0e577ce96b2f 4430 }
elab 0:0e577ce96b2f 4431 return status;
elab 0:0e577ce96b2f 4432 }
elab 0:0e577ce96b2f 4433
elab 0:0e577ce96b2f 4434 /******************************************************************************/
elab 0:0e577ce96b2f 4435
elab 0:0e577ce96b2f 4436 /****************** Write and read functions from I2C *************************/
elab 0:0e577ce96b2f 4437
elab 0:0e577ce96b2f 4438 VL53L0X_Error VL53L0X::VL53L0X_read_multi( uint8_t index, uint8_t *p_data, uint32_t count)
elab 0:0e577ce96b2f 4439 { if (count >= VL53L0X_MAX_I2C_XFER_SIZE) {
elab 0:0e577ce96b2f 4440 return VL53L0X_ERROR_INVALID_PARAMS;}
elab 0:0e577ce96b2f 4441 else { return VL53L0X_i2c_read(index, p_data, (uint16_t)count); }
elab 0:0e577ce96b2f 4442 }
elab 0:0e577ce96b2f 4443
elab 0:0e577ce96b2f 4444 VL53L0X_Error VL53L0X::VL53L0X_write_byte( uint8_t index, uint8_t data)
elab 0:0e577ce96b2f 4445 { return VL53L0X_i2c_write(index, &data, 1);
elab 0:0e577ce96b2f 4446 }
elab 0:0e577ce96b2f 4447
elab 0:0e577ce96b2f 4448 VL53L0X_Error VL53L0X::VL53L0X_write_word( uint8_t index, uint16_t data)
elab 0:0e577ce96b2f 4449 { int status;
elab 0:0e577ce96b2f 4450 uint8_t buffer[2];
elab 0:0e577ce96b2f 4451
elab 0:0e577ce96b2f 4452 buffer[0] = data >> 8;
elab 0:0e577ce96b2f 4453 buffer[1] = data & 0x00FF;
elab 0:0e577ce96b2f 4454 status = VL53L0X_i2c_write(index, (uint8_t *)buffer, 2);
elab 0:0e577ce96b2f 4455 return status;
elab 0:0e577ce96b2f 4456 }
elab 0:0e577ce96b2f 4457
elab 0:0e577ce96b2f 4458 VL53L0X_Error VL53L0X::VL53L0X_write_dword( uint8_t index, uint32_t data)
elab 0:0e577ce96b2f 4459 { int status;
elab 0:0e577ce96b2f 4460 uint8_t buffer[4];
elab 0:0e577ce96b2f 4461
elab 0:0e577ce96b2f 4462 buffer[0] = (data >> 24) & 0xFF;
elab 0:0e577ce96b2f 4463 buffer[1] = (data >> 16) & 0xFF;
elab 0:0e577ce96b2f 4464 buffer[2] = (data >> 8) & 0xFF;
elab 0:0e577ce96b2f 4465 buffer[3] = (data >> 0) & 0xFF;
elab 0:0e577ce96b2f 4466 status = VL53L0X_i2c_write(index, (uint8_t *)buffer, 4);
elab 0:0e577ce96b2f 4467 return status;
elab 0:0e577ce96b2f 4468 }
elab 0:0e577ce96b2f 4469
elab 0:0e577ce96b2f 4470 VL53L0X_Error VL53L0X::VL53L0X_read_byte( uint8_t index, uint8_t *p_data)
elab 0:0e577ce96b2f 4471 { return VL53L0X_i2c_read(index, p_data, 1); }
elab 0:0e577ce96b2f 4472
elab 0:0e577ce96b2f 4473 VL53L0X_Error VL53L0X::VL53L0X_read_word( uint8_t index, uint16_t *p_data)
elab 0:0e577ce96b2f 4474 { int status;
elab 0:0e577ce96b2f 4475 uint8_t buffer[2] = {0, 0};
elab 0:0e577ce96b2f 4476
elab 0:0e577ce96b2f 4477 status = VL53L0X_i2c_read(index, buffer, 2);
elab 0:0e577ce96b2f 4478 if (!status) {*p_data = (buffer[0] << 8) + buffer[1];}
elab 0:0e577ce96b2f 4479 return status;
elab 0:0e577ce96b2f 4480 }
elab 0:0e577ce96b2f 4481
elab 0:0e577ce96b2f 4482 VL53L0X_Error VL53L0X::VL53L0X_read_dword( uint8_t index, uint32_t *p_data)
elab 0:0e577ce96b2f 4483 { int status;
elab 0:0e577ce96b2f 4484 uint8_t buffer[4] = {0, 0, 0, 0};
elab 0:0e577ce96b2f 4485
elab 0:0e577ce96b2f 4486 status = VL53L0X_i2c_read(index, buffer, 4);
elab 0:0e577ce96b2f 4487 if (!status) { *p_data = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]; }
elab 0:0e577ce96b2f 4488 return status;
elab 0:0e577ce96b2f 4489 }
elab 0:0e577ce96b2f 4490
elab 0:0e577ce96b2f 4491 VL53L0X_Error VL53L0X::VL53L0X_update_byte( uint8_t index, uint8_t and_data, uint8_t or_data)
elab 0:0e577ce96b2f 4492 { int status;
elab 0:0e577ce96b2f 4493 uint8_t buffer = 0;
elab 0:0e577ce96b2f 4494
elab 0:0e577ce96b2f 4495 /* read data direct onto buffer */
elab 0:0e577ce96b2f 4496 status = VL53L0X_i2c_read(index, &buffer, 1);
elab 0:0e577ce96b2f 4497 if (!status) {
elab 0:0e577ce96b2f 4498 buffer = (buffer & and_data) | or_data;
elab 0:0e577ce96b2f 4499 status = VL53L0X_i2c_write(index, &buffer, (uint8_t)1);
elab 0:0e577ce96b2f 4500 }
elab 0:0e577ce96b2f 4501 return status;
elab 0:0e577ce96b2f 4502 }
elab 0:0e577ce96b2f 4503
elab 0:0e577ce96b2f 4504 VL53L0X_Error VL53L0X::VL53L0X_i2c_write(uint8_t RegisterAddr, uint8_t *p_data,
elab 0:0e577ce96b2f 4505 uint16_t NumByteToWrite)
elab 0:0e577ce96b2f 4506 { /** Writes a buffer towards the I2C peripheral device. */
elab 0:0e577ce96b2f 4507 static uint8_t tmp[VL53L0X_MAX_I2C_XFER_SIZE];
elab 0:0e577ce96b2f 4508
elab 0:0e577ce96b2f 4509 if(NumByteToWrite >= VL53L0X_MAX_I2C_XFER_SIZE) return -2;
elab 0:0e577ce96b2f 4510
elab 0:0e577ce96b2f 4511 /* First, send device address. Then, send data and STOP condition */
elab 0:0e577ce96b2f 4512 tmp[0] = RegisterAddr;
elab 0:0e577ce96b2f 4513 memcpy(tmp+1, p_data, NumByteToWrite);
elab 0:0e577ce96b2f 4514
elab 0:0e577ce96b2f 4515 if (_dev_i2c->write(I2cDevAddr, (const char*)tmp, NumByteToWrite+1, false) != 0 )
elab 0:0e577ce96b2f 4516 { return -1; }
elab 0:0e577ce96b2f 4517 return 0;
elab 0:0e577ce96b2f 4518 }
elab 0:0e577ce96b2f 4519
elab 0:0e577ce96b2f 4520 VL53L0X_Error VL53L0X::VL53L0X_i2c_read(uint8_t RegisterAddr, uint8_t *p_data, uint16_t NumByteToRead)
elab 0:0e577ce96b2f 4521 { /** Reads a buffer from the I2C peripheral device. */
elab 0:0e577ce96b2f 4522
elab 0:0e577ce96b2f 4523 /* First Send device address, with no STOP condition */
elab 0:0e577ce96b2f 4524 int ret = _dev_i2c->write(I2cDevAddr, (const char*)&RegisterAddr, 1, true);
elab 0:0e577ce96b2f 4525
elab 0:0e577ce96b2f 4526 /* all ok ? then Read data, with STOP condition */
elab 0:0e577ce96b2f 4527 if (ret == 0) { ret = _dev_i2c->read(I2cDevAddr, (char*)p_data, NumByteToRead, false); }
elab 0:0e577ce96b2f 4528
elab 0:0e577ce96b2f 4529 if (ret != 0 ){ return -1; }
elab 0:0e577ce96b2f 4530 return 0;
elab 0:0e577ce96b2f 4531 }
elab 0:0e577ce96b2f 4532