32#ifndef VL53L0X_TYPES_H
33#define VL53L0X_TYPES_H
38#include "../utilities.h"
39#include "vl53l0x_registers.h"
62 return ((value >= 0.0) && (value <
float(1 << INTEGRAL_BITS)));
73 static constexpr uint16_t
convert(
float value)
75 return is_valid(value) ? uint16_t(value * (1 << DECIMAL_BITS)) : 0U;
83 static constexpr float convert(uint16_t value)
85 return value / float(1 << DECIMAL_BITS);
89 static constexpr uint16_t INTEGRAL_BITS = 9;
90 static constexpr uint16_t DECIMAL_BITS = 7;
94 class TimeoutUtilities
97 static constexpr uint32_t PLL_PERIOD_PS = 1655UL;
98 static constexpr uint32_t MACRO_PERIOD_VCLKS = 2304UL;
102 static constexpr uint16_t encode_timeout(uint32_t timeout_macro_clks)
104 constexpr uint32_t MSB24_MASK = 0xFF'FF'FF'00UL;
105 constexpr uint32_t LSB8_MASK = 0xFFUL;
107 if (timeout_macro_clks == 0UL)
return 0U;
108 uint32_t lsb = timeout_macro_clks - 1UL;
110 while (lsb & MSB24_MASK)
119 static constexpr uint32_t decode_timeout(uint16_t encoded_timeout)
123 return (lsb << msb) + 1UL;
126 static constexpr uint32_t calculate_macro_period_ps(uint8_t vcsel_period_pclks)
128 constexpr uint32_t PS_TO_NS_DIVIDER = 1000UL;
129 constexpr uint32_t PS_TO_NS_ROUNDING_ADDITION = 500UL;
130 return ((PLL_PERIOD_PS * MACRO_PERIOD_VCLKS * vcsel_period_pclks) + PS_TO_NS_ROUNDING_ADDITION)
133 static constexpr uint32_t calculate_timeout_us(uint16_t timeout_period_mclks, uint8_t vcsel_period_pclks)
135 constexpr uint32_t NS_TO_US_DIVIDER = 1000UL;
136 constexpr uint32_t NS_TO_US_ROUNDING_ADDITION = 500UL;
137 const uint32_t macro_period_ns = calculate_macro_period_ps(vcsel_period_pclks);
138 return ((timeout_period_mclks * macro_period_ns) + NS_TO_US_ROUNDING_ADDITION) / NS_TO_US_DIVIDER;
140 static constexpr uint32_t calculate_timeout_mclks(uint16_t timeout_period_us, uint8_t vcsel_period_pclks)
142 constexpr uint32_t US_TO_NS_MULTIPLIER = 1000UL;
143 const uint32_t macro_period_ns = calculate_macro_period_ps(vcsel_period_pclks);
144 return ((timeout_period_us * US_TO_NS_MULTIPLIER) + (macro_period_ns / 2)) / macro_period_ns;
159 VCSEL_CONTINUITY_TEST_FAILURE = 1,
160 VCSEL_WATCHDOG_TEST_FAILURE = 2,
161 NO_VHV_VALUE_FOUND = 3,
164 RANGE_PHASE_CHECK = 6,
165 SIGMA_THRESHOLD_CHECK = 7,
167 PHASE_CONSISTENCY = 9,
173 RANGE_IGNORE_THRESHOLD = 14,
179 template<
typename OSTREAM> OSTREAM& operator<<(OSTREAM& out,
DeviceError error)
188 case DeviceError::VCSEL_CONTINUITY_TEST_FAILURE:
189 return F(
"VCSEL_CONTINUITY_TEST_FAILURE");
191 case DeviceError::VCSEL_WATCHDOG_TEST_FAILURE:
192 return F(
"VCSEL_WATCHDOG_TEST_FAILURE");
194 case DeviceError::NO_VHV_VALUE_FOUND:
195 return F(
"NO_VHV_VALUE_FOUND");
197 case DeviceError::MSRC_NO_TARGET:
198 return F(
"MSRC_NO_TARGET");
200 case DeviceError::SNR_CHECK:
201 return F(
"SNR_CHECK");
203 case DeviceError::RANGE_PHASE_CHECK:
204 return F(
"RANGE_PHASE_CHECK");
206 case DeviceError::SIGMA_THRESHOLD_CHECK:
207 return F(
"SIGMA_THRESHOLD_CHECK");
209 case DeviceError::TCC:
212 case DeviceError::PHASE_CONSISTENCY:
213 return F(
"PHASE_CONSISTENCY");
215 case DeviceError::MIN_CLIP:
216 return F(
"MIN_CLIP");
219 return F(
"RANGE_COMPLETE");
221 case DeviceError::ALGO_UNDERFLOW:
222 return F(
"ALGO_UNDERFLOW");
224 case DeviceError::ALGO_OVERFLOW:
225 return F(
"ALGO_OVERFLOW");
227 case DeviceError::RANGE_IGNORE_THRESHOLD:
228 return F(
"RANGE_IGNORE_THRESHOLD");
237 return out << convert(error);
258 return DeviceError((status_ >> ERROR_SHIFT) & ERROR_MASK);
267 return status_ & DATA_READY_MASK;
272 static constexpr uint8_t DATA_READY_MASK = 0x01;
273 static constexpr uint8_t ERROR_SHIFT = 3;
274 static constexpr uint8_t ERROR_MASK = 0x0F;
278 template<
typename OSTREAM> OSTREAM& operator<<(OSTREAM& out, DeviceStatus status)
280 return out <<
'(' << status.error() <<
',' << status.data_ready() <<
')';
295 template<
typename OSTREAM> OSTREAM& operator<<(OSTREAM& out,
PowerMode mode)
301 case PowerMode::IDLE:
304 case PowerMode::STANDBY:
311 return out << convert(mode);
336 template<
typename OSTREAM> OSTREAM& operator<<(OSTREAM& out,
GPIOFunction function)
343 return F(
"DISABLED");
346 return F(
"LEVEL_LOW");
349 return F(
"LEVEL_HIGH");
352 return F(
"OUT_OF_WINDOW");
355 return F(
"SAMPLE_READY");
361 return out << convert(function);
446 return high_polarity_;
453 return low_threshold_;
460 return high_threshold_;
465 bool high_polarity_ =
false;
466 uint16_t low_threshold_ = 0;
467 uint16_t high_threshold_ = 0;
471 template<
typename OSTREAM> OSTREAM& operator<<(OSTREAM& out,
const GPIOSettings& settings)
473 out <<
F(
"(GPIO function=");
475 out << settings.function()
476 <<
F(
", ") << (settings.high_polarity() ?
F(
"HIGH") :
F(
"LOW")) <<
F(
" polarity")
477 <<
F(
", low_threshold=");
479 out << settings.low_threshold()
480 <<
F(
", high_threshold=");
482 out << settings.high_threshold() <<
')';
488 class InterruptStatus
491 InterruptStatus() =
default;
493 explicit operator uint8_t()
const
495 return status_ & STATUS_MASK;
500 static constexpr uint8_t STATUS_MASK = 0x07;
517 static constexpr uint8_t NUM_PADS_BYTES = 6;
521 memcpy(spad_refs_,
spad_refs, NUM_PADS_BYTES);
544 uint8_t spad_refs_[NUM_PADS_BYTES];
559 PRE_RANGE = uint8_t(vl53l0x::Register::PRE_RANGE_CONFIG_VCSEL_PERIOD),
560 FINAL_RANGE = uint8_t(vl53l0x::Register::FINAL_RANGE_CONFIG_VCSEL_PERIOD)
586 static constexpr uint8_t FORCED_BITS =
bits::BV8(5);
588 static constexpr uint8_t TCC =
bits::BV8(4);
590 static constexpr uint8_t DSS =
bits::BV8(3);
592 static constexpr uint8_t MSRC =
bits::BV8(2);
594 static constexpr uint8_t PRE_RANGE =
bits::BV8(6);
596 static constexpr uint8_t FINAL_RANGE =
bits::BV8(7);
617 return SequenceSteps{TCC | DSS | MSRC | PRE_RANGE | FINAL_RANGE};
733 return steps_ & MSRC;
741 return steps_ & PRE_RANGE;
749 return steps_ & FINAL_RANGE;
753 explicit constexpr SequenceSteps(uint8_t steps) : steps_{uint8_t(steps | FORCED_BITS)} {}
755 uint8_t steps_ = FORCED_BITS;
757 template<
typename MANAGER>
friend class VL53L0X;
761 template<
typename OSTREAM> OSTREAM& operator<<(OSTREAM& out, SequenceSteps steps)
763 auto with_without = [](OSTREAM& o,
bool with,
const flash::FlashStorage* label)
770 with_without(out, steps.is_tcc(),
F(
"TCC"));
772 with_without(out, steps.is_dss(),
F(
"DSS"));
774 with_without(out, steps.is_msrc(),
F(
"MSRC"));
776 with_without(out, steps.is_pre_range(),
F(
"PRE_RANGE"));
778 with_without(out, steps.is_final_range(),
F(
"FINAL_RANGE"));
802 return pre_range_vcsel_period_pclks_;
810 return final_range_vcsel_period_pclks_;
818 return msrc_dss_tcc_mclks_ + 1;
826 return TimeoutUtilities::decode_timeout(pre_range_mclks_);
837 uint16_t temp_final_range_mclks = TimeoutUtilities::decode_timeout(final_range_mclks_);
838 return (is_pre_range ? (temp_final_range_mclks -
pre_range_mclks()) : temp_final_range_mclks);
867 return TimeoutUtilities::calculate_timeout_us(
880 uint8_t pre_range_vcsel_period_pclks_ = 0;
881 uint8_t final_range_vcsel_period_pclks_ = 0;
883 uint8_t msrc_dss_tcc_mclks_ = 0;
884 uint16_t pre_range_mclks_ = 0;
885 uint16_t final_range_mclks_ = 0;
887 template<
typename MANAGER>
friend class VL53L0X;
891 template<
typename OSTREAM> OSTREAM& operator<<(OSTREAM& out,
const SequenceStepsTimeout& timeouts)
893 out <<
F(
"(pre_range_vcsel_period_pclks=");
895 out << timeouts.pre_range_vcsel_period_pclks()
896 <<
F(
", final_range_vcsel_period_pclks=")
897 << timeouts.final_range_vcsel_period_pclks()
898 <<
F(
", msrc_dss_tcc_mclks=")
899 << timeouts.msrc_dss_tcc_mclks()
900 <<
F(
", pre_range_mclks=")
901 << timeouts.pre_range_mclks()
902 <<
F(
", final_range_mclks(with pre-range)=")
903 << timeouts.final_range_mclks(
true) <<
')'
904 <<
F(
", final_range_mclks(no pre-range)=")
905 << timeouts.final_range_mclks(
false) <<
')'
906 <<
F(
", msrc_dss_tcc_us()=")
907 << timeouts.msrc_dss_tcc_us() <<
F(
"us,")
908 <<
F(
", pre_range_us()=")
909 << timeouts.pre_range_us() <<
F(
"us,")
910 <<
F(
", final_range_us(with pre-range)=")
911 << timeouts.final_range_us(
true) <<
F(
"us,")
912 <<
F(
", final_range_us(no pre-range)=")
913 << timeouts.final_range_us(
false) <<
F(
"us)");
929 static constexpr uint8_t APERTURE =
bits::BV8(7);
930 static constexpr uint8_t COUNT =
bits::CBV8(7);
935 explicit SPADInfo(uint8_t info) : info_{info} {}
944 return info_ & APERTURE;
952 return info_ & COUNT;
960 template<
typename OSTREAM> OSTREAM& operator<<(OSTREAM& out, SPADInfo info)
962 out <<
F(
"(aperture=") << info.is_aperture()
965 out << info.count() <<
')';
Status of device as retrieved by VL53L0X::get_range_status().
bool data_ready() const
Indicate if data (range) is ready for reading.
DeviceError error() const
Device error.
Helper class to handle VL53L0X special fix-point 9.7 values.
static constexpr bool is_valid(float value)
Check that a float value is valid for conversion to 9.7 fix-point.
static constexpr uint16_t convert(float value)
Convert a float value into an 9.7 fix-point.
static constexpr float convert(uint16_t value)
Convert an 9.7 fix-point value into a float.
Settings for behavior of VL53L0X GPIO pin.
static constexpr GPIOSettings out_of_window(uint16_t low_threshold, uint16_t high_threshold, bool high_polarity=false)
Create GPIOSettings for interrupt triggered when range is outside a window between low_threshold and ...
uint16_t low_threshold() const
Return the current low threshold, in mm.
bool high_polarity() const
Return the current polarity level of GPIO interrupts.
uint16_t high_threshold() const
Return the current high threshold, in mm.
static constexpr GPIOSettings sample_ready(bool high_polarity=false)
Create GPIOSettings for interrupt triggered when range sample is ready.
static constexpr GPIOSettings low_threshold(uint16_t threshold, bool high_polarity=false)
Create GPIOSettings for interrupt triggered when range is under threshold.
static constexpr GPIOSettings high_threshold(uint16_t threshold, bool high_polarity=false)
Create GPIOSettings for interrupt triggered when range is above threshold.
GPIOFunction function() const
Return the current GPIO interrupt trigger source.
Hold SPAD information from VL53L0X device.
bool is_aperture() const
Indicate which is the first SPAD to enable, if false this is SPAD 0, else it is SPAD 12.
uint8_t count() const
Indicate the number of SPADs to enable.
Hold reference SPADs (Single Photon Avalanche Diode).
const uint8_t * spad_refs() const
Get a pointer to the 6-byte array stored in this SPADReference instance.
uint8_t * spad_refs()
Get a pointer to the 6-byte array stored in this SPADReference instance.
Hold VL53L0X sequence steps to use for ranging.
constexpr SequenceSteps no_msrc() const
Create a new SequenceSteps by removing MSRC from steps of this instance.
bool is_msrc() const
Indicate if this instance has MSRC (Minimum Signal Rate Check) step.
constexpr SequenceSteps no_final_range() const
Create a new SequenceSteps by removing FINAL-RANGE from steps of this instance.
bool is_final_range() const
Indicate if this instance has FINAL-RANGE step.
constexpr SequenceSteps dss() const
Create a new SequenceSteps by adding DSS to steps of this instance.
constexpr SequenceSteps tcc() const
Create a new SequenceSteps by adding TCC to steps of this instance.
constexpr SequenceSteps pre_range() const
Create a new SequenceSteps by adding PRE-RANGE to steps of this instance.
bool is_pre_range() const
Indicate if this instance has PRE-RANGE step.
uint8_t value() const
Get steps of this instance as a byte.
constexpr SequenceSteps no_dss() const
Create a new SequenceSteps by removing DSS from steps of this instance.
constexpr SequenceSteps no_tcc() const
Create a new SequenceSteps by removing TCC from steps of this instance.
static constexpr SequenceSteps all()
Create a full step sequence with all steps, with the possibility to remove steps you do not want:
constexpr SequenceSteps final_range() const
Create a new SequenceSteps by adding FINAL-RANGE to steps of this instance.
static constexpr SequenceSteps create()
Create an empty step sequence for further adding individual steps.
constexpr SequenceSteps msrc() const
Create a new SequenceSteps by adding MSRC to steps of this instance.
constexpr SequenceSteps no_pre_range() const
Create a new SequenceSteps by removing PRE-RANGE from steps of this instance.
bool is_dss() const
Indicate if this instance has DSS (Dynamic SPAD Selection) step.
bool is_tcc() const
Indicate if this instance has TCC (Target Center Check) step.
Hold VL53L0X sequence steps timeouts and other related settings used for ranging.
uint8_t final_range_vcsel_period_pclks() const
VCSEL PCLK value for final-range step.
uint32_t final_range_us(bool is_pre_range) const
Calculate the timing in us of FINAL-RANGE step.
uint16_t final_range_mclks(bool is_pre_range) const
MCLK for FINAL-RANGE step.
uint32_t msrc_dss_tcc_us() const
Calculate the timing in us of any of MSRC, DSS or TCC steps.
uint32_t pre_range_us() const
Calculate the timing in us of PRE-RANGE step.
uint16_t msrc_dss_tcc_mclks() const
MCLK for any of MSRC, DSS or TCC steps.
uint8_t pre_range_vcsel_period_pclks() const
VCSEL PCLK value for pre-range step.
uint16_t pre_range_mclks() const
MCLK for PRE-RANGE step.
static constexpr fmtflags basefield
Bitmask constant used with setf(fmtflags, fmtflags) when changing the output base format.
static constexpr fmtflags dec
Read or write integral values using decimal (0..9) base format.
static constexpr fmtflags hex
Read or write integral values using hexadecimal (0..9,A..F) base format.
#define F(ptr)
Force string constant to be stored as flash storage.
static constexpr uint8_t COMPL(uint8_t value)
Return the uint8_t 2-complement of a byte.
static constexpr uint8_t CBV8(uint8_t bit)
Create a uint8_t inverted bitmask for the given bit number.
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
Defines API for VL53L0X Time-of-Flight ranging sensor chip usage.
VcselPeriodType
Type of pulse period configured for VL53L0X device VCSEL (Vertical Cavity Surface Emitting Laser).
PowerMode
Possible power modes of VL53L0X device as returned by VL53L0X::get_power_mode().
GPIOFunction
Possible triggers for VL53L0X GPIO pin.
@ DISABLED
No interrupt triggered on GPIO pin.
@ OUT_OF_WINDOW
Interrupt triggered when range is outside a window between low and high thresholds.
@ SAMPLE_READY
Interrupt triggered when a range is ready to read.
@ LEVEL_LOW
Interrupt triggered when range is under a low threshold.
@ LEVEL_HIGH
Interrupt triggered when range is above a high threshold.
DeviceError
Possible error codes returned by VL53L0X device.
@ RANGE_COMPLETE
Range completed, range value is available for reading.
Profile
Possible profiles of ranging for VL53L0X top-level API VL53L0X::begin().
@ LONG_RANGE_ACCURATE
Accurate long range profile: 200ms ranging time, high accuracy, 2.0m range.
@ STANDARD_ACCURATE
Accurate standard profile: 200ms ranging time, high accuracy, 1.2m range.
@ STANDARD_FAST
Standard fast profile: 20ms ranging time, low accuracy, 1.2m range.
@ STANDARD
Standard profile: 33ms ranging time, common accuracy, 1.2m range.
@ LONG_RANGE_FAST
Standard long range profile: 20ms ranging time, low accuracy, 2.0m range.
@ LONG_RANGE
Long range profile: 33ms ranging time, common accuracy, 2.0m range.
constexpr uint8_t high_byte(uint16_t word)
Extract the high order byte of a 16-bits word.
constexpr uint16_t as_uint16_t(uint8_t high, uint8_t low)
Convert 2 bytes into an unsigned int.
constexpr uint8_t low_byte(uint16_t word)
Extract the low order byte of a 16-bits word.