M5Unit-TOF 0.2.1 git rev:ffeb3c9
Loading...
Searching...
No Matches
unit_VL53L1X.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_TOF_UNIT_VL53L1X_HPP
11#define M5_UNIT_TOF_UNIT_VL53L1X_HPP
12
13#include <M5UnitComponent.hpp>
14#include <m5_utility/container/circular_buffer.hpp>
15#include <m5_utility/types.hpp>
16#include <array>
17#include <limits> // NaN
18
19namespace m5 {
20namespace unit {
21
22namespace vl53l1x {
23
28enum class Operating : uint8_t {
29 ConditionStandard,
30 Condition2V8
31};
32
37enum class Distance : int8_t {
38 Unknown = -1,
39 Short,
40 Long,
41};
42
49enum class Timing : int8_t {
50 BudgetUnknown = -1,
58};
59
64enum class RangeStatus : uint8_t {
65 OK,
66 SigmaFailure,
67 SignalFailure,
68 RangeValidMinRangeClipped,
69 OutOfBounds,
70 HardwareFailure,
71 Unknown6,
72 Wraparound,
73 Unknown8,
74 XtalkSignalFailure,
75 SynchronizationInt,
76 Unknown11,
77 Unknown12,
78 MinRangeFailure,
79 Unknown255 = 255,
80};
81
98enum class Window : uint8_t {
99 Below,
100 Beyond,
101 Out,
102 In,
103 Regular = 0x20,
104};
105
110struct Data {
111 std::array<uint8_t, 17> raw{};
120 inline bool valid() const
121 {
122 return raw[0] == 9;
123 }
129 inline int16_t range() const
130 {
131 return valid() ? m5::types::big_uint16_t(raw[13], raw[14]).get() : -1;
132 }
133};
134
135} // namespace vl53l1x
136
141class UnitVL53L1X : public Component, public PeriodicMeasurementAdapter<UnitVL53L1X, vl53l1x::Data> {
142 M5_UNIT_COMPONENT_HPP_BUILDER(UnitVL53L1X, 0x29);
143
144public:
149 struct config_t {
151 vl53l1x::Operating operating{vl53l1x::Operating::Condition2V8};
153 vl53l1x::Distance distance{vl53l1x::Distance::Long};
155 vl53l1x::Timing timing_budget{vl53l1x::Timing::Budget100ms};
157 bool start_periodic{true};
159 bool calibrate_offset{false};
161 bool calibrate_xtalk{false};
162 };
163
166 explicit UnitVL53L1X(const uint8_t addr = DEFAULT_ADDRESS)
167 : Component(addr), _data{new m5::container::CircularBuffer<vl53l1x::Data>(1)}
168 {
169 auto ccfg = component_config();
170 ccfg.clock = 400 * 1000U;
171 component_config(ccfg);
172 }
173 virtual ~UnitVL53L1X()
174 {
175 }
176
178 virtual bool begin() override;
180 virtual void update(const bool force = false) override;
181
184
185 inline config_t config() const
186 {
187 return _cfg;
188 }
190 inline void config(const config_t& cfg)
191 {
192 _cfg = cfg;
193 }
195
198
202 inline int16_t range() const
203 {
204 return !empty() ? oldest().range() : -1;
205 }
207 inline bool valid() const
208 {
209 return !empty() && oldest().valid();
210 }
213 {
214 return !empty() ? oldest().range_status() : vl53l1x::RangeStatus::Unknown255;
215 }
217
220
225 {
226 return _distance;
227 }
233 {
234 return _tb;
235 }
237
240
245 {
246 return PeriodicMeasurementAdapter<UnitVL53L1X, vl53l1x::Data>::startPeriodicMeasurement();
247 }
255 const vl53l1x::Timing tb = vl53l1x::Timing::Budget50ms)
256 {
257 return PeriodicMeasurementAdapter<UnitVL53L1X, vl53l1x::Data>::startPeriodicMeasurement(dist, tb);
258 }
264 {
265 return PeriodicMeasurementAdapter<UnitVL53L1X, vl53l1x::Data>::stopPeriodicMeasurement();
266 }
268
271
280
293
296 bool softReset();
297
300
306 bool calibrateOffset(int16_t& offset, const uint16_t targetmm = 100);
312 bool readOffset(int16_t& offset);
319 bool writeOffset(const int16_t offset);
321
324
330 bool calibrateXtalk(uint16_t& xtalk, const uint16_t targetmm = 100);
336 bool readXtalk(uint16_t& xtalk);
342 bool writeXtalk(const uint16_t xtalk);
344
347
359 inline bool writeTimingBudget(const vl53l1x::Timing tb)
360 {
361 return write_timing_budget(tb, distanceMode());
362 }
368 bool readInterMeasurementPeriod(uint16_t& ms);
375 bool writeInterMeasurementPeriod(const uint16_t ms);
377
380
391 bool readDistanceThresholdLow(uint16_t& mm);
397 bool readDistanceThresholdHigh(uint16_t& mm);
405 bool writeDistanceThreshold(const vl53l1x::Window window, const uint16_t low, const uint16_t high);
411 {
412 return writeDistanceThreshold(vl53l1x::Window::Regular, 0, 0);
413 }
415
440
446 bool readROI(uint8_t& wid, uint8_t& hgt);
452 bool readROICenter(uint8_t& center);
461 bool writeROI(const uint8_t wid, const uint8_t hgt);
468 bool writeROICenter(const uint8_t center);
470
474
479 bool readI2CAddress(uint8_t& i2c_address);
485 bool changeI2CAddress(const uint8_t i2c_address);
487
488protected:
489 bool start_periodic_measurement();
490 bool start_periodic_measurement(const vl53l1x::Distance dist, const vl53l1x::Timing tb);
491 bool stop_periodic_measurement();
492
493 bool write_operating_condition(const vl53l1x::Operating oc);
494 bool write_timing_budget(const vl53l1x::Timing tb, const vl53l1x::Distance distance);
495
496 bool read_data_ready_status();
497 bool read_measurement(vl53l1x::Data& d);
498
499 bool soft_reset();
500 bool write_default_values();
501 bool wait_booted();
502
503 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitVL53L1X, vl53l1x::Data);
504
505protected:
506 vl53l1x::Distance _distance{vl53l1x::Distance::Unknown};
507 vl53l1x::Timing _tb{vl53l1x::Timing::BudgetUnknown};
508
509 std::unique_ptr<m5::container::CircularBuffer<vl53l1x::Data>> _data{};
510 config_t _cfg{};
511};
512
514namespace vl53l1x {
515namespace command {
516// clang-format off
517constexpr uint16_t SOFT_RESET {0x0000};
518constexpr uint16_t I2C_SLAVE_DEVICE_ADDRESS {0x0001};
519constexpr uint16_t OSC_MEASURED_FAST_OSC_FREQUENCY {0x0006};
520constexpr uint16_t VHV_CONFIG_TIMEOUT_MACROP_LOOP_BOUND {0x0008};
521constexpr uint16_t VHV_CONFIG_INIT {0x000B};
522constexpr uint16_t ALGO_CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS {0x0016};// [15:0] fixed point 7.9)
523constexpr uint16_t ALGO_CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS {0x0018};
524constexpr uint16_t ALGO_CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS {0x001A};
525constexpr uint16_t ALGO_PART_TO_PART_RANGE_OFFSET_MM {0x001E};// [12:0] fixed point 11.2
526constexpr uint16_t MM_CONFIG_INNER_OFFSET_MM {0x0020};
527constexpr uint16_t MM_CONFIG_OUTER_OFFSET_MM {0x0022};
528constexpr uint16_t DSS_CONFIG_TARGET_TOTAL_RATE_MCPS {0x0024};
529constexpr uint16_t EXTSUP_CONFIG {0x002E};
530constexpr uint16_t GPIO_HV_MUX_CTRL {0x0030};
531constexpr uint16_t GPIO_TIO_HV_STATUS {0x0031};
532constexpr uint16_t SIGMA_ESTIMATOR_EFFECTIVE_PULSE_WIDTH_NS {0x0036};
533constexpr uint16_t SIGMA_ESTIMATOR_EFFECTIVE_AMBIENT_WIDTH_NS {0x0037};
534constexpr uint16_t ALGO_CROSSTALK_COMPENSATION_VALID_HEIGHT_MM {0x0039};
535constexpr uint16_t ALGO_RANGE_IGNORE_VALID_HEIGHT_MM {0x003E};
536constexpr uint16_t ALGO_RANGE_MIN_CLIP {0x003F};
537constexpr uint16_t ALGO_CONSISTENCY_CHECK_TOLERANCE {0x0040};
538constexpr uint16_t SYSTEM_INTERRUPT_CONFIG_GPIO {0x0046};
539constexpr uint16_t CAL_CONFIG_VCSEL_START {0x0047};
540constexpr uint16_t PHASECAL_CONFIG_TIMEOUT_MACROP {0x004B};
541constexpr uint16_t PHASECAL_CONFIG_OVERRIDE {0x004D};
542constexpr uint16_t DSS_CONFIG_ROI_MODE_CONTROL {0x004F};
543constexpr uint16_t SYSTEM_THRESH_RATE_HIGH {0x0050};
544constexpr uint16_t SYSTEM_THRESH_RATE_LOW {0x0052};
545constexpr uint16_t DSS_CONFIG_MANUAL_EFFECTIVE_SPADS_SELECT {0x0054};
546constexpr uint16_t DSS_CONFIG_APERTURE_ATTENUATION {0x0057};
547constexpr uint16_t MM_CONFIG_TIMEOUT_MACROP_A {0x005A};
548constexpr uint16_t MM_CONFIG_TIMEOUT_MACROP_B {0x005C};
549constexpr uint16_t RANGE_CONFIG_TIMEOUT_MACROP_A {0x005E};
550constexpr uint16_t RANGE_CONFIG_TIMEOUT_MACROP_A_HI {0x005E}; // Alias of _A (ULD naming)
551constexpr uint16_t RANGE_CONFIG_VCSEL_PERIOD_A {0x0060};
552constexpr uint16_t RANGE_CONFIG_TIMEOUT_MACROP_B {0x0061};
553constexpr uint16_t RANGE_CONFIG_TIMEOUT_MACROP_B_HI {0x0061}; // Alias of _B (ULD naming)
554constexpr uint16_t RANGE_CONFIG_VCSEL_PERIOD_B {0x0063};
555constexpr uint16_t RANGE_CONFIG_SIGMA_THRESH {0x0064};
556constexpr uint16_t RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT_MCPS {0x0066};
557constexpr uint16_t RANGE_CONFIG_VALID_PHASE_HIGH {0x0069};
558constexpr uint16_t SYSTEM_INTERMEASUREMENT_PERIOD {0x006C};
559constexpr uint16_t SYSTEM_GROUPED_PARAMETER_HOLD_0 {0x0071};
560constexpr uint16_t SYSTEM_THRESH_HIGH {0x0072};
561constexpr uint16_t SYSTEM_THRESH_LOW {0x0074};
562constexpr uint16_t SYSTEM_SEED_CONFIG {0x0077};
563constexpr uint16_t SD_CONFIG_WOI_SD0 {0x0078};
564constexpr uint16_t SD_CONFIG_WOI_SD1 {0x0079};
565constexpr uint16_t SD_CONFIG_INITIAL_PHASE_SD0 {0x007A};
566constexpr uint16_t SD_CONFIG_INITIAL_PHASE_SD1 {0x007B};
567constexpr uint16_t SYSTEM_GROUPED_PARAMETER_HOLD_1 {0x007C};
568constexpr uint16_t SD_CONFIG_QUANTIFIER {0x007E};
569constexpr uint16_t ROI_CONFIG_USER_ROI_CENTRE_SPAD {0x007F};
570constexpr uint16_t ROI_CONFIG_USER_ROI_REQUESTED_GLOBAL_XY_SIZE {0x0080};
571constexpr uint16_t SYSTEM_SEQUENCE_CONFIG {0x0081};
572constexpr uint16_t SYSTEM_GROUPED_PARAMETER_HOLD {0x0082};
573constexpr uint16_t SYSTEM_INTERRUPT_CLEAR {0x0086};
574constexpr uint16_t SYSTEM_MODE_START {0x0087};
575constexpr uint16_t RESULT_RANGE_STATUS {0x0089}; // result size is 17bytes
576constexpr uint16_t RESULT_DSS_ACTUAL_EFFECTIVE_SPADS_SD0 {0x008C};
577constexpr uint16_t RESULT_FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 {0x0096};
578constexpr uint16_t RESULT_PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 {0x0098};
579constexpr uint16_t PHASECAL_RESULT_VCSEL_START {0x00D8};
580constexpr uint16_t RESULT_OSC_CALIBRATE_VAL {0x00DE};
581constexpr uint16_t FIRMWARE_SYSTEM_STATUS {0x00E5};
582//
583constexpr uint16_t MODEL_ID {0x010F};
584constexpr uint16_t MODULE_TYPE {0x0110};
585constexpr uint16_t MASK_REVISION {0x0111};
586// clang-format on
587} // namespace command
588} // namespace vl53l1x
590
591} // namespace unit
592} // namespace m5
593#endif
ToF4M unit.
Definition unit_VL53L1X.hpp:141
bool clearDistanceThreshold()
Go back to the regular ranging mode.
Definition unit_VL53L1X.hpp:410
bool writeROICenter(const uint8_t center)
Write the center of the ROI.
Definition unit_VL53L1X.cpp:757
bool startPeriodicMeasurement()
Start periodic measurement in the current settings.
Definition unit_VL53L1X.hpp:244
bool readDistanceThresholdWindow(vl53l1x::Window &window)
Read the window detection mode.
Definition unit_VL53L1X.cpp:678
int16_t range() const
Oldest measured range(mm)
Definition unit_VL53L1X.hpp:202
bool writeDistanceMode(const vl53l1x::Distance d)
Write the distance mode.
Definition unit_VL53L1X.cpp:396
virtual void update(const bool force=false) override
Update periodic measurement data.
Definition unit_VL53L1X.cpp:220
bool readDistanceThresholdHigh(uint16_t &mm)
Read the higher distance threshold.
Definition unit_VL53L1X.cpp:696
bool readTimingBudget(vl53l1x::Timing &tb)
Read the timing budget.
Definition unit_VL53L1X.cpp:585
bool writeROI(const uint8_t wid, const uint8_t hgt)
Write the ROI width and height.
Definition unit_VL53L1X.cpp:737
bool readDistanceThresholdLow(uint16_t &mm)
Read the lower distance threshold.
Definition unit_VL53L1X.cpp:692
bool readXtalk(uint16_t &xtalk)
Read the crosstalk.
Definition unit_VL53L1X.cpp:565
vl53l1x::RangeStatus range_status() const
Oldest measured range status.
Definition unit_VL53L1X.hpp:212
bool readDistanceMode(vl53l1x::Distance &d)
Read the distance mode.
Definition unit_VL53L1X.cpp:386
vl53l1x::Timing timingBudget() const
Gets the inner timing budget.
Definition unit_VL53L1X.hpp:232
bool writeDistanceThreshold(const vl53l1x::Window window, const uint16_t low, const uint16_t high)
Write the threshold and window detection mode.
Definition unit_VL53L1X.cpp:701
bool readInterMeasurementPeriod(uint16_t &ms)
Read the inter-measurement period(IMP)
Definition unit_VL53L1X.cpp:648
bool readROI(uint8_t &wid, uint8_t &hgt)
Read the ROI width and height.
Definition unit_VL53L1X.cpp:721
bool startPeriodicMeasurement(const vl53l1x::Distance dist, const vl53l1x::Timing tb=vl53l1x::Timing::Budget50ms)
Start periodic measurement.
Definition unit_VL53L1X.hpp:254
bool writeOffset(const int16_t offset)
Write the offset.
Definition unit_VL53L1X.cpp:488
bool writeXtalk(const uint16_t xtalk)
Write the crosstalk.
Definition unit_VL53L1X.cpp:577
virtual bool begin() override
Begin communication with the sensor.
Definition unit_VL53L1X.cpp:120
vl53l1x::Distance distanceMode() const
Gets the inner distance mode.
Definition unit_VL53L1X.hpp:224
bool changeI2CAddress(const uint8_t i2c_address)
Change unit I2C address.
Definition unit_VL53L1X.cpp:343
bool calibrateOffset(int16_t &offset, const uint16_t targetmm=100)
Calculate and write calibration offsets for a given target value.
Definition unit_VL53L1X.cpp:432
bool measureSingleshot(vl53l1x::Data &data)
Measurement single shot in the current settings.
Definition unit_VL53L1X.cpp:277
void config(const config_t &cfg)
Set the configuration.
Definition unit_VL53L1X.hpp:190
bool readI2CAddress(uint8_t &i2c_address)
Read the I2C address.
Definition unit_VL53L1X.cpp:337
bool calibrateXtalk(uint16_t &xtalk, const uint16_t targetmm=100)
Calculate and write calibration crosstalk for a given target value.
Definition unit_VL53L1X.cpp:501
bool writeInterMeasurementPeriod(const uint16_t ms)
Write the inter-measurement period(IMP)
Definition unit_VL53L1X.cpp:662
bool writeTimingBudget(const vl53l1x::Timing tb)
Write the timing budget.
Definition unit_VL53L1X.hpp:359
bool valid() const
Is valid oldest data?
Definition unit_VL53L1X.hpp:207
bool softReset()
Software reset.
Definition unit_VL53L1X.cpp:298
UnitVL53L1X(const uint8_t addr=DEFAULT_ADDRESS)
Constructor.
Definition unit_VL53L1X.hpp:166
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_VL53L1X.hpp:263
bool readOffset(int16_t &offset)
Read the offset.
Definition unit_VL53L1X.cpp:473
config_t config() const
Gets the configuration.
Definition unit_VL53L1X.hpp:185
bool readROICenter(uint8_t &center)
Read the center of the ROI.
Definition unit_VL53L1X.cpp:732
Top level namespace of M5stack.
Unit-related namespace.
Settings for begin.
Definition unit_VL53L1X.hpp:149
bool calibrate_xtalk
Calibrate crosstalk if start on begin.
Definition unit_VL53L1X.hpp:161
bool start_periodic
Start periodic measurement on begin?
Definition unit_VL53L1X.hpp:157
bool calibrate_offset
Calibrate offset if start on begin.
Definition unit_VL53L1X.hpp:159
vl53l1x::Timing timing_budget
Timing budget.
Definition unit_VL53L1X.hpp:155
vl53l1x::Operating operating
Operating condition.
Definition unit_VL53L1X.hpp:151
vl53l1x::Distance distance
Distance mode.
Definition unit_VL53L1X.hpp:153
Measurement data group.
Definition unit_VL53L1X.hpp:110
bool valid() const
Is data valid?
Definition unit_VL53L1X.hpp:120
RangeStatus range_status() const
Range status.
Definition unit_VL53L1X.cpp:92
std::array< uint8_t, 17 > raw
RAW data.
Definition unit_VL53L1X.hpp:111
int16_t range() const
range (mm)
Definition unit_VL53L1X.hpp:129
Window
Window detection mode.
Definition unit_VL53L1X.hpp:98
@ Beyond
Beyond a certain distance.
@ Out
Out of distance range (min/max), "out of Window".
@ Regular
Regular ranging (without window)
@ Below
Below a certain distance.
@ In
Within the distance range (min/max), "inside Window".
RangeStatus
Range status interpretation.
Definition unit_VL53L1X.hpp:64
Operating
Operating condition.
Definition unit_VL53L1X.hpp:28
Timing
Timing budget for ranging.
Definition unit_VL53L1X.hpp:49
@ Budget15ms
15 ms (Only possible when Short mode)
Distance
Distance mode.
Definition unit_VL53L1X.hpp:37
@ Short
Short (limited to 1.3m)
@ Long
Long (limited to 4.0m)