├── .github
├── ISSUE_TEMPLATE
│ ├── bug-report-or-feature-request.md
│ └── config.yml
└── workflows
│ └── ci.yaml
├── .gitignore
├── .gitlab-ci.yml
├── LICENSE.txt
├── README.md
├── VL53L1X.cpp
├── VL53L1X.h
├── examples
├── Continuous
│ └── Continuous.ino
├── ContinuousMultipleSensors
│ └── ContinuousMultipleSensors.ino
└── ContinuousWithDetails
│ └── ContinuousWithDetails.ino
├── keywords.txt
└── library.properties
/.github/ISSUE_TEMPLATE/bug-report-or-feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report or feature request
3 | about: Did you find a specific bug in the code for this project? Do you want to request
4 | a new feature? Please open an issue!
5 | title: ''
6 | labels: ''
7 | assignees: ''
8 |
9 | ---
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Pololu Forum
4 | url: https://forum.pololu.com/
5 | about: Do you need help getting started? Can't get this code to work at all? Having problems with electronics? Please post on our forum!
6 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: "CI"
2 | on:
3 | pull_request:
4 | push:
5 | jobs:
6 | ci:
7 | runs-on: ubuntu-20.04
8 | steps:
9 | - name: Checkout this repository
10 | uses: actions/checkout@v2.3.4
11 | - name: Cache for arduino-ci
12 | uses: actions/cache@v2.1.3
13 | with:
14 | path: |
15 | ~/.arduino15
16 | key: ${{ runner.os }}-arduino
17 | - name: Install nix
18 | uses: cachix/install-nix-action@v12
19 | - run: nix-shell -I nixpkgs=channel:nixpkgs-unstable -p arduino-ci --run "arduino-ci"
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /docs/
2 | /out/
3 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | image: $CI_REGISTRY_IMAGE/nixos/nix:2.3.6
2 |
3 | stages:
4 | - ci
5 |
6 | ci:
7 | stage: ci
8 | tags:
9 | - nix
10 | script:
11 | - nix-shell -I nixpkgs=channel:nixpkgs-unstable -p arduino-ci --run "arduino-ci"
12 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Most of the functionality of this library is based on the VL53L1X API provided
2 | provided by ST (STSW-IMG007), and some of the explanatory comments are quoted
3 | or paraphrased from the API source code, API user manual (UM2356), and VL53L1X
4 | datasheet. Therefore, the license terms for the API source code (BSD 3-clause
5 | "New" or "Revised" License) also apply to this derivative work, as specified
6 | below.
7 |
8 | For more information, see
9 |
10 | https://www.pololu.com/
11 | https://forum.pololu.com/
12 |
13 | --------------------------------------------------------------------------------
14 |
15 | Copyright (c) 2017, STMicroelectronics
16 | Copyright (c) 2018-2022, Pololu Corporation
17 | All Rights Reserved
18 |
19 | Redistribution and use in source and binary forms, with or without
20 | modification, are permitted provided that the following conditions are met:
21 |
22 | 1. Redistributions of source code must retain the above copyright notice, this
23 | list of conditions and the following disclaimer.
24 |
25 | 2. Redistributions in binary form must reproduce the above copyright notice,
26 | this list of conditions and the following disclaimer in the documentation
27 | and/or other materials provided with the distribution.
28 |
29 | 3. Neither the name of the copyright holder nor the names of its contributors
30 | may be used to endorse or promote products derived from this software
31 | without specific prior written permission.
32 |
33 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
37 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
40 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
41 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
42 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VL53L1X library for Arduino
2 | [www.pololu.com](https://www.pololu.com/)
3 |
4 | ## Summary
5 |
6 | This is a library for the Arduino IDE that helps interface with ST's [VL53L1X time-of-flight distance sensor](https://www.pololu.com/product/3415). The library makes it simple to configure the sensor and read range data from it via I²C.
7 |
8 | ## Supported platforms
9 |
10 | This library is designed to work with the Arduino IDE versions 1.6.x or later; we have not tested it with earlier versions. This library should support any Arduino-compatible board, including the [Pololu A-Star controllers](https://www.pololu.com/category/149/a-star-programmable-controllers).
11 |
12 | ## Getting started
13 |
14 | ### Hardware
15 |
16 | A [VL53L1X carrier](https://www.pololu.com/product/3415) can be purchased from Pololu's website. Before continuing, careful reading of the [product page](https://www.pololu.com/product/3415) as well as the VL53L1X datasheet is recommended.
17 |
18 | Make the following connections between the Arduino and the VL53L1X board:
19 |
20 | #### 5V Arduino boards
21 |
22 | (including Arduino Uno, Leonardo, Mega; Pololu A-Star 32U4)
23 |
24 | Arduino VL53L1X board
25 | ------- -------------
26 | 5V - VIN
27 | GND - GND
28 | SDA - SDA
29 | SCL - SCL
30 |
31 | #### 3.3V Arduino boards
32 |
33 | (including Arduino Due)
34 |
35 | Arduino VL53L1X board
36 | ------- -------------
37 | 3V3 - VIN
38 | GND - GND
39 | SDA - SDA
40 | SCL - SCL
41 |
42 | ### Software
43 |
44 | If you are using version 1.6.2 or later of the [Arduino software (IDE)](http://www.arduino.cc/en/Main/Software), you can use the Library Manager to install this library:
45 |
46 | 1. In the Arduino IDE, open the "Sketch" menu, select "Include Library", then "Manage Libraries...".
47 | 2. Search for "VL53L1X".
48 | 3. Click the VL53L1X entry in the list.
49 | 4. Click "Install".
50 |
51 | If this does not work, you can manually install the library:
52 |
53 | 1. Download the [latest release archive from GitHub](https://github.com/pololu/vl53l1x-arduino/releases) and decompress it.
54 | 2. Rename the folder "vl53l1x-arduino-master" to "VL53L1X".
55 | 3. Move the "VL53L1X" folder into the "libraries" directory inside your Arduino sketchbook directory. You can view your sketchbook location by opening the "File" menu and selecting "Preferences" in the Arduino IDE. If there is not already a "libraries" folder in that location, you should make the folder yourself.
56 | 4. After installing the library, restart the Arduino IDE.
57 |
58 | ## Examples
59 |
60 | Several example sketches are available that show how to use the library. You can access them from the Arduino IDE by opening the "File" menu, selecting "Examples", and then selecting "VL53L1X". If you cannot find these examples, the library was probably installed incorrectly and you should retry the installation instructions above.
61 |
62 | ## ST's VL53L1X API and this library
63 |
64 | Most of the functionality of this library is based on the [VL53L1X API](http://www.st.com/content/st_com/en/products/embedded-software/proximity-sensors-software/stsw-img007.html) provided by ST (STSW-IMG007), and some of the explanatory comments in the code are quoted or paraphrased from the API source code, API user manual (UM2356), and the VL53L1X datasheet. For more explanation about the library code and how it was derived from the API, see the comments in VL53L1X.cpp.
65 |
66 | This library is intended to provide a quicker and easier way to get started using the VL53L1X with an Arduino-compatible controller, in contrast to using ST's API on the Arduino. The library has a more streamlined interface, as well as smaller storage and memory footprints. However, it does not currently implement some of the more advanced functionality available in the API (for example, calibrating the sensor to work well under a cover glass or selecting a smaller region of interest (ROI)), and it has less robust error checking. For advanced applications, especially when storage and memory are less of an issue, consider using the VL53L1X API directly. We have an [implementation of ST's VL53L1X API for Arduino](https://github.com/pololu/vl53l1x-st-api-arduino) available.
67 |
68 | ## Library reference
69 |
70 | * `RangingData ranging_data`
71 | This struct contains information about the last ranging measurement. Its members are:
72 | * `uint16_t range_mm`
73 | Range reading from the last measurement, in millimeters. (This reading can also be obtained as the return value of `read()`.)
74 | * `RangeStatus range_status`
75 | Status of the last measurement; see the definition of the `RangeStatus` enumeration type in VL53L1X.h (or the API user manual and source code) for descriptions of the possible statuses. A status of `VL53L1X::RangeValid` means there were no problems with the measurement.
76 | * `float peak_signal_count_rate_MCPS`
77 | Peak signal count rate of the last measurement, in units of mega counts per second.
78 | * `float ambient_count_rate_MCPS`
79 | Ambient count rate of the last measurement, in units of mega counts per second.
80 |
81 | * `uint8_t last_status`
82 | The status of the last I²C write transmission. See the [`Wire.endTransmission()` documentation](http://arduino.cc/en/Reference/WireEndTransmission) for return values.
83 |
84 | * `VL53L1X()`
85 | Constructor.
86 |
87 | * `void setBus(TwoWire * bus)`
88 | Configures this object to use the specified I²C bus. `bus` should be a pointer to a `TwoWire` object; the default bus is `Wire`, which is typically the first or only I²C bus on an Arduino. If your Arduino has more than one I²C bus and you have the VL53L0X connected to the second bus, which is typically called `Wire1`, you can call `sensor.setBus(&Wire1);`.
89 |
90 | * `TwoWire * getBus()`
91 | Returns a pointer to the I²C bus this object is using.
92 |
93 | * `void setAddress(uint8_t new_addr)`
94 | Changes the I²C slave device address of the VL53L1X to the given value (7-bit).
95 |
96 | * `uint8_t getAddress()`
97 | Returns the current I²C address.
98 |
99 | * `bool init(bool io_2v8 = true)`
100 | Iniitializes and configures the sensor. If the optional argument `io_2v8` is true (the default if not specified), the sensor is configured for 2V8 mode (2.8 V I/O); if false, the sensor is left in 1V8 mode. The return value is a boolean indicating whether the initialization completed successfully.
101 |
102 | * `void writeReg(uint16_t reg, uint8_t value)`
103 | Writes an 8-bit sensor register with the given value.
104 |
105 | Register address constants are defined by the `regAddr` enumeration type in VL53L1X.h.
106 | Example use: `sensor.writeReg(VL53L1X::SOFT_RESET, 0x00);`
107 |
108 | * `void writeReg16Bit(uint16_t reg, uint16_t value)`
109 | Writes a 16-bit sensor register with the given value.
110 |
111 | * `void writeReg32Bit(uint16_t reg, uint32_t value)`
112 | Writes a 32-bit sensor register with the given value.
113 |
114 | * `uint8_t readReg(uint16_t reg)`
115 | Reads an 8-bit sensor register and returns the value read.
116 |
117 | * `uint16_t readReg16Bit(uint16_t reg)`
118 | Reads a 16-bit sensor register and returns the value read.
119 |
120 | * `uint32_t readReg32Bit(uint16_t reg)`
121 | Reads a 32-bit sensor register and returns the value read.
122 |
123 | * `bool setDistanceMode(DistanceMode mode)`
124 | Sets the distance mode of the sensor (`VL53L1X::Short`, `VL53L1X::Medium`, or `VL53L1X::Long`). Shorter distance modes are less affected by ambient light but have lower maximum ranges. See the datasheet for more information. The return value is a boolean indicating whether the requested mode was valid.
125 |
126 | * `DistanceMode getDistanceMode()`
127 | Returns the previously set distance mode.
128 |
129 | * `bool setMeasurementTimingBudget(uint32_t budget_us)`
130 | Sets the measurement timing budget to the given value in microseconds. This is the time allowed for one range measurement; a longer timing budget allows for more accurate measurements. The minimum budget is 20 ms (20000 us) in short distance mode and 33 ms for medium and long distance modes. See the VL53L1X datasheet for more information on range and timing limits. The return value is a boolean indicating whether the requested budget was valid.
131 |
132 | * `uint32_t getMeasurementTimingBudget()`
133 | Returns the current measurement timing budget in microseconds.
134 |
135 | * `void setROISize(uint8_t width, uint8_t height)`
136 | Changes the size of the sensor's region of interest (ROI), allowing a smaller field of view (FoV) to be configured at the cost of losing some sensitivity. The default and maximum ROI is 16x16, which covers the VL53L1X's full array of sensing elements (single-photon avalanche diodes, or SPADs). The minimum ROI is 4x4. See the datasheet and ST user manual [UM2555](https://www.st.com/resource/en/user_manual/dm00600212-vl53l1x-ultra-lite-driver-multiple-zone-implementation-stmicroelectronics.pdf) for more information.
137 |
138 | * `void getROISize(uint8_t * width, uint8_t * height)`
139 | Retrieves the size of the sensor's currently configured ROI. This function takes pointers to two `uint8_t`s and copies the width and height values to those locations.
140 |
141 | * `void setROICenter(uint8_t spadNum)`
142 | Sets the center of the sensor's ROI, allowing the sensor's FoV to be shifted off-center when a smaller FoV is configured. `spadNum` is the number of the selected center SPAD; information on selecting a SPAD number are in vl53l1x.cpp and [UM2555](https://www.st.com/resource/en/user_manual/dm00600212-vl53l1x-ultra-lite-driver-multiple-zone-implementation-stmicroelectronics.pdf). The default center SPAD is 199, which centers the sensor's FoV.
143 |
144 | * `uint8_t getROICenter()`
145 | Returns the number of the currently configured center SPAD, which determines the center of the sensor's ROI.
146 |
147 | * `void startContinuous(uint32_t period_ms)`
148 | Starts continuous ranging measurements. The specified inter-measurement period in milliseconds determines how often the sensor takes a measurement; if it is shorter than the timing budget, the sensor will start a new measurement as soon as the previous one finishes.
149 |
150 | * `void stopContinuous()`
151 | Stops continuous mode.
152 |
153 | * `uint16_t read(bool blocking = true)`
154 | After continuous ranging measurements have been started, calling this function returns a range reading in millimeters and updates the `ranging_data` struct with details about the last measurement. If the optional argument `blocking` is true (the default if not specified), this function will wait until data from a new measurement is available before returning.
155 |
156 | If you do not want this function to block, you can use the `dataReady()` function to check if new data is available before calling `read(false)`. Calling `read(false)` before new data is available results in undefined behavior.
157 |
158 | * `uint16_t readRangeContinuousMillimeters(bool blocking = true)`
159 | Alias of `read()` for convenience.
160 |
161 | * `uint16_t readSingle(bool blocking = true)`
162 | Starts a single-shot ranging measurement. If the optional argument `blocking` is true (the default if not specified), this function will wait until data from the measurement is available before returning and updating `ranging_data`. Otherwise, this function returns 0 immediately.
163 |
164 | To perform a single non-blocking read, you can call `readSingle(false)` to start the measurement, use `dataReady()` to wait until data is available, and finally call `read(false)` to get the data.
165 |
166 | * `uint16_t readRangeSingleMillimeters(bool blocking = true)`
167 | Alias of `readSingle()` for convenience.
168 |
169 | * `bool dataReady()`
170 | Returns a boolean indicating whether data from a new measurement is available from the sensor.
171 |
172 | * `static const char * rangeStatusToString(RangeStatus status)`
173 | Converts a `RangeStatus` into a readable string describing that status.
174 |
175 | Note that on an AVR, the strings in this function are stored in RAM (dynamic memory), which makes working with them easier but uses up 200+ bytes of RAM (many AVR-based Arduinos only have about 2000 bytes of RAM). You can avoid this memory usage if you do not call this function in your sketch.
176 |
177 | * `void setTimeout(uint16_t timeout)`
178 | Sets a timeout period in milliseconds after which read operations will abort if the sensor is not ready. A value of 0 disables the timeout.
179 |
180 | * `uint16_t getTimeout()`
181 | Returns the current timeout period setting.
182 |
183 | * `bool timeoutOccurred()`
184 | Indicates whether a read timeout has occurred since the last call to `timeoutOccurred()`.
185 |
186 | ## Version history
187 |
188 | * 1.3.1 (2022-02-18): Explicitly cast `Wire.write()` arguments to `uint8_t` (thanks giulcioffi). Added multiple sensors example.
189 | * 1.3.0 (2021-04-16): Added functions to configure and retrieve a custom region of interest (ROI) for the VL53L1X.
190 | * 1.2.1 (2020-11-23): Fixed compile error on platforms where `TwoWire` isn't a class.
191 | * 1.2.0 (2020-11-13): Added support for alternative I²C buses (thanks mampfes).
192 | * 1.1.0 (2020-09-21):
193 | * Added support for single-shot range measurements.
194 | * Changed timeout behavior on blocking reads to not clear `ranging_data`.
195 | * Fixed an incorrect error status returned by `getRangingData()`. (thanks rejnok93)
196 | * 1.0.1 (2018-09-19): Fixed Arduino 101 hanging in init().
197 | * 1.0.0 (2018-05-31): Original release.
198 |
--------------------------------------------------------------------------------
/VL53L1X.cpp:
--------------------------------------------------------------------------------
1 | // Most of the functionality of this library is based on the VL53L1X API
2 | // provided by ST (STSW-IMG007), and some of the explanatory comments are quoted
3 | // or paraphrased from the API source code, API user manual (UM2356), and
4 | // VL53L1X datasheet.
5 |
6 | #include "VL53L1X.h"
7 |
8 | // Constructors ////////////////////////////////////////////////////////////////
9 |
10 | VL53L1X::VL53L1X()
11 | #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_TWOWIRE)
12 | : bus(&Wire)
13 | #else
14 | : bus(nullptr)
15 | #endif
16 | , address(AddressDefault)
17 | , io_timeout(0) // no timeout
18 | , did_timeout(false)
19 | , calibrated(false)
20 | , saved_vhv_init(0)
21 | , saved_vhv_timeout(0)
22 | , distance_mode(Unknown)
23 | {
24 | }
25 |
26 | // Public Methods //////////////////////////////////////////////////////////////
27 |
28 | void VL53L1X::setAddress(uint8_t new_addr)
29 | {
30 | writeReg(I2C_SLAVE__DEVICE_ADDRESS, new_addr & 0x7F);
31 | address = new_addr;
32 | }
33 |
34 | // Initialize sensor using settings taken mostly from VL53L1_DataInit() and
35 | // VL53L1_StaticInit().
36 | // If io_2v8 (optional) is true or not given, the sensor is configured for 2V8
37 | // mode.
38 | bool VL53L1X::init(bool io_2v8)
39 | {
40 | // check model ID and module type registers (values specified in datasheet)
41 | if (readReg16Bit(IDENTIFICATION__MODEL_ID) != 0xEACC) { return false; }
42 |
43 | // VL53L1_software_reset() begin
44 |
45 | writeReg(SOFT_RESET, 0x00);
46 | delayMicroseconds(100);
47 | writeReg(SOFT_RESET, 0x01);
48 |
49 | // give it some time to boot; otherwise the sensor NACKs during the readReg()
50 | // call below and the Arduino 101 doesn't seem to handle that well
51 | delay(1);
52 |
53 | // VL53L1_poll_for_boot_completion() begin
54 |
55 | startTimeout();
56 |
57 | // check last_status in case we still get a NACK to try to deal with it correctly
58 | while ((readReg(FIRMWARE__SYSTEM_STATUS) & 0x01) == 0 || last_status != 0)
59 | {
60 | if (checkTimeoutExpired())
61 | {
62 | did_timeout = true;
63 | return false;
64 | }
65 | }
66 | // VL53L1_poll_for_boot_completion() end
67 |
68 | // VL53L1_software_reset() end
69 |
70 | // VL53L1_DataInit() begin
71 |
72 | // sensor uses 1V8 mode for I/O by default; switch to 2V8 mode if necessary
73 | if (io_2v8)
74 | {
75 | writeReg(PAD_I2C_HV__EXTSUP_CONFIG,
76 | readReg(PAD_I2C_HV__EXTSUP_CONFIG) | 0x01);
77 | }
78 |
79 | // store oscillator info for later use
80 | fast_osc_frequency = readReg16Bit(OSC_MEASURED__FAST_OSC__FREQUENCY);
81 | osc_calibrate_val = readReg16Bit(RESULT__OSC_CALIBRATE_VAL);
82 |
83 | // VL53L1_DataInit() end
84 |
85 | // VL53L1_StaticInit() begin
86 |
87 | // Note that the API does not actually apply the configuration settings below
88 | // when VL53L1_StaticInit() is called: it keeps a copy of the sensor's
89 | // register contents in memory and doesn't actually write them until a
90 | // measurement is started. Writing the configuration here means we don't have
91 | // to keep it all in memory and avoids a lot of redundant writes later.
92 |
93 | // the API sets the preset mode to LOWPOWER_AUTONOMOUS here:
94 | // VL53L1_set_preset_mode() begin
95 |
96 | // VL53L1_preset_mode_standard_ranging() begin
97 |
98 | // values labeled "tuning parm default" are from vl53l1_tuning_parm_defaults.h
99 | // (API uses these in VL53L1_init_tuning_parm_storage_struct())
100 |
101 | // static config
102 | // API resets PAD_I2C_HV__EXTSUP_CONFIG here, but maybe we don't want to do
103 | // that? (seems like it would disable 2V8 mode)
104 | writeReg16Bit(DSS_CONFIG__TARGET_TOTAL_RATE_MCPS, TargetRate); // should already be this value after reset
105 | writeReg(GPIO__TIO_HV_STATUS, 0x02);
106 | writeReg(SIGMA_ESTIMATOR__EFFECTIVE_PULSE_WIDTH_NS, 8); // tuning parm default
107 | writeReg(SIGMA_ESTIMATOR__EFFECTIVE_AMBIENT_WIDTH_NS, 16); // tuning parm default
108 | writeReg(ALGO__CROSSTALK_COMPENSATION_VALID_HEIGHT_MM, 0x01);
109 | writeReg(ALGO__RANGE_IGNORE_VALID_HEIGHT_MM, 0xFF);
110 | writeReg(ALGO__RANGE_MIN_CLIP, 0); // tuning parm default
111 | writeReg(ALGO__CONSISTENCY_CHECK__TOLERANCE, 2); // tuning parm default
112 |
113 | // general config
114 | writeReg16Bit(SYSTEM__THRESH_RATE_HIGH, 0x0000);
115 | writeReg16Bit(SYSTEM__THRESH_RATE_LOW, 0x0000);
116 | writeReg(DSS_CONFIG__APERTURE_ATTENUATION, 0x38);
117 |
118 | // timing config
119 | // most of these settings will be determined later by distance and timing
120 | // budget configuration
121 | writeReg16Bit(RANGE_CONFIG__SIGMA_THRESH, 360); // tuning parm default
122 | writeReg16Bit(RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS, 192); // tuning parm default
123 |
124 | // dynamic config
125 |
126 | writeReg(SYSTEM__GROUPED_PARAMETER_HOLD_0, 0x01);
127 | writeReg(SYSTEM__GROUPED_PARAMETER_HOLD_1, 0x01);
128 | writeReg(SD_CONFIG__QUANTIFIER, 2); // tuning parm default
129 |
130 | // VL53L1_preset_mode_standard_ranging() end
131 |
132 | // from VL53L1_preset_mode_timed_ranging_*
133 | // GPH is 0 after reset, but writing GPH0 and GPH1 above seem to set GPH to 1,
134 | // and things don't seem to work if we don't set GPH back to 0 (which the API
135 | // does here).
136 | writeReg(SYSTEM__GROUPED_PARAMETER_HOLD, 0x00);
137 | writeReg(SYSTEM__SEED_CONFIG, 1); // tuning parm default
138 |
139 | // from VL53L1_config_low_power_auto_mode
140 | writeReg(SYSTEM__SEQUENCE_CONFIG, 0x8B); // VHV, PHASECAL, DSS1, RANGE
141 | writeReg16Bit(DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT, 200 << 8);
142 | writeReg(DSS_CONFIG__ROI_MODE_CONTROL, 2); // REQUESTED_EFFFECTIVE_SPADS
143 |
144 | // VL53L1_set_preset_mode() end
145 |
146 | // default to long range, 50 ms timing budget
147 | // note that this is different than what the API defaults to
148 | setDistanceMode(Long);
149 | setMeasurementTimingBudget(50000);
150 |
151 | // VL53L1_StaticInit() end
152 |
153 | // the API triggers this change in VL53L1_init_and_start_range() once a
154 | // measurement is started; assumes MM1 and MM2 are disabled
155 | writeReg16Bit(ALGO__PART_TO_PART_RANGE_OFFSET_MM,
156 | readReg16Bit(MM_CONFIG__OUTER_OFFSET_MM) * 4);
157 |
158 | return true;
159 | }
160 |
161 | // Write an 8-bit register
162 | void VL53L1X::writeReg(uint16_t reg, uint8_t value)
163 | {
164 | bus->beginTransmission(address);
165 | bus->write((uint8_t)(reg >> 8)); // reg high byte
166 | bus->write((uint8_t)(reg)); // reg low byte
167 | bus->write(value);
168 | last_status = bus->endTransmission();
169 | }
170 |
171 | // Write a 16-bit register
172 | void VL53L1X::writeReg16Bit(uint16_t reg, uint16_t value)
173 | {
174 | bus->beginTransmission(address);
175 | bus->write((uint8_t)(reg >> 8)); // reg high byte
176 | bus->write((uint8_t)(reg)); // reg low byte
177 | bus->write((uint8_t)(value >> 8)); // value high byte
178 | bus->write((uint8_t)(value)); // value low byte
179 | last_status = bus->endTransmission();
180 | }
181 |
182 | // Write a 32-bit register
183 | void VL53L1X::writeReg32Bit(uint16_t reg, uint32_t value)
184 | {
185 | bus->beginTransmission(address);
186 | bus->write((uint8_t)(reg >> 8)); // reg high byte
187 | bus->write((uint8_t)(reg)); // reg low byte
188 | bus->write((uint8_t)(value >> 24)); // value highest byte
189 | bus->write((uint8_t)(value >> 16));
190 | bus->write((uint8_t)(value >> 8));
191 | bus->write((uint8_t)(value)); // value lowest byte
192 | last_status = bus->endTransmission();
193 | }
194 |
195 | // Read an 8-bit register
196 | uint8_t VL53L1X::readReg(regAddr reg)
197 | {
198 | uint8_t value;
199 |
200 | bus->beginTransmission(address);
201 | bus->write((uint8_t)(reg >> 8)); // reg high byte
202 | bus->write((uint8_t)(reg)); // reg low byte
203 | last_status = bus->endTransmission();
204 |
205 | bus->requestFrom(address, (uint8_t)1);
206 | value = bus->read();
207 |
208 | return value;
209 | }
210 |
211 | // Read a 16-bit register
212 | uint16_t VL53L1X::readReg16Bit(uint16_t reg)
213 | {
214 | uint16_t value;
215 |
216 | bus->beginTransmission(address);
217 | bus->write((uint8_t)(reg >> 8)); // reg high byte
218 | bus->write((uint8_t)(reg)); // reg low byte
219 | last_status = bus->endTransmission();
220 |
221 | bus->requestFrom(address, (uint8_t)2);
222 | value = (uint16_t)bus->read() << 8; // value high byte
223 | value |= bus->read(); // value low byte
224 |
225 | return value;
226 | }
227 |
228 | // Read a 32-bit register
229 | uint32_t VL53L1X::readReg32Bit(uint16_t reg)
230 | {
231 | uint32_t value;
232 |
233 | bus->beginTransmission(address);
234 | bus->write((uint8_t)(reg >> 8)); // reg high byte
235 | bus->write((uint8_t)(reg)); // reg low byte
236 | last_status = bus->endTransmission();
237 |
238 | bus->requestFrom(address, (uint8_t)4);
239 | value = (uint32_t)bus->read() << 24; // value highest byte
240 | value |= (uint32_t)bus->read() << 16;
241 | value |= (uint16_t)bus->read() << 8;
242 | value |= bus->read(); // value lowest byte
243 |
244 | return value;
245 | }
246 |
247 | // set distance mode to Short, Medium, or Long
248 | // based on VL53L1_SetDistanceMode()
249 | bool VL53L1X::setDistanceMode(DistanceMode mode)
250 | {
251 | // save existing timing budget
252 | uint32_t budget_us = getMeasurementTimingBudget();
253 |
254 | switch (mode)
255 | {
256 | case Short:
257 | // from VL53L1_preset_mode_standard_ranging_short_range()
258 |
259 | // timing config
260 | writeReg(RANGE_CONFIG__VCSEL_PERIOD_A, 0x07);
261 | writeReg(RANGE_CONFIG__VCSEL_PERIOD_B, 0x05);
262 | writeReg(RANGE_CONFIG__VALID_PHASE_HIGH, 0x38);
263 |
264 | // dynamic config
265 | writeReg(SD_CONFIG__WOI_SD0, 0x07);
266 | writeReg(SD_CONFIG__WOI_SD1, 0x05);
267 | writeReg(SD_CONFIG__INITIAL_PHASE_SD0, 6); // tuning parm default
268 | writeReg(SD_CONFIG__INITIAL_PHASE_SD1, 6); // tuning parm default
269 |
270 | break;
271 |
272 | case Medium:
273 | // from VL53L1_preset_mode_standard_ranging()
274 |
275 | // timing config
276 | writeReg(RANGE_CONFIG__VCSEL_PERIOD_A, 0x0B);
277 | writeReg(RANGE_CONFIG__VCSEL_PERIOD_B, 0x09);
278 | writeReg(RANGE_CONFIG__VALID_PHASE_HIGH, 0x78);
279 |
280 | // dynamic config
281 | writeReg(SD_CONFIG__WOI_SD0, 0x0B);
282 | writeReg(SD_CONFIG__WOI_SD1, 0x09);
283 | writeReg(SD_CONFIG__INITIAL_PHASE_SD0, 10); // tuning parm default
284 | writeReg(SD_CONFIG__INITIAL_PHASE_SD1, 10); // tuning parm default
285 |
286 | break;
287 |
288 | case Long: // long
289 | // from VL53L1_preset_mode_standard_ranging_long_range()
290 |
291 | // timing config
292 | writeReg(RANGE_CONFIG__VCSEL_PERIOD_A, 0x0F);
293 | writeReg(RANGE_CONFIG__VCSEL_PERIOD_B, 0x0D);
294 | writeReg(RANGE_CONFIG__VALID_PHASE_HIGH, 0xB8);
295 |
296 | // dynamic config
297 | writeReg(SD_CONFIG__WOI_SD0, 0x0F);
298 | writeReg(SD_CONFIG__WOI_SD1, 0x0D);
299 | writeReg(SD_CONFIG__INITIAL_PHASE_SD0, 14); // tuning parm default
300 | writeReg(SD_CONFIG__INITIAL_PHASE_SD1, 14); // tuning parm default
301 |
302 | break;
303 |
304 | default:
305 | // unrecognized mode - do nothing
306 | return false;
307 | }
308 |
309 | // reapply timing budget
310 | setMeasurementTimingBudget(budget_us);
311 |
312 | // save mode so it can be returned by getDistanceMode()
313 | distance_mode = mode;
314 |
315 | return true;
316 | }
317 |
318 | // Set the measurement timing budget in microseconds, which is the time allowed
319 | // for one measurement. A longer timing budget allows for more accurate
320 | // measurements.
321 | // based on VL53L1_SetMeasurementTimingBudgetMicroSeconds()
322 | bool VL53L1X::setMeasurementTimingBudget(uint32_t budget_us)
323 | {
324 | // assumes PresetMode is LOWPOWER_AUTONOMOUS
325 |
326 | if (budget_us <= TimingGuard) { return false; }
327 |
328 | uint32_t range_config_timeout_us = budget_us -= TimingGuard;
329 | if (range_config_timeout_us > 1100000) { return false; } // FDA_MAX_TIMING_BUDGET_US * 2
330 |
331 | range_config_timeout_us /= 2;
332 |
333 | // VL53L1_calc_timeout_register_values() begin
334 |
335 | uint32_t macro_period_us;
336 |
337 | // "Update Macro Period for Range A VCSEL Period"
338 | macro_period_us = calcMacroPeriod(readReg(RANGE_CONFIG__VCSEL_PERIOD_A));
339 |
340 | // "Update Phase timeout - uses Timing A"
341 | // Timeout of 1000 is tuning parm default (TIMED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT)
342 | // via VL53L1_get_preset_mode_timing_cfg().
343 | uint32_t phasecal_timeout_mclks = timeoutMicrosecondsToMclks(1000, macro_period_us);
344 | if (phasecal_timeout_mclks > 0xFF) { phasecal_timeout_mclks = 0xFF; }
345 | writeReg(PHASECAL_CONFIG__TIMEOUT_MACROP, phasecal_timeout_mclks);
346 |
347 | // "Update MM Timing A timeout"
348 | // Timeout of 1 is tuning parm default (LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US_DEFAULT)
349 | // via VL53L1_get_preset_mode_timing_cfg(). With the API, the register
350 | // actually ends up with a slightly different value because it gets assigned,
351 | // retrieved, recalculated with a different macro period, and reassigned,
352 | // but it probably doesn't matter because it seems like the MM ("mode
353 | // mitigation"?) sequence steps are disabled in low power auto mode anyway.
354 | writeReg16Bit(MM_CONFIG__TIMEOUT_MACROP_A, encodeTimeout(
355 | timeoutMicrosecondsToMclks(1, macro_period_us)));
356 |
357 | // "Update Range Timing A timeout"
358 | writeReg16Bit(RANGE_CONFIG__TIMEOUT_MACROP_A, encodeTimeout(
359 | timeoutMicrosecondsToMclks(range_config_timeout_us, macro_period_us)));
360 |
361 | // "Update Macro Period for Range B VCSEL Period"
362 | macro_period_us = calcMacroPeriod(readReg(RANGE_CONFIG__VCSEL_PERIOD_B));
363 |
364 | // "Update MM Timing B timeout"
365 | // (See earlier comment about MM Timing A timeout.)
366 | writeReg16Bit(MM_CONFIG__TIMEOUT_MACROP_B, encodeTimeout(
367 | timeoutMicrosecondsToMclks(1, macro_period_us)));
368 |
369 | // "Update Range Timing B timeout"
370 | writeReg16Bit(RANGE_CONFIG__TIMEOUT_MACROP_B, encodeTimeout(
371 | timeoutMicrosecondsToMclks(range_config_timeout_us, macro_period_us)));
372 |
373 | // VL53L1_calc_timeout_register_values() end
374 |
375 | return true;
376 | }
377 |
378 | // Get the measurement timing budget in microseconds
379 | // based on VL53L1_SetMeasurementTimingBudgetMicroSeconds()
380 | uint32_t VL53L1X::getMeasurementTimingBudget()
381 | {
382 | // assumes PresetMode is LOWPOWER_AUTONOMOUS and these sequence steps are
383 | // enabled: VHV, PHASECAL, DSS1, RANGE
384 |
385 | // VL53L1_get_timeouts_us() begin
386 |
387 | // "Update Macro Period for Range A VCSEL Period"
388 | uint32_t macro_period_us = calcMacroPeriod(readReg(RANGE_CONFIG__VCSEL_PERIOD_A));
389 |
390 | // "Get Range Timing A timeout"
391 |
392 | uint32_t range_config_timeout_us = timeoutMclksToMicroseconds(decodeTimeout(
393 | readReg16Bit(RANGE_CONFIG__TIMEOUT_MACROP_A)), macro_period_us);
394 |
395 | // VL53L1_get_timeouts_us() end
396 |
397 | return 2 * range_config_timeout_us + TimingGuard;
398 | }
399 |
400 | // Set the width and height of the region of interest
401 | // based on VL53L1X_SetROI() from STSW-IMG009 Ultra Lite Driver
402 | //
403 | // ST user manual UM2555 explains ROI selection in detail, so we recommend
404 | // reading that document carefully.
405 | void VL53L1X::setROISize(uint8_t width, uint8_t height)
406 | {
407 | if ( width > 16) { width = 16; }
408 | if (height > 16) { height = 16; }
409 |
410 | // Force ROI to be centered if width or height > 10, matching what the ULD API
411 | // does. (This can probably be overridden by calling setROICenter()
412 | // afterwards.)
413 | if (width > 10 || height > 10)
414 | {
415 | writeReg(ROI_CONFIG__USER_ROI_CENTRE_SPAD, 199);
416 | }
417 |
418 | writeReg(ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE,
419 | (height - 1) << 4 | (width - 1));
420 | }
421 |
422 | // Get the width and height of the region of interest (ROI)
423 | // based on VL53L1X_GetROI_XY() from STSW-IMG009 Ultra Lite Driver
424 | void VL53L1X::getROISize(uint8_t * width, uint8_t * height)
425 | {
426 | uint8_t reg_val = readReg(ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE);
427 | *width = (reg_val & 0xF) + 1;
428 | *height = (reg_val >> 4) + 1;
429 | }
430 |
431 | // Set the center SPAD of the region of interest (ROI)
432 | // based on VL53L1X_SetROICenter() from STSW-IMG009 Ultra Lite Driver
433 | //
434 | // ST user manual UM2555 explains ROI selection in detail, so we recommend
435 | // reading that document carefully. Here is a table of SPAD locations from
436 | // UM2555 (199 is the default/center):
437 | //
438 | // 128,136,144,152,160,168,176,184, 192,200,208,216,224,232,240,248
439 | // 129,137,145,153,161,169,177,185, 193,201,209,217,225,233,241,249
440 | // 130,138,146,154,162,170,178,186, 194,202,210,218,226,234,242,250
441 | // 131,139,147,155,163,171,179,187, 195,203,211,219,227,235,243,251
442 | // 132,140,148,156,164,172,180,188, 196,204,212,220,228,236,244,252
443 | // 133,141,149,157,165,173,181,189, 197,205,213,221,229,237,245,253
444 | // 134,142,150,158,166,174,182,190, 198,206,214,222,230,238,246,254
445 | // 135,143,151,159,167,175,183,191, 199,207,215,223,231,239,247,255
446 | //
447 | // 127,119,111,103, 95, 87, 79, 71, 63, 55, 47, 39, 31, 23, 15, 7
448 | // 126,118,110,102, 94, 86, 78, 70, 62, 54, 46, 38, 30, 22, 14, 6
449 | // 125,117,109,101, 93, 85, 77, 69, 61, 53, 45, 37, 29, 21, 13, 5
450 | // 124,116,108,100, 92, 84, 76, 68, 60, 52, 44, 36, 28, 20, 12, 4
451 | // 123,115,107, 99, 91, 83, 75, 67, 59, 51, 43, 35, 27, 19, 11, 3
452 | // 122,114,106, 98, 90, 82, 74, 66, 58, 50, 42, 34, 26, 18, 10, 2
453 | // 121,113,105, 97, 89, 81, 73, 65, 57, 49, 41, 33, 25, 17, 9, 1
454 | // 120,112,104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 <- Pin 1
455 | //
456 | // This table is oriented as if looking into the front of the sensor (or top of
457 | // the chip). SPAD 0 is closest to pin 1 of the VL53L1X, which is the corner
458 | // closest to the VDD pin on the Pololu VL53L1X carrier board:
459 | //
460 | // +--------------+
461 | // | O| GPIO1
462 | // | |
463 | // | O|
464 | // | 128 248 |
465 | // |+----------+ O|
466 | // ||+--+ +--+| |
467 | // ||| | | || O|
468 | // ||+--+ +--+| |
469 | // |+----------+ O|
470 | // | 120 0 |
471 | // | O|
472 | // | |
473 | // | O| VDD
474 | // +--------------+
475 | //
476 | // However, note that the lens inside the VL53L1X inverts the image it sees
477 | // (like the way a camera works). So for example, to shift the sensor's FOV to
478 | // sense objects toward the upper left, you should pick a center SPAD in the
479 | // lower right.
480 | void VL53L1X::setROICenter(uint8_t spadNumber)
481 | {
482 | writeReg(ROI_CONFIG__USER_ROI_CENTRE_SPAD, spadNumber);
483 | }
484 |
485 | // Get the center SPAD of the region of interest
486 | // based on VL53L1X_GetROICenter() from STSW-IMG009 Ultra Lite Driver
487 | uint8_t VL53L1X::getROICenter()
488 | {
489 | return readReg(ROI_CONFIG__USER_ROI_CENTRE_SPAD);
490 | }
491 |
492 | // Start continuous ranging measurements, with the given inter-measurement
493 | // period in milliseconds determining how often the sensor takes a measurement.
494 | void VL53L1X::startContinuous(uint32_t period_ms)
495 | {
496 | // from VL53L1_set_inter_measurement_period_ms()
497 | writeReg32Bit(SYSTEM__INTERMEASUREMENT_PERIOD, period_ms * osc_calibrate_val);
498 |
499 | writeReg(SYSTEM__INTERRUPT_CLEAR, 0x01); // sys_interrupt_clear_range
500 | writeReg(SYSTEM__MODE_START, 0x40); // mode_range__timed
501 | }
502 |
503 | // Stop continuous measurements
504 | // based on VL53L1_stop_range()
505 | void VL53L1X::stopContinuous()
506 | {
507 | writeReg(SYSTEM__MODE_START, 0x80); // mode_range__abort
508 |
509 | // VL53L1_low_power_auto_data_stop_range() begin
510 |
511 | calibrated = false;
512 |
513 | // "restore vhv configs"
514 | if (saved_vhv_init != 0)
515 | {
516 | writeReg(VHV_CONFIG__INIT, saved_vhv_init);
517 | }
518 | if (saved_vhv_timeout != 0)
519 | {
520 | writeReg(VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, saved_vhv_timeout);
521 | }
522 |
523 | // "remove phasecal override"
524 | writeReg(PHASECAL_CONFIG__OVERRIDE, 0x00);
525 |
526 | // VL53L1_low_power_auto_data_stop_range() end
527 | }
528 |
529 | // Returns a range reading in millimeters when continuous mode is active. If
530 | // blocking is true (the default), this function waits for a new measurement to
531 | // be available. If blocking is false, it will try to return data immediately.
532 | // (readSingle() also calls this function after starting a single-shot range
533 | // measurement)
534 | uint16_t VL53L1X::read(bool blocking)
535 | {
536 | if (blocking)
537 | {
538 | startTimeout();
539 | while (!dataReady())
540 | {
541 | if (checkTimeoutExpired())
542 | {
543 | did_timeout = true;
544 | return 0;
545 | }
546 | }
547 | }
548 |
549 | readResults();
550 |
551 | if (!calibrated)
552 | {
553 | setupManualCalibration();
554 | calibrated = true;
555 | }
556 |
557 | updateDSS();
558 |
559 | getRangingData();
560 |
561 | writeReg(SYSTEM__INTERRUPT_CLEAR, 0x01); // sys_interrupt_clear_range
562 |
563 | return ranging_data.range_mm;
564 | }
565 |
566 | // Starts a single-shot range measurement. If blocking is true (the default),
567 | // this function waits for the measurement to finish and returns the reading.
568 | // Otherwise, it returns 0 immediately.
569 | uint16_t VL53L1X::readSingle(bool blocking)
570 | {
571 | writeReg(SYSTEM__INTERRUPT_CLEAR, 0x01); // sys_interrupt_clear_range
572 | writeReg(SYSTEM__MODE_START, 0x10); // mode_range__single_shot
573 |
574 | if (blocking)
575 | {
576 | return read(true);
577 | }
578 | else
579 | {
580 | return 0;
581 | }
582 | }
583 |
584 | // convert a RangeStatus to a readable string
585 | // Note that on an AVR, these strings are stored in RAM (dynamic memory), which
586 | // makes working with them easier but uses up 200+ bytes of RAM (many AVR-based
587 | // Arduinos only have about 2000 bytes of RAM). You can avoid this memory usage
588 | // if you do not call this function in your sketch.
589 | const char * VL53L1X::rangeStatusToString(RangeStatus status)
590 | {
591 | switch (status)
592 | {
593 | case RangeValid:
594 | return "range valid";
595 |
596 | case SigmaFail:
597 | return "sigma fail";
598 |
599 | case SignalFail:
600 | return "signal fail";
601 |
602 | case RangeValidMinRangeClipped:
603 | return "range valid, min range clipped";
604 |
605 | case OutOfBoundsFail:
606 | return "out of bounds fail";
607 |
608 | case HardwareFail:
609 | return "hardware fail";
610 |
611 | case RangeValidNoWrapCheckFail:
612 | return "range valid, no wrap check fail";
613 |
614 | case WrapTargetFail:
615 | return "wrap target fail";
616 |
617 | case XtalkSignalFail:
618 | return "xtalk signal fail";
619 |
620 | case SynchronizationInt:
621 | return "synchronization int";
622 |
623 | case MinRangeFail:
624 | return "min range fail";
625 |
626 | case None:
627 | return "no update";
628 |
629 | default:
630 | return "unknown status";
631 | }
632 | }
633 |
634 | // Did a timeout occur in one of the read functions since the last call to
635 | // timeoutOccurred()?
636 | bool VL53L1X::timeoutOccurred()
637 | {
638 | bool tmp = did_timeout;
639 | did_timeout = false;
640 | return tmp;
641 | }
642 |
643 | // Private Methods /////////////////////////////////////////////////////////////
644 |
645 | // "Setup ranges after the first one in low power auto mode by turning off
646 | // FW calibration steps and programming static values"
647 | // based on VL53L1_low_power_auto_setup_manual_calibration()
648 | void VL53L1X::setupManualCalibration()
649 | {
650 | // "save original vhv configs"
651 | saved_vhv_init = readReg(VHV_CONFIG__INIT);
652 | saved_vhv_timeout = readReg(VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND);
653 |
654 | // "disable VHV init"
655 | writeReg(VHV_CONFIG__INIT, saved_vhv_init & 0x7F);
656 |
657 | // "set loop bound to tuning param"
658 | writeReg(VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,
659 | (saved_vhv_timeout & 0x03) + (3 << 2)); // tuning parm default (LOWPOWERAUTO_VHV_LOOP_BOUND_DEFAULT)
660 |
661 | // "override phasecal"
662 | writeReg(PHASECAL_CONFIG__OVERRIDE, 0x01);
663 | writeReg(CAL_CONFIG__VCSEL_START, readReg(PHASECAL_RESULT__VCSEL_START));
664 | }
665 |
666 | // read measurement results into buffer
667 | void VL53L1X::readResults()
668 | {
669 | bus->beginTransmission(address);
670 | bus->write((uint8_t)(RESULT__RANGE_STATUS >> 8)); // reg high byte
671 | bus->write((uint8_t)(RESULT__RANGE_STATUS)); // reg low byte
672 | last_status = bus->endTransmission();
673 |
674 | bus->requestFrom(address, (uint8_t)17);
675 |
676 | results.range_status = bus->read();
677 |
678 | bus->read(); // report_status: not used
679 |
680 | results.stream_count = bus->read();
681 |
682 | results.dss_actual_effective_spads_sd0 = (uint16_t)bus->read() << 8; // high byte
683 | results.dss_actual_effective_spads_sd0 |= bus->read(); // low byte
684 |
685 | bus->read(); // peak_signal_count_rate_mcps_sd0: not used
686 | bus->read();
687 |
688 | results.ambient_count_rate_mcps_sd0 = (uint16_t)bus->read() << 8; // high byte
689 | results.ambient_count_rate_mcps_sd0 |= bus->read(); // low byte
690 |
691 | bus->read(); // sigma_sd0: not used
692 | bus->read();
693 |
694 | bus->read(); // phase_sd0: not used
695 | bus->read();
696 |
697 | results.final_crosstalk_corrected_range_mm_sd0 = (uint16_t)bus->read() << 8; // high byte
698 | results.final_crosstalk_corrected_range_mm_sd0 |= bus->read(); // low byte
699 |
700 | results.peak_signal_count_rate_crosstalk_corrected_mcps_sd0 = (uint16_t)bus->read() << 8; // high byte
701 | results.peak_signal_count_rate_crosstalk_corrected_mcps_sd0 |= bus->read(); // low byte
702 | }
703 |
704 | // perform Dynamic SPAD Selection calculation/update
705 | // based on VL53L1_low_power_auto_update_DSS()
706 | void VL53L1X::updateDSS()
707 | {
708 | uint16_t spadCount = results.dss_actual_effective_spads_sd0;
709 |
710 | if (spadCount != 0)
711 | {
712 | // "Calc total rate per spad"
713 |
714 | uint32_t totalRatePerSpad =
715 | (uint32_t)results.peak_signal_count_rate_crosstalk_corrected_mcps_sd0 +
716 | results.ambient_count_rate_mcps_sd0;
717 |
718 | // "clip to 16 bits"
719 | if (totalRatePerSpad > 0xFFFF) { totalRatePerSpad = 0xFFFF; }
720 |
721 | // "shift up to take advantage of 32 bits"
722 | totalRatePerSpad <<= 16;
723 |
724 | totalRatePerSpad /= spadCount;
725 |
726 | if (totalRatePerSpad != 0)
727 | {
728 | // "get the target rate and shift up by 16"
729 | uint32_t requiredSpads = ((uint32_t)TargetRate << 16) / totalRatePerSpad;
730 |
731 | // "clip to 16 bit"
732 | if (requiredSpads > 0xFFFF) { requiredSpads = 0xFFFF; }
733 |
734 | // "override DSS config"
735 | writeReg16Bit(DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT, requiredSpads);
736 | // DSS_CONFIG__ROI_MODE_CONTROL should already be set to REQUESTED_EFFFECTIVE_SPADS
737 |
738 | return;
739 | }
740 | }
741 |
742 | // If we reached this point, it means something above would have resulted in a
743 | // divide by zero.
744 | // "We want to gracefully set a spad target, not just exit with an error"
745 |
746 | // "set target to mid point"
747 | writeReg16Bit(DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT, 0x8000);
748 | }
749 |
750 | // get range, status, rates from results buffer
751 | // based on VL53L1_GetRangingMeasurementData()
752 | void VL53L1X::getRangingData()
753 | {
754 | // VL53L1_copy_sys_and_core_results_to_range_results() begin
755 |
756 | uint16_t range = results.final_crosstalk_corrected_range_mm_sd0;
757 |
758 | // "apply correction gain"
759 | // gain factor of 2011 is tuning parm default (VL53L1_TUNINGPARM_LITE_RANGING_GAIN_FACTOR_DEFAULT)
760 | // Basically, this appears to scale the result by 2011/2048, or about 98%
761 | // (with the 1024 added for proper rounding).
762 | ranging_data.range_mm = ((uint32_t)range * 2011 + 0x0400) / 0x0800;
763 |
764 | // VL53L1_copy_sys_and_core_results_to_range_results() end
765 |
766 | // set range_status in ranging_data based on value of RESULT__RANGE_STATUS register
767 | // mostly based on ConvertStatusLite()
768 | switch(results.range_status)
769 | {
770 | case 17: // MULTCLIPFAIL
771 | case 2: // VCSELWATCHDOGTESTFAILURE
772 | case 1: // VCSELCONTINUITYTESTFAILURE
773 | case 3: // NOVHVVALUEFOUND
774 | // from SetSimpleData()
775 | ranging_data.range_status = HardwareFail;
776 | break;
777 |
778 | case 13: // USERROICLIP
779 | // from SetSimpleData()
780 | ranging_data.range_status = MinRangeFail;
781 | break;
782 |
783 | case 18: // GPHSTREAMCOUNT0READY
784 | ranging_data.range_status = SynchronizationInt;
785 | break;
786 |
787 | case 5: // RANGEPHASECHECK
788 | ranging_data.range_status = OutOfBoundsFail;
789 | break;
790 |
791 | case 4: // MSRCNOTARGET
792 | ranging_data.range_status = SignalFail;
793 | break;
794 |
795 | case 6: // SIGMATHRESHOLDCHECK
796 | ranging_data.range_status = SigmaFail;
797 | break;
798 |
799 | case 7: // PHASECONSISTENCY
800 | ranging_data.range_status = WrapTargetFail;
801 | break;
802 |
803 | case 12: // RANGEIGNORETHRESHOLD
804 | ranging_data.range_status = XtalkSignalFail;
805 | break;
806 |
807 | case 8: // MINCLIP
808 | ranging_data.range_status = RangeValidMinRangeClipped;
809 | break;
810 |
811 | case 9: // RANGECOMPLETE
812 | // from VL53L1_copy_sys_and_core_results_to_range_results()
813 | if (results.stream_count == 0)
814 | {
815 | ranging_data.range_status = RangeValidNoWrapCheckFail;
816 | }
817 | else
818 | {
819 | ranging_data.range_status = RangeValid;
820 | }
821 | break;
822 |
823 | default:
824 | ranging_data.range_status = None;
825 | }
826 |
827 | // from SetSimpleData()
828 | ranging_data.peak_signal_count_rate_MCPS =
829 | countRateFixedToFloat(results.peak_signal_count_rate_crosstalk_corrected_mcps_sd0);
830 | ranging_data.ambient_count_rate_MCPS =
831 | countRateFixedToFloat(results.ambient_count_rate_mcps_sd0);
832 | }
833 |
834 | // Decode sequence step timeout in MCLKs from register value
835 | // based on VL53L1_decode_timeout()
836 | uint32_t VL53L1X::decodeTimeout(uint16_t reg_val)
837 | {
838 | return ((uint32_t)(reg_val & 0xFF) << (reg_val >> 8)) + 1;
839 | }
840 |
841 | // Encode sequence step timeout register value from timeout in MCLKs
842 | // based on VL53L1_encode_timeout()
843 | uint16_t VL53L1X::encodeTimeout(uint32_t timeout_mclks)
844 | {
845 | // encoded format: "(LSByte * 2^MSByte) + 1"
846 |
847 | uint32_t ls_byte = 0;
848 | uint16_t ms_byte = 0;
849 |
850 | if (timeout_mclks > 0)
851 | {
852 | ls_byte = timeout_mclks - 1;
853 |
854 | while ((ls_byte & 0xFFFFFF00) > 0)
855 | {
856 | ls_byte >>= 1;
857 | ms_byte++;
858 | }
859 |
860 | return (ms_byte << 8) | (ls_byte & 0xFF);
861 | }
862 | else { return 0; }
863 | }
864 |
865 | // Convert sequence step timeout from macro periods to microseconds with given
866 | // macro period in microseconds (12.12 format)
867 | // based on VL53L1_calc_timeout_us()
868 | uint32_t VL53L1X::timeoutMclksToMicroseconds(uint32_t timeout_mclks, uint32_t macro_period_us)
869 | {
870 | return ((uint64_t)timeout_mclks * macro_period_us + 0x800) >> 12;
871 | }
872 |
873 | // Convert sequence step timeout from microseconds to macro periods with given
874 | // macro period in microseconds (12.12 format)
875 | // based on VL53L1_calc_timeout_mclks()
876 | uint32_t VL53L1X::timeoutMicrosecondsToMclks(uint32_t timeout_us, uint32_t macro_period_us)
877 | {
878 | return (((uint32_t)timeout_us << 12) + (macro_period_us >> 1)) / macro_period_us;
879 | }
880 |
881 | // Calculate macro period in microseconds (12.12 format) with given VCSEL period
882 | // assumes fast_osc_frequency has been read and stored
883 | // based on VL53L1_calc_macro_period_us()
884 | uint32_t VL53L1X::calcMacroPeriod(uint8_t vcsel_period)
885 | {
886 | // from VL53L1_calc_pll_period_us()
887 | // fast osc frequency in 4.12 format; PLL period in 0.24 format
888 | uint32_t pll_period_us = ((uint32_t)0x01 << 30) / fast_osc_frequency;
889 |
890 | // from VL53L1_decode_vcsel_period()
891 | uint8_t vcsel_period_pclks = (vcsel_period + 1) << 1;
892 |
893 | // VL53L1_MACRO_PERIOD_VCSEL_PERIODS = 2304
894 | uint32_t macro_period_us = (uint32_t)2304 * pll_period_us;
895 | macro_period_us >>= 6;
896 | macro_period_us *= vcsel_period_pclks;
897 | macro_period_us >>= 6;
898 |
899 | return macro_period_us;
900 | }
901 |
--------------------------------------------------------------------------------
/VL53L1X.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | class VL53L1X
7 | {
8 | public:
9 |
10 | // register addresses from API vl53l1x_register_map.h
11 | enum regAddr : uint16_t
12 | {
13 | SOFT_RESET = 0x0000,
14 | I2C_SLAVE__DEVICE_ADDRESS = 0x0001,
15 | ANA_CONFIG__VHV_REF_SEL_VDDPIX = 0x0002,
16 | ANA_CONFIG__VHV_REF_SEL_VQUENCH = 0x0003,
17 | ANA_CONFIG__REG_AVDD1V2_SEL = 0x0004,
18 | ANA_CONFIG__FAST_OSC__TRIM = 0x0005,
19 | OSC_MEASURED__FAST_OSC__FREQUENCY = 0x0006,
20 | OSC_MEASURED__FAST_OSC__FREQUENCY_HI = 0x0006,
21 | OSC_MEASURED__FAST_OSC__FREQUENCY_LO = 0x0007,
22 | VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND = 0x0008,
23 | VHV_CONFIG__COUNT_THRESH = 0x0009,
24 | VHV_CONFIG__OFFSET = 0x000A,
25 | VHV_CONFIG__INIT = 0x000B,
26 | GLOBAL_CONFIG__SPAD_ENABLES_REF_0 = 0x000D,
27 | GLOBAL_CONFIG__SPAD_ENABLES_REF_1 = 0x000E,
28 | GLOBAL_CONFIG__SPAD_ENABLES_REF_2 = 0x000F,
29 | GLOBAL_CONFIG__SPAD_ENABLES_REF_3 = 0x0010,
30 | GLOBAL_CONFIG__SPAD_ENABLES_REF_4 = 0x0011,
31 | GLOBAL_CONFIG__SPAD_ENABLES_REF_5 = 0x0012,
32 | GLOBAL_CONFIG__REF_EN_START_SELECT = 0x0013,
33 | REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS = 0x0014,
34 | REF_SPAD_MAN__REF_LOCATION = 0x0015,
35 | ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS = 0x0016,
36 | ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS_HI = 0x0016,
37 | ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS_LO = 0x0017,
38 | ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS = 0x0018,
39 | ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS_HI = 0x0018,
40 | ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS_LO = 0x0019,
41 | ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS = 0x001A,
42 | ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS_HI = 0x001A,
43 | ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS_LO = 0x001B,
44 | REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS = 0x001C,
45 | REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS_HI = 0x001C,
46 | REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS_LO = 0x001D,
47 | ALGO__PART_TO_PART_RANGE_OFFSET_MM = 0x001E,
48 | ALGO__PART_TO_PART_RANGE_OFFSET_MM_HI = 0x001E,
49 | ALGO__PART_TO_PART_RANGE_OFFSET_MM_LO = 0x001F,
50 | MM_CONFIG__INNER_OFFSET_MM = 0x0020,
51 | MM_CONFIG__INNER_OFFSET_MM_HI = 0x0020,
52 | MM_CONFIG__INNER_OFFSET_MM_LO = 0x0021,
53 | MM_CONFIG__OUTER_OFFSET_MM = 0x0022,
54 | MM_CONFIG__OUTER_OFFSET_MM_HI = 0x0022,
55 | MM_CONFIG__OUTER_OFFSET_MM_LO = 0x0023,
56 | DSS_CONFIG__TARGET_TOTAL_RATE_MCPS = 0x0024,
57 | DSS_CONFIG__TARGET_TOTAL_RATE_MCPS_HI = 0x0024,
58 | DSS_CONFIG__TARGET_TOTAL_RATE_MCPS_LO = 0x0025,
59 | DEBUG__CTRL = 0x0026,
60 | TEST_MODE__CTRL = 0x0027,
61 | CLK_GATING__CTRL = 0x0028,
62 | NVM_BIST__CTRL = 0x0029,
63 | NVM_BIST__NUM_NVM_WORDS = 0x002A,
64 | NVM_BIST__START_ADDRESS = 0x002B,
65 | HOST_IF__STATUS = 0x002C,
66 | PAD_I2C_HV__CONFIG = 0x002D,
67 | PAD_I2C_HV__EXTSUP_CONFIG = 0x002E,
68 | GPIO_HV_PAD__CTRL = 0x002F,
69 | GPIO_HV_MUX__CTRL = 0x0030,
70 | GPIO__TIO_HV_STATUS = 0x0031,
71 | GPIO__FIO_HV_STATUS = 0x0032,
72 | ANA_CONFIG__SPAD_SEL_PSWIDTH = 0x0033,
73 | ANA_CONFIG__VCSEL_PULSE_WIDTH_OFFSET = 0x0034,
74 | ANA_CONFIG__FAST_OSC__CONFIG_CTRL = 0x0035,
75 | SIGMA_ESTIMATOR__EFFECTIVE_PULSE_WIDTH_NS = 0x0036,
76 | SIGMA_ESTIMATOR__EFFECTIVE_AMBIENT_WIDTH_NS = 0x0037,
77 | SIGMA_ESTIMATOR__SIGMA_REF_MM = 0x0038,
78 | ALGO__CROSSTALK_COMPENSATION_VALID_HEIGHT_MM = 0x0039,
79 | SPARE_HOST_CONFIG__STATIC_CONFIG_SPARE_0 = 0x003A,
80 | SPARE_HOST_CONFIG__STATIC_CONFIG_SPARE_1 = 0x003B,
81 | ALGO__RANGE_IGNORE_THRESHOLD_MCPS = 0x003C,
82 | ALGO__RANGE_IGNORE_THRESHOLD_MCPS_HI = 0x003C,
83 | ALGO__RANGE_IGNORE_THRESHOLD_MCPS_LO = 0x003D,
84 | ALGO__RANGE_IGNORE_VALID_HEIGHT_MM = 0x003E,
85 | ALGO__RANGE_MIN_CLIP = 0x003F,
86 | ALGO__CONSISTENCY_CHECK__TOLERANCE = 0x0040,
87 | SPARE_HOST_CONFIG__STATIC_CONFIG_SPARE_2 = 0x0041,
88 | SD_CONFIG__RESET_STAGES_MSB = 0x0042,
89 | SD_CONFIG__RESET_STAGES_LSB = 0x0043,
90 | GPH_CONFIG__STREAM_COUNT_UPDATE_VALUE = 0x0044,
91 | GLOBAL_CONFIG__STREAM_DIVIDER = 0x0045,
92 | SYSTEM__INTERRUPT_CONFIG_GPIO = 0x0046,
93 | CAL_CONFIG__VCSEL_START = 0x0047,
94 | CAL_CONFIG__REPEAT_RATE = 0x0048,
95 | CAL_CONFIG__REPEAT_RATE_HI = 0x0048,
96 | CAL_CONFIG__REPEAT_RATE_LO = 0x0049,
97 | GLOBAL_CONFIG__VCSEL_WIDTH = 0x004A,
98 | PHASECAL_CONFIG__TIMEOUT_MACROP = 0x004B,
99 | PHASECAL_CONFIG__TARGET = 0x004C,
100 | PHASECAL_CONFIG__OVERRIDE = 0x004D,
101 | DSS_CONFIG__ROI_MODE_CONTROL = 0x004F,
102 | SYSTEM__THRESH_RATE_HIGH = 0x0050,
103 | SYSTEM__THRESH_RATE_HIGH_HI = 0x0050,
104 | SYSTEM__THRESH_RATE_HIGH_LO = 0x0051,
105 | SYSTEM__THRESH_RATE_LOW = 0x0052,
106 | SYSTEM__THRESH_RATE_LOW_HI = 0x0052,
107 | SYSTEM__THRESH_RATE_LOW_LO = 0x0053,
108 | DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT = 0x0054,
109 | DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT_HI = 0x0054,
110 | DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT_LO = 0x0055,
111 | DSS_CONFIG__MANUAL_BLOCK_SELECT = 0x0056,
112 | DSS_CONFIG__APERTURE_ATTENUATION = 0x0057,
113 | DSS_CONFIG__MAX_SPADS_LIMIT = 0x0058,
114 | DSS_CONFIG__MIN_SPADS_LIMIT = 0x0059,
115 | MM_CONFIG__TIMEOUT_MACROP_A = 0x005A, // added by Pololu for 16-bit accesses
116 | MM_CONFIG__TIMEOUT_MACROP_A_HI = 0x005A,
117 | MM_CONFIG__TIMEOUT_MACROP_A_LO = 0x005B,
118 | MM_CONFIG__TIMEOUT_MACROP_B = 0x005C, // added by Pololu for 16-bit accesses
119 | MM_CONFIG__TIMEOUT_MACROP_B_HI = 0x005C,
120 | MM_CONFIG__TIMEOUT_MACROP_B_LO = 0x005D,
121 | RANGE_CONFIG__TIMEOUT_MACROP_A = 0x005E, // added by Pololu for 16-bit accesses
122 | RANGE_CONFIG__TIMEOUT_MACROP_A_HI = 0x005E,
123 | RANGE_CONFIG__TIMEOUT_MACROP_A_LO = 0x005F,
124 | RANGE_CONFIG__VCSEL_PERIOD_A = 0x0060,
125 | RANGE_CONFIG__TIMEOUT_MACROP_B = 0x0061, // added by Pololu for 16-bit accesses
126 | RANGE_CONFIG__TIMEOUT_MACROP_B_HI = 0x0061,
127 | RANGE_CONFIG__TIMEOUT_MACROP_B_LO = 0x0062,
128 | RANGE_CONFIG__VCSEL_PERIOD_B = 0x0063,
129 | RANGE_CONFIG__SIGMA_THRESH = 0x0064,
130 | RANGE_CONFIG__SIGMA_THRESH_HI = 0x0064,
131 | RANGE_CONFIG__SIGMA_THRESH_LO = 0x0065,
132 | RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS = 0x0066,
133 | RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS_HI = 0x0066,
134 | RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS_LO = 0x0067,
135 | RANGE_CONFIG__VALID_PHASE_LOW = 0x0068,
136 | RANGE_CONFIG__VALID_PHASE_HIGH = 0x0069,
137 | SYSTEM__INTERMEASUREMENT_PERIOD = 0x006C,
138 | SYSTEM__INTERMEASUREMENT_PERIOD_3 = 0x006C,
139 | SYSTEM__INTERMEASUREMENT_PERIOD_2 = 0x006D,
140 | SYSTEM__INTERMEASUREMENT_PERIOD_1 = 0x006E,
141 | SYSTEM__INTERMEASUREMENT_PERIOD_0 = 0x006F,
142 | SYSTEM__FRACTIONAL_ENABLE = 0x0070,
143 | SYSTEM__GROUPED_PARAMETER_HOLD_0 = 0x0071,
144 | SYSTEM__THRESH_HIGH = 0x0072,
145 | SYSTEM__THRESH_HIGH_HI = 0x0072,
146 | SYSTEM__THRESH_HIGH_LO = 0x0073,
147 | SYSTEM__THRESH_LOW = 0x0074,
148 | SYSTEM__THRESH_LOW_HI = 0x0074,
149 | SYSTEM__THRESH_LOW_LO = 0x0075,
150 | SYSTEM__ENABLE_XTALK_PER_QUADRANT = 0x0076,
151 | SYSTEM__SEED_CONFIG = 0x0077,
152 | SD_CONFIG__WOI_SD0 = 0x0078,
153 | SD_CONFIG__WOI_SD1 = 0x0079,
154 | SD_CONFIG__INITIAL_PHASE_SD0 = 0x007A,
155 | SD_CONFIG__INITIAL_PHASE_SD1 = 0x007B,
156 | SYSTEM__GROUPED_PARAMETER_HOLD_1 = 0x007C,
157 | SD_CONFIG__FIRST_ORDER_SELECT = 0x007D,
158 | SD_CONFIG__QUANTIFIER = 0x007E,
159 | ROI_CONFIG__USER_ROI_CENTRE_SPAD = 0x007F,
160 | ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE = 0x0080,
161 | SYSTEM__SEQUENCE_CONFIG = 0x0081,
162 | SYSTEM__GROUPED_PARAMETER_HOLD = 0x0082,
163 | POWER_MANAGEMENT__GO1_POWER_FORCE = 0x0083,
164 | SYSTEM__STREAM_COUNT_CTRL = 0x0084,
165 | FIRMWARE__ENABLE = 0x0085,
166 | SYSTEM__INTERRUPT_CLEAR = 0x0086,
167 | SYSTEM__MODE_START = 0x0087,
168 | RESULT__INTERRUPT_STATUS = 0x0088,
169 | RESULT__RANGE_STATUS = 0x0089,
170 | RESULT__REPORT_STATUS = 0x008A,
171 | RESULT__STREAM_COUNT = 0x008B,
172 | RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x008C,
173 | RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x008C,
174 | RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x008D,
175 | RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0 = 0x008E,
176 | RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_HI = 0x008E,
177 | RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_LO = 0x008F,
178 | RESULT__AMBIENT_COUNT_RATE_MCPS_SD0 = 0x0090,
179 | RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_HI = 0x0090,
180 | RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_LO = 0x0091,
181 | RESULT__SIGMA_SD0 = 0x0092,
182 | RESULT__SIGMA_SD0_HI = 0x0092,
183 | RESULT__SIGMA_SD0_LO = 0x0093,
184 | RESULT__PHASE_SD0 = 0x0094,
185 | RESULT__PHASE_SD0_HI = 0x0094,
186 | RESULT__PHASE_SD0_LO = 0x0095,
187 | RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 = 0x0096,
188 | RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_HI = 0x0096,
189 | RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_LO = 0x0097,
190 | RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 = 0x0098,
191 | RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_HI = 0x0098,
192 | RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO = 0x0099,
193 | RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x009A,
194 | RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x009A,
195 | RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x009B,
196 | RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x009C,
197 | RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x009C,
198 | RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x009D,
199 | RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0 = 0x009E,
200 | RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_HI = 0x009E,
201 | RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_LO = 0x009F,
202 | RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1 = 0x00A0,
203 | RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_HI = 0x00A0,
204 | RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_LO = 0x00A1,
205 | RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1 = 0x00A2,
206 | RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_HI = 0x00A2,
207 | RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_LO = 0x00A3,
208 | RESULT__AMBIENT_COUNT_RATE_MCPS_SD1 = 0x00A4,
209 | RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_HI = 0x00A4,
210 | RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_LO = 0x00A5,
211 | RESULT__SIGMA_SD1 = 0x00A6,
212 | RESULT__SIGMA_SD1_HI = 0x00A6,
213 | RESULT__SIGMA_SD1_LO = 0x00A7,
214 | RESULT__PHASE_SD1 = 0x00A8,
215 | RESULT__PHASE_SD1_HI = 0x00A8,
216 | RESULT__PHASE_SD1_LO = 0x00A9,
217 | RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1 = 0x00AA,
218 | RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_HI = 0x00AA,
219 | RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_LO = 0x00AB,
220 | RESULT__SPARE_0_SD1 = 0x00AC,
221 | RESULT__SPARE_0_SD1_HI = 0x00AC,
222 | RESULT__SPARE_0_SD1_LO = 0x00AD,
223 | RESULT__SPARE_1_SD1 = 0x00AE,
224 | RESULT__SPARE_1_SD1_HI = 0x00AE,
225 | RESULT__SPARE_1_SD1_LO = 0x00AF,
226 | RESULT__SPARE_2_SD1 = 0x00B0,
227 | RESULT__SPARE_2_SD1_HI = 0x00B0,
228 | RESULT__SPARE_2_SD1_LO = 0x00B1,
229 | RESULT__SPARE_3_SD1 = 0x00B2,
230 | RESULT__THRESH_INFO = 0x00B3,
231 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 = 0x00B4,
232 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_3 = 0x00B4,
233 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_2 = 0x00B5,
234 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_1 = 0x00B6,
235 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_0 = 0x00B7,
236 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD0 = 0x00B8,
237 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_3 = 0x00B8,
238 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_2 = 0x00B9,
239 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_1 = 0x00BA,
240 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_0 = 0x00BB,
241 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0 = 0x00BC,
242 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_3 = 0x00BC,
243 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_2 = 0x00BD,
244 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_1 = 0x00BE,
245 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_0 = 0x00BF,
246 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0 = 0x00C0,
247 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_3 = 0x00C0,
248 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_2 = 0x00C1,
249 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_1 = 0x00C2,
250 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_0 = 0x00C3,
251 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1 = 0x00C4,
252 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_3 = 0x00C4,
253 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_2 = 0x00C5,
254 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_1 = 0x00C6,
255 | RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_0 = 0x00C7,
256 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD1 = 0x00C8,
257 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_3 = 0x00C8,
258 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_2 = 0x00C9,
259 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_1 = 0x00CA,
260 | RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_0 = 0x00CB,
261 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1 = 0x00CC,
262 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_3 = 0x00CC,
263 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_2 = 0x00CD,
264 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_1 = 0x00CE,
265 | RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_0 = 0x00CF,
266 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1 = 0x00D0,
267 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_3 = 0x00D0,
268 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_2 = 0x00D1,
269 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_1 = 0x00D2,
270 | RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_0 = 0x00D3,
271 | RESULT_CORE__SPARE_0 = 0x00D4,
272 | PHASECAL_RESULT__REFERENCE_PHASE = 0x00D6,
273 | PHASECAL_RESULT__REFERENCE_PHASE_HI = 0x00D6,
274 | PHASECAL_RESULT__REFERENCE_PHASE_LO = 0x00D7,
275 | PHASECAL_RESULT__VCSEL_START = 0x00D8,
276 | REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS = 0x00D9,
277 | REF_SPAD_CHAR_RESULT__REF_LOCATION = 0x00DA,
278 | VHV_RESULT__COLDBOOT_STATUS = 0x00DB,
279 | VHV_RESULT__SEARCH_RESULT = 0x00DC,
280 | VHV_RESULT__LATEST_SETTING = 0x00DD,
281 | RESULT__OSC_CALIBRATE_VAL = 0x00DE,
282 | RESULT__OSC_CALIBRATE_VAL_HI = 0x00DE,
283 | RESULT__OSC_CALIBRATE_VAL_LO = 0x00DF,
284 | ANA_CONFIG__POWERDOWN_GO1 = 0x00E0,
285 | ANA_CONFIG__REF_BG_CTRL = 0x00E1,
286 | ANA_CONFIG__REGDVDD1V2_CTRL = 0x00E2,
287 | ANA_CONFIG__OSC_SLOW_CTRL = 0x00E3,
288 | TEST_MODE__STATUS = 0x00E4,
289 | FIRMWARE__SYSTEM_STATUS = 0x00E5,
290 | FIRMWARE__MODE_STATUS = 0x00E6,
291 | FIRMWARE__SECONDARY_MODE_STATUS = 0x00E7,
292 | FIRMWARE__CAL_REPEAT_RATE_COUNTER = 0x00E8,
293 | FIRMWARE__CAL_REPEAT_RATE_COUNTER_HI = 0x00E8,
294 | FIRMWARE__CAL_REPEAT_RATE_COUNTER_LO = 0x00E9,
295 | FIRMWARE__HISTOGRAM_BIN = 0x00EA,
296 | GPH__SYSTEM__THRESH_HIGH = 0x00EC,
297 | GPH__SYSTEM__THRESH_HIGH_HI = 0x00EC,
298 | GPH__SYSTEM__THRESH_HIGH_LO = 0x00ED,
299 | GPH__SYSTEM__THRESH_LOW = 0x00EE,
300 | GPH__SYSTEM__THRESH_LOW_HI = 0x00EE,
301 | GPH__SYSTEM__THRESH_LOW_LO = 0x00EF,
302 | GPH__SYSTEM__ENABLE_XTALK_PER_QUADRANT = 0x00F0,
303 | GPH__SPARE_0 = 0x00F1,
304 | GPH__SD_CONFIG__WOI_SD0 = 0x00F2,
305 | GPH__SD_CONFIG__WOI_SD1 = 0x00F3,
306 | GPH__SD_CONFIG__INITIAL_PHASE_SD0 = 0x00F4,
307 | GPH__SD_CONFIG__INITIAL_PHASE_SD1 = 0x00F5,
308 | GPH__SD_CONFIG__FIRST_ORDER_SELECT = 0x00F6,
309 | GPH__SD_CONFIG__QUANTIFIER = 0x00F7,
310 | GPH__ROI_CONFIG__USER_ROI_CENTRE_SPAD = 0x00F8,
311 | GPH__ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE = 0x00F9,
312 | GPH__SYSTEM__SEQUENCE_CONFIG = 0x00FA,
313 | GPH__GPH_ID = 0x00FB,
314 | SYSTEM__INTERRUPT_SET = 0x00FC,
315 | INTERRUPT_MANAGER__ENABLES = 0x00FD,
316 | INTERRUPT_MANAGER__CLEAR = 0x00FE,
317 | INTERRUPT_MANAGER__STATUS = 0x00FF,
318 | MCU_TO_HOST_BANK__WR_ACCESS_EN = 0x0100,
319 | POWER_MANAGEMENT__GO1_RESET_STATUS = 0x0101,
320 | PAD_STARTUP_MODE__VALUE_RO = 0x0102,
321 | PAD_STARTUP_MODE__VALUE_CTRL = 0x0103,
322 | PLL_PERIOD_US = 0x0104,
323 | PLL_PERIOD_US_3 = 0x0104,
324 | PLL_PERIOD_US_2 = 0x0105,
325 | PLL_PERIOD_US_1 = 0x0106,
326 | PLL_PERIOD_US_0 = 0x0107,
327 | INTERRUPT_SCHEDULER__DATA_OUT = 0x0108,
328 | INTERRUPT_SCHEDULER__DATA_OUT_3 = 0x0108,
329 | INTERRUPT_SCHEDULER__DATA_OUT_2 = 0x0109,
330 | INTERRUPT_SCHEDULER__DATA_OUT_1 = 0x010A,
331 | INTERRUPT_SCHEDULER__DATA_OUT_0 = 0x010B,
332 | NVM_BIST__COMPLETE = 0x010C,
333 | NVM_BIST__STATUS = 0x010D,
334 | IDENTIFICATION__MODEL_ID = 0x010F,
335 | IDENTIFICATION__MODULE_TYPE = 0x0110,
336 | IDENTIFICATION__REVISION_ID = 0x0111,
337 | IDENTIFICATION__MODULE_ID = 0x0112,
338 | IDENTIFICATION__MODULE_ID_HI = 0x0112,
339 | IDENTIFICATION__MODULE_ID_LO = 0x0113,
340 | ANA_CONFIG__FAST_OSC__TRIM_MAX = 0x0114,
341 | ANA_CONFIG__FAST_OSC__FREQ_SET = 0x0115,
342 | ANA_CONFIG__VCSEL_TRIM = 0x0116,
343 | ANA_CONFIG__VCSEL_SELION = 0x0117,
344 | ANA_CONFIG__VCSEL_SELION_MAX = 0x0118,
345 | PROTECTED_LASER_SAFETY__LOCK_BIT = 0x0119,
346 | LASER_SAFETY__KEY = 0x011A,
347 | LASER_SAFETY__KEY_RO = 0x011B,
348 | LASER_SAFETY__CLIP = 0x011C,
349 | LASER_SAFETY__MULT = 0x011D,
350 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_0 = 0x011E,
351 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_1 = 0x011F,
352 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_2 = 0x0120,
353 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_3 = 0x0121,
354 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_4 = 0x0122,
355 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_5 = 0x0123,
356 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_6 = 0x0124,
357 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_7 = 0x0125,
358 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_8 = 0x0126,
359 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_9 = 0x0127,
360 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_10 = 0x0128,
361 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_11 = 0x0129,
362 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_12 = 0x012A,
363 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_13 = 0x012B,
364 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_14 = 0x012C,
365 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_15 = 0x012D,
366 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_16 = 0x012E,
367 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_17 = 0x012F,
368 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_18 = 0x0130,
369 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_19 = 0x0131,
370 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_20 = 0x0132,
371 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_21 = 0x0133,
372 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_22 = 0x0134,
373 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_23 = 0x0135,
374 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_24 = 0x0136,
375 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_25 = 0x0137,
376 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_26 = 0x0138,
377 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_27 = 0x0139,
378 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_28 = 0x013A,
379 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_29 = 0x013B,
380 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_30 = 0x013C,
381 | GLOBAL_CONFIG__SPAD_ENABLES_RTN_31 = 0x013D,
382 | ROI_CONFIG__MODE_ROI_CENTRE_SPAD = 0x013E,
383 | ROI_CONFIG__MODE_ROI_XY_SIZE = 0x013F,
384 | GO2_HOST_BANK_ACCESS__OVERRIDE = 0x0300,
385 | MCU_UTIL_MULTIPLIER__MULTIPLICAND = 0x0400,
386 | MCU_UTIL_MULTIPLIER__MULTIPLICAND_3 = 0x0400,
387 | MCU_UTIL_MULTIPLIER__MULTIPLICAND_2 = 0x0401,
388 | MCU_UTIL_MULTIPLIER__MULTIPLICAND_1 = 0x0402,
389 | MCU_UTIL_MULTIPLIER__MULTIPLICAND_0 = 0x0403,
390 | MCU_UTIL_MULTIPLIER__MULTIPLIER = 0x0404,
391 | MCU_UTIL_MULTIPLIER__MULTIPLIER_3 = 0x0404,
392 | MCU_UTIL_MULTIPLIER__MULTIPLIER_2 = 0x0405,
393 | MCU_UTIL_MULTIPLIER__MULTIPLIER_1 = 0x0406,
394 | MCU_UTIL_MULTIPLIER__MULTIPLIER_0 = 0x0407,
395 | MCU_UTIL_MULTIPLIER__PRODUCT_HI = 0x0408,
396 | MCU_UTIL_MULTIPLIER__PRODUCT_HI_3 = 0x0408,
397 | MCU_UTIL_MULTIPLIER__PRODUCT_HI_2 = 0x0409,
398 | MCU_UTIL_MULTIPLIER__PRODUCT_HI_1 = 0x040A,
399 | MCU_UTIL_MULTIPLIER__PRODUCT_HI_0 = 0x040B,
400 | MCU_UTIL_MULTIPLIER__PRODUCT_LO = 0x040C,
401 | MCU_UTIL_MULTIPLIER__PRODUCT_LO_3 = 0x040C,
402 | MCU_UTIL_MULTIPLIER__PRODUCT_LO_2 = 0x040D,
403 | MCU_UTIL_MULTIPLIER__PRODUCT_LO_1 = 0x040E,
404 | MCU_UTIL_MULTIPLIER__PRODUCT_LO_0 = 0x040F,
405 | MCU_UTIL_MULTIPLIER__START = 0x0410,
406 | MCU_UTIL_MULTIPLIER__STATUS = 0x0411,
407 | MCU_UTIL_DIVIDER__START = 0x0412,
408 | MCU_UTIL_DIVIDER__STATUS = 0x0413,
409 | MCU_UTIL_DIVIDER__DIVIDEND = 0x0414,
410 | MCU_UTIL_DIVIDER__DIVIDEND_3 = 0x0414,
411 | MCU_UTIL_DIVIDER__DIVIDEND_2 = 0x0415,
412 | MCU_UTIL_DIVIDER__DIVIDEND_1 = 0x0416,
413 | MCU_UTIL_DIVIDER__DIVIDEND_0 = 0x0417,
414 | MCU_UTIL_DIVIDER__DIVISOR = 0x0418,
415 | MCU_UTIL_DIVIDER__DIVISOR_3 = 0x0418,
416 | MCU_UTIL_DIVIDER__DIVISOR_2 = 0x0419,
417 | MCU_UTIL_DIVIDER__DIVISOR_1 = 0x041A,
418 | MCU_UTIL_DIVIDER__DIVISOR_0 = 0x041B,
419 | MCU_UTIL_DIVIDER__QUOTIENT = 0x041C,
420 | MCU_UTIL_DIVIDER__QUOTIENT_3 = 0x041C,
421 | MCU_UTIL_DIVIDER__QUOTIENT_2 = 0x041D,
422 | MCU_UTIL_DIVIDER__QUOTIENT_1 = 0x041E,
423 | MCU_UTIL_DIVIDER__QUOTIENT_0 = 0x041F,
424 | TIMER0__VALUE_IN = 0x0420,
425 | TIMER0__VALUE_IN_3 = 0x0420,
426 | TIMER0__VALUE_IN_2 = 0x0421,
427 | TIMER0__VALUE_IN_1 = 0x0422,
428 | TIMER0__VALUE_IN_0 = 0x0423,
429 | TIMER1__VALUE_IN = 0x0424,
430 | TIMER1__VALUE_IN_3 = 0x0424,
431 | TIMER1__VALUE_IN_2 = 0x0425,
432 | TIMER1__VALUE_IN_1 = 0x0426,
433 | TIMER1__VALUE_IN_0 = 0x0427,
434 | TIMER0__CTRL = 0x0428,
435 | TIMER1__CTRL = 0x0429,
436 | MCU_GENERAL_PURPOSE__GP_0 = 0x042C,
437 | MCU_GENERAL_PURPOSE__GP_1 = 0x042D,
438 | MCU_GENERAL_PURPOSE__GP_2 = 0x042E,
439 | MCU_GENERAL_PURPOSE__GP_3 = 0x042F,
440 | MCU_RANGE_CALC__CONFIG = 0x0430,
441 | MCU_RANGE_CALC__OFFSET_CORRECTED_RANGE = 0x0432,
442 | MCU_RANGE_CALC__OFFSET_CORRECTED_RANGE_HI = 0x0432,
443 | MCU_RANGE_CALC__OFFSET_CORRECTED_RANGE_LO = 0x0433,
444 | MCU_RANGE_CALC__SPARE_4 = 0x0434,
445 | MCU_RANGE_CALC__SPARE_4_3 = 0x0434,
446 | MCU_RANGE_CALC__SPARE_4_2 = 0x0435,
447 | MCU_RANGE_CALC__SPARE_4_1 = 0x0436,
448 | MCU_RANGE_CALC__SPARE_4_0 = 0x0437,
449 | MCU_RANGE_CALC__AMBIENT_DURATION_PRE_CALC = 0x0438,
450 | MCU_RANGE_CALC__AMBIENT_DURATION_PRE_CALC_HI = 0x0438,
451 | MCU_RANGE_CALC__AMBIENT_DURATION_PRE_CALC_LO = 0x0439,
452 | MCU_RANGE_CALC__ALGO_VCSEL_PERIOD = 0x043C,
453 | MCU_RANGE_CALC__SPARE_5 = 0x043D,
454 | MCU_RANGE_CALC__ALGO_TOTAL_PERIODS = 0x043E,
455 | MCU_RANGE_CALC__ALGO_TOTAL_PERIODS_HI = 0x043E,
456 | MCU_RANGE_CALC__ALGO_TOTAL_PERIODS_LO = 0x043F,
457 | MCU_RANGE_CALC__ALGO_ACCUM_PHASE = 0x0440,
458 | MCU_RANGE_CALC__ALGO_ACCUM_PHASE_3 = 0x0440,
459 | MCU_RANGE_CALC__ALGO_ACCUM_PHASE_2 = 0x0441,
460 | MCU_RANGE_CALC__ALGO_ACCUM_PHASE_1 = 0x0442,
461 | MCU_RANGE_CALC__ALGO_ACCUM_PHASE_0 = 0x0443,
462 | MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS = 0x0444,
463 | MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS_3 = 0x0444,
464 | MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS_2 = 0x0445,
465 | MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS_1 = 0x0446,
466 | MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS_0 = 0x0447,
467 | MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS = 0x0448,
468 | MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS_3 = 0x0448,
469 | MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS_2 = 0x0449,
470 | MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS_1 = 0x044A,
471 | MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS_0 = 0x044B,
472 | MCU_RANGE_CALC__SPARE_6 = 0x044C,
473 | MCU_RANGE_CALC__SPARE_6_HI = 0x044C,
474 | MCU_RANGE_CALC__SPARE_6_LO = 0x044D,
475 | MCU_RANGE_CALC__ALGO_ADJUST_VCSEL_PERIOD = 0x044E,
476 | MCU_RANGE_CALC__ALGO_ADJUST_VCSEL_PERIOD_HI = 0x044E,
477 | MCU_RANGE_CALC__ALGO_ADJUST_VCSEL_PERIOD_LO = 0x044F,
478 | MCU_RANGE_CALC__NUM_SPADS = 0x0450,
479 | MCU_RANGE_CALC__NUM_SPADS_HI = 0x0450,
480 | MCU_RANGE_CALC__NUM_SPADS_LO = 0x0451,
481 | MCU_RANGE_CALC__PHASE_OUTPUT = 0x0452,
482 | MCU_RANGE_CALC__PHASE_OUTPUT_HI = 0x0452,
483 | MCU_RANGE_CALC__PHASE_OUTPUT_LO = 0x0453,
484 | MCU_RANGE_CALC__RATE_PER_SPAD_MCPS = 0x0454,
485 | MCU_RANGE_CALC__RATE_PER_SPAD_MCPS_3 = 0x0454,
486 | MCU_RANGE_CALC__RATE_PER_SPAD_MCPS_2 = 0x0455,
487 | MCU_RANGE_CALC__RATE_PER_SPAD_MCPS_1 = 0x0456,
488 | MCU_RANGE_CALC__RATE_PER_SPAD_MCPS_0 = 0x0457,
489 | MCU_RANGE_CALC__SPARE_7 = 0x0458,
490 | MCU_RANGE_CALC__SPARE_8 = 0x0459,
491 | MCU_RANGE_CALC__PEAK_SIGNAL_RATE_MCPS = 0x045A,
492 | MCU_RANGE_CALC__PEAK_SIGNAL_RATE_MCPS_HI = 0x045A,
493 | MCU_RANGE_CALC__PEAK_SIGNAL_RATE_MCPS_LO = 0x045B,
494 | MCU_RANGE_CALC__AVG_SIGNAL_RATE_MCPS = 0x045C,
495 | MCU_RANGE_CALC__AVG_SIGNAL_RATE_MCPS_HI = 0x045C,
496 | MCU_RANGE_CALC__AVG_SIGNAL_RATE_MCPS_LO = 0x045D,
497 | MCU_RANGE_CALC__AMBIENT_RATE_MCPS = 0x045E,
498 | MCU_RANGE_CALC__AMBIENT_RATE_MCPS_HI = 0x045E,
499 | MCU_RANGE_CALC__AMBIENT_RATE_MCPS_LO = 0x045F,
500 | MCU_RANGE_CALC__XTALK = 0x0460,
501 | MCU_RANGE_CALC__XTALK_HI = 0x0460,
502 | MCU_RANGE_CALC__XTALK_LO = 0x0461,
503 | MCU_RANGE_CALC__CALC_STATUS = 0x0462,
504 | MCU_RANGE_CALC__DEBUG = 0x0463,
505 | MCU_RANGE_CALC__PEAK_SIGNAL_RATE_XTALK_CORR_MCPS = 0x0464,
506 | MCU_RANGE_CALC__PEAK_SIGNAL_RATE_XTALK_CORR_MCPS_HI = 0x0464,
507 | MCU_RANGE_CALC__PEAK_SIGNAL_RATE_XTALK_CORR_MCPS_LO = 0x0465,
508 | MCU_RANGE_CALC__SPARE_0 = 0x0468,
509 | MCU_RANGE_CALC__SPARE_1 = 0x0469,
510 | MCU_RANGE_CALC__SPARE_2 = 0x046A,
511 | MCU_RANGE_CALC__SPARE_3 = 0x046B,
512 | PATCH__CTRL = 0x0470,
513 | PATCH__JMP_ENABLES = 0x0472,
514 | PATCH__JMP_ENABLES_HI = 0x0472,
515 | PATCH__JMP_ENABLES_LO = 0x0473,
516 | PATCH__DATA_ENABLES = 0x0474,
517 | PATCH__DATA_ENABLES_HI = 0x0474,
518 | PATCH__DATA_ENABLES_LO = 0x0475,
519 | PATCH__OFFSET_0 = 0x0476,
520 | PATCH__OFFSET_0_HI = 0x0476,
521 | PATCH__OFFSET_0_LO = 0x0477,
522 | PATCH__OFFSET_1 = 0x0478,
523 | PATCH__OFFSET_1_HI = 0x0478,
524 | PATCH__OFFSET_1_LO = 0x0479,
525 | PATCH__OFFSET_2 = 0x047A,
526 | PATCH__OFFSET_2_HI = 0x047A,
527 | PATCH__OFFSET_2_LO = 0x047B,
528 | PATCH__OFFSET_3 = 0x047C,
529 | PATCH__OFFSET_3_HI = 0x047C,
530 | PATCH__OFFSET_3_LO = 0x047D,
531 | PATCH__OFFSET_4 = 0x047E,
532 | PATCH__OFFSET_4_HI = 0x047E,
533 | PATCH__OFFSET_4_LO = 0x047F,
534 | PATCH__OFFSET_5 = 0x0480,
535 | PATCH__OFFSET_5_HI = 0x0480,
536 | PATCH__OFFSET_5_LO = 0x0481,
537 | PATCH__OFFSET_6 = 0x0482,
538 | PATCH__OFFSET_6_HI = 0x0482,
539 | PATCH__OFFSET_6_LO = 0x0483,
540 | PATCH__OFFSET_7 = 0x0484,
541 | PATCH__OFFSET_7_HI = 0x0484,
542 | PATCH__OFFSET_7_LO = 0x0485,
543 | PATCH__OFFSET_8 = 0x0486,
544 | PATCH__OFFSET_8_HI = 0x0486,
545 | PATCH__OFFSET_8_LO = 0x0487,
546 | PATCH__OFFSET_9 = 0x0488,
547 | PATCH__OFFSET_9_HI = 0x0488,
548 | PATCH__OFFSET_9_LO = 0x0489,
549 | PATCH__OFFSET_10 = 0x048A,
550 | PATCH__OFFSET_10_HI = 0x048A,
551 | PATCH__OFFSET_10_LO = 0x048B,
552 | PATCH__OFFSET_11 = 0x048C,
553 | PATCH__OFFSET_11_HI = 0x048C,
554 | PATCH__OFFSET_11_LO = 0x048D,
555 | PATCH__OFFSET_12 = 0x048E,
556 | PATCH__OFFSET_12_HI = 0x048E,
557 | PATCH__OFFSET_12_LO = 0x048F,
558 | PATCH__OFFSET_13 = 0x0490,
559 | PATCH__OFFSET_13_HI = 0x0490,
560 | PATCH__OFFSET_13_LO = 0x0491,
561 | PATCH__OFFSET_14 = 0x0492,
562 | PATCH__OFFSET_14_HI = 0x0492,
563 | PATCH__OFFSET_14_LO = 0x0493,
564 | PATCH__OFFSET_15 = 0x0494,
565 | PATCH__OFFSET_15_HI = 0x0494,
566 | PATCH__OFFSET_15_LO = 0x0495,
567 | PATCH__ADDRESS_0 = 0x0496,
568 | PATCH__ADDRESS_0_HI = 0x0496,
569 | PATCH__ADDRESS_0_LO = 0x0497,
570 | PATCH__ADDRESS_1 = 0x0498,
571 | PATCH__ADDRESS_1_HI = 0x0498,
572 | PATCH__ADDRESS_1_LO = 0x0499,
573 | PATCH__ADDRESS_2 = 0x049A,
574 | PATCH__ADDRESS_2_HI = 0x049A,
575 | PATCH__ADDRESS_2_LO = 0x049B,
576 | PATCH__ADDRESS_3 = 0x049C,
577 | PATCH__ADDRESS_3_HI = 0x049C,
578 | PATCH__ADDRESS_3_LO = 0x049D,
579 | PATCH__ADDRESS_4 = 0x049E,
580 | PATCH__ADDRESS_4_HI = 0x049E,
581 | PATCH__ADDRESS_4_LO = 0x049F,
582 | PATCH__ADDRESS_5 = 0x04A0,
583 | PATCH__ADDRESS_5_HI = 0x04A0,
584 | PATCH__ADDRESS_5_LO = 0x04A1,
585 | PATCH__ADDRESS_6 = 0x04A2,
586 | PATCH__ADDRESS_6_HI = 0x04A2,
587 | PATCH__ADDRESS_6_LO = 0x04A3,
588 | PATCH__ADDRESS_7 = 0x04A4,
589 | PATCH__ADDRESS_7_HI = 0x04A4,
590 | PATCH__ADDRESS_7_LO = 0x04A5,
591 | PATCH__ADDRESS_8 = 0x04A6,
592 | PATCH__ADDRESS_8_HI = 0x04A6,
593 | PATCH__ADDRESS_8_LO = 0x04A7,
594 | PATCH__ADDRESS_9 = 0x04A8,
595 | PATCH__ADDRESS_9_HI = 0x04A8,
596 | PATCH__ADDRESS_9_LO = 0x04A9,
597 | PATCH__ADDRESS_10 = 0x04AA,
598 | PATCH__ADDRESS_10_HI = 0x04AA,
599 | PATCH__ADDRESS_10_LO = 0x04AB,
600 | PATCH__ADDRESS_11 = 0x04AC,
601 | PATCH__ADDRESS_11_HI = 0x04AC,
602 | PATCH__ADDRESS_11_LO = 0x04AD,
603 | PATCH__ADDRESS_12 = 0x04AE,
604 | PATCH__ADDRESS_12_HI = 0x04AE,
605 | PATCH__ADDRESS_12_LO = 0x04AF,
606 | PATCH__ADDRESS_13 = 0x04B0,
607 | PATCH__ADDRESS_13_HI = 0x04B0,
608 | PATCH__ADDRESS_13_LO = 0x04B1,
609 | PATCH__ADDRESS_14 = 0x04B2,
610 | PATCH__ADDRESS_14_HI = 0x04B2,
611 | PATCH__ADDRESS_14_LO = 0x04B3,
612 | PATCH__ADDRESS_15 = 0x04B4,
613 | PATCH__ADDRESS_15_HI = 0x04B4,
614 | PATCH__ADDRESS_15_LO = 0x04B5,
615 | SPI_ASYNC_MUX__CTRL = 0x04C0,
616 | CLK__CONFIG = 0x04C4,
617 | GPIO_LV_MUX__CTRL = 0x04CC,
618 | GPIO_LV_PAD__CTRL = 0x04CD,
619 | PAD_I2C_LV__CONFIG = 0x04D0,
620 | PAD_STARTUP_MODE__VALUE_RO_GO1 = 0x04D4,
621 | HOST_IF__STATUS_GO1 = 0x04D5,
622 | MCU_CLK_GATING__CTRL = 0x04D8,
623 | TEST__BIST_ROM_CTRL = 0x04E0,
624 | TEST__BIST_ROM_RESULT = 0x04E1,
625 | TEST__BIST_ROM_MCU_SIG = 0x04E2,
626 | TEST__BIST_ROM_MCU_SIG_HI = 0x04E2,
627 | TEST__BIST_ROM_MCU_SIG_LO = 0x04E3,
628 | TEST__BIST_RAM_CTRL = 0x04E4,
629 | TEST__BIST_RAM_RESULT = 0x04E5,
630 | TEST__TMC = 0x04E8,
631 | TEST__PLL_BIST_MIN_THRESHOLD = 0x04F0,
632 | TEST__PLL_BIST_MIN_THRESHOLD_HI = 0x04F0,
633 | TEST__PLL_BIST_MIN_THRESHOLD_LO = 0x04F1,
634 | TEST__PLL_BIST_MAX_THRESHOLD = 0x04F2,
635 | TEST__PLL_BIST_MAX_THRESHOLD_HI = 0x04F2,
636 | TEST__PLL_BIST_MAX_THRESHOLD_LO = 0x04F3,
637 | TEST__PLL_BIST_COUNT_OUT = 0x04F4,
638 | TEST__PLL_BIST_COUNT_OUT_HI = 0x04F4,
639 | TEST__PLL_BIST_COUNT_OUT_LO = 0x04F5,
640 | TEST__PLL_BIST_GONOGO = 0x04F6,
641 | TEST__PLL_BIST_CTRL = 0x04F7,
642 | RANGING_CORE__DEVICE_ID = 0x0680,
643 | RANGING_CORE__REVISION_ID = 0x0681,
644 | RANGING_CORE__CLK_CTRL1 = 0x0683,
645 | RANGING_CORE__CLK_CTRL2 = 0x0684,
646 | RANGING_CORE__WOI_1 = 0x0685,
647 | RANGING_CORE__WOI_REF_1 = 0x0686,
648 | RANGING_CORE__START_RANGING = 0x0687,
649 | RANGING_CORE__LOW_LIMIT_1 = 0x0690,
650 | RANGING_CORE__HIGH_LIMIT_1 = 0x0691,
651 | RANGING_CORE__LOW_LIMIT_REF_1 = 0x0692,
652 | RANGING_CORE__HIGH_LIMIT_REF_1 = 0x0693,
653 | RANGING_CORE__QUANTIFIER_1_MSB = 0x0694,
654 | RANGING_CORE__QUANTIFIER_1_LSB = 0x0695,
655 | RANGING_CORE__QUANTIFIER_REF_1_MSB = 0x0696,
656 | RANGING_CORE__QUANTIFIER_REF_1_LSB = 0x0697,
657 | RANGING_CORE__AMBIENT_OFFSET_1_MSB = 0x0698,
658 | RANGING_CORE__AMBIENT_OFFSET_1_LSB = 0x0699,
659 | RANGING_CORE__AMBIENT_OFFSET_REF_1_MSB = 0x069A,
660 | RANGING_CORE__AMBIENT_OFFSET_REF_1_LSB = 0x069B,
661 | RANGING_CORE__FILTER_STRENGTH_1 = 0x069C,
662 | RANGING_CORE__FILTER_STRENGTH_REF_1 = 0x069D,
663 | RANGING_CORE__SIGNAL_EVENT_LIMIT_1_MSB = 0x069E,
664 | RANGING_CORE__SIGNAL_EVENT_LIMIT_1_LSB = 0x069F,
665 | RANGING_CORE__SIGNAL_EVENT_LIMIT_REF_1_MSB = 0x06A0,
666 | RANGING_CORE__SIGNAL_EVENT_LIMIT_REF_1_LSB = 0x06A1,
667 | RANGING_CORE__TIMEOUT_OVERALL_PERIODS_MSB = 0x06A4,
668 | RANGING_CORE__TIMEOUT_OVERALL_PERIODS_LSB = 0x06A5,
669 | RANGING_CORE__INVERT_HW = 0x06A6,
670 | RANGING_CORE__FORCE_HW = 0x06A7,
671 | RANGING_CORE__STATIC_HW_VALUE = 0x06A8,
672 | RANGING_CORE__FORCE_CONTINUOUS_AMBIENT = 0x06A9,
673 | RANGING_CORE__TEST_PHASE_SELECT_TO_FILTER = 0x06AA,
674 | RANGING_CORE__TEST_PHASE_SELECT_TO_TIMING_GEN = 0x06AB,
675 | RANGING_CORE__INITIAL_PHASE_VALUE_1 = 0x06AC,
676 | RANGING_CORE__INITIAL_PHASE_VALUE_REF_1 = 0x06AD,
677 | RANGING_CORE__FORCE_UP_IN = 0x06AE,
678 | RANGING_CORE__FORCE_DN_IN = 0x06AF,
679 | RANGING_CORE__STATIC_UP_VALUE_1 = 0x06B0,
680 | RANGING_CORE__STATIC_UP_VALUE_REF_1 = 0x06B1,
681 | RANGING_CORE__STATIC_DN_VALUE_1 = 0x06B2,
682 | RANGING_CORE__STATIC_DN_VALUE_REF_1 = 0x06B3,
683 | RANGING_CORE__MONITOR_UP_DN = 0x06B4,
684 | RANGING_CORE__INVERT_UP_DN = 0x06B5,
685 | RANGING_CORE__CPUMP_1 = 0x06B6,
686 | RANGING_CORE__CPUMP_2 = 0x06B7,
687 | RANGING_CORE__CPUMP_3 = 0x06B8,
688 | RANGING_CORE__OSC_1 = 0x06B9,
689 | RANGING_CORE__PLL_1 = 0x06BB,
690 | RANGING_CORE__PLL_2 = 0x06BC,
691 | RANGING_CORE__REFERENCE_1 = 0x06BD,
692 | RANGING_CORE__REFERENCE_3 = 0x06BF,
693 | RANGING_CORE__REFERENCE_4 = 0x06C0,
694 | RANGING_CORE__REFERENCE_5 = 0x06C1,
695 | RANGING_CORE__REGAVDD1V2 = 0x06C3,
696 | RANGING_CORE__CALIB_1 = 0x06C4,
697 | RANGING_CORE__CALIB_2 = 0x06C5,
698 | RANGING_CORE__CALIB_3 = 0x06C6,
699 | RANGING_CORE__TST_MUX_SEL1 = 0x06C9,
700 | RANGING_CORE__TST_MUX_SEL2 = 0x06CA,
701 | RANGING_CORE__TST_MUX = 0x06CB,
702 | RANGING_CORE__GPIO_OUT_TESTMUX = 0x06CC,
703 | RANGING_CORE__CUSTOM_FE = 0x06CD,
704 | RANGING_CORE__CUSTOM_FE_2 = 0x06CE,
705 | RANGING_CORE__SPAD_READOUT = 0x06CF,
706 | RANGING_CORE__SPAD_READOUT_1 = 0x06D0,
707 | RANGING_CORE__SPAD_READOUT_2 = 0x06D1,
708 | RANGING_CORE__SPAD_PS = 0x06D2,
709 | RANGING_CORE__LASER_SAFETY_2 = 0x06D4,
710 | RANGING_CORE__NVM_CTRL__MODE = 0x0780,
711 | RANGING_CORE__NVM_CTRL__PDN = 0x0781,
712 | RANGING_CORE__NVM_CTRL__PROGN = 0x0782,
713 | RANGING_CORE__NVM_CTRL__READN = 0x0783,
714 | RANGING_CORE__NVM_CTRL__PULSE_WIDTH_MSB = 0x0784,
715 | RANGING_CORE__NVM_CTRL__PULSE_WIDTH_LSB = 0x0785,
716 | RANGING_CORE__NVM_CTRL__HV_RISE_MSB = 0x0786,
717 | RANGING_CORE__NVM_CTRL__HV_RISE_LSB = 0x0787,
718 | RANGING_CORE__NVM_CTRL__HV_FALL_MSB = 0x0788,
719 | RANGING_CORE__NVM_CTRL__HV_FALL_LSB = 0x0789,
720 | RANGING_CORE__NVM_CTRL__TST = 0x078A,
721 | RANGING_CORE__NVM_CTRL__TESTREAD = 0x078B,
722 | RANGING_CORE__NVM_CTRL__DATAIN_MMM = 0x078C,
723 | RANGING_CORE__NVM_CTRL__DATAIN_LMM = 0x078D,
724 | RANGING_CORE__NVM_CTRL__DATAIN_LLM = 0x078E,
725 | RANGING_CORE__NVM_CTRL__DATAIN_LLL = 0x078F,
726 | RANGING_CORE__NVM_CTRL__DATAOUT_MMM = 0x0790,
727 | RANGING_CORE__NVM_CTRL__DATAOUT_LMM = 0x0791,
728 | RANGING_CORE__NVM_CTRL__DATAOUT_LLM = 0x0792,
729 | RANGING_CORE__NVM_CTRL__DATAOUT_LLL = 0x0793,
730 | RANGING_CORE__NVM_CTRL__ADDR = 0x0794,
731 | RANGING_CORE__NVM_CTRL__DATAOUT_ECC = 0x0795,
732 | RANGING_CORE__RET_SPAD_EN_0 = 0x0796,
733 | RANGING_CORE__RET_SPAD_EN_1 = 0x0797,
734 | RANGING_CORE__RET_SPAD_EN_2 = 0x0798,
735 | RANGING_CORE__RET_SPAD_EN_3 = 0x0799,
736 | RANGING_CORE__RET_SPAD_EN_4 = 0x079A,
737 | RANGING_CORE__RET_SPAD_EN_5 = 0x079B,
738 | RANGING_CORE__RET_SPAD_EN_6 = 0x079C,
739 | RANGING_CORE__RET_SPAD_EN_7 = 0x079D,
740 | RANGING_CORE__RET_SPAD_EN_8 = 0x079E,
741 | RANGING_CORE__RET_SPAD_EN_9 = 0x079F,
742 | RANGING_CORE__RET_SPAD_EN_10 = 0x07A0,
743 | RANGING_CORE__RET_SPAD_EN_11 = 0x07A1,
744 | RANGING_CORE__RET_SPAD_EN_12 = 0x07A2,
745 | RANGING_CORE__RET_SPAD_EN_13 = 0x07A3,
746 | RANGING_CORE__RET_SPAD_EN_14 = 0x07A4,
747 | RANGING_CORE__RET_SPAD_EN_15 = 0x07A5,
748 | RANGING_CORE__RET_SPAD_EN_16 = 0x07A6,
749 | RANGING_CORE__RET_SPAD_EN_17 = 0x07A7,
750 | RANGING_CORE__SPAD_SHIFT_EN = 0x07BA,
751 | RANGING_CORE__SPAD_DISABLE_CTRL = 0x07BB,
752 | RANGING_CORE__SPAD_EN_SHIFT_OUT_DEBUG = 0x07BC,
753 | RANGING_CORE__SPI_MODE = 0x07BD,
754 | RANGING_CORE__GPIO_DIR = 0x07BE,
755 | RANGING_CORE__VCSEL_PERIOD = 0x0880,
756 | RANGING_CORE__VCSEL_START = 0x0881,
757 | RANGING_CORE__VCSEL_STOP = 0x0882,
758 | RANGING_CORE__VCSEL_1 = 0x0885,
759 | RANGING_CORE__VCSEL_STATUS = 0x088D,
760 | RANGING_CORE__STATUS = 0x0980,
761 | RANGING_CORE__LASER_CONTINUITY_STATE = 0x0981,
762 | RANGING_CORE__RANGE_1_MMM = 0x0982,
763 | RANGING_CORE__RANGE_1_LMM = 0x0983,
764 | RANGING_CORE__RANGE_1_LLM = 0x0984,
765 | RANGING_CORE__RANGE_1_LLL = 0x0985,
766 | RANGING_CORE__RANGE_REF_1_MMM = 0x0986,
767 | RANGING_CORE__RANGE_REF_1_LMM = 0x0987,
768 | RANGING_CORE__RANGE_REF_1_LLM = 0x0988,
769 | RANGING_CORE__RANGE_REF_1_LLL = 0x0989,
770 | RANGING_CORE__AMBIENT_WINDOW_EVENTS_1_MMM = 0x098A,
771 | RANGING_CORE__AMBIENT_WINDOW_EVENTS_1_LMM = 0x098B,
772 | RANGING_CORE__AMBIENT_WINDOW_EVENTS_1_LLM = 0x098C,
773 | RANGING_CORE__AMBIENT_WINDOW_EVENTS_1_LLL = 0x098D,
774 | RANGING_CORE__RANGING_TOTAL_EVENTS_1_MMM = 0x098E,
775 | RANGING_CORE__RANGING_TOTAL_EVENTS_1_LMM = 0x098F,
776 | RANGING_CORE__RANGING_TOTAL_EVENTS_1_LLM = 0x0990,
777 | RANGING_CORE__RANGING_TOTAL_EVENTS_1_LLL = 0x0991,
778 | RANGING_CORE__SIGNAL_TOTAL_EVENTS_1_MMM = 0x0992,
779 | RANGING_CORE__SIGNAL_TOTAL_EVENTS_1_LMM = 0x0993,
780 | RANGING_CORE__SIGNAL_TOTAL_EVENTS_1_LLM = 0x0994,
781 | RANGING_CORE__SIGNAL_TOTAL_EVENTS_1_LLL = 0x0995,
782 | RANGING_CORE__TOTAL_PERIODS_ELAPSED_1_MM = 0x0996,
783 | RANGING_CORE__TOTAL_PERIODS_ELAPSED_1_LM = 0x0997,
784 | RANGING_CORE__TOTAL_PERIODS_ELAPSED_1_LL = 0x0998,
785 | RANGING_CORE__AMBIENT_MISMATCH_MM = 0x0999,
786 | RANGING_CORE__AMBIENT_MISMATCH_LM = 0x099A,
787 | RANGING_CORE__AMBIENT_MISMATCH_LL = 0x099B,
788 | RANGING_CORE__AMBIENT_WINDOW_EVENTS_REF_1_MMM = 0x099C,
789 | RANGING_CORE__AMBIENT_WINDOW_EVENTS_REF_1_LMM = 0x099D,
790 | RANGING_CORE__AMBIENT_WINDOW_EVENTS_REF_1_LLM = 0x099E,
791 | RANGING_CORE__AMBIENT_WINDOW_EVENTS_REF_1_LLL = 0x099F,
792 | RANGING_CORE__RANGING_TOTAL_EVENTS_REF_1_MMM = 0x09A0,
793 | RANGING_CORE__RANGING_TOTAL_EVENTS_REF_1_LMM = 0x09A1,
794 | RANGING_CORE__RANGING_TOTAL_EVENTS_REF_1_LLM = 0x09A2,
795 | RANGING_CORE__RANGING_TOTAL_EVENTS_REF_1_LLL = 0x09A3,
796 | RANGING_CORE__SIGNAL_TOTAL_EVENTS_REF_1_MMM = 0x09A4,
797 | RANGING_CORE__SIGNAL_TOTAL_EVENTS_REF_1_LMM = 0x09A5,
798 | RANGING_CORE__SIGNAL_TOTAL_EVENTS_REF_1_LLM = 0x09A6,
799 | RANGING_CORE__SIGNAL_TOTAL_EVENTS_REF_1_LLL = 0x09A7,
800 | RANGING_CORE__TOTAL_PERIODS_ELAPSED_REF_1_MM = 0x09A8,
801 | RANGING_CORE__TOTAL_PERIODS_ELAPSED_REF_1_LM = 0x09A9,
802 | RANGING_CORE__TOTAL_PERIODS_ELAPSED_REF_1_LL = 0x09AA,
803 | RANGING_CORE__AMBIENT_MISMATCH_REF_MM = 0x09AB,
804 | RANGING_CORE__AMBIENT_MISMATCH_REF_LM = 0x09AC,
805 | RANGING_CORE__AMBIENT_MISMATCH_REF_LL = 0x09AD,
806 | RANGING_CORE__GPIO_CONFIG__A0 = 0x0A00,
807 | RANGING_CORE__RESET_CONTROL__A0 = 0x0A01,
808 | RANGING_CORE__INTR_MANAGER__A0 = 0x0A02,
809 | RANGING_CORE__POWER_FSM_TIME_OSC__A0 = 0x0A06,
810 | RANGING_CORE__VCSEL_ATEST__A0 = 0x0A07,
811 | RANGING_CORE__VCSEL_PERIOD_CLIPPED__A0 = 0x0A08,
812 | RANGING_CORE__VCSEL_STOP_CLIPPED__A0 = 0x0A09,
813 | RANGING_CORE__CALIB_2__A0 = 0x0A0A,
814 | RANGING_CORE__STOP_CONDITION__A0 = 0x0A0B,
815 | RANGING_CORE__STATUS_RESET__A0 = 0x0A0C,
816 | RANGING_CORE__READOUT_CFG__A0 = 0x0A0D,
817 | RANGING_CORE__WINDOW_SETTING__A0 = 0x0A0E,
818 | RANGING_CORE__VCSEL_DELAY__A0 = 0x0A1A,
819 | RANGING_CORE__REFERENCE_2__A0 = 0x0A1B,
820 | RANGING_CORE__REGAVDD1V2__A0 = 0x0A1D,
821 | RANGING_CORE__TST_MUX__A0 = 0x0A1F,
822 | RANGING_CORE__CUSTOM_FE_2__A0 = 0x0A20,
823 | RANGING_CORE__SPAD_READOUT__A0 = 0x0A21,
824 | RANGING_CORE__CPUMP_1__A0 = 0x0A22,
825 | RANGING_CORE__SPARE_REGISTER__A0 = 0x0A23,
826 | RANGING_CORE__VCSEL_CONT_STAGE5_BYPASS__A0 = 0x0A24,
827 | RANGING_CORE__RET_SPAD_EN_18 = 0x0A25,
828 | RANGING_CORE__RET_SPAD_EN_19 = 0x0A26,
829 | RANGING_CORE__RET_SPAD_EN_20 = 0x0A27,
830 | RANGING_CORE__RET_SPAD_EN_21 = 0x0A28,
831 | RANGING_CORE__RET_SPAD_EN_22 = 0x0A29,
832 | RANGING_CORE__RET_SPAD_EN_23 = 0x0A2A,
833 | RANGING_CORE__RET_SPAD_EN_24 = 0x0A2B,
834 | RANGING_CORE__RET_SPAD_EN_25 = 0x0A2C,
835 | RANGING_CORE__RET_SPAD_EN_26 = 0x0A2D,
836 | RANGING_CORE__RET_SPAD_EN_27 = 0x0A2E,
837 | RANGING_CORE__RET_SPAD_EN_28 = 0x0A2F,
838 | RANGING_CORE__RET_SPAD_EN_29 = 0x0A30,
839 | RANGING_CORE__RET_SPAD_EN_30 = 0x0A31,
840 | RANGING_CORE__RET_SPAD_EN_31 = 0x0A32,
841 | RANGING_CORE__REF_SPAD_EN_0__EWOK = 0x0A33,
842 | RANGING_CORE__REF_SPAD_EN_1__EWOK = 0x0A34,
843 | RANGING_CORE__REF_SPAD_EN_2__EWOK = 0x0A35,
844 | RANGING_CORE__REF_SPAD_EN_3__EWOK = 0x0A36,
845 | RANGING_CORE__REF_SPAD_EN_4__EWOK = 0x0A37,
846 | RANGING_CORE__REF_SPAD_EN_5__EWOK = 0x0A38,
847 | RANGING_CORE__REF_EN_START_SELECT = 0x0A39,
848 | RANGING_CORE__REGDVDD1V2_ATEST__EWOK = 0x0A41,
849 | SOFT_RESET_GO1 = 0x0B00,
850 | PRIVATE__PATCH_BASE_ADDR_RSLV = 0x0E00,
851 | PREV_SHADOW_RESULT__INTERRUPT_STATUS = 0x0ED0,
852 | PREV_SHADOW_RESULT__RANGE_STATUS = 0x0ED1,
853 | PREV_SHADOW_RESULT__REPORT_STATUS = 0x0ED2,
854 | PREV_SHADOW_RESULT__STREAM_COUNT = 0x0ED3,
855 | PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x0ED4,
856 | PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x0ED4,
857 | PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x0ED5,
858 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0 = 0x0ED6,
859 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_HI = 0x0ED6,
860 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_LO = 0x0ED7,
861 | PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0 = 0x0ED8,
862 | PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_HI = 0x0ED8,
863 | PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_LO = 0x0ED9,
864 | PREV_SHADOW_RESULT__SIGMA_SD0 = 0x0EDA,
865 | PREV_SHADOW_RESULT__SIGMA_SD0_HI = 0x0EDA,
866 | PREV_SHADOW_RESULT__SIGMA_SD0_LO = 0x0EDB,
867 | PREV_SHADOW_RESULT__PHASE_SD0 = 0x0EDC,
868 | PREV_SHADOW_RESULT__PHASE_SD0_HI = 0x0EDC,
869 | PREV_SHADOW_RESULT__PHASE_SD0_LO = 0x0EDD,
870 | PREV_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 = 0x0EDE,
871 | PREV_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_HI = 0x0EDE,
872 | PREV_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_LO = 0x0EDF,
873 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 = 0x0EE0,
874 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_HI = 0x0EE0,
875 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO = 0x0EE1,
876 | PREV_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x0EE2,
877 | PREV_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x0EE2,
878 | PREV_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x0EE3,
879 | PREV_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x0EE4,
880 | PREV_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x0EE4,
881 | PREV_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x0EE5,
882 | PREV_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0 = 0x0EE6,
883 | PREV_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_HI = 0x0EE6,
884 | PREV_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_LO = 0x0EE7,
885 | PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1 = 0x0EE8,
886 | PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_HI = 0x0EE8,
887 | PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_LO = 0x0EE9,
888 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1 = 0x0EEA,
889 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_HI = 0x0EEA,
890 | PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_LO = 0x0EEB,
891 | PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1 = 0x0EEC,
892 | PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_HI = 0x0EEC,
893 | PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_LO = 0x0EED,
894 | PREV_SHADOW_RESULT__SIGMA_SD1 = 0x0EEE,
895 | PREV_SHADOW_RESULT__SIGMA_SD1_HI = 0x0EEE,
896 | PREV_SHADOW_RESULT__SIGMA_SD1_LO = 0x0EEF,
897 | PREV_SHADOW_RESULT__PHASE_SD1 = 0x0EF0,
898 | PREV_SHADOW_RESULT__PHASE_SD1_HI = 0x0EF0,
899 | PREV_SHADOW_RESULT__PHASE_SD1_LO = 0x0EF1,
900 | PREV_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1 = 0x0EF2,
901 | PREV_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_HI = 0x0EF2,
902 | PREV_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_LO = 0x0EF3,
903 | PREV_SHADOW_RESULT__SPARE_0_SD1 = 0x0EF4,
904 | PREV_SHADOW_RESULT__SPARE_0_SD1_HI = 0x0EF4,
905 | PREV_SHADOW_RESULT__SPARE_0_SD1_LO = 0x0EF5,
906 | PREV_SHADOW_RESULT__SPARE_1_SD1 = 0x0EF6,
907 | PREV_SHADOW_RESULT__SPARE_1_SD1_HI = 0x0EF6,
908 | PREV_SHADOW_RESULT__SPARE_1_SD1_LO = 0x0EF7,
909 | PREV_SHADOW_RESULT__SPARE_2_SD1 = 0x0EF8,
910 | PREV_SHADOW_RESULT__SPARE_2_SD1_HI = 0x0EF8,
911 | PREV_SHADOW_RESULT__SPARE_2_SD1_LO = 0x0EF9,
912 | PREV_SHADOW_RESULT__SPARE_3_SD1 = 0x0EFA,
913 | PREV_SHADOW_RESULT__SPARE_3_SD1_HI = 0x0EFA,
914 | PREV_SHADOW_RESULT__SPARE_3_SD1_LO = 0x0EFB,
915 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 = 0x0EFC,
916 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_3 = 0x0EFC,
917 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_2 = 0x0EFD,
918 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_1 = 0x0EFE,
919 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_0 = 0x0EFF,
920 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0 = 0x0F00,
921 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_3 = 0x0F00,
922 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_2 = 0x0F01,
923 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_1 = 0x0F02,
924 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_0 = 0x0F03,
925 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0 = 0x0F04,
926 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_3 = 0x0F04,
927 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_2 = 0x0F05,
928 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_1 = 0x0F06,
929 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_0 = 0x0F07,
930 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0 = 0x0F08,
931 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_3 = 0x0F08,
932 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_2 = 0x0F09,
933 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_1 = 0x0F0A,
934 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_0 = 0x0F0B,
935 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1 = 0x0F0C,
936 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_3 = 0x0F0C,
937 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_2 = 0x0F0D,
938 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_1 = 0x0F0E,
939 | PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_0 = 0x0F0F,
940 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1 = 0x0F10,
941 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_3 = 0x0F10,
942 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_2 = 0x0F11,
943 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_1 = 0x0F12,
944 | PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_0 = 0x0F13,
945 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1 = 0x0F14,
946 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_3 = 0x0F14,
947 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_2 = 0x0F15,
948 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_1 = 0x0F16,
949 | PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_0 = 0x0F17,
950 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1 = 0x0F18,
951 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_3 = 0x0F18,
952 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_2 = 0x0F19,
953 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_1 = 0x0F1A,
954 | PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_0 = 0x0F1B,
955 | PREV_SHADOW_RESULT_CORE__SPARE_0 = 0x0F1C,
956 | RESULT__DEBUG_STATUS = 0x0F20,
957 | RESULT__DEBUG_STAGE = 0x0F21,
958 | GPH__SYSTEM__THRESH_RATE_HIGH = 0x0F24,
959 | GPH__SYSTEM__THRESH_RATE_HIGH_HI = 0x0F24,
960 | GPH__SYSTEM__THRESH_RATE_HIGH_LO = 0x0F25,
961 | GPH__SYSTEM__THRESH_RATE_LOW = 0x0F26,
962 | GPH__SYSTEM__THRESH_RATE_LOW_HI = 0x0F26,
963 | GPH__SYSTEM__THRESH_RATE_LOW_LO = 0x0F27,
964 | GPH__SYSTEM__INTERRUPT_CONFIG_GPIO = 0x0F28,
965 | GPH__DSS_CONFIG__ROI_MODE_CONTROL = 0x0F2F,
966 | GPH__DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT = 0x0F30,
967 | GPH__DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT_HI = 0x0F30,
968 | GPH__DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT_LO = 0x0F31,
969 | GPH__DSS_CONFIG__MANUAL_BLOCK_SELECT = 0x0F32,
970 | GPH__DSS_CONFIG__MAX_SPADS_LIMIT = 0x0F33,
971 | GPH__DSS_CONFIG__MIN_SPADS_LIMIT = 0x0F34,
972 | GPH__MM_CONFIG__TIMEOUT_MACROP_A_HI = 0x0F36,
973 | GPH__MM_CONFIG__TIMEOUT_MACROP_A_LO = 0x0F37,
974 | GPH__MM_CONFIG__TIMEOUT_MACROP_B_HI = 0x0F38,
975 | GPH__MM_CONFIG__TIMEOUT_MACROP_B_LO = 0x0F39,
976 | GPH__RANGE_CONFIG__TIMEOUT_MACROP_A_HI = 0x0F3A,
977 | GPH__RANGE_CONFIG__TIMEOUT_MACROP_A_LO = 0x0F3B,
978 | GPH__RANGE_CONFIG__VCSEL_PERIOD_A = 0x0F3C,
979 | GPH__RANGE_CONFIG__VCSEL_PERIOD_B = 0x0F3D,
980 | GPH__RANGE_CONFIG__TIMEOUT_MACROP_B_HI = 0x0F3E,
981 | GPH__RANGE_CONFIG__TIMEOUT_MACROP_B_LO = 0x0F3F,
982 | GPH__RANGE_CONFIG__SIGMA_THRESH = 0x0F40,
983 | GPH__RANGE_CONFIG__SIGMA_THRESH_HI = 0x0F40,
984 | GPH__RANGE_CONFIG__SIGMA_THRESH_LO = 0x0F41,
985 | GPH__RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS = 0x0F42,
986 | GPH__RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS_HI = 0x0F42,
987 | GPH__RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS_LO = 0x0F43,
988 | GPH__RANGE_CONFIG__VALID_PHASE_LOW = 0x0F44,
989 | GPH__RANGE_CONFIG__VALID_PHASE_HIGH = 0x0F45,
990 | FIRMWARE__INTERNAL_STREAM_COUNT_DIV = 0x0F46,
991 | FIRMWARE__INTERNAL_STREAM_COUNTER_VAL = 0x0F47,
992 | DSS_CALC__ROI_CTRL = 0x0F54,
993 | DSS_CALC__SPARE_1 = 0x0F55,
994 | DSS_CALC__SPARE_2 = 0x0F56,
995 | DSS_CALC__SPARE_3 = 0x0F57,
996 | DSS_CALC__SPARE_4 = 0x0F58,
997 | DSS_CALC__SPARE_5 = 0x0F59,
998 | DSS_CALC__SPARE_6 = 0x0F5A,
999 | DSS_CALC__SPARE_7 = 0x0F5B,
1000 | DSS_CALC__USER_ROI_SPAD_EN_0 = 0x0F5C,
1001 | DSS_CALC__USER_ROI_SPAD_EN_1 = 0x0F5D,
1002 | DSS_CALC__USER_ROI_SPAD_EN_2 = 0x0F5E,
1003 | DSS_CALC__USER_ROI_SPAD_EN_3 = 0x0F5F,
1004 | DSS_CALC__USER_ROI_SPAD_EN_4 = 0x0F60,
1005 | DSS_CALC__USER_ROI_SPAD_EN_5 = 0x0F61,
1006 | DSS_CALC__USER_ROI_SPAD_EN_6 = 0x0F62,
1007 | DSS_CALC__USER_ROI_SPAD_EN_7 = 0x0F63,
1008 | DSS_CALC__USER_ROI_SPAD_EN_8 = 0x0F64,
1009 | DSS_CALC__USER_ROI_SPAD_EN_9 = 0x0F65,
1010 | DSS_CALC__USER_ROI_SPAD_EN_10 = 0x0F66,
1011 | DSS_CALC__USER_ROI_SPAD_EN_11 = 0x0F67,
1012 | DSS_CALC__USER_ROI_SPAD_EN_12 = 0x0F68,
1013 | DSS_CALC__USER_ROI_SPAD_EN_13 = 0x0F69,
1014 | DSS_CALC__USER_ROI_SPAD_EN_14 = 0x0F6A,
1015 | DSS_CALC__USER_ROI_SPAD_EN_15 = 0x0F6B,
1016 | DSS_CALC__USER_ROI_SPAD_EN_16 = 0x0F6C,
1017 | DSS_CALC__USER_ROI_SPAD_EN_17 = 0x0F6D,
1018 | DSS_CALC__USER_ROI_SPAD_EN_18 = 0x0F6E,
1019 | DSS_CALC__USER_ROI_SPAD_EN_19 = 0x0F6F,
1020 | DSS_CALC__USER_ROI_SPAD_EN_20 = 0x0F70,
1021 | DSS_CALC__USER_ROI_SPAD_EN_21 = 0x0F71,
1022 | DSS_CALC__USER_ROI_SPAD_EN_22 = 0x0F72,
1023 | DSS_CALC__USER_ROI_SPAD_EN_23 = 0x0F73,
1024 | DSS_CALC__USER_ROI_SPAD_EN_24 = 0x0F74,
1025 | DSS_CALC__USER_ROI_SPAD_EN_25 = 0x0F75,
1026 | DSS_CALC__USER_ROI_SPAD_EN_26 = 0x0F76,
1027 | DSS_CALC__USER_ROI_SPAD_EN_27 = 0x0F77,
1028 | DSS_CALC__USER_ROI_SPAD_EN_28 = 0x0F78,
1029 | DSS_CALC__USER_ROI_SPAD_EN_29 = 0x0F79,
1030 | DSS_CALC__USER_ROI_SPAD_EN_30 = 0x0F7A,
1031 | DSS_CALC__USER_ROI_SPAD_EN_31 = 0x0F7B,
1032 | DSS_CALC__USER_ROI_0 = 0x0F7C,
1033 | DSS_CALC__USER_ROI_1 = 0x0F7D,
1034 | DSS_CALC__MODE_ROI_0 = 0x0F7E,
1035 | DSS_CALC__MODE_ROI_1 = 0x0F7F,
1036 | SIGMA_ESTIMATOR_CALC__SPARE_0 = 0x0F80,
1037 | VHV_RESULT__PEAK_SIGNAL_RATE_MCPS = 0x0F82,
1038 | VHV_RESULT__PEAK_SIGNAL_RATE_MCPS_HI = 0x0F82,
1039 | VHV_RESULT__PEAK_SIGNAL_RATE_MCPS_LO = 0x0F83,
1040 | VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF = 0x0F84,
1041 | VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF_3 = 0x0F84,
1042 | VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF_2 = 0x0F85,
1043 | VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF_1 = 0x0F86,
1044 | VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF_0 = 0x0F87,
1045 | PHASECAL_RESULT__PHASE_OUTPUT_REF = 0x0F88,
1046 | PHASECAL_RESULT__PHASE_OUTPUT_REF_HI = 0x0F88,
1047 | PHASECAL_RESULT__PHASE_OUTPUT_REF_LO = 0x0F89,
1048 | DSS_RESULT__TOTAL_RATE_PER_SPAD = 0x0F8A,
1049 | DSS_RESULT__TOTAL_RATE_PER_SPAD_HI = 0x0F8A,
1050 | DSS_RESULT__TOTAL_RATE_PER_SPAD_LO = 0x0F8B,
1051 | DSS_RESULT__ENABLED_BLOCKS = 0x0F8C,
1052 | DSS_RESULT__NUM_REQUESTED_SPADS = 0x0F8E,
1053 | DSS_RESULT__NUM_REQUESTED_SPADS_HI = 0x0F8E,
1054 | DSS_RESULT__NUM_REQUESTED_SPADS_LO = 0x0F8F,
1055 | MM_RESULT__INNER_INTERSECTION_RATE = 0x0F92,
1056 | MM_RESULT__INNER_INTERSECTION_RATE_HI = 0x0F92,
1057 | MM_RESULT__INNER_INTERSECTION_RATE_LO = 0x0F93,
1058 | MM_RESULT__OUTER_COMPLEMENT_RATE = 0x0F94,
1059 | MM_RESULT__OUTER_COMPLEMENT_RATE_HI = 0x0F94,
1060 | MM_RESULT__OUTER_COMPLEMENT_RATE_LO = 0x0F95,
1061 | MM_RESULT__TOTAL_OFFSET = 0x0F96,
1062 | MM_RESULT__TOTAL_OFFSET_HI = 0x0F96,
1063 | MM_RESULT__TOTAL_OFFSET_LO = 0x0F97,
1064 | XTALK_CALC__XTALK_FOR_ENABLED_SPADS = 0x0F98,
1065 | XTALK_CALC__XTALK_FOR_ENABLED_SPADS_3 = 0x0F98,
1066 | XTALK_CALC__XTALK_FOR_ENABLED_SPADS_2 = 0x0F99,
1067 | XTALK_CALC__XTALK_FOR_ENABLED_SPADS_1 = 0x0F9A,
1068 | XTALK_CALC__XTALK_FOR_ENABLED_SPADS_0 = 0x0F9B,
1069 | XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS = 0x0F9C,
1070 | XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS_3 = 0x0F9C,
1071 | XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS_2 = 0x0F9D,
1072 | XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS_1 = 0x0F9E,
1073 | XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS_0 = 0x0F9F,
1074 | XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS = 0x0FA0,
1075 | XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS_3 = 0x0FA0,
1076 | XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS_2 = 0x0FA1,
1077 | XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS_1 = 0x0FA2,
1078 | XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS_0 = 0x0FA3,
1079 | XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS = 0x0FA4,
1080 | XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS_3 = 0x0FA4,
1081 | XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS_2 = 0x0FA5,
1082 | XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS_1 = 0x0FA6,
1083 | XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS_0 = 0x0FA7,
1084 | RANGE_RESULT__ACCUM_PHASE = 0x0FA8,
1085 | RANGE_RESULT__ACCUM_PHASE_3 = 0x0FA8,
1086 | RANGE_RESULT__ACCUM_PHASE_2 = 0x0FA9,
1087 | RANGE_RESULT__ACCUM_PHASE_1 = 0x0FAA,
1088 | RANGE_RESULT__ACCUM_PHASE_0 = 0x0FAB,
1089 | RANGE_RESULT__OFFSET_CORRECTED_RANGE = 0x0FAC,
1090 | RANGE_RESULT__OFFSET_CORRECTED_RANGE_HI = 0x0FAC,
1091 | RANGE_RESULT__OFFSET_CORRECTED_RANGE_LO = 0x0FAD,
1092 | SHADOW_PHASECAL_RESULT__VCSEL_START = 0x0FAE,
1093 | SHADOW_RESULT__INTERRUPT_STATUS = 0x0FB0,
1094 | SHADOW_RESULT__RANGE_STATUS = 0x0FB1,
1095 | SHADOW_RESULT__REPORT_STATUS = 0x0FB2,
1096 | SHADOW_RESULT__STREAM_COUNT = 0x0FB3,
1097 | SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x0FB4,
1098 | SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x0FB4,
1099 | SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x0FB5,
1100 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0 = 0x0FB6,
1101 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_HI = 0x0FB6,
1102 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_LO = 0x0FB7,
1103 | SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0 = 0x0FB8,
1104 | SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_HI = 0x0FB8,
1105 | SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_LO = 0x0FB9,
1106 | SHADOW_RESULT__SIGMA_SD0 = 0x0FBA,
1107 | SHADOW_RESULT__SIGMA_SD0_HI = 0x0FBA,
1108 | SHADOW_RESULT__SIGMA_SD0_LO = 0x0FBB,
1109 | SHADOW_RESULT__PHASE_SD0 = 0x0FBC,
1110 | SHADOW_RESULT__PHASE_SD0_HI = 0x0FBC,
1111 | SHADOW_RESULT__PHASE_SD0_LO = 0x0FBD,
1112 | SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 = 0x0FBE,
1113 | SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_HI = 0x0FBE,
1114 | SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_LO = 0x0FBF,
1115 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 = 0x0FC0,
1116 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_HI = 0x0FC0,
1117 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO = 0x0FC1,
1118 | SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x0FC2,
1119 | SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x0FC2,
1120 | SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x0FC3,
1121 | SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0 = 0x0FC4,
1122 | SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x0FC4,
1123 | SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x0FC5,
1124 | SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0 = 0x0FC6,
1125 | SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_HI = 0x0FC6,
1126 | SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_LO = 0x0FC7,
1127 | SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1 = 0x0FC8,
1128 | SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_HI = 0x0FC8,
1129 | SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_LO = 0x0FC9,
1130 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1 = 0x0FCA,
1131 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_HI = 0x0FCA,
1132 | SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_LO = 0x0FCB,
1133 | SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1 = 0x0FCC,
1134 | SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_HI = 0x0FCC,
1135 | SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_LO = 0x0FCD,
1136 | SHADOW_RESULT__SIGMA_SD1 = 0x0FCE,
1137 | SHADOW_RESULT__SIGMA_SD1_HI = 0x0FCE,
1138 | SHADOW_RESULT__SIGMA_SD1_LO = 0x0FCF,
1139 | SHADOW_RESULT__PHASE_SD1 = 0x0FD0,
1140 | SHADOW_RESULT__PHASE_SD1_HI = 0x0FD0,
1141 | SHADOW_RESULT__PHASE_SD1_LO = 0x0FD1,
1142 | SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1 = 0x0FD2,
1143 | SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_HI = 0x0FD2,
1144 | SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_LO = 0x0FD3,
1145 | SHADOW_RESULT__SPARE_0_SD1 = 0x0FD4,
1146 | SHADOW_RESULT__SPARE_0_SD1_HI = 0x0FD4,
1147 | SHADOW_RESULT__SPARE_0_SD1_LO = 0x0FD5,
1148 | SHADOW_RESULT__SPARE_1_SD1 = 0x0FD6,
1149 | SHADOW_RESULT__SPARE_1_SD1_HI = 0x0FD6,
1150 | SHADOW_RESULT__SPARE_1_SD1_LO = 0x0FD7,
1151 | SHADOW_RESULT__SPARE_2_SD1 = 0x0FD8,
1152 | SHADOW_RESULT__SPARE_2_SD1_HI = 0x0FD8,
1153 | SHADOW_RESULT__SPARE_2_SD1_LO = 0x0FD9,
1154 | SHADOW_RESULT__SPARE_3_SD1 = 0x0FDA,
1155 | SHADOW_RESULT__THRESH_INFO = 0x0FDB,
1156 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 = 0x0FDC,
1157 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_3 = 0x0FDC,
1158 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_2 = 0x0FDD,
1159 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_1 = 0x0FDE,
1160 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_0 = 0x0FDF,
1161 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0 = 0x0FE0,
1162 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_3 = 0x0FE0,
1163 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_2 = 0x0FE1,
1164 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_1 = 0x0FE2,
1165 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_0 = 0x0FE3,
1166 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0 = 0x0FE4,
1167 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_3 = 0x0FE4,
1168 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_2 = 0x0FE5,
1169 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_1 = 0x0FE6,
1170 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_0 = 0x0FE7,
1171 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0 = 0x0FE8,
1172 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_3 = 0x0FE8,
1173 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_2 = 0x0FE9,
1174 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_1 = 0x0FEA,
1175 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_0 = 0x0FEB,
1176 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1 = 0x0FEC,
1177 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_3 = 0x0FEC,
1178 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_2 = 0x0FED,
1179 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_1 = 0x0FEE,
1180 | SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_0 = 0x0FEF,
1181 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1 = 0x0FF0,
1182 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_3 = 0x0FF0,
1183 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_2 = 0x0FF1,
1184 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_1 = 0x0FF2,
1185 | SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_0 = 0x0FF3,
1186 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1 = 0x0FF4,
1187 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_3 = 0x0FF4,
1188 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_2 = 0x0FF5,
1189 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_1 = 0x0FF6,
1190 | SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_0 = 0x0FF7,
1191 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1 = 0x0FF8,
1192 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_3 = 0x0FF8,
1193 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_2 = 0x0FF9,
1194 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_1 = 0x0FFA,
1195 | SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_0 = 0x0FFB,
1196 | SHADOW_RESULT_CORE__SPARE_0 = 0x0FFC,
1197 | SHADOW_PHASECAL_RESULT__REFERENCE_PHASE_HI = 0x0FFE,
1198 | SHADOW_PHASECAL_RESULT__REFERENCE_PHASE_LO = 0x0FFF,
1199 | };
1200 |
1201 | enum DistanceMode { Short, Medium, Long, Unknown };
1202 |
1203 | enum RangeStatus : uint8_t
1204 | {
1205 | RangeValid = 0,
1206 |
1207 | // "sigma estimator check is above the internal defined threshold"
1208 | // (sigma = standard deviation of measurement)
1209 | SigmaFail = 1,
1210 |
1211 | // "signal value is below the internal defined threshold"
1212 | SignalFail = 2,
1213 |
1214 | // "Target is below minimum detection threshold."
1215 | RangeValidMinRangeClipped = 3,
1216 |
1217 | // "phase is out of bounds"
1218 | // (nothing detected in range; try a longer distance mode if applicable)
1219 | OutOfBoundsFail = 4,
1220 |
1221 | // "HW or VCSEL failure"
1222 | HardwareFail = 5,
1223 |
1224 | // "The Range is valid but the wraparound check has not been done."
1225 | RangeValidNoWrapCheckFail = 6,
1226 |
1227 | // "Wrapped target, not matching phases"
1228 | // "no matching phase in other VCSEL period timing."
1229 | WrapTargetFail = 7,
1230 |
1231 | // "Internal algo underflow or overflow in lite ranging."
1232 | // ProcessingFail = 8: not used in API
1233 |
1234 | // "Specific to lite ranging."
1235 | // should never occur with this lib (which uses low power auto ranging,
1236 | // as the API does)
1237 | XtalkSignalFail = 9,
1238 |
1239 | // "1st interrupt when starting ranging in back to back mode. Ignore
1240 | // data."
1241 | // should never occur with this lib
1242 | SynchronizationInt = 10, // (the API spells this "syncronisation")
1243 |
1244 | // "All Range ok but object is result of multiple pulses merging together.
1245 | // Used by RQL for merged pulse detection"
1246 | // RangeValid MergedPulse = 11: not used in API
1247 |
1248 | // "Used by RQL as different to phase fail."
1249 | // TargetPresentLackOfSignal = 12:
1250 |
1251 | // "Target is below minimum detection threshold."
1252 | MinRangeFail = 13,
1253 |
1254 | // "The reported range is invalid"
1255 | // RangeInvalid = 14: can't actually be returned by API (range can never become negative, even after correction)
1256 |
1257 | // "No Update."
1258 | None = 255,
1259 | };
1260 |
1261 | struct RangingData
1262 | {
1263 | uint16_t range_mm;
1264 | RangeStatus range_status;
1265 | float peak_signal_count_rate_MCPS;
1266 | float ambient_count_rate_MCPS;
1267 | };
1268 |
1269 | RangingData ranging_data;
1270 |
1271 | uint8_t last_status; // status of last I2C transmission
1272 |
1273 | VL53L1X();
1274 |
1275 | void setBus(TwoWire * bus) { this->bus = bus; }
1276 | TwoWire * getBus() { return bus; }
1277 |
1278 | void setAddress(uint8_t new_addr);
1279 | uint8_t getAddress() { return address; }
1280 |
1281 | bool init(bool io_2v8 = true);
1282 |
1283 | void writeReg(uint16_t reg, uint8_t value);
1284 | void writeReg16Bit(uint16_t reg, uint16_t value);
1285 | void writeReg32Bit(uint16_t reg, uint32_t value);
1286 | uint8_t readReg(regAddr reg);
1287 | uint16_t readReg16Bit(uint16_t reg);
1288 | uint32_t readReg32Bit(uint16_t reg);
1289 |
1290 | bool setDistanceMode(DistanceMode mode);
1291 | DistanceMode getDistanceMode() { return distance_mode; }
1292 |
1293 | bool setMeasurementTimingBudget(uint32_t budget_us);
1294 | uint32_t getMeasurementTimingBudget();
1295 |
1296 | void setROISize(uint8_t width, uint8_t height);
1297 | void getROISize(uint8_t * width, uint8_t * height);
1298 | void setROICenter(uint8_t spadNum);
1299 | uint8_t getROICenter();
1300 |
1301 | void startContinuous(uint32_t period_ms);
1302 | void stopContinuous();
1303 | uint16_t read(bool blocking = true);
1304 | uint16_t readRangeContinuousMillimeters(bool blocking = true) { return read(blocking); } // alias of read()
1305 | uint16_t readSingle(bool blocking = true);
1306 | uint16_t readRangeSingleMillimeters(bool blocking = true) { return readSingle(blocking); } // alias of readSingle()
1307 |
1308 | // check if sensor has new reading available
1309 | // assumes interrupt is active low (GPIO_HV_MUX__CTRL bit 4 is 1)
1310 | bool dataReady() { return (readReg(GPIO__TIO_HV_STATUS) & 0x01) == 0; }
1311 |
1312 | static const char * rangeStatusToString(RangeStatus status);
1313 |
1314 | void setTimeout(uint16_t timeout) { io_timeout = timeout; }
1315 | uint16_t getTimeout() { return io_timeout; }
1316 | bool timeoutOccurred();
1317 |
1318 | private:
1319 |
1320 | // The Arduino two-wire interface uses a 7-bit number for the address,
1321 | // and sets the last bit correctly based on reads and writes
1322 | static const uint8_t AddressDefault = 0b0101001;
1323 |
1324 | // value used in measurement timing budget calculations
1325 | // assumes PresetMode is LOWPOWER_AUTONOMOUS
1326 | //
1327 | // vhv = LOWPOWER_AUTO_VHV_LOOP_DURATION_US + LOWPOWERAUTO_VHV_LOOP_BOUND
1328 | // (tuning parm default) * LOWPOWER_AUTO_VHV_LOOP_DURATION_US
1329 | // = 245 + 3 * 245 = 980
1330 | // TimingGuard = LOWPOWER_AUTO_OVERHEAD_BEFORE_A_RANGING +
1331 | // LOWPOWER_AUTO_OVERHEAD_BETWEEN_A_B_RANGING + vhv
1332 | // = 1448 + 2100 + 980 = 4528
1333 | static const uint32_t TimingGuard = 4528;
1334 |
1335 | // value in DSS_CONFIG__TARGET_TOTAL_RATE_MCPS register, used in DSS
1336 | // calculations
1337 | static const uint16_t TargetRate = 0x0A00;
1338 |
1339 | // for storing values read from RESULT__RANGE_STATUS (0x0089)
1340 | // through RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LOW
1341 | // (0x0099)
1342 | struct ResultBuffer
1343 | {
1344 | uint8_t range_status;
1345 | // uint8_t report_status: not used
1346 | uint8_t stream_count;
1347 | uint16_t dss_actual_effective_spads_sd0;
1348 | // uint16_t peak_signal_count_rate_mcps_sd0: not used
1349 | uint16_t ambient_count_rate_mcps_sd0;
1350 | // uint16_t sigma_sd0: not used
1351 | // uint16_t phase_sd0: not used
1352 | uint16_t final_crosstalk_corrected_range_mm_sd0;
1353 | uint16_t peak_signal_count_rate_crosstalk_corrected_mcps_sd0;
1354 | };
1355 |
1356 | // making this static would save RAM for multiple instances as long as there
1357 | // aren't multiple sensors being read at the same time (e.g. on separate
1358 | // I2C buses)
1359 | ResultBuffer results;
1360 |
1361 | TwoWire * bus;
1362 |
1363 | uint8_t address;
1364 |
1365 | uint16_t io_timeout;
1366 | bool did_timeout;
1367 | uint16_t timeout_start_ms;
1368 |
1369 | uint16_t fast_osc_frequency;
1370 | uint16_t osc_calibrate_val;
1371 |
1372 | bool calibrated;
1373 | uint8_t saved_vhv_init;
1374 | uint8_t saved_vhv_timeout;
1375 |
1376 | DistanceMode distance_mode;
1377 |
1378 | // Record the current time to check an upcoming timeout against
1379 | void startTimeout() { timeout_start_ms = millis(); }
1380 |
1381 | // Check if timeout is enabled (set to nonzero value) and has expired
1382 | bool checkTimeoutExpired() {return (io_timeout > 0) && ((uint16_t)(millis() - timeout_start_ms) > io_timeout); }
1383 |
1384 | void setupManualCalibration();
1385 | void readResults();
1386 | void updateDSS();
1387 | void getRangingData();
1388 |
1389 | static uint32_t decodeTimeout(uint16_t reg_val);
1390 | static uint16_t encodeTimeout(uint32_t timeout_mclks);
1391 | static uint32_t timeoutMclksToMicroseconds(uint32_t timeout_mclks, uint32_t macro_period_us);
1392 | static uint32_t timeoutMicrosecondsToMclks(uint32_t timeout_us, uint32_t macro_period_us);
1393 | uint32_t calcMacroPeriod(uint8_t vcsel_period);
1394 |
1395 | // Convert count rate from fixed point 9.7 format to float
1396 | float countRateFixedToFloat(uint16_t count_rate_fixed) { return (float)count_rate_fixed / (1 << 7); }
1397 | };
1398 |
--------------------------------------------------------------------------------
/examples/Continuous/Continuous.ino:
--------------------------------------------------------------------------------
1 | /*
2 | This example shows how to take simple range measurements with the VL53L1X. The
3 | range readings are in units of mm.
4 | */
5 |
6 | #include
7 | #include
8 |
9 | VL53L1X sensor;
10 |
11 | void setup()
12 | {
13 | while (!Serial) {}
14 | Serial.begin(115200);
15 | Wire.begin();
16 | Wire.setClock(400000); // use 400 kHz I2C
17 |
18 | sensor.setTimeout(500);
19 | if (!sensor.init())
20 | {
21 | Serial.println("Failed to detect and initialize sensor!");
22 | while (1);
23 | }
24 |
25 | // Use long distance mode and allow up to 50000 us (50 ms) for a measurement.
26 | // You can change these settings to adjust the performance of the sensor, but
27 | // the minimum timing budget is 20 ms for short distance mode and 33 ms for
28 | // medium and long distance modes. See the VL53L1X datasheet for more
29 | // information on range and timing limits.
30 | sensor.setDistanceMode(VL53L1X::Long);
31 | sensor.setMeasurementTimingBudget(50000);
32 |
33 | // Start continuous readings at a rate of one measurement every 50 ms (the
34 | // inter-measurement period). This period should be at least as long as the
35 | // timing budget.
36 | sensor.startContinuous(50);
37 | }
38 |
39 | void loop()
40 | {
41 | Serial.print(sensor.read());
42 | if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
43 |
44 | Serial.println();
45 | }
46 |
--------------------------------------------------------------------------------
/examples/ContinuousMultipleSensors/ContinuousMultipleSensors.ino:
--------------------------------------------------------------------------------
1 | /*
2 | This example shows how to set up and read multiple VL53L1X sensors connected to
3 | the same I2C bus. Each sensor needs to have its XSHUT pin connected to a
4 | different Arduino pin, and you should change sensorCount and the xshutPins array
5 | below to match your setup.
6 |
7 | For more information, see ST's application note AN4846 ("Using multiple VL53L0X
8 | in a single design"). The principles described there apply to the VL53L1X as
9 | well.
10 | */
11 |
12 | #include
13 | #include
14 |
15 | // The number of sensors in your system.
16 | const uint8_t sensorCount = 3;
17 |
18 | // The Arduino pin connected to the XSHUT pin of each sensor.
19 | const uint8_t xshutPins[sensorCount] = { 4, 5, 6 };
20 |
21 | VL53L1X sensors[sensorCount];
22 |
23 | void setup()
24 | {
25 | while (!Serial) {}
26 | Serial.begin(115200);
27 | Wire.begin();
28 | Wire.setClock(400000); // use 400 kHz I2C
29 |
30 | // Disable/reset all sensors by driving their XSHUT pins low.
31 | for (uint8_t i = 0; i < sensorCount; i++)
32 | {
33 | pinMode(xshutPins[i], OUTPUT);
34 | digitalWrite(xshutPins[i], LOW);
35 | }
36 |
37 | // Enable, initialize, and start each sensor, one by one.
38 | for (uint8_t i = 0; i < sensorCount; i++)
39 | {
40 | // Stop driving this sensor's XSHUT low. This should allow the carrier
41 | // board to pull it high. (We do NOT want to drive XSHUT high since it is
42 | // not level shifted.) Then wait a bit for the sensor to start up.
43 | pinMode(xshutPins[i], INPUT);
44 | delay(10);
45 |
46 | sensors[i].setTimeout(500);
47 | if (!sensors[i].init())
48 | {
49 | Serial.print("Failed to detect and initialize sensor ");
50 | Serial.println(i);
51 | while (1);
52 | }
53 |
54 | // Each sensor must have its address changed to a unique value other than
55 | // the default of 0x29 (except for the last one, which could be left at
56 | // the default). To make it simple, we'll just count up from 0x2A.
57 | sensors[i].setAddress(0x2A + i);
58 |
59 | sensors[i].startContinuous(50);
60 | }
61 | }
62 |
63 | void loop()
64 | {
65 | for (uint8_t i = 0; i < sensorCount; i++)
66 | {
67 | Serial.print(sensors[i].read());
68 | if (sensors[i].timeoutOccurred()) { Serial.print(" TIMEOUT"); }
69 | Serial.print('\t');
70 | }
71 | Serial.println();
72 | }
73 |
--------------------------------------------------------------------------------
/examples/ContinuousWithDetails/ContinuousWithDetails.ino:
--------------------------------------------------------------------------------
1 | /*
2 | This example takes range measurements with the VL53L1X and displays additional
3 | details (status and signal/ambient rates) for each measurement, which can help
4 | you determine whether the sensor is operating normally and the reported range is
5 | valid. The range is in units of mm, and the rates are in units of MCPS (mega
6 | counts per second).
7 | */
8 |
9 | #include
10 | #include
11 |
12 | VL53L1X sensor;
13 |
14 | void setup()
15 | {
16 | while (!Serial) {}
17 | Serial.begin(115200);
18 | Wire.begin();
19 | Wire.setClock(400000); // use 400 kHz I2C
20 |
21 | sensor.setTimeout(500);
22 | if (!sensor.init())
23 | {
24 | Serial.println("Failed to detect and initialize sensor!");
25 | while (1);
26 | }
27 |
28 | // Use long distance mode and allow up to 50000 us (50 ms) for a measurement.
29 | // You can change these settings to adjust the performance of the sensor, but
30 | // the minimum timing budget is 20 ms for short distance mode and 33 ms for
31 | // medium and long distance modes. See the VL53L1X datasheet for more
32 | // information on range and timing limits.
33 | sensor.setDistanceMode(VL53L1X::Long);
34 | sensor.setMeasurementTimingBudget(50000);
35 |
36 | // Start continuous readings at a rate of one measurement every 50 ms (the
37 | // inter-measurement period). This period should be at least as long as the
38 | // timing budget.
39 | sensor.startContinuous(50);
40 | }
41 |
42 | void loop()
43 | {
44 | sensor.read();
45 |
46 | Serial.print("range: ");
47 | Serial.print(sensor.ranging_data.range_mm);
48 | Serial.print("\tstatus: ");
49 | Serial.print(VL53L1X::rangeStatusToString(sensor.ranging_data.range_status));
50 | Serial.print("\tpeak signal: ");
51 | Serial.print(sensor.ranging_data.peak_signal_count_rate_MCPS);
52 | Serial.print("\tambient: ");
53 | Serial.print(sensor.ranging_data.ambient_count_rate_MCPS);
54 |
55 | Serial.println();
56 | }
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | VL53L1X KEYWORD1
2 |
3 | setBus KEYWORD2
4 | getBus KEYWORD2
5 | setAddress KEYWORD2
6 | getAddress KEYWORD2
7 | init KEYWORD2
8 | writeReg KEYWORD2
9 | writeReg16Bit KEYWORD2
10 | writeReg32Bit KEYWORD2
11 | readReg KEYWORD2
12 | readReg16Bit KEYWORD2
13 | readReg32Bit KEYWORD2
14 | setDistanceMode KEYWORD2
15 | getDistanceMode KEYWORD2
16 | setMeasurementTimingBudget KEYWORD2
17 | getMeasurementTimingBudget KEYWORD2
18 | setROISize KEYWORD2
19 | getROISize KEYWORD2
20 | setROICenter KEYWORD2
21 | getROICenter KEYWORD2
22 | startContinuous KEYWORD2
23 | stopContinuous KEYWORD2
24 | read KEYWORD2
25 | readRangeContinuousMillimeters KEYWORD2
26 | rangeStatusToString KEYWORD2
27 | setTimeout KEYWORD2
28 | getTimeout KEYWORD2
29 | timeoutOccurred KEYWORD2
30 |
31 | Short LITERAL1
32 | Medium LITERAL1
33 | Long LITERAL1
34 | Unknown LITERAL1
35 |
36 | RangeValid LITERAL1
37 | SigmaFail LITERAL1
38 | SignalFail LITERAL1
39 | RangeValidMinRangeClipped LITERAL1
40 | OutOfBoundsFail LITERAL1
41 | HardwareFail LITERAL1
42 | RangeValidNoWrapCheckFail LITERAL1
43 | WrapTargetFail LITERAL1
44 | XtalkSignalFail LITERAL1
45 | SyncronisationInt LITERAL1
46 | MinRangeFail LITERAL1
47 | None LITERAL1
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=VL53L1X
2 | version=1.3.1
3 | author=Pololu
4 | maintainer=Pololu
5 | sentence=VL53L1X distance sensor library
6 | paragraph=This is a library for the Arduino IDE that helps interface with ST's VL53L1X distance sensor.
7 | category=Sensors
8 | url=https://github.com/pololu/vl53l1x-arduino
9 | architectures=*
10 |
--------------------------------------------------------------------------------